--- /dev/null
+2007-03-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * AT91SAM7 CAN driver package created
+ * cdl/can_at91sam7.cdl
+ * include/can_at91sam7.inl
+ * src/can_at91sam7.c
+
+//===========================================================================
+//####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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# can_at91sam7.cdl
+#
+# eCos AT91SAM7 CAN module configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2007-02-10
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_CAN_AT91SAM7 {
+ display "Atmel AT91SAM7 CAN device drivers"
+ parent CYGPKG_IO_CAN_DEVICES
+ active_if CYGPKG_IO_CAN
+ active_if CYGPKG_HAL_ARM_AT91SAM7
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the CAN device drivers for the
+ Atmel AT91SAM7."
+ compile -library=libextras.a can_at91sam7.c
+ define_proc {
+ puts $::cdl_system_header "/***** CAN driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_HEADER <pkgconf/devs_can_at91sam7.h>"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_INL <cyg/io/can_at91sam7.inl>"
+ puts $::cdl_system_header "/***** CAN driver proc output end *****/"
+ }
+
+ cdl_interface CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS {
+ display "AT91SAM7 CAN Channel"
+ flavor bool
+ description "
+ This interface is implemented for each single CAN channnel
+ of an AT91SAM7 chip and counts the number of available
+ channels."
+ }
+
+
+ # Support up one on-chip CAN module. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::sam7can 0 } { $::sam7can < 1 } { incr ::sam7can } {
+
+ cdl_interface CYGINT_DEVS_CAN_AT91SAM7_CAN[set ::sam7can] {
+ display "Platform provides CAN [set ::sam7can]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific AT91SAM7
+ processor being used has on-chip CAN [set ::sam7can], and if
+ that CAN module is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_DEVS_CAN_AT91SAM7_CAN[set ::sam7can] {
+ display "Allow access to the on-chip CAN [set ::sam7can] via a CAN driver"
+ flavor bool
+ active_if CYGINT_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]
+ default_value 1
+ implements CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS
+ implements CYGINT_IO_CAN_TIMESTAMP
+ implements CYGINT_IO_CAN_RUNTIME_MBOX_CFG
+ implements CYGINT_IO_CAN_REMOTE_BUF
+ implements CYGINT_IO_CAN_AUTOBAUD
+ description "
+ If the application needs to access the on-chip CAN module [set ::sam7can]
+ via an eCos CAN driver then this option should be enabled."
+
+ cdl_option CYGPKG_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_NAME {
+ display "Device name for CAN module [set ::sam7can]"
+ flavor data
+ default_value [format {"\"/dev/can%d\""} $::sam7can]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_KBAUD {
+ display "Default baud rate for CAN module [set ::sam7can]"
+ flavor data
+ default_value 100
+ legal_values { 10 20 50 100 125 250 500 800 1000 "AUTO"}
+ description "This option determines the initial baud rate in KBaud for
+ CAN module [set ::sam7can]"
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_QUEUESIZE_TX {
+ display "Size of TX Queue for the CAN module [set ::sam7can] driver"
+ flavor data
+ default_value 8
+ legal_values 1 to 64
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of outgoing data. This option controls the number
+ of CAN messages the TX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_QUEUESIZE_RX {
+ display "Size of RX Queue for the CAN module [set ::sam7can] driver"
+ flavor data
+ default_value 32
+ legal_values 8 to 128
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of incoming data. This option controls the number
+ of CAN events the RX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_ISR_PRIORITY {
+ display "Interrupt priority"
+ flavor data
+ default_value 4
+ legal_values 0 to 7
+ description "
+ Interrupt priority CAN module [set ::sam7can]. Each interrupt source
+ has a programmable priority level of 0 to 7. Level 7 is the
+ highest priority and level 0 the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_DEFAULT_TX_MBOX {
+ display "Default TX message box"
+ flavor data
+ calculated 7
+ description "
+ By default one message buffer will be used for message transmission.
+ This option selects one of the 8 CAN message buffers for
+ transmission."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_STD_MBOXES {
+ display "11 Bit standard ID msg. buffers"
+ flavor booldata
+ implements CYGINT_IO_CAN_STD_CAN_ID
+ default_value 3
+ legal_values 1 to 7
+ requires CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_STD_MBOXES + CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_EXT_MBOXES < 8
+ description "
+ The CAN module provides 8 message buffers. One message buffer
+ is reserved for message transmission. The remaining 7 buffers are
+ available for reception of messages. This configuration option
+ defines the number of message boxes for reception of CAN messages
+ with standard identifier. This configuration option does not matter
+ when you configure message filters at runtime. Only if the CAN
+ modul is configured to receive all available CAN identifiers,
+ then this configuration option is important. If you get
+ RX overrun events, you should raise the number of message boxes or
+ lower the CAN baud rate."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_EXT_MBOXES {
+ display "29 Bit extended ID msg. buffers"
+ flavor booldata
+ implements CYGINT_IO_CAN_EXT_CAN_ID
+ default_value 4
+ legal_values 1 to 7
+ requires CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_STD_MBOXES + CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_EXT_MBOXES < 8
+ description "
+ The CAN module provides 8 message buffers. One message buffer
+ is reserved for message transmission. The remaining 7 buffers are
+ available for reception of messages. This configuration option
+ defines the number of message boxes for reception of CAN messages
+ with extended identifier. This configuration option does not matter
+ when you configure message filters at runtime. Only if the FlexCAN
+ modul is configured to receive all available CAN identifiers,
+ then this configuration option is important. If you get
+ RX overrun events, you should raise the number of message boxes or
+ lower the CAN baud rate."
+ }
+ }
+ }
+
+ cdl_option CYGDBG_DEVS_CAN_AT91SAM7_DEBUG {
+ display "Support printing debug information"
+ default_value 0
+ description "
+ Check this box to turn ON debug options for AT91SAM7 CAN device driver."
+ }
+}
--- /dev/null
+#ifndef CYGONCE_CAN_AT91SAM7_H
+#define CYGONCE_CAN_AT91SAM7_H
+//==========================================================================
+//
+// devs/can/arm/at91sam7x/current/include/can_at91sam7.inl
+//
+// CAN message macros for Atmel AT91SAM7X CAN driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-02-08
+// Purpose: Support AT91SAM7X on-chip CAN moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDE
+//==========================================================================
+#include <pkgconf/devs_can_at91sam7.h>
+
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// We define our own CAN message data type here. This structure needs less
+// memory than the common CAN message defined by IO layer. This is important
+// because the AT91SAM7 contains only 64 KBytes RAM memory
+//
+typedef struct st_at91sam7_can_message
+{
+ cyg_can_msg_data data;// 8 data bytes
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_uint32 id; // also extended identifiers (29 Bit) are supported
+ cyg_uint8 ctrl;// control stores extended flag, rtr flag and dlc
+#else
+ //
+ // only standard identifiers are supported - we need only 11 bit of
+ // the data word to store the identifier. So we have 5 bit left to store
+ // the the rtr flag and the dlc flag. We do not need the IDE flag because
+ // only standard identifiers are supported
+ //
+ cyg_uint16 id;
+#endif
+} at91sam7_can_message;
+
+
+//--------------------------------------------------------------------------
+// We also define an own event structure here to store the received events
+// This event structure uses the device CAN message structure and
+// 16 Bit value for timestamps
+//
+typedef struct st_at91sam7_can_event
+{
+ cyg_uint16 flags;
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ cyg_uint16 timestamp;
+#endif
+ at91sam7_can_message msg;
+} at91sam7_can_event;
+
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+//
+// If we use extended identifier then we store the message parameters
+// into control word
+//
+#define AT91SAM7_CAN_SET_DLC(_msg_, _dlc_) ((_msg_).ctrl = (_dlc_)) // this also clears the ctrl
+#define AT91SAM7_CAN_SET_EXT(_msg_) ((_msg_).ctrl |= 0x01 << 4)
+#define AT91SAM7_CAN_SET_RTR(_msg_) ((_msg_).ctrl |= 0x01 << 5)
+
+#define AT91SAM7_CAN_GET_DLC(_msg_) ((_msg_).ctrl & 0x0F)
+#define AT91SAM7_CAN_IS_EXT(_msg_) ((((_msg_).ctrl >> 4) & 0x01) != 0)
+#define AT91SAM7_CAN_IS_RTR(_msg_) ((((_msg_).ctrl >> 5) & 0x01) != 0)
+#define AT91SAM7_CAN_GET_ID(_msg_) ((_msg_).id & CYG_CAN_EXT_ID_MASK)
+#else // CYGOPT_IO_CAN_EXT_CAN_ID
+//
+// We use only standard identifiers and we can store the message parameters
+// into the upper 5 bits of the 16 bit id field (only 11 bits are required for
+// standard frames
+//
+#define AT91SAM7_CAN_SET_DLC(_msg_, _dlc_) ((_msg_).id |= (_dlc_) << 11)
+#define AT91SAM7_CAN_SET_EXT(_msg_) // we do not need to support this flag - only std IDs supported
+#define AT91SAM7_CAN_SET_RTR(_msg_) ((_msg_).id |= 0x01 << 15)
+
+#define AT91SAM7_CAN_GET_DLC(_msg_) (((_msg_).id >> 11) & 0x0F)
+#define AT91SAM7_CAN_IS_EXT(_msg_) 0 // we do not support extended identifiers so this is always false
+#define AT91SAM7_CAN_IS_RTR(_msg_) ((((_msg_).id >> 15) & 0x01) != 0)
+#define AT91SAM7_CAN_GET_ID(_msg_) ((_msg_).id & CYG_CAN_STD_ID_MASK)
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+
+//---------------------------------------------------------------------------
+// The foolowing macros are required for CAN devicedriver. We define our own
+// CAN messaeg and event structures and therefore we also need to define the
+// two message conversion macros that translate out message/event into the
+// standard CAN message/event
+//
+#define CYG_CAN_MSG_T at91sam7_can_message
+#define CYG_CAN_EVENT_T at91sam7_can_event
+
+//
+// We need to copy the timestamp field only if timestamps are supported by
+// driver
+//
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+#define CYG_CAN_READ_TIMESTAMP(_ioevent_ptr_, _devevent_ptr_) ((_ioevent_ptr_)->timestamp = (_devevent_ptr_)->timestamp)
+#else
+#define CYG_CAN_READ_TIMESTAMP(_ioevent_ptr_, _devevent_ptr_)
+#endif
+
+
+#define CYG_CAN_WRITE_MSG(_devmsg_ptr_, _iomsg_ptr_) \
+CYG_MACRO_START \
+ (_devmsg_ptr_)->data = (_iomsg_ptr_)->data; \
+ (_devmsg_ptr_)->id = (_iomsg_ptr_)->id; \
+ AT91SAM7_CAN_SET_DLC(*(_devmsg_ptr_), (_iomsg_ptr_)->dlc); \
+ if (CYGNUM_CAN_ID_EXT == (_iomsg_ptr_)->ext) {AT91SAM7_CAN_SET_EXT(*(_devmsg_ptr_));} \
+ if (CYGNUM_CAN_FRAME_RTR == (_iomsg_ptr_)->rtr) {AT91SAM7_CAN_SET_RTR(*(_devmsg_ptr_));} \
+CYG_MACRO_END
+
+
+#define CYG_CAN_READ_EVENT(_ioevent_ptr_, _devevent_ptr_) \
+CYG_MACRO_START \
+ (_ioevent_ptr_)->flags = (_devevent_ptr_)->flags; \
+ (_ioevent_ptr_)->msg.data = (_devevent_ptr_)->msg.data; \
+ (_ioevent_ptr_)->msg.id = AT91SAM7_CAN_GET_ID((_devevent_ptr_)->msg); \
+ (_ioevent_ptr_)->msg.dlc = AT91SAM7_CAN_GET_DLC((_devevent_ptr_)->msg); \
+ if (AT91SAM7_CAN_IS_EXT((_devevent_ptr_)->msg)) { \
+ (_ioevent_ptr_)->msg.ext = CYGNUM_CAN_ID_EXT; } \
+ else { \
+ (_ioevent_ptr_)->msg.ext = CYGNUM_CAN_ID_STD; } \
+ if (AT91SAM7_CAN_IS_RTR((_devevent_ptr_)->msg)) { \
+ (_ioevent_ptr_)->msg.rtr = CYGNUM_CAN_FRAME_RTR; } \
+ else { \
+ (_ioevent_ptr_)->msg.rtr = CYGNUM_CAN_FRAME_DATA; } \
+ CYG_CAN_READ_TIMESTAMP(_ioevent_ptr_, _devevent_ptr_); \
+CYG_MACRO_END
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_CAN_AT91SAM7_H
--- /dev/null
+//==========================================================================
+//
+// devs/can/arm/at91sam7x/current/src/can_at91sam7x.c
+//
+// CAN driver for Atmel AT91SAM7X microcontrollers
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-01-06
+// Purpose: Support at91sam7 on-chip CAN moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/io_can.h>
+#include <pkgconf/io.h>
+#include <pkgconf/devs_can_at91sam7.h>
+
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/can.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_ass.h>
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+
+//
+// Support debug output if this option is enabled in CDL file
+//
+#ifdef CYGDBG_DEVS_CAN_AT91SAM7_DEBUG
+#define AT91SAM7_DBG_PRINT diag_printf
+#else
+#define AT91SAM7_DBG_PRINT( fmt, ... )
+#endif
+
+
+//
+// we define our own set of register bits in order to be independent from
+// platform specific names
+//
+
+//---------------------------------------------------------------------------
+// Mailbox bits
+//
+#define BIT_MB0 (0x01 << 0)
+#define BIT_MB1 (0x01 << 1)
+#define BIT_MB2 (0x01 << 2)
+#define BIT_MB3 (0x01 << 3)
+#define BIT_MB4 (0x01 << 4)
+#define BIT_MB5 (0x01 << 5)
+#define BIT_MB6 (0x01 << 6)
+#define BIT_MB7 (0x01 << 7)
+
+
+//---------------------------------------------------------------------------
+// CAN Mode Register bits (CAN_MR)
+//
+#define MR_CAN_ENABLE (0x01 << 0)
+#define MR_LOW_POWER (0x01 << 1)
+#define MR_AUTOBAUD (0x01 << 2)
+#define MR_OVERLOAD (0x01 << 3)
+#define MR_TIMESTAMP_EOF (0x01 << 4)
+#define MR_TIME_TRIG (0x01 << 5)
+#define MR_TIMER_FREEZE (0x01 << 6)
+#define MR_DISABLE_REPEAT (0x01 << 7)
+
+
+//---------------------------------------------------------------------------
+// CAN Interrupt Enable/Disable, Mask and Status Register bits (CAN_IER, CAN_IDR, CAN_IMR)
+//
+#define INT_ERR_ACTIVE (0x01 << 16)
+#define INT_WARN (0x01 << 17)
+#define INT_ERR_PASSIVE (0x01 << 18)
+#define INT_BUS_OFF (0x01 << 19)
+#define INT_SLEEP (0x01 << 20)
+#define INT_WAKEUP (0x01 << 21)
+#define INT_TMR_OVF (0x01 << 22)
+#define INT_TIMESTAMP (0x01 << 23)
+#define INT_CRC_ERR (0x01 << 24)
+#define INT_STUFF_ERR (0x01 << 25)
+#define INT_ACKN_ERR (0x01 << 26)
+#define INT_FORM_ERR (0x01 << 27)
+#define INT_BIT_ERR (0x01 << 28)
+#define INT_MB 0xFF // message box intterupt (mbox 1 - 8)
+#define INT_MB_RX 0x7F // rx message box interrupts
+#define INT_MB_TX 0x80 // tx message box interrupts
+
+//
+// We do not enable INT_WARN by default because this flug is buggy and causes interrupts
+// event if no counter reached warning level.
+//
+#define INT_ALL_ERR (INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR)
+#define INT_DEFAULT (INT_ERR_PASSIVE | INT_BUS_OFF | INT_SLEEP | INT_WAKEUP | INT_ALL_ERR)
+
+
+//
+// these bits are only in status register (CAN_SR)
+//
+#define SR_RX_BUSY (0x01 << 29)
+#define SR_TX_BUSY (0x01 << 30)
+#define SR_OVL_BUSY (0x01 << 31)
+
+
+//---------------------------------------------------------------------------
+// CAN Baudrate Register (CAN_BR)
+//
+#define BR_PHASE2_BITMASK 0x00000007
+#define BR_PHASE1_BITMASK 0x00000070
+#define BR_PROPAG_BITMASK 0x00000700
+#define BR_SJW_BITMASK 0x00003000
+#define BR_BRP_BITMASK 0x007F0000
+#define BR_SMP_BITMASK 0x01000000
+
+
+//---------------------------------------------------------------------------
+// CAN Error Counter Register (CAN_ECR)
+//
+#define ECR_GET_TEC(_ecr_) (((_ecr_) >> 16) & 0xFF)
+#define ECR_GET_REC(_ecr_) ((_ecr_) & 0xFF)
+
+
+//---------------------------------------------------------------------------
+// CAN Transfer Command Resgister (CAN_TCR)
+//
+#define TCR_TMR_RESET 0x80000000
+
+
+//---------------------------------------------------------------------------
+// CAN Message Mode Register (CAN_MMRx)
+//
+#define MMR_TIMEMARK_BITMASK 0x0000FFFF
+#define MMR_PRIOR_BITMASK 0x000F0000
+
+#define MMR_MB_SHIFTER 24
+#define MMR_MB_TYPE_BITMASK (0x07 << MMR_MB_SHIFTER) // mask the mot bits
+#define MMR_MB_TYPE_DISABLED (0x00 << MMR_MB_SHIFTER) // message box disabled
+#define MMR_MB_TYPE_RX (0x01 << MMR_MB_SHIFTER) // rx message box
+#define MMR_MB_TYPE_RX_OVW (0x02 << MMR_MB_SHIFTER) // rx message box with overwrite
+#define MMR_MB_TYPE_TX (0x03 << MMR_MB_SHIFTER) // tx message box
+#define MMR_MB_TYPE_CONSUME (0x04 << MMR_MB_SHIFTER) // consumer - receives RTR and sends its content
+#define MMR_MB_TYPE_PRODUCE (0x05 << MMR_MB_SHIFTER) // producer - sends a RTR and waits for answer
+#define MMR_MB_GET_TYPE(_mb_) ((_mb_) & MMR_MB_TYPE_BITMASK)
+
+//---------------------------------------------------------------------------
+// CAN Message Acceptance Mask/ID Register (CAN_MAMx, CAN_MIDx)
+//
+#define MID_MIDvB_BITMASK 0x0003FFFF
+#define MID_MIDvA_BITMASK 0x1FFC0000
+#define MID_MIDE 0x20000000
+#define MID_MIDvA_SHIFTER 18
+#define MID_SET_STD(_id_) (((_id_) << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK)
+#define MID_SET_EXT(_id_) ((_id_) | MID_MIDE)
+#define MAM_SET_STD ((((0x7FF << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK) | MID_MIDE))
+#define MAM_SET_EXT 0xFFFFFFFF
+#define MID_GET_STD(_mid_) (((_mid_) >> MID_MIDvA_SHIFTER) & CYG_CAN_STD_ID_MASK)
+#define MID_GET_EXT(_mid_) ((_mid_) & CYG_CAN_EXT_ID_MASK)
+
+
+//---------------------------------------------------------------------------
+// CAN Message Status Register (CAN_MSRx)
+//
+#define MSR_TIMESTAMP 0x0000FFFF
+#define MSR_DLC 0x000F0000
+#define MSR_RTR 0x00100000
+#define MSR_MSG_ABORT 0x00400000
+#define MSR_RDY 0x00800000
+#define MSR_MSG_IGNORED 0x01000000
+#define MSR_DLC_SHIFTER 16
+#define MSR_DLC_GET(_msr_) (((_msr_) >> 16) & 0x0F)
+
+//---------------------------------------------------------------------------
+// CAN Message Control Register (CAN_MCRx)
+//
+#define MCR_DLC 0x000F0000 // MDLC
+#define MCR_RTR 0x00100000 // MRTR
+#define MCR_MSG_ABORT 0x00400000 // MACR
+#define MCR_TRANSFER_CMD 0x00800000 // MTCR
+#define MCR_DLC_SHIFTER 16
+#define MCR_DLC_CREATE(_len_) ((_len_) << MCR_DLC_SHIFTER)
+
+//---------------------------------------------------------------------------
+// CAN Module Register Layout
+//
+#define CANREG_MR 0x0000
+#define CANREG_IER 0x0004
+#define CANREG_IDR 0x0008
+#define CANREG_IMR 0x000C
+#define CANREG_SR 0x0010
+#define CANREG_BR 0x0014
+#define CANREG_TIM 0x0018
+#define CANREG_TIMESTAMP 0x001C
+#define CANREG_ECR 0x0020
+#define CANREG_TCR 0x0024
+#define CANREG_ACR 0x0028
+
+#define CANREG_MB_BASE 0x0200
+
+//
+// Register layout of message box relativ to base register of a certain
+// message box
+//
+#define CANREG_MMR 0x0000
+#define CANREG_MAM 0x0004
+#define CANREG_MID 0x0008
+#define CANREG_MFID 0x000C
+#define CANREG_MSR 0x0010
+#define CANREG_MDL 0x0014
+#define CANREG_MDH 0x0018
+#define CANREG_MCR 0x001C
+
+
+#define AT91SAM7_CAN_PERIPHERAL_ID 15
+#define CAN_MBOX_MIN 0
+#define CAN_MBOX_MAX 7
+#define CAN_MBOX_CNT 8
+#define CAN_MBOX_RX_MIN 0
+#define CAN_MBOX_RX_MAX (CAN_MBOX_MAX - 1) // one message box is tx
+#define CAN_MBOX_RX_CNT (CAN_MBOX_CNT - 1) // one message box is tx
+
+#define CAN_MR(_extra_) (CAN_BASE(_extra_) + CANREG_MR)
+#define CAN_IER(_extra_) (CAN_BASE(_extra_) + CANREG_IER)
+#define CAN_IDR(_extra_) (CAN_BASE(_extra_) + CANREG_IDR)
+#define CAN_IMR(_etxra_) (CAN_BASE(_extra_) + CANREG_IMR)
+#define CAN_SR(_etxra_) (CAN_BASE(_extra_) + CANREG_SR)
+#define CAN_BR(_etxra_) (CAN_BASE(_extra_) + CANREG_BR)
+#define CAN_TIM(_etxra_) (CAN_BASE(_extra_) + CANREG_TIM)
+#define CAN_TIMESTAMP(_etxra_) (CAN_BASE(_extra_) + CANREG_TIMESTAMP)
+#define CAN_ECR(_etxra_) (CAN_BASE(_extra_) + CANREG_ECR)
+#define CAN_TCR(_etxra_) (CAN_BASE(_extra_) + CANREG_TCR)
+#define CAN_ACR(_etxra_) (CAN_BASE(_extra_) + CANREG_ACR)
+
+//
+// Message box registers
+//
+#define CAN_MB_BASE(_extra_) (CAN_BASE(_extra_) + CANREG_MB_BASE)
+#define CAN_MB_MMR(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MMR)
+#define CAN_MB_MAM(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MAM)
+#define CAN_MB_MID(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MID)
+#define CAN_MB_MFID(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MFID)
+#define CAN_MB_MSR(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MSR)
+#define CAN_MB_MDL(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MDL)
+#define CAN_MB_MDH(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MDH)
+#define CAN_MB_MCR(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MCR)
+
+
+//---------------------------------------------------------------------------
+// Optimize for the case of a single CAN channel, while still allowing
+// multiple channels. At the moment only AT91SAM7 controllers with one
+// CAN channel are known.
+//
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+#define CAN_PID(_extra_) AT91SAM7_CAN_PERIPHERAL_ID
+#define CAN_ISRVEC(_extra_) CAN_PID(_extra_)
+#define CAN_ISRPRIO(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_ISR_PRIORITY
+#define CAN_BASE(_extra_) AT91_CAN
+#define CAN_DECLARE_INFO(_chan_)
+#define CAN_MBOX_TX(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_DEFAULT_TX_MBOX
+#define CAN_MBOX_STD_CNT(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES
+#define CAN_MBOX_EXT_CNT(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES
+#define CAN_MBOX_RX_ALL_CNT(_extra) (CAN_MBOX_STD_CNT(_extra_) + CAN_MBOX_EXT_CNT(_extra_))
+
+#ifndef CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES
+#define CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES 0
+#endif
+
+#ifndef CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES
+#define CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES 0
+#endif
+
+#else // #if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+#define CAN_PID(_extra_) ((_extra_)->isrvec)
+#define CAN_ISRVEC(_extra_) ((_extra_)->isrvec)
+#define CAN_ISRPRIO(_extra_) ((_extra_)->isrprio)
+#define CAN_BASE(_extra_) ((_extra_)->base)
+#define CAN_DECLARE_INFO(_chan_) at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+#define CAN_MBOX_TX(_extra_) 7 // normally it is always the last mailbox
+#define CAN_MBOX_STD_CNT(_extra_) ((_extra_)->mboxes_std_cnt)
+#define CAN_MBOX_EXT_CNT(_extra_) ((_extra_)->mboxes_ext_cnt)
+#define CAN_MBOX_RX_ALL_CNT(_extra) ((_extra_)->mboxes_rx_all_cnt)
+
+#endif // #if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct at91sam7_can_info_t
+{
+ cyg_interrupt interrupt;
+ cyg_handle_t interrupt_handle;
+ cyg_uint32 stat; // buffers status register value between ISR and DSR
+ cyg_uint8 free_mboxes; // number of free message boxes for msg filters and rtr buffers
+ bool rx_all; // true if reception of call can messages is active
+ cyg_can_state state; // state of CAN controller
+
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+ cyg_uint32 base; // Per-bus h/w details
+ cyg_uint8 isrpri; // ISR priority
+ cyg_uint8 isrvec; // ISR vector (peripheral id)
+ cyg_uint8 mboxes_std_cnt; // contains number of standard message boxes available
+ cyg_uint8 mboxes_ext_cnt; // number of message boxes with ext id
+ cyg_uint8 mboxes_rx_all_cnt;// number of all available mboxes
+#endif
+} at91sam7_can_info_t;
+
+
+//
+// at91sam7 info initialisation
+//
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+#define AT91SAM7_CAN_INFO(_l, _base, _isrpri, _isrvec, _std_mboxes, _ext_mboxes) \
+at91sam7_can_info_t _l { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+ base : (_base), \
+ isrpri : (_isrpri), \
+ isrvec : (_isrvec), \
+ mboxes_std_cnt : (_std_mboxes), \
+ mboxes_ext_cnt : (_ext_mboxes), \
+ mboxes_rx_all_cnt : ((_std_mboxes) + (_ext_mboxes)), \
+};
+#else
+#define AT91SAM7_CAN_INFO(_l) \
+at91sam7_can_info_t _l = { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+};
+#endif
+
+
+//===========================================================================
+// GLOBAL DATA
+//===========================================================================
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+//
+// ToDo - Initialisation of individual CAN channels if more than one channel
+// is supported
+//
+#else // CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+//
+// Only one single CAN channel supported by SAM7 chip
+//
+AT91SAM7_CAN_INFO(at91sam7_can0_info);
+#endif
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+//
+// Macro for creation of CAN_BR value for baudrate tbl
+//
+
+#define CAN_BR_TBL_ENTRY(_brp_, _propag_, _phase1_, _phase2_, _sjw_) \
+ ((_brp_ << 16) | (_propag_ << 8) | (_phase2_) | (_phase1_ << 4) | (_sjw_ << 12))
+
+//
+// Table with register values for baudrates at main clock of 48 MHz
+//
+static const cyg_uint32 at91sam7_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(0xef, 0x07, 0x07, 0x02, 0), // 10 kbaud
+ CAN_BR_TBL_ENTRY(0x95, 0x04, 0x07, 0x01, 0), // 20 kbaud
+ CAN_BR_TBL_ENTRY(0x3b, 0x04, 0x07, 0x01, 0), // 50 kbaud
+ CAN_BR_TBL_ENTRY(0x1d, 0x04, 0x07, 0x01, 0), // 100 kbaud
+ CAN_BR_TBL_ENTRY(0x17, 0x04, 0x07, 0x01, 0), // 125 kbaud
+ CAN_BR_TBL_ENTRY(0x0b, 0x04, 0x07, 0x01, 0), // 250 kbaud
+ CAN_BR_TBL_ENTRY(0x05, 0x04, 0x07, 0x01, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY(0x03, 0x03, 0x07, 0x01, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY(0x02, 0x04, 0x07, 0x01, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY(0x00, 0x00, 0x00, 0x00, 0), // Autobaud
+};
+
+//
+// Macro fills baudrate register value depending on selected baudrate
+// For a standard AT91 clock speed of 48 MHz we provide a pre calculated
+// baudrate table. If the board uses another clock speed, then the platform
+// HAL needs to provide an own HAL_AT91SAM7_GET_CAN_BR() macro that returns
+// valid baudrate register values
+//
+#ifdef CYGNUM_HAL_ARM_AT91_CLOCK_SPEED_48000000
+#define HAL_AT91SAM7_GET_CAN_BR(_baudrate_, _br_) \
+CYG_MACRO_START \
+ _br_ = at91sam7_br_tbl[(_baudrate_) - CYGNUM_CAN_KBAUD_10]; \
+CYG_MACRO_END
+#endif
+
+
+//===========================================================================
+// PROTOTYPES
+//===========================================================================
+
+//--------------------------------------------------------------------------
+// Device driver interface functions
+//
+static bool at91sam7_can_init(struct cyg_devtab_entry* devtab_entry);
+static Cyg_ErrNo at91sam7_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name);
+static Cyg_ErrNo at91sam7_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static Cyg_ErrNo at91sam7_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static bool at91sam7_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata);
+static bool at91sam7_can_getevent(can_channel *priv, CYG_CAN_EVENT_T *pevent, void *pdata);
+static void at91sam7_can_start_xmit(can_channel* chan);
+static void at91sam7_can_stop_xmit(can_channel* chan);
+
+
+//--------------------------------------------------------------------------
+// ISRs and DSRs
+//
+static cyg_uint32 at91sam7_can_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void at91sam7_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+
+//--------------------------------------------------------------------------
+// Private utility functions
+//
+static bool at91sam7_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init);
+static bool at91sam7_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate);
+static void at91sam7_can_mbox_config_rx_all(can_channel *chan);
+static void at91sam7_can_setup_mbox(can_channel *chan, // channel
+ cyg_uint8 mbox, // message box number (0 -7)
+ cyg_uint32 mid, // message identifier
+ cyg_uint32 mam, // acceptance mask for this message box
+ cyg_uint32 rxtype); // RX or RX with overwrite are valid values
+static void at91sam7_enter_lowpower_mode(can_channel *chan);
+static void at91sam7_start_module(can_channel *chan);
+static cyg_can_state at91sam7_get_state(at91sam7_can_info_t *info);
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+static void at91sam7_can_config_rx_none(can_channel *chan);
+static Cyg_ErrNo at91sam7_can_set_config_msgbuf(can_channel *chan, cyg_can_msgbuf_cfg *buf);
+#endif
+
+
+
+
+//===========================================================================
+// GENERIC CAN IO DATA INITIALISATION
+//===========================================================================
+CAN_LOWLEVEL_FUNS(at91sam7_can_lowlevel_funs,
+ at91sam7_can_putmsg,
+ at91sam7_can_getevent,
+ at91sam7_can_get_config,
+ at91sam7_can_set_config,
+ at91sam7_can_start_xmit,
+ at91sam7_can_stop_xmit
+ );
+
+
+CYG_CAN_EVENT_T at91sam7_can0_rxbuf[CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T at91sam7_can0_txbuf[CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(at91sam7_can0_chan,
+ at91sam7_can_lowlevel_funs,
+ at91sam7_can0_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_AT91SAM7_CAN0_KBAUD),
+ at91sam7_can0_txbuf, CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_TX,
+ at91sam7_can0_rxbuf, CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(at91sam7_can_devtab,
+ CYGPKG_DEVS_CAN_AT91SAM7_CAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ at91sam7_can_init,
+ at91sam7_can_lookup, // CAN driver may need initializing
+ &at91sam7_can0_chan
+ );
+
+
+//===========================================================================
+// IMPLEMENTATION
+//===========================================================================
+
+
+
+//===========================================================================
+/// First initialisation and reset of CAN modul.
+//===========================================================================
+static bool at91sam7_can_init(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("AT91 CAN init\n");
+#endif
+ cyg_drv_interrupt_create(CAN_ISRVEC(info),
+ CAN_ISRPRIO(info), // Priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ at91sam7_can_ISR,
+ at91sam7_can_DSR,
+ &info->interrupt_handle,
+ &info->interrupt);
+ cyg_drv_interrupt_attach(info->interrupt_handle);
+ cyg_drv_interrupt_unmask(CAN_ISRVEC(info));
+
+ return at91sam7_can_config_channel(chan, &chan->config, true);
+}
+
+
+//===========================================================================
+// Lookup the device and return its handle
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
+{
+ can_channel* chan = (can_channel*) (*tab)->priv;
+ CAN_DECLARE_INFO(chan);
+
+ chan->callbacks->can_init(chan);
+ HAL_WRITE_UINT32(CAN_IER(info), INT_DEFAULT); // enable wakeup and error interrupts
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 1 << CAN_PID(info)); // Enable the peripheral clock to the device
+
+ //
+ // It is important to setup the message buffer configuration after enabling the
+ // peripheral clock. This is nowhere documented in the at91sam7 hardware manual.
+ // If the message buffer configuration is set before the peripheral clock is
+ // enabled, then message buffers that receive extended frames might not work
+ // properly
+ //
+ at91sam7_can_mbox_config_rx_all(chan);
+
+ return ENOERR;
+}
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Setup AT91SAM7 CAN module in a state where all message boxes are disabled
+// After this callit is possible to add single message buffers and filters
+//===========================================================================
+static void at91sam7_can_config_rx_none(can_channel *chan)
+{
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint8 i;
+
+ //
+ // setup all RX messages moxes into a disabled state and disable all
+ // interrupts - maybe we have to abort pending transfers before $$$$
+ //
+ HAL_WRITE_UINT32(CAN_IDR(info), INT_MB_RX);
+ for (i = 0; i < CAN_MBOX_RX_CNT; ++i)
+ {
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, i), MMR_MB_TYPE_DISABLED); // first disable message box
+ }
+
+ info->free_mboxes = CAN_MBOX_RX_CNT;
+ info->rx_all = false;
+}
+
+
+//===========================================================================
+// Add single message filter - setupm message box and enable interrupt
+//===========================================================================
+static void at91sam7_can_add_rx_filter(can_channel *chan, cyg_uint8 mbox, cyg_can_message *msg)
+{
+ CAN_DECLARE_INFO(chan);
+
+ if (msg->ext)
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_EXT(msg->id), MAM_SET_EXT, MMR_MB_TYPE_RX);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_STD(msg->id), MAM_SET_STD, MMR_MB_TYPE_RX);
+ }
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << mbox);
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Allocate message box
+// Try to find a free message box and return its ID
+//===========================================================================
+static cyg_int8 at91sam7_can_alloc_mbox(at91sam7_can_info_t *info)
+{
+ cyg_uint8 i;
+ cyg_int8 res = CYGNUM_CAN_MSGBUF_NA;
+
+ if (info->free_mboxes)
+ {
+ for (i = (CAN_MBOX_RX_CNT - info->free_mboxes); i <= CAN_MBOX_RX_MAX; ++i)
+ {
+ cyg_uint32 mmr;
+ HAL_READ_UINT32(CAN_MB_MMR(info, i), mmr);
+ if ((mmr & MMR_MB_TYPE_BITMASK) == MMR_MB_TYPE_DISABLED)
+ {
+ info->free_mboxes--;
+ res = i;
+ break;
+ }
+ }
+ } // if (info->free_mboxes)
+
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifdef CYGOPT_IO_CAN_REMOTE_BUF
+//===========================================================================
+// Setup a RTR response message box
+//===========================================================================
+static bool at91sam7_can_setup_rtrmbox(can_channel *chan,
+ cyg_uint32 mbox,
+ cyg_can_message *pmsg,
+ bool init)
+{
+ CAN_DECLARE_INFO(chan);
+ cyg_uint32 mcr;
+
+ //
+ // To prevent concurrent access with the internal CAN core, the application
+ // must disable the mailbox before writing to CAN_MIDx registers - so we
+ // do this here
+ //
+ if (init)
+ {
+ if (pmsg->ext)
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_EXT(pmsg->id), MAM_SET_EXT, MMR_MB_TYPE_PRODUCE);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_STD(pmsg->id), MAM_SET_STD, MMR_MB_TYPE_PRODUCE);
+ }
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << mbox); // enable interrupt
+ }
+ else
+ {
+ cyg_uint32 msr;
+ //
+ // Check if this message box is ready for transmission or if it still transmits
+ // a message - we read the MSR register to check the ready flag
+ //
+ HAL_READ_UINT32(CAN_MB_MSR(info, mbox), msr);
+ if (!(msr & MSR_RDY))
+ {
+ AT91SAM7_DBG_PRINT("(RTR) !MSR_RDY\n");
+ return false;
+ }
+ }
+
+ HAL_WRITE_UINT32(CAN_MB_MDL(info, mbox), pmsg->data.dwords[0]); // set data
+ HAL_WRITE_UINT32(CAN_MB_MDH(info, mbox), pmsg->data.dwords[1]); // set data
+ mcr = (pmsg->dlc << MCR_DLC_SHIFTER) | MCR_TRANSFER_CMD; // set data lengt and transfer request
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), mcr); // transfer request
+ return true;
+}
+#endif // CYGOPT_IO_CAN_REMOTE_BUF
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message buffers
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_set_config_msgbuf(can_channel *chan, cyg_can_msgbuf_cfg *buf)
+{
+ Cyg_ErrNo res = ENOERR;
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+
+ switch (buf->cfg_id)
+ {
+ //
+ // clear all message filters and remote buffers - prepare for message buffer
+ // configuration
+ //
+ case CYGNUM_CAN_MSGBUF_RESET_ALL :
+ {
+ at91sam7_can_config_rx_none(chan);
+ }
+ break;
+
+ //
+ // setup AT91SAM7 CAN module for reception of all standard and extended messages
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ALL :
+ {
+ if (!info->rx_all) // if rx_all is enabled we do not need to do anything
+ {
+ at91sam7_can_mbox_config_rx_all(chan); // setup RX all state
+ }
+ }
+ break;
+
+ //
+ // add single message filter, message with filter ID will be received
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ADD :
+ {
+ cyg_can_filter *filter = (cyg_can_filter*) buf;
+
+ //
+ // if AT91SAM7 CAN module is configured to receive all messages then
+ // it is not allowed to add single message filters because then more
+ // than one message buffer would receive the same CAN id
+ //
+ if (info->rx_all)
+ {
+ return -EPERM;
+ }
+
+ //
+ // try to allocate a free message box - if we have a free one
+ // then we can prepare the message box for reception of the
+ // desired message id
+ //
+ filter->handle = at91sam7_can_alloc_mbox(info);
+ if (filter->handle > CYGNUM_CAN_MSGBUF_NA)
+ {
+ at91sam7_can_add_rx_filter(chan, filter->handle, &filter->msg);
+ }
+ }
+ break; //CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+
+
+#ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ //
+ // Try to add a new RTR response message buffer for automatic transmisson
+ // of data frame on reception of a remote frame
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD :
+ {
+ cyg_can_remote_buf *rtr_buf = (cyg_can_remote_buf*) buf;
+ rtr_buf->handle = at91sam7_can_alloc_mbox(info);
+
+ if (rtr_buf->handle > CYGNUM_CAN_MSGBUF_NA)
+ {
+ //
+ // if we have a free message buffer then we setup this buffer
+ // for remote frame reception
+ //
+ at91sam7_can_setup_rtrmbox(chan, rtr_buf->handle, &rtr_buf->msg, true);
+ }
+ }
+ break;
+
+ //
+ // write data into remote response buffer
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE :
+ {
+ cyg_can_remote_buf *rtr_buf = (cyg_can_remote_buf*) buf;
+ //
+ // If we have a valid rtr buf handle then we can store data into
+ // rtr message box
+ //
+ if ((rtr_buf->handle >= 0) && (rtr_buf->handle <= CAN_MBOX_RX_MAX))
+ {
+ if (!at91sam7_can_setup_rtrmbox(chan, rtr_buf->handle, &rtr_buf->msg, false))
+ {
+ res = -EAGAIN;
+ }
+ }
+ else
+ {
+ res = -EINVAL;
+ }
+ }
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ } // switch (buf->cfg_id)
+
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//===========================================================================
+// Read state of CAN controller
+// The CAN state variable for each channel is modiefied by DSR so if we
+// read the state we need to lock DSRs to protect the data access
+//===========================================================================
+static cyg_can_state at91sam7_get_state(at91sam7_can_info_t *info)
+{
+ cyg_can_state result;
+
+ cyg_drv_dsr_lock();
+ result = info->state;
+ cyg_drv_dsr_unlock();
+
+ return result;
+}
+
+
+//===========================================================================
+// Enter low power mode
+// Before stopping the CAN clock (PMC), the CAN Controller must be in
+// Low-power Mode to complete the current transfer. After restarting the
+// clock, the application must disable the Low-power Mode of the
+// CAN controller. If the power mode is entered, a sleep interrupt is
+// generated.
+//===========================================================================
+static void at91sam7_enter_lowpower_mode(can_channel *chan)
+{
+ CAN_DECLARE_INFO(chan);
+
+
+ cyg_uint32 mr;
+ HAL_READ_UINT32(CAN_MR(info), mr);
+ HAL_WRITE_UINT32(CAN_MR(info), mr | MR_LOW_POWER);
+ HAL_WRITE_UINT32(CAN_IER(info), INT_SLEEP);
+}
+
+
+//===========================================================================
+// Start CAN module (or leave the low power mode)
+// If the CAN module is in STANDBY state then we enable the module clock
+// and leave the low power mode by clearing the low power flag.
+//===========================================================================
+static void at91sam7_start_module(can_channel *chan)
+{
+ CAN_DECLARE_INFO(chan);
+ cyg_uint32 mr;
+
+ HAL_WRITE_UINT32(CAN_IER(info), INT_DEFAULT); // enable wakeup interrupt
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 1 << CAN_PID(info)); // restart peripheral clock
+ HAL_READ_UINT32(CAN_MR(info), mr);
+ mr &= ~MR_LOW_POWER ;
+ HAL_WRITE_UINT32(CAN_MR(info), mr | MR_CAN_ENABLE); // clear the low power flag to leave standby
+}
+
+//===========================================================================
+// Change device configuration
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+
+ switch (key)
+ {
+ //
+ // Setup a new CAN configuration. This will i.e. setup a new baud rate
+ //
+ case CYG_IO_SET_CONFIG_CAN_INFO:
+ {
+ cyg_can_info_t* config = (cyg_can_info_t*) buf;
+ if (*len < sizeof(cyg_can_info_t))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_info_t);
+ if (!at91sam7_can_config_channel(chan, config, false))
+ {
+ return -EINVAL;
+ }
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // configure message buffers
+ //
+ case CYG_IO_SET_CONFIG_CAN_MSGBUF :
+ {
+ cyg_can_msgbuf_cfg *msg_buf = (cyg_can_msgbuf_cfg *)buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_cfg))
+ {
+ return -EINVAL;
+ }
+
+ res = at91sam7_can_set_config_msgbuf(chan, msg_buf);
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+ //
+ // Change CAN state of AT91SAM7 CAN module
+ //
+ case CYG_IO_SET_CONFIG_CAN_MODE :
+ {
+ cyg_can_mode *can_mode = (cyg_can_mode*) buf;
+
+ if (*len != sizeof(cyg_can_mode))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_mode);
+
+ //
+ // decide what to do acording to mode
+ //
+ switch (*can_mode)
+ {
+ //
+ // The controller does not support a stopped and standby state so we
+ // simply enter the low power state here. This state is also safe for
+ // message buffer configuration
+ //
+ case CYGNUM_CAN_MODE_STOP : at91sam7_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_START : at91sam7_start_module(chan); break;
+ case CYGNUM_CAN_MODE_STANDBY : at91sam7_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_CONFIG : at91sam7_enter_lowpower_mode(chan); break;
+ }
+ }
+ break; // case CYG_IO_SET_CONFIG_CAN_MODE :
+ } // switch (key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Query device configuration
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+
+ switch(key)
+ {
+ //
+ // query state of CAN controller
+ //
+ case CYG_IO_GET_CONFIG_CAN_STATE :
+ {
+ cyg_can_state *can_state = (cyg_can_state*) buf;
+
+ if (*len != sizeof(cyg_can_state))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_state);
+ *can_state = at91sam7_get_state(info);
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // Query message box information - returns available and free message
+ // boxes
+ //
+ case CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO :
+ {
+ cyg_can_msgbuf_info *mbox_info = (cyg_can_msgbuf_info*) buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_info))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_msgbuf_info);
+
+ mbox_info->count = CAN_MBOX_RX_CNT;
+ mbox_info->free = info->free_mboxes;
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+ //
+ // Query hardware description of FlexCAN device driver
+ //
+ case CYG_IO_GET_CONFIG_CAN_HDI :
+ {
+ cyg_can_hdi *hdi = (cyg_can_hdi *)buf;
+ //
+ // comes from high level driver so we do not need to
+ // check buffer size here
+ //
+ hdi->support_flags = CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE
+ | CYGNUM_CAN_HDI_FULLCAN
+ | CYGNUM_CAN_HDI_AUTBAUD;
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ hdi->support_flags |= CYGNUM_CAN_HDI_TIMESTAMP;
+#endif
+ }
+ break;
+
+ default :
+ res = -EINVAL;
+ }// switch(key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Send single message
+//===========================================================================
+static bool at91sam7_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata)
+{
+ CAN_DECLARE_INFO(priv);
+ cyg_uint32 msr;
+ cyg_uint32 mcr = 0;
+
+ //
+ // First check if this message box is ready fro transmission or if it still transmits
+ // a message - we read the MSR register to check the ready flag
+ //
+ HAL_READ_UINT32(CAN_MB_MSR(info, CAN_MBOX_TX(info)), msr);
+ if (!(msr & MSR_RDY))
+ {
+ AT91SAM7_DBG_PRINT("!MSR_RDY\n");
+ return false;
+ }
+
+ //
+ // To prevent concurrent access with the internal CAN core, the application must disable
+ // the mailbox before writing to CAN_MIDx registers - so we do this now
+ //
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_DISABLED);
+
+ //
+ // Setup the message identifier - this depends on the frame type (standard or extended)
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (AT91SAM7_CAN_IS_EXT(*pmsg))
+ {
+ HAL_WRITE_UINT32(CAN_MB_MID(info, CAN_MBOX_TX(info)),
+ pmsg->id | MID_MIDE); // set extended message id
+ }
+ else
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ HAL_WRITE_UINT32(CAN_MB_MID(info, CAN_MBOX_TX(info)),
+ (pmsg->id << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK); // set standard message id
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ }
+
+ HAL_WRITE_UINT32(CAN_MB_MDL(info, CAN_MBOX_TX(info)), pmsg->data.dwords[0]); // set data
+ HAL_WRITE_UINT32(CAN_MB_MDH(info, CAN_MBOX_TX(info)), pmsg->data.dwords[1]); // set data
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_TX); // reenable the message box
+ mcr = (AT91SAM7_CAN_GET_DLC(*pmsg) << MCR_DLC_SHIFTER) | MCR_TRANSFER_CMD; // set data lengt and transfer request
+
+ if (AT91SAM7_CAN_IS_RTR(*pmsg))
+ {
+ mcr |= MCR_RTR;
+ }
+
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, CAN_MBOX_TX(info)), mcr);
+ return true;
+}
+
+
+//===========================================================================
+// Read event from device driver
+//===========================================================================
+static bool at91sam7_can_getevent(can_channel *chan, CYG_CAN_EVENT_T *pevent, void *pdata)
+{
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint32* pstat = (cyg_uint32 *)pdata;
+ cyg_uint8 mboxflags = (*pstat & INT_MB_RX);
+ cyg_uint8 mbox = 0;
+ bool res = true;
+
+ //
+ // First check if a message box interrupt occured if a message box interrupt
+ // occured process the lowest message box that caused an interrupt
+ //
+ if (mboxflags)
+ {
+ cyg_uint32 msr;
+ cyg_uint32 mid;
+ cyg_uint32 mmr;
+
+ while (!(mboxflags & 0x01))
+ {
+ mboxflags >>= 1;
+ mbox++;
+ }
+
+ //
+ // If the message box that caused the interrupt is an PRODUCER message box,
+ // then we received an remote request message, if not, then this is a normal
+ // RX message
+ //
+ HAL_READ_UINT32(CAN_MB_MMR(info, mbox), mmr);
+ HAL_READ_UINT32(CAN_MB_MSR(info, mbox), msr);
+ *pstat &= ~(0x01 << mbox); // clear flag
+
+ if (MMR_MB_GET_TYPE(mmr) != MMR_MB_TYPE_PRODUCE)
+ {
+ HAL_READ_UINT32(CAN_MB_MID(info, mbox), mid);
+ pevent->flags |= CYGNUM_CAN_EVENT_RX;
+ if (msr & MSR_MSG_IGNORED)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_OVERRUN_RX;
+ }
+
+ //
+ // It is important to set the DLC first because this also clears the ctrl
+ // field if extended identifiers are supported
+ //
+ AT91SAM7_CAN_SET_DLC(pevent->msg, MSR_DLC_GET(msr));
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (mid & MID_MIDE)
+ {
+ pevent->msg.id = MID_GET_EXT(mid);
+ AT91SAM7_CAN_SET_EXT(pevent->msg);
+ }
+ else
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ pevent->msg.id = MID_GET_STD(mid);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ }
+
+ if (msr & MSR_RTR)
+ {
+ AT91SAM7_CAN_SET_RTR(pevent->msg);
+ }
+ else
+ {
+ HAL_READ_UINT32(CAN_MB_MDL(info, mbox), pevent->msg.data.dwords[0]);
+ HAL_READ_UINT32(CAN_MB_MDH(info, mbox), pevent->msg.data.dwords[1]);
+ }
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ pevent->timestamp = msr & MSR_TIMESTAMP;
+#endif
+
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), MCR_TRANSFER_CMD); // transfer request
+ AT91SAM7_DBG_PRINT("RXID: %x\n", AT91SAM7_CAN_GET_ID(pevent->msg));
+ } // if (!(mbox & info->rtr_mboxes)
+ else
+ {
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), (msr & MSR_DLC) | MCR_TRANSFER_CMD); // transfer request
+ //
+ // We do not need to store an event into receive queue if the stat field does
+ // not contain any further event flags. If stat is empty we can set res
+ // to false and no event will bestore
+ //
+ res = !(*pstat == 0);
+ }
+
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << mbox); // enable interruptfor this message box
+ } // if (mboxflags)
+
+ //
+ // Now check if additional events occured
+ //
+ if (*pstat)
+ {
+ if (*pstat & INT_WAKEUP)
+ {
+ AT91SAM7_DBG_PRINT("WAKE\n");
+ pevent->flags |= CYGNUM_CAN_EVENT_LEAVING_STANDBY;
+ *pstat &= ~INT_WAKEUP;
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ }
+
+ if (*pstat & INT_ERR_PASSIVE)
+ {
+ AT91SAM7_DBG_PRINT("ERRP\n");
+ pevent->flags |= CYGNUM_CAN_EVENT_ERR_PASSIVE;
+ *pstat &= ~INT_ERR_PASSIVE;
+ info->state = CYGNUM_CAN_STATE_ERR_PASSIVE;
+ HAL_WRITE_UINT32(CAN_IER(info), INT_WAKEUP);
+ }
+
+ if (*pstat & INT_WARN)
+ {
+ //
+ // check which counter reached its warning level (> 96)
+ //
+ cyg_uint8 ecr;
+ HAL_READ_UINT32(CAN_ECR(info), ecr);
+ if (ECR_GET_REC(ecr) > 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_RX;
+ AT91SAM7_DBG_PRINT("WARN TX\n");
+ }
+ if (ECR_GET_TEC(ecr) > 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
+ AT91SAM7_DBG_PRINT("WARN RX\n");
+ }
+ *pstat &= ~INT_WARN;
+ info->state = CYGNUM_CAN_STATE_BUS_WARN;
+ HAL_WRITE_UINT32(CAN_IER(info), INT_ERR_PASSIVE | INT_BUS_OFF);
+ }
+
+ if (*pstat & INT_BUS_OFF)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_BUS_OFF;
+ AT91SAM7_DBG_PRINT("BOFF\n");
+ *pstat &= ~INT_BUS_OFF;
+ info->state = CYGNUM_CAN_STATE_BUS_OFF;
+ HAL_WRITE_UINT32(CAN_IER(info), INT_WAKEUP);
+ }
+
+ if (*pstat & INT_SLEEP)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ENTERING_STANDBY;
+ AT91SAM7_DBG_PRINT("SLEEP\n");
+ *pstat &= ~INT_SLEEP;
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCDR, 1 << CAN_PID(info)); // disable module clock
+ info->state = CYGNUM_CAN_STATE_STANDBY; // set state variable
+ HAL_WRITE_UINT32(CAN_IER(info), INT_WAKEUP); // enable wakeup interrupt
+ }
+
+ if (*pstat & (INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR))
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_CAN_ERR;
+ AT91SAM7_DBG_PRINT("CERR\n");
+ *pstat &= ~(INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR);
+ }
+ } // if (*pstat)
+
+ return res;
+}
+
+
+//===========================================================================
+// Kick transmitter
+//===========================================================================
+static void at91sam7_can_start_xmit(can_channel* chan)
+{
+ CAN_DECLARE_INFO(chan);
+
+ AT91SAM7_DBG_PRINT("start_xmit\n");
+ cyg_drv_dsr_lock();
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << CAN_MBOX_TX(info)); // enable tx interrupt
+ cyg_drv_dsr_unlock();
+}
+
+
+//===========================================================================
+// Stop transmitter
+//===========================================================================
+static void at91sam7_can_stop_xmit(can_channel* chan)
+{
+ CAN_DECLARE_INFO(chan);
+
+ HAL_WRITE_UINT32(CAN_IDR(info), 0x01 << CAN_MBOX_TX(info)); // disable tx interrupt
+ AT91SAM7_DBG_PRINT("stop_xmit\n");
+}
+
+
+//===========================================================================
+// Configure can channel
+//===========================================================================
+static bool at91sam7_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init)
+{
+ CAN_DECLARE_INFO(chan);
+ cyg_uint32 temp32;
+ bool res = true;
+
+ if (init)
+ {
+ //
+ // If the platform that uses the driver needs to do some platform specific
+ // initialisation steps, it can do it inside of this macro. I.e. some platforms
+ // need to setup the CAN transceiver properly here (this is necessary for the
+ // Atmel AT91SAM7X-EK)
+ //
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1 && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+ HAL_AT91SAM7_CAN0_PLF_INIT();
+#else // CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+#if defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN0) && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+ if (info == &at91sam7_can0_info) {
+ HAL_AT91SAM7_CAN0_PLF_INIT();
+ }
+#endif // defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN0) && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+#if defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN1) && defined(HAL_AT91SAM7_CAN1_PLF_INIT)
+ if (info == &at91sam7_can1_info) {
+ HAL_AT91SAM7_CAN1_PLF_INIT();
+ }
+#endif // defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN0) && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+#endif // CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+ HAL_WRITE_UINT32(CAN_IDR(info), 0xFFFFFFFF); // disable all interrupts
+ HAL_WRITE_UINT32(CAN_MR(info), 0x00); // disable CAN module
+ HAL_ARM_AT91_PIO_CFG(AT91_CAN_CANRX); // Enable the CAN module to drive the CAN port pins
+ HAL_ARM_AT91_PIO_CFG(AT91_CAN_CANTX);
+
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_DISABLED); // first disable tx message box
+ HAL_WRITE_UINT32(CAN_MB_MAM(info, CAN_MBOX_TX(info)), 0x00000000); // set acceptance mask once
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_TX); // setup as tx message box
+
+ HAL_WRITE_UINT32(CAN_MR(info), MR_CAN_ENABLE); // enable CAN module
+
+ //
+ // The device should go into error active state right after enabling it
+ //
+ HAL_READ_UINT32(CAN_SR(info), temp32);
+ if (!(temp32 & INT_ERR_ACTIVE))
+ {
+ res = false;
+ }
+ } // if (init)
+
+ res = at91sam7_can_set_baud(chan, &config->baud); // set baudrate
+
+ //
+ // store new config values
+ //
+ if (config != &chan->config)
+ {
+ chan->config = *config;
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Low level interrupt handler
+//===========================================================================
+static cyg_uint32 at91sam7_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ at91sam7_can_info_t * const info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint32 sr;
+ cyg_uint32 imr;
+
+
+ HAL_READ_UINT32(CAN_IMR(info), imr);
+ HAL_READ_UINT32(CAN_SR(info), sr);
+ AT91SAM7_DBG_PRINT("CAN_ISR SR %x\n", sr);
+ sr &= imr;
+ HAL_WRITE_UINT32(CAN_IDR(info), sr);
+
+ info->stat |= sr;
+ cyg_drv_interrupt_acknowledge(vector);
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// High level interrupt handler
+//===========================================================================
+static void at91sam7_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ at91sam7_can_info_t * const info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint32 stat = 0;
+
+ do
+ {
+ //
+ // If a number of events occured then we process all events now in
+ // in this DSR the get_event() function clears the flags in the stat
+ // field
+ //
+ while (stat)
+ {
+ if (stat & (0x01 << CAN_MBOX_TX(info)))
+ {
+ AT91SAM7_DBG_PRINT("TX_DSR\n");
+ chan->callbacks->xmt_msg(chan, 0); // send next message
+ stat &= ~INT_MB_TX; // clear flag
+ }
+ else if (stat)
+ {
+ AT91SAM7_DBG_PRINT("EVENT_DSR\n");
+ chan->callbacks->rcv_event(chan, &stat);
+ }
+ }
+
+ //
+ // We check, if a new event occured while we processed other events. If new events
+ // occured, then we process the new events
+ //
+ cyg_drv_interrupt_mask(vector);
+ stat = info->stat;
+ info->stat = 0;
+ cyg_drv_interrupt_unmask(vector);
+ } while (stat);
+}
+
+
+//===========================================================================
+// Set baudrate of certain can channel
+//===========================================================================
+static bool at91sam7_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate)
+{
+ bool res = true;
+ cyg_uint32 mrbck;
+ cyg_uint32 canbr;
+ CAN_DECLARE_INFO(chan);
+
+
+#ifdef CYGOPT_IO_CAN_AUTOBAUD
+ if (CYGNUM_CAN_KBAUD_AUTO == *baudrate)
+ {
+ cyg_can_baud_rate_t i;
+ cyg_uint8 j;
+ cyg_uint32 sr;
+
+ res = false;
+ for (i = CYGNUM_CAN_KBAUD_10; i <= CYGNUM_CAN_KBAUD_1000; ++i)
+ {
+ HAL_AT91SAM7_GET_CAN_BR(i, canbr);
+ if (0 == canbr)
+ {
+ continue;
+ }
+
+ HAL_READ_UINT32(CAN_SR(info), sr);
+ HAL_WRITE_UINT32(CAN_MR(info), 0); // disable the module
+ HAL_WRITE_UINT32(CAN_BR(info), canbr); // write baudrate register
+ HAL_WRITE_UINT32(CAN_MR(info), MR_CAN_ENABLE | MR_AUTOBAUD); // enable controller in auto aud mode
+ for(j = 0; j < 200; ++j)
+ {
+ HAL_DELAY_US(1000); // wait at least 11 bit times for synchronization
+ }
+ HAL_READ_UINT32(CAN_SR(info), sr); // read status register
+ if (!(sr & INT_ALL_ERR) && (sr & INT_WAKEUP))
+ {
+ HAL_WRITE_UINT32(CAN_MR(info), 0); // disable the module
+ HAL_WRITE_UINT32(CAN_MR(info), MR_CAN_ENABLE); // enable controller
+ *baudrate = i; // store baudrate
+ return true;
+ } // if (!(sr & INT_ALL_ERR))
+ }
+ }
+ else
+#endif // CYGOPT_IO_CAN_AUTOBAUD
+ {
+ //
+ // Get bit timings from HAL because bit timings depend on sysclock
+ // For main clock of 48 MHz this macro is implemented in this device
+ // driver. If the macro fills the canbr value with 0 then the baudrate
+ // is not supported and the function returns false
+ //
+ HAL_AT91SAM7_GET_CAN_BR(*baudrate, canbr);
+ if (0 == canbr)
+ {
+ return false;
+ }
+
+ //
+ // Any modificatons to the baudrate register must be done while CAN
+ // module is disabled. So we first disable CAN module, then we set
+ // baudrate and then we reenable the CAN module by setting the CAN enable
+ // flag
+ //
+ HAL_READ_UINT32(CAN_MR(info), mrbck); // backup value of mode register
+ HAL_WRITE_UINT32(CAN_MR(info), mrbck &~MR_CAN_ENABLE); // disable controller
+ HAL_WRITE_UINT32(CAN_BR(info), canbr); // write baudrate register
+
+ //
+ // Now restore the previous state - if the module was started then
+ // it will no be started again, if it was stopped, then it remains stopped
+ //
+ HAL_WRITE_UINT32(CAN_MR(info), mrbck);
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Setup one single message box for reception of can message
+//===========================================================================
+static void at91sam7_can_setup_mbox(can_channel *chan, cyg_uint8 mbox, cyg_uint32 mid, cyg_uint32 mam, cyg_uint32 rxtype)
+{
+ CAN_DECLARE_INFO(chan);
+ CYG_ASSERT(mbox < 7, "invalid rx mbox number");
+
+
+ //
+ // To prevent concurrent access with the internal CAN core, the application
+ // must disable the mailbox before writing to CAN_MIDx registers - so we
+ // do this here
+ //
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, mbox), MMR_MB_TYPE_DISABLED); // first disable message box
+ HAL_WRITE_UINT32(CAN_MB_MAM(info, mbox), mam); // set acceptance mask
+ HAL_WRITE_UINT32(CAN_MB_MID(info, mbox), mid); // set message identifier
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, mbox), rxtype); // setup message box as rx message box (with or without overwrite)
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), MCR_TRANSFER_CMD); // transfer request - we do not enable interrupts here
+}
+
+
+//===========================================================================
+// Configure message boxes for reception of any CAN message
+//===========================================================================
+static void at91sam7_can_mbox_config_rx_all(can_channel *chan)
+{
+ at91sam7_can_info_t * const info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint8 i;
+ cyg_uint8 mbox_int_mask = 0;
+ cyg_uint8 mbox_rx_all_cnt = CAN_MBOX_RX_ALL_CNT(info);
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ cyg_uint8 last_std_rx_mbox = CAN_MBOX_STD_CNT(info) - 1;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_uint8 last_ext_rx_mbox = mbox_rx_all_cnt - 1;
+#endif// CYGOPT_IO_CAN_EXT_CAN_ID
+
+ //
+ // Now setup all rx message boxes. One message box (the last one - no 8) is
+ // used for transmission so we have 7 message boxes for reception of can messages
+ // We setup the message boxes 0 - 5 as RX mboxes and message box 6 as RX mbox with
+ // overwrite.
+ //
+ for (i = 0; i < mbox_rx_all_cnt; ++i)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (i < CAN_MBOX_STD_CNT(info))
+ {
+ //
+ // setup message boxes for standard frames
+ //
+ if (i < last_std_rx_mbox)
+ {
+ at91sam7_can_setup_mbox(chan, i, 0, MID_MIDE, MMR_MB_TYPE_RX);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, i, 0, MID_MIDE, MMR_MB_TYPE_RX_OVW);
+ }
+ }
+ else
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ //
+ // setup message boxes for extended frames
+ //
+ if (i < last_ext_rx_mbox)
+ {
+ at91sam7_can_setup_mbox(chan, i, MID_MIDE, MID_MIDE, MMR_MB_TYPE_RX);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, i, MID_MIDE, MID_MIDE, MMR_MB_TYPE_RX_OVW);
+ }
+#endif// CYGOPT_IO_CAN_EXT_CAN_ID
+ } // if (i < CAN_MBOX_STD_CNT(info))
+
+ mbox_int_mask = (mbox_int_mask << 1) | 0x01; // enable interrupt
+ } // for (i = 0; i < CAN_MBOX_RX_CNT; ++i)*/
+
+ info->free_mboxes = CAN_MBOX_RX_CNT - mbox_rx_all_cnt;
+ info->rx_all = true;
+ HAL_WRITE_UINT32(CAN_IER(info), mbox_int_mask); // Now finally enable the interrupts for als RX mboxes
+}
+
+
+//---------------------------------------------------------------------------
+// EOF can_at91am7.c
--- /dev/null
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
--- /dev/null
+2008-07-21 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
+ arbitration lost interrupt optional. Added option
+ CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY to configure the interrupt
+ priority for global CAN interrupt in LPC24xx variants.
+
+ * include/can_lpc2xxx_baudrates.h: Replaced CYGNUM_CAN_LPC2XXX_VPB_CLK
+ by CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK because newer variants like LPC24xx
+ do not have a global VPB_CLK.
+
+ * src/can_accfilt_lpc2xxx.c: Adjusted LPC2XXX_CAN_FIRST_IN_LUT to
+ be 0 for LPC24xxx variants. Added macro CAN_CHAN_NO_LUT(_info_) to
+ abstract channel numbering from acceptance filter code.
+
+ * src/can_lpc2xxx.c: Removed icr data field from lpc2xxx_can_info_st
+ structure because it is not required any longer. A lot of small
+ modifications to make the driver usable with newer LPC2xxx variants like
+ LPC24xx. ISR and DSR code changed - instead of disabling interrupts in
+ IER register they are disabled in VIC by using cyg_drv_interrupt_mask()
+ function calls. Added global CAN ISR and DSR for LPC24xx variants
+ (they do not support individual interrupt vectors for RX and TX
+ interrupts). Moved LUT error checking code from ISR into DSR to keep
+ ISR as short as possible and made LUT error checking code optional.
+
+2008-05-23 Alexey Shusharin <mrfinch@mail.ru>
+
+ * cdl/can_lpc2xxx.cdl: add CAN interrupt priorities
+
+ * src/can_lpc2xxx.c: add CAN interrupt priorities,
+ repair "chan" definition missing in rx_ISR
+
+ * src/can_accfilt_lpc2xxx.c: add various types of CAN controllers
+ numbering (depends on LPC2XXX version)
+
+2007-08-17 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * src/can_lpc2xxx.c: The definition of "info" is missing when only
+ one CAN channel is configured.
+
+2007-08-17 Uwe Kindler <uwe_kindler@web.de>
+
+ * include/can_lpc2xxx_baudrates.h: Removed all prefixed zeros from
+ baudrate table entries (they aren't intended to be interpreted as
+ octal)
+
+ * tests/can_baudrates.c
+ tests/can_busload.c
+ tests/can_rx_tx.c: removed #include pkgconf/devs_can_loop.h
+
+2007-08-02 Alexey Shusharin <mrfinch@mail.ru>
+
+ * src/can_lpc2xxx.c: Added acknowledging call in rx interrupt
+ (self-reception part)
+
+2007-07-07 Alexey Shusharin <mrfinch@mail.ru>
+
+ * cdl/can_lpx2xxx.cdl: Option
+ CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION added for enabling
+ self reception requests instead of transmission requests.
+
+ * src/can_lpc2xxx.c: Some small bugs fixed. Added support for LUT
+ error. Support for self transmission request added. Debug output
+ improved.
+
+ * src/can_accfilt_lpc2xxx.c: Added support for baudrates of 10kbaud
+ and 20 kbaud at clock speed of 60 MHz
+
+2007-07-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * LPC2xxx CAN driver package created
+ * cdl/can_lpc2xxx.cdl
+ * include/can_lpc2xxx.h
+ * include/can_lpc2xxx_baudrates.h
+ * src/can_lpc2xxx.c
+ * src/can_accfilt_lpc2xxx.c
+
+//===========================================================================
+//####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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# can_lpc2xxx.cdl
+#
+# eCos LPC2xxx CAN module configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2007-02-10
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_CAN_LPC2XXX {
+ display "Philips LPC2xxx CAN device drivers"
+ parent CYGPKG_IO_CAN_DEVICES
+ active_if CYGPKG_IO_CAN
+ active_if CYGPKG_HAL_ARM_LPC2XXX || CYGPKG_HAL_ARM_LPC24XX
+ requires CYGPKG_ERROR
+
+ implements CYGINT_IO_CAN_STD_CAN_ID
+ implements CYGINT_IO_CAN_EXT_CAN_ID
+
+ include_dir cyg/io
+ description "
+ This option enables the CAN device drivers for the
+ Philips LPC2XXX."
+ compile -library=libextras.a can_lpc2xxx.c
+ define_proc {
+ puts $::cdl_system_header "/***** CAN driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_HEADER <pkgconf/devs_can_lpc2xxx.h>"
+ puts $::cdl_system_header "/***** CAN driver proc output end *****/"
+ }
+
+ cdl_component CYGOPT_DEVS_CAN_LPC2XXX_RUNTIME_ACCFILT {
+ display "Acceptance filter runtime configuration"
+ flavor bool
+ implements CYGINT_IO_CAN_RUNTIME_MBOX_CFG
+ description "
+ The LPC2xxx CAN module supports a global acceptance
+ filter. Enabling this option provides support for runtime
+ configuration of this acceptance filter. If each CAN
+ channel should receive all CAN messages and individual
+ message filtering is not required then disable this option
+ to eliminate almost the complete acceptance filter code
+ and to decrease code size. If this option is disabled the
+ option CYGOPT_IO_CAN_RUNTIME_MBOX_CFG is not available and
+ the configuration key CYG_IO_SET_CONFIG_CAN_MSGBUF is not
+ supported by this driver."
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS {
+ display "Extended acceptance filtering"
+ flavor bool
+ default_value 0
+ description "
+ The common CAN I/O layer supports setup of single
+ message filters for reception of single CAN
+ messages. The global LPC2xxx acceptance filter
+ supports not only single message filters but also
+ message groups. A message group is defined by a
+ lower bound CAN identifier and an upper bound CAN
+ identifier. The acceptance filter will accept all
+ messages within this range of CAN identifiers. The
+ acceptance filter supports a number of message
+ groups for each CAN channel. The support of
+ message filter groups is not conform to the
+ standard API of the CAN I/O layer and should only
+ be used for application where portability is not
+ important."
+ }
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP {
+ display "LUT Error Support"
+ flavor bool
+ default_value 0
+ description "
+ The CAN module contains a look-up table for
+ acceptance filtering of incoming CAN messages. The
+ look-up table indicates errors in the LUT error
+ registers. If this option is enabled, additional
+ error check code is executed if an interrupt is
+ serviced. Normally the acceptance filter code should
+ fill the look-up table properly and no LUT error
+ should ever occur. You need to decide if LUT error
+ checking is required for your application because it
+ adds some bytes of code and slows down the ISR/DSR
+ handling a little bit because of the additional code
+ that need to be executed."
+ }
+ }
+
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION {
+ display "Use Self Reception Request command"
+ flavor bool
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 0
+ description "
+ Enable this option for using work-around of problem with
+ receiving messages while arbitration is lost. If this work
+ around is used each transmitted CAN message will be
+ received. This will produce additional RX interrupts an
+ requires additional time for processing these interrupts
+ and for filtering of received messages.
+
+ The errata sheet tells the following about this issue:
+ Introduction: The CAN module can lose arbitration to
+ another CAN node during an attempt to transmit a CAN
+ message. The message of the CAN node the arbitration was
+ lost to is supposed to be received correctly by the CAN
+ module.
+
+ Problem: Messages might not be received correctly if
+ during a CAN Transmission the CAN bus arbitration is lost
+ to another CAN node.
+
+ Work-around: Use the Self Reception Request command
+ instead of the Transmission Request command. However, it
+ has to be taken into account that now all transmitted
+ messages may be received if not prevented by appropriate
+ Acceptance Filter settings. (Don't set up Acceptance
+ Filter Message Identifiers for the messages you are
+ transmitting yourself.)."
+ }
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_ALIE {
+ display "Arbitration lost interrupt enable"
+ flavor bool
+ default_value 0
+ description "
+ If the CAN controller loses arbitration while attempting to
+ transmit a message, an interrupt can be triggered. Normally
+ this is no real error condition and it is not necessary to
+ propagate these events to upper layers. But you can enable
+ this option if you want to check for arbitration lost events."
+ }
+
+ cdl_option CYGDBG_DEVS_CAN_LPC2XXX_DEBUG {
+ display "Support printing debug information"
+ default_value 0
+ description "
+ Check this box to turn ON debug options for LPC2XXXX
+ CAN device driver."
+ }
+
+ # Support up to 4 on-chip CAN modules. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::channel 0 } { $::channel < 4 } { incr ::channel } {
+
+ cdl_interface CYGINT_DEVS_CAN_LPC2XXX_CAN[set ::channel] {
+ display "Platform provides CAN [set ::channel]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific LPC2xxx
+ processor being used has on-chip CAN [set ::channel], and if
+ that CAN module is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_DEVS_CAN_LPC2XXX_CAN[set ::channel] {
+ display "Allow access to the on-chip CAN [set ::channel] via a CAN driver"
+ flavor bool
+ active_if CYGINT_DEVS_CAN_LPC2XXX_CAN[set ::channel]
+ implements CYGINT_IO_CAN_CHANNELS
+ default_value 1
+ description "
+ If the application needs to access the on-chip CAN
+ module [set ::channel] via an eCos CAN driver then
+ this option should be enabled."
+
+ cdl_option CYGPKG_DEVS_CAN_LPC2XXX_CAN[set ::channel]_NAME {
+ display "Device name for CAN module [set ::channel]"
+ flavor data
+ default_value [format {"\"/dev/can%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_KBAUD {
+ display "Default baud rate for CAN module [set ::channel]"
+ flavor data
+ default_value 100
+ legal_values { 10 20 50 100 125 250 500 800 1000 "AUTO"}
+ description "
+ This option determines the initial baud rate in
+ KBaud for CAN module [set ::channel]"
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_QUEUESIZE_TX {
+ display "Size of TX Queue for the CAN module [set ::channel] driver"
+ flavor data
+ default_value 32
+ legal_values 1 to 1024
+ description "
+ The CAN device driver will run in interrupt mode
+ and will perform buffering of outgoing data. This
+ option controls the number of CAN messages the TX
+ queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_QUEUESIZE_RX {
+ display "Size of RX Queue for the CAN module [set ::channel] driver"
+ flavor data
+ default_value 64
+ legal_values 8 to 4096
+ description "
+ The CAN device driver will run in interrupt mode
+ and will perform buffering of incoming data. This
+ option controls the number of CAN events the RX
+ queue can store."
+ }
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_CAN[set ::channel]_ACCFILT_STARTUP_CFG {
+ display "Acceptance filter startup configuration"
+ flavor data
+ legal_values {"RX_ALL" "RX_NONE"}
+ default_value {"RX_ALL"}
+ active_if CYGOPT_DEVS_CAN_LPC2XXX_RUNTIME_ACCFILT
+ description "
+ Normally the acceptance filter will be configured
+ at startup time to receive all available CAN
+ messages. The application can setup single message
+ filters during runtime later. If RX_NONE is
+ selected then the acceptance filter for this
+ channel is configured to receive no CAN message
+ identifier."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_RX_INT_PRIORITY {
+ display "Priority level of CAN module [set ::channel] receive interrupt"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN module [set ::channel]
+ device receive interrupt priority level. We
+ support up to 17 interrupt levels. Interrupts
+ 0 - 15 are vectored interrupt
+ requests. Priority 16 indicates a non vectored
+ IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the
+ highest priority and slot 15 has the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_TX_INT_PRIORITY {
+ display "Priority level of CAN module [set ::channel] transmit interrupt"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN module [set ::channel]
+ device transmit interrupt priority level. We
+ support up to 17 interrupt levels. Interrupts
+ 0 - 15 are vectored interrupt
+ requests. Priority 16 indicates a non vectored
+ IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the
+ highest priority and slot 15 has the lowest."
+ }
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY {
+ display "Priority level of CAN error interrupt"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN device error interrupt priority level.
+ We support up to 17 interrupt levels. Interrupts 0 - 15
+ are vectored interrupt requests. Priority 16 indicates a
+ non vectored IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the highest priority
+ and slot 15 has the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY {
+ display "Priority level of all CAN interrupts"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION >= 4
+ default_value 15
+ legal_values 0 to 15
+ description "
+ The LPC24xx family uses one single interrupt vector for
+ all CAN interrupts of all CAN channels. This if very
+ different from former LPC2xxx variants where each CAN
+ channels has its own interrupt vectors for transmit
+ and receive interrupts. There are 16 priority
+ levels, corresponding to the values 0 through 15 decimal,
+ of which 15 is the lowest priority. The reset value of
+ these interrupt priority registers defaults all interrupts
+ to the lowest priority 15, allowing a single write to
+ elevate the priority of an individual interrupt."
+ }
+
+ cdl_option CYGPKG_DEVS_CAN_LPC2XXX_TESTS {
+ display "CAN LPC2xxx device driver tests"
+ flavor data
+ no_define
+ calculated { "tests/can_busload tests/can_rx_tx" }
+ description "
+ This option specifies the set of tests for the LPC2xxx
+ CAN device driver."
+ }
+
+ cdl_option CYGBLD_DEVS_CAN_LPC2XXX_EXTRA_TESTS {
+ display "Build extra CAN tests"
+ default_value 0
+ no_define
+ description "
+ This option enables the building of some extra tests which
+ can be used when testing / debugging the LPC2xxx CAN driver. These
+ are not built by default since they do not use the dedicated
+ testing infrastructure. All tests require a properly configured
+ CAN network with a second CAN node that can send and receive
+ CAN messages."
+
+ make -priority 320 {
+ <PREFIX>/bin/can_multichan_rx : <PACKAGE>/tests/can_multichan_rx.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_multichan_rx.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_multichan_rx.o
+ }
+
+ make -priority 320 {
+ <PREFIX>/bin/can_multichan_tx : <PACKAGE>/tests/can_multichan_tx.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_multichan_tx.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_multichan_tx.o
+ }
+
+ make -priority 320 {
+ <PREFIX>/bin/can_baudrates : <PACKAGE>/tests/can_baudrates.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_baudrates.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_baudrates.o
+ }
+
+ make -priority 320 {
+ <PREFIX>/bin/can_extended_cfg : <PACKAGE>/tests/can_extended_cfg.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_extended_cfg.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_extended_cfg.o
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_CAN_LPC2XXX_H
+#define CYGONCE_CAN_LPC2XXX_H
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/include/can_lpc2xxx.h
+//
+// Extended configuration option for LPC2xxx CAN driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-02-08
+// Purpose: Extended configuration options for LPC2xxx CAN driver
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+//
+// The LPC2XXX supports enhanced configuration options that are not supported
+// be the generic CAN I/O layer. Be careful with using this extension
+// because they may reduce portability of your application
+//
+
+//--------------------------------------------------------------------------
+// Message filter configuration
+//
+#define CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP CYG_IO_SET_CONFIG_CAN_ABORT + 0x10 // add message filter group
+
+
+//--------------------------------------------------------------------------
+// Mode setup of LPC2XXX
+//
+#define CYGNUM_CAN_MODE_LPC2XXX_LISTEN_ONLY 0x80 // set controller in listen only mode
+
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+//
+// structure for configuration of message filter groups
+//
+typedef struct cyg_can_filtergroup_cfg_st
+{
+ cyg_can_id_type ext;
+ cyg_uint32 lower_id_bound;
+ cyg_uint32 upper_id_bound;
+} cyg_can_filtergroup_cfg;
+
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_CAN_LPC2XXX_H
--- /dev/null
+#ifndef CYGONCE_CAN_LPC2XXX_BAUDRATES_H
+#define CYGONCE_CAN_LPC2XXX_BAUDRATES_H
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/include/can_lpc2xxx_baudrates.h
+//
+// Precalculated values for bit timing register
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-07-01
+// Purpose: Precalculated bit timing values for various baudrates
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//
+// Macro for creation of CAN_BR value for baudrate tbl
+//
+#define CAN_BR_TBL_ENTRY(_brp_, _tseg1_, _tseg2_, _sjw_, _sam_) \
+ ((_sam_ << 23) | (_tseg2_ << 20) | (_tseg1_ << 16) | (_sjw_ << 14) | (_brp_))
+
+
+#ifndef CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK
+#error "CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK not defined"
+#endif
+//==========================================================================
+// BAUDRATES
+//==========================================================================
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 60000000
+//
+// Table with register values for baudrates at peripheral clock of 60 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(300, 15, 2, 0, 1), // 10 kbaud
+ CAN_BR_TBL_ENTRY(150, 15, 2, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(39, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 4, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 60000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 30000000
+//
+// Table with register values for baudrates at peripheral clock of 30 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 20 kbaud - not supported
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(39, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 4, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 30000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 15000000
+//
+// Table with register values for baudrates at peripheral clock of 15 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(59, 15, 7, 0, 1), // 10 kbaud
+ CAN_BR_TBL_ENTRY(49, 11, 1, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(19, 11, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY( 9, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 1, 11, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 800 kbaud - not supported
+ CAN_BR_TBL_ENTRY( 0, 11, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 15000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 48000000
+//
+// Table with register values for baudrates at peripheral clock of 48 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 20 kbaud - not supported
+ CAN_BR_TBL_ENTRY(59, 12, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(23, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY(11, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 5, 12, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 2, 12, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 48000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 24000000
+//
+// Table with register values for baudrates at peripheral clock of 24 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(11, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY( 5, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 2, 12, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 1, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 1, 5, 0, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 24000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 12000000
+//
+// Table with register values for baudrates at peripheral clock of 12 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY(39, 11, 1, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY( 5, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY( 2, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 2, 05, 0, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 0, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 0, 9, 0, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 12000000
+
+
+//==========================================================================
+// BIT TIMING MACRO
+//==========================================================================
+//
+// Macro fills baudrate register value depending on selected baudrate
+// For several LPC2XXX peripheral clock speeds we provide a pre calculated
+// baudrate table. If the board uses another clock speed, then the platform
+// HAL needs to provide an own HAL_LPC2XXX_GET_CAN_BR() macro that returns
+// valid baudrate register values or it needs to patch this file with
+// an additional table for the desired clock speed
+//
+//
+// If a certain baudrate is not supported, then this macro shall return
+// 0 as the baudrate register value
+//
+#ifdef HAL_LPC2XXX_BAUD_TBL_DEFINED
+#define HAL_LPC2XXX_GET_CAN_BR(_baudrate_, _br_) \
+CYG_MACRO_START \
+ _br_ = lpc2xxx_br_tbl[(_baudrate_) - CYGNUM_CAN_KBAUD_10]; \
+CYG_MACRO_END
+#endif // HAL_LPC2XXX_BAUD_TBL_DEFINED
+
+//-------------------------------------------------------------------------
+#endif // #ifndef CYGONCE_CAN_LPC2XXX_BAUDRATES_H
--- /dev/null
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c
+//
+// Acceptance filter management for LPC2xxx CAN driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-05-28
+// Purpose: Support LPC2xxx on-chip CAN acceptance filters
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//===========================================================================
+// Data types
+//===========================================================================
+//
+// Acceptance filter entry
+//
+typedef struct lpc2xxx_accfilt_entry
+{
+ cyg_uint32 data; // the value inclusive channel number
+ cyg_uint32 id;
+ cyg_uint32 lower_id_bound;
+ cyg_uint32 upper_id_bound;
+ cyg_uint8 channel_no;
+} lpc2xxx_accfilt_entry_t;
+
+
+//===========================================================================
+// Declarations
+//===========================================================================
+//--------------------------------------------------------------------------
+// On no-suffix and /00 devices, the CAN controllers are numbered 1 to n
+// (n = 2 or 4) in the LUT tables. However, on /01 devices, the CAN controllers
+// are numbered 0 to nâ1 in the LUT tables.
+//
+// On the LPC2468 the LUT channel numbers are also numbered from 0 - 4.
+//
+#if defined(CYGHWR_HAL_ARM_LPC2XXX_SUFFIX_01) || (CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION == 4)
+# define LPC2XXX_CAN_FIRST_IN_LUT (0)
+#else
+# define LPC2XXX_CAN_FIRST_IN_LUT (1)
+#endif
+
+//
+// This macro calculates the chanel number from the channel info. The channel
+// number is numbered from 0 - 3 but in the LUT the channel number may differ
+// depending on the device suffix. For some devices the channel number in
+// LUT are numbered 0 - 3 and for other devices the channels in LUT are
+// numbered 1 - 4. This macro abstrats this fact from the acceptance filter
+// code
+//
+#define CAN_CHAN_NO_LUT(_info_) (CAN_CHAN_NO(_info_) + LPC2XXX_CAN_FIRST_IN_LUT)
+
+//--------------------------------------------------------------------------
+// Lowlevel acceptance filter access
+//
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+static bool lpc2xxx_can_accfilt_add(lpc2xxx_can_info_t *info,
+ cyg_uint32 lower_id,
+ cyg_uint32 upper_id,
+ cyg_can_id_type ext);
+void lpc2xxx_can_accfilt_ram_insert_entry(cyg_uint32 TableAddress, cyg_uint16 EntryNo);
+void lpc2xxx_can_accfilt_ram_remove_entry(cyg_uint32 TableAddress, cyg_uint16 EntryNo);
+void lpc2xxx_can_accfilt_remove_all_ctrl_entries(lpc2xxx_can_info_t *info);
+#else
+static void lpc2xxx_can_accfilt_simple_rx_all(void);
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+void lpc2xxx_can_accfilt_reset(void);
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+void lpc2xxx_can_accfilt_dbg_dump(void);
+void lpc2xxx_can_reg_dump(struct cyg_devtab_entry* devtab_entry);
+#endif
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Calculate address of entry in certain table
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_accfilt_calc_entry_address(cyg_uint32 TableAddressRegister, cyg_uint16 EntryNo)
+{
+ cyg_uint32 EntryAddress = 0xFFFFFFFF;
+ cyg_uint32 TableAddress;
+
+ HAL_READ_UINT32(TableAddressRegister, TableAddress);
+ switch (TableAddressRegister)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ EntryAddress = ((EntryNo / 2) << 2) + TableAddress;
+ break;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ EntryAddress = TableAddress + (EntryNo << 2);
+ break;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ EntryAddress = TableAddress + (EntryNo << 2);
+ break;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ EntryAddress = TableAddress + (EntryNo << 3);
+ break;
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ default:
+ CYG_ASSERT(0, "Wrong TableAddressRegister");
+ }
+
+ return EntryAddress;
+}
+
+
+//===========================================================================
+// Remove one single entry from acceptance filter table
+//===========================================================================
+void lpc2xxx_can_accfilt_ram_remove_entry(cyg_uint32 Table, cyg_uint16 EntryNo)
+{
+ cyg_int32 remove_address = lpc2xxx_can_accfilt_calc_entry_address(Table, EntryNo);
+ cyg_int32 entry_address;
+ lsc_buf_t lsc_val;
+ cyg_uint8 entry_size = sizeof(cyg_uint32);
+ cyg_uint32 sff_sa;
+ cyg_uint32 sff_grp_sa;
+ cyg_uint32 eff_sa;
+ cyg_uint32 eff_grp_sa;
+ cyg_int32 end_of_table;
+
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+ //
+ // Do not try to remove from an empty table
+ //
+ if (!end_of_table)
+ {
+ return;
+ }
+
+ entry_address = remove_address;
+
+ if ((remove_address < eff_grp_sa) && (CAN_ACCFILT_EFF_GRP_SA != Table))
+ {
+ if ((remove_address < eff_sa) && (CAN_ACCFILT_EFF_SA != Table))
+ {
+ if ((remove_address < sff_grp_sa) && (CAN_ACCFILT_SFF_GRP_SA != Table))
+ {
+ lsc_buf_t nextval;
+
+ if (EntryNo % 2)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + remove_address, lsc_val.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + remove_address + sizeof(cyg_uint32), nextval.dword);
+ lsc_val.column.upper = nextval.column.lower;
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Start copy immediatelly after removed entry
+ //
+ while (entry_address < sff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address + sizeof(cyg_uint32), nextval.dword);
+ lsc_val.column.lower = lsc_val.column.upper;
+ lsc_val.column.upper = nextval.column.lower;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // now check if the lower identifier is disabled - if it is disabled, then
+ // also the upper identifier is invalid and we can remove the entry completely
+ // if the lower identifier is not disabled, then it is valid and we need
+ // to disable the upper identifier because it contains an invalid entry
+ //
+ if (lsc_val.column.lower & ACCFILT_STD_DIS)
+ {
+ sff_grp_sa -= sizeof(cyg_uint32);
+ entry_address = sff_grp_sa;
+ }
+ else
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword);
+ lsc_val.column.upper = 0xffff;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword);
+ entry_size = 0; // we do not need to remove anything
+ }
+ } // if (pLine < pStdGrpStart)
+
+ eff_sa -= entry_size;
+ } // if (pLine < pExtIdStart)
+
+ eff_grp_sa -= entry_size;
+ } // if (pLine < pExtGrpStart)
+
+ //
+ // If no entry was removed then we can leave immediately without changing any
+ // table pointers because we only did a change inside the sff table
+ //
+ if (!entry_size)
+ {
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+ return;
+ }
+
+ if (CAN_ACCFILT_EFF_GRP_SA == Table)
+ {
+ //
+ // If we are in the area of extended groups then we need to remove
+ // 2 lines because lower and upper identifier need 1 line each
+ //
+ entry_size += sizeof(cyg_uint32);
+ }
+
+ end_of_table -= entry_size;
+
+ //
+ // Move all entries one or two dword downwards - that means we remove a line
+ //
+ while (entry_address < end_of_table)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address + entry_size, lsc_val.dword);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+}
+
+//===========================================================================
+// Insert one empty line into ram - all entries behind this line will be
+// moved one entry upwards
+//===========================================================================
+void lpc2xxx_can_accfilt_ram_insert_entry(cyg_uint32 Table, cyg_uint16 EntryNo)
+{
+ cyg_int16 insert_address = lpc2xxx_can_accfilt_calc_entry_address(Table, EntryNo);
+ cyg_int16 entry_address;
+ cyg_int16 copy_start = insert_address;
+ lsc_buf_t lsc_val;
+ cyg_uint8 entry_size = sizeof(cyg_uint32);
+ cyg_uint32 sff_sa;
+ cyg_uint32 sff_grp_sa;
+ cyg_uint32 eff_sa;
+ cyg_uint32 eff_grp_sa;
+ cyg_uint32 end_of_table;
+
+
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+ if ((insert_address <= eff_grp_sa) && (CAN_ACCFILT_EFF_GRP_SA != Table))
+ {
+ if ((insert_address <= eff_sa) && (CAN_ACCFILT_EFF_SA != Table))
+ {
+ if ((insert_address <= sff_grp_sa) && (CAN_ACCFILT_SFF_GRP_SA != Table))
+ {
+ //
+ // If we are in the range of standard identifiers then we need to
+ // do some special copy procedure for this area because a standard entry
+ // is only 2 byte long. Copy only til start of area with standard groups
+ //
+ if (sff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword); // read last entry
+ //
+ // now check if the upper identifier is disabled - if it is disabled, then
+ // we have an odd number of std ids in the list. Then we do not need to
+ // insert a new line - we simply need to copy all entries 2 bytes upwards
+ // that means we only need to change the std id area and do not need to touch
+ // any other filter id area.
+ // If the last entry is not disabled, then we have a valid filter here.
+ // Then we need to insert a complete new line, that means we also have to move
+ // all following entries and filter tables one dword upwards.
+ //
+ if (lsc_val.words.low & ACCFILT_STD_DIS)
+ {
+ copy_start = end_of_table + sizeof(cyg_uint32); // we do not need to insert a new line and do not copy anything
+ entry_size = 0;
+ }
+ }
+
+ if (entry_size)
+ {
+ copy_start = sff_grp_sa; // copy everything behind std id group
+ sff_grp_sa += entry_size;
+ }
+ } // if (pLine < pStdGrpStart)
+
+ eff_sa += entry_size;
+ } // if (pLine < pExtIdStart)
+
+ eff_grp_sa += entry_size;
+ } // if (pLine < pExtGrpStart)
+
+ if (CAN_ACCFILT_EFF_GRP_SA == Table)
+ {
+ //
+ // If we are in the area of extended groups then we need to insert
+ // 2 lines because lower and upper identifier need 1 line each
+ //
+ entry_size += sizeof(cyg_uint32); // one entry is 2 dword long
+ }
+
+ entry_address = end_of_table - sizeof(cyg_uint32);
+ end_of_table += entry_size; // add one additional entry
+
+ //
+ // Move all entries one or two dwords upwards - that means we insert a new empty line
+ //
+ while (entry_address >= copy_start)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address + entry_size, lsc_val.dword);
+ entry_address -= sizeof(cyg_uint32);
+ }
+
+ //
+ // For the std ID area we need a special procedure
+ //
+ if (CAN_ACCFILT_SFF_SA == Table)
+ {
+ lsc_buf_t preval;
+ //
+ // Start copy with last entry of std id table
+ //
+ entry_address = sff_grp_sa - sizeof(cyg_uint32);
+
+ while (entry_address > insert_address)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address - sizeof(cyg_uint32), preval.dword);
+ lsc_val.column.upper = lsc_val.column.lower;
+ lsc_val.column.lower = preval.column.upper;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword);
+ entry_address -= sizeof(cyg_uint32);
+ }
+
+ //
+ // If we insert an entry into the lower column, then we need to move the
+ // content of the lower column into the upper column
+ //
+ if (!(EntryNo % 2))
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)insert_address, lsc_val.dword);
+ lsc_val.column.upper = lsc_val.column.lower;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)insert_address, lsc_val.dword);
+ }
+
+ //
+ // If we inserted a new line, then we have an odd number of identifiers now
+ // and need to disable the last (the upper) entry
+ //
+ if (entry_size)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32) , lsc_val.dword);
+ lsc_val.column.upper = 0xFFFF; // disable the entry
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32) , lsc_val.dword);
+ }
+ }
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+}
+
+
+//===========================================================================
+// Query number of entries in a certain table
+//===========================================================================
+static cyg_uint16 lpc2xxx_can_accfilt_get_table_entries(cyg_uint32 TableStartAddress)
+{
+ cyg_uint32 start;
+ cyg_uint32 end;
+
+ switch (TableStartAddress)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, end);
+ if (end - start)
+ {
+ lsc_buf_t data;
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + end - sizeof(cyg_uint32), data.dword);
+ if (data.column.upper & ACCFILT_STD_DIS)
+ {
+ return (((end - start) >> 1) - 1);
+ }
+ }
+ return (end - start) >> 1;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, end);
+ return (end - start) >> 2;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, end);
+ return (end - start) >> 2;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end);
+ return (end - start) >> 3;
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ default:
+ CYG_FAIL("Invalid identifier table address");
+ return 0;
+ } // switch (TableStartAddress)
+}
+
+//===========================================================================
+// Query certain entry from table
+//===========================================================================
+static void lpc2xxx_can_accfilt_get_entry(cyg_uint32 TableStartAddress, cyg_uint16 EntryNo, lpc2xxx_accfilt_entry_t *pEntry)
+{
+ cyg_uint32 EntryAddress = lpc2xxx_can_accfilt_calc_entry_address(TableStartAddress, EntryNo);
+ lsc_buf_t Data;
+
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword);
+ pEntry->data = Data.dword;
+ switch (TableStartAddress)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ {
+ cyg_uint16 column;
+ if (EntryNo % 2)
+ {
+ column = Data.column.upper;
+ }
+ else
+ {
+ column = Data.column.lower;
+ }
+ pEntry->id = ACCFILT_STD_GET_ID(column);
+ pEntry->channel_no = ACCFILT_STD_GET_CTRL(column);
+ }
+ break;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ pEntry->lower_id_bound = ACCFILT_STD_GET_ID(Data.column.lower);
+ pEntry->upper_id_bound = ACCFILT_STD_GET_ID(Data.column.upper);
+ pEntry->channel_no = ACCFILT_STD_GET_CTRL(Data.column.lower);
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ pEntry->id = ACCFILT_EXT_GET_ID(Data.dword);
+ pEntry->channel_no = ACCFILT_EXT_GET_CTRL(Data.dword);
+ break;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ pEntry->lower_id_bound = ACCFILT_EXT_GET_ID(Data.dword);
+ pEntry->channel_no = ACCFILT_EXT_GET_CTRL(Data.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE+ EntryAddress + sizeof(cyg_uint32), Data.dword);
+ pEntry->upper_id_bound = ACCFILT_EXT_GET_ID(Data.dword);
+ break;
+#endif // #ifedf CYGOPT_IO_CAN_EXT_CAN_ID
+ default:
+ CYG_FAIL("Invalid identifier table address");
+ } // switch ()
+}
+
+
+//===========================================================================
+// Set certain entry in table
+//===========================================================================
+static void lpc2xxx_can_accfilt_set_entry(cyg_uint32 TableStartAddress, cyg_uint16 EntryNo, lpc2xxx_accfilt_entry_t *pEntry)
+{
+ cyg_uint32 EntryAddress = lpc2xxx_can_accfilt_calc_entry_address(TableStartAddress, EntryNo);
+ lsc_buf_t Data;
+
+ switch (TableStartAddress)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword);
+ if (EntryNo % 2)
+ {
+ Data.column.upper = (pEntry->channel_no << 13) | (pEntry->id & ACCFILT_STD_ID_MASK);
+ }
+ else
+ {
+ Data.column.lower = (pEntry->channel_no << 13) | (pEntry->id & ACCFILT_STD_ID_MASK);
+ }
+ }
+ break;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ Data.column.lower = (pEntry->channel_no << 13) | (pEntry->lower_id_bound & ACCFILT_STD_ID_MASK);
+ Data.column.upper = (pEntry->channel_no << 13) | (pEntry->upper_id_bound & ACCFILT_STD_ID_MASK);
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ Data.dword = (pEntry->channel_no << 29) | (pEntry->id & ACCFILT_EXT_ID_MASK);
+ break;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ {
+ lsc_buf_t Data2;
+
+ Data.dword = (pEntry->channel_no << 29) | (pEntry->lower_id_bound & ACCFILT_EXT_ID_MASK);
+ Data2.dword = (pEntry->channel_no << 29) | (pEntry->upper_id_bound & ACCFILT_EXT_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress + sizeof(cyg_uint32), Data2.dword);
+ }
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+
+ default:
+ CYG_FAIL("Invalid identifier table address");
+ } // switch ()
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword);
+}
+
+
+//===========================================================================
+// Add one entry to acceptance filter RAM
+// If upper ID is > lower ID then we have to add a group filter - else we
+// have to add a single message filter here
+//===========================================================================
+static bool lpc2xxx_can_accfilt_add(lpc2xxx_can_info_t *info,
+ cyg_uint32 lower_id,
+ cyg_uint32 upper_id,
+ cyg_can_id_type ext)
+{
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ cyg_uint32 end_of_table;
+ cyg_uint32 table;
+ lpc2xxx_accfilt_entry_t entry;
+ lpc2xxx_accfilt_entry_t new_entry;
+
+
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // Check if table is full
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+ if (end_of_table >= ACCFILT_RAM_SIZE)
+ {
+ return false;
+ }
+
+ new_entry.id = lower_id;
+ new_entry.lower_id_bound = lower_id;
+ new_entry.upper_id_bound = upper_id;
+
+ //
+ // Here we rely on the ISR vector ordering for calculation of channel number
+ // Maybe this is not the right way for newer LPC parts
+ //
+ new_entry.channel_no = CAN_CHAN_NO_LUT(info);
+
+ //
+ // If lower_id == upper_id then we know that we have to setup a single message filter
+ // here. If it is not equal the it is group of identifiers to receive
+ //
+ if ((lower_id == upper_id) || (lower_id > upper_id))
+ {
+ //
+ // setup single message filter (standard or extended) here
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (ext)
+ {
+ table = CAN_ACCFILT_EFF_SA;
+ }
+ else
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ table = CAN_ACCFILT_SFF_SA;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ }
+ }
+ else
+ {
+ //
+ // setup single message filter (standard or extended) here
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (ext)
+ {
+ table = CAN_ACCFILT_EFF_GRP_SA;
+ }
+ else
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ table = CAN_ACCFILT_SFF_GRP_SA;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ }
+ }
+
+ cyg_uint16 entries = lpc2xxx_can_accfilt_get_table_entries(table);
+ cyg_uint16 i;
+
+
+ for (i = 0; i < entries; ++i)
+ {
+ lpc2xxx_can_accfilt_get_entry(table, i, &entry);
+
+ if (entry.channel_no > new_entry.channel_no)
+ {
+ break;
+ }
+
+ if ((entry.channel_no == new_entry.channel_no)
+ && (entry.id > new_entry.id))
+ {
+ break;
+ }
+ } // for (i = 0; i < entries; ++i)
+
+ lpc2xxx_can_accfilt_ram_insert_entry(table, i);
+ lpc2xxx_can_accfilt_set_entry(table, i, &new_entry);
+
+ //
+ // finally restore the previous state of the acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ return true;
+}
+
+
+//===========================================================================
+// Remove all entries from a certain controller
+//===========================================================================
+void lpc2xxx_can_accfilt_remove_all_ctrl_entries(lpc2xxx_can_info_t *info)
+{
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ cyg_uint16 i;
+ cyg_uint16 entries;
+ cyg_uint32 TableStartAddress = CAN_ACCFILT_SFF_SA;
+ lpc2xxx_accfilt_entry_t Entry;
+ cyg_uint8 channel_no = CAN_CHAN_NO_LUT(info);
+ cyg_uint16 entry_idx;
+
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // now remove all entries for a certain controller
+ //
+ for (TableStartAddress = CAN_ACCFILT_SFF_SA; TableStartAddress < CAN_ACCFILT_ENDOFTABLE; TableStartAddress += 4)
+ {
+ entries = lpc2xxx_can_accfilt_get_table_entries(TableStartAddress);
+ entry_idx = 0;
+ for (i = 0; i < entries; ++i)
+ {
+ lpc2xxx_can_accfilt_get_entry(TableStartAddress, entry_idx, &Entry);
+ if (Entry.channel_no == channel_no)
+ {
+ lpc2xxx_can_accfilt_ram_remove_entry(TableStartAddress, entry_idx);
+ }
+ else
+ {
+ entry_idx++;
+ }
+ } // for (i = 0; i < entries; ++i)
+ } // for (TableStartAddress = CAN_ACCFILT_SFF_SA ...
+
+ //
+ // finally restore the previous state of the acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifndef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Setup reception of all CAN identifiers
+// If runtime acceptance filter configuration is not required then we simply
+// setup the acceptance filter here to receive all CAN identifiers
+//===========================================================================
+static void lpc2xxx_can_accfilt_simple_rx_all(void)
+{
+ cyg_uint32 regval;
+
+ //
+ // First check if it is really necessary to setup filters. If end of table is
+ // != 0 then the acceptance filter is already setup properly
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, regval);
+ if (regval)
+ {
+ return;
+ }
+
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ cyg_uint8 i = 0; // loop counter
+ lsc_buf_t accfilt_entry; // std group entry
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ cyg_uint8 std_address = 0; // std group entry address
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_uint8 ext_address = lpc2xxx_global_can_info.init_cnt << 2;
+#endif
+#else
+ cyg_uint8 ext_address = 0;
+#endif
+
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // Write table start adresses - we use only standard group and extended filter
+ // group
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, ext_address);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, ext_address);
+
+ //
+ // Now loop through all active CAN channels and setup the acceptance filter for
+ // each channel to receive all standard and extended CAN identifiers
+ //
+ while (lpc2xxx_global_can_info.active_channels[i])
+ {
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)lpc2xxx_global_can_info.active_channels[i++]->dev_priv;
+ cyg_uint8 channel_no = CAN_CHAN_NO_LUT(info);
+
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ accfilt_entry.column.lower = (channel_no << 13) | (0x000 & ACCFILT_STD_ID_MASK);
+ accfilt_entry.column.upper = (channel_no << 13) | (0x7FF & ACCFILT_STD_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + std_address, accfilt_entry.dword);
+ std_address += sizeof(cyg_uint32);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ accfilt_entry.dword = (channel_no << 29) | (0x00000000 & ACCFILT_EXT_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + ext_address, accfilt_entry.dword);
+ ext_address += sizeof(cyg_uint32);
+ accfilt_entry.dword = (channel_no << 29) | (0x1FFFFFFF & ACCFILT_EXT_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + ext_address, accfilt_entry.dword);
+ ext_address += sizeof(cyg_uint32);
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ } // while (lpc2xxx_global_can_info.active_channels[i])
+
+ //
+ // finally store end of table value and restore the previous state of the
+ // acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, ext_address);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//===========================================================================
+// Reset acceptance filter to poweron defaults
+//===========================================================================
+void lpc2xxx_can_accfilt_reset(void)
+{
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // Now write zero to all addresses of acceptance filter table
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, 0);
+
+ //
+ // finally restore the previous state of the acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+}
+
+
+//===========================================================================
+// Dump content of acceptance filter lookup table
+//===========================================================================
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+void lpc2xxx_can_accfilt_dbg_dump(void)
+{
+ cyg_uint32 sff_sa;
+ cyg_uint32 sff_grp_sa;
+ cyg_uint32 eff_sa;
+ cyg_uint32 eff_grp_sa;
+ cyg_uint32 end_of_table;
+ cyg_uint32 entry_address;
+ lsc_buf_t data;
+
+
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+ entry_address = sff_sa;
+
+ //
+ // Print lookup table registers
+ //
+ diag_printf("\n\nDUMP CAN ACCEPTANCE FILTER REGISTERS\n");
+ diag_printf("----------------------------------------\n");
+ diag_printf("SFF_sa:\t\t0x%08x\n", sff_sa);
+ diag_printf("SFF_GRP_sa:\t0x%08x\n", sff_grp_sa);
+ diag_printf("EFF_sa:\t\t0x%08x\n", eff_sa);
+ diag_printf("EFF_GRP_sa:\t0x%08x\n", eff_grp_sa);
+ diag_printf("EOT:\t\t0x%08x\n", end_of_table);
+
+ //
+ // Print table of standard identifiers
+ //
+ diag_printf("\n\nDUMP CAN LOOKUP TABLE RAM");
+ diag_printf("\nSFF_sa\t\tcolumn_lower\tcolumn_upper\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < sff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t0x%x\t\t0x%x\t\t0x%x\n", entry_address, data.column.lower, data.column.upper, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Print table of standard identifier groups
+ //
+ diag_printf("\nSFF_GRP_sa\tcolumn_lower\tcolumn_upper\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < eff_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t0x%x\t\t0x%x\t\t0x%x\n", entry_address, data.column.lower, data.column.upper, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Print table of extended identifiers
+ //
+ diag_printf("\nEFF_sa\t\t-\t\t-\t\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < eff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t\t\t\t\t0x%x\n", entry_address, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Print table of extended identifier groups
+ //
+ diag_printf("\nEFF_GRP_sa\t-\t\t-\t\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < end_of_table)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t\t\t\t\t0x%x\n", entry_address, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+}
+#endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+
+//===========================================================================
+// Dump content of acceptance filter lookup table
+//===========================================================================
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+void lpc2xxx_can_reg_dump(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ cyg_uint32 reg_val;
+ CAN_DECLARE_INFO(chan);
+
+ chan = chan; // avoid compiler warnings for unused variables
+ //
+ // Print table of extended identifier groups
+ //
+ diag_printf("\n\nCAN REGISTER DUMP\n");
+ diag_printf("\nRegister\tValue\n");
+ diag_printf("----------------------------------------------------------\n");
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), reg_val);
+ diag_printf("CANMOD\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_CMR(info), reg_val);
+ diag_printf("CANCMR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), reg_val);
+ diag_printf("CANGSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), reg_val);
+ diag_printf("CANICR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_IER(info), reg_val);
+ diag_printf("CANIER\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_BTR(info), reg_val);
+ diag_printf("CANBTR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_EWL(info), reg_val);
+ diag_printf("CANEWL\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_SR(info), reg_val);
+ diag_printf("CANSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RFS(info), reg_val);
+ diag_printf("CANRFS\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RID(info), reg_val);
+ diag_printf("CANRID\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RDA(info), reg_val);
+ diag_printf("CANRDA\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RDB(info), reg_val);
+ diag_printf("CANRDB\t\t0x%08x\n", reg_val);
+
+ diag_printf("\n\nCAN CENTRAL REGISTER DUMP\n");
+ diag_printf("\nRegister\tValue\n");
+ diag_printf("----------------------------------------------------------\n");
+ HAL_READ_UINT32(CAN_CENTRAL_TXSR, reg_val);
+ diag_printf("CANTxSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CENTRAL_RXSR, reg_val);
+ diag_printf("CANRxSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CENTRAL_MSR, reg_val);
+ diag_printf("CANMSR\t\t0x%08x\n", reg_val);
+
+ diag_printf("\n\nCAN ACCEPTANCE FILTER REGISTER DUMP\n");
+ diag_printf("\nRegister\tValue\n");
+ diag_printf("----------------------------------------------------------\n");
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, reg_val);
+ diag_printf("AFMR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, reg_val);
+ diag_printf("LUTERR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, reg_val);
+ diag_printf("LUTERRADDR\t0x%08x\n", reg_val);
+}
+#endif // #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+
+//---------------------------------------------------------------------------
+// EOF can_accfilt_lpc2xxx.c
--- /dev/null
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
+//
+// CAN driver for LPC2xxx microcontrollers
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-04-09
+// Purpose: Support LPC2xxx on-chip CAN moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/io_can.h>
+#include <pkgconf/io.h>
+#include <pkgconf/devs_can_lpc2xxx.h>
+
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/can.h>
+#include <cyg/io/can_lpc2xxx.h>
+#include <cyg/io/can_lpc2xxx_baudrates.h>
+
+
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+//
+// Check if the macro HAL_LPC2XXX_GET_CAN_BR is provided
+//
+#ifndef HAL_LPC2XXX_GET_CAN_BR
+#error "Macro HAL_LPC2XXX_GET_CAN_BR() missing"
+#endif
+
+//
+// Support debug output if this option is enabled in CDL file
+//
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+#define LPC2XXX_DBG_PRINT diag_printf
+#else
+#define LPC2XXX_DBG_PRINT( fmt, ... )
+#endif
+
+
+//---------------------------------------------------------------------------
+// we define our own set of register bits in order to be independent from
+// platform specific names
+//
+
+//---------------------------------------------------------------------------
+// Memory map of CAN block
+//
+#define CAN_ACCFILT_RAM_BASE 0xE0038000
+#define CAN_ACCFILT_REG_BASE 0xE003C000
+#define CAN_CENTRAL_REG_BASE 0xE0040000
+#define CAN_CTRL_1_REG_BASE 0xE0044000
+#define CAN_CTRL_2_REG_BASE 0xE0048000
+#define CAN_CTRL_3_REG_BASE 0xE004C000
+#define CAN_CTRL_4_REG_BASE 0xE0050000
+
+
+//---------------------------------------------------------------------------
+// CAN Acceptance Filter register layout
+//
+#define CAN_ACCFILT_AFMR (CAN_ACCFILT_REG_BASE + 0x0000)
+#define CAN_ACCFILT_SFF_SA (CAN_ACCFILT_REG_BASE + 0x0004)
+#define CAN_ACCFILT_SFF_GRP_SA (CAN_ACCFILT_REG_BASE + 0x0008)
+#define CAN_ACCFILT_EFF_SA (CAN_ACCFILT_REG_BASE + 0x000C)
+#define CAN_ACCFILT_EFF_GRP_SA (CAN_ACCFILT_REG_BASE + 0x0010)
+#define CAN_ACCFILT_ENDOFTABLE (CAN_ACCFILT_REG_BASE + 0x0014)
+#define CAN_ACCFILT_LUT_ERR_ADDR (CAN_ACCFILT_REG_BASE + 0x0018)
+#define CAN_ACCFILT_LUT_ERR (CAN_ACCFILT_REG_BASE + 0x001C)
+
+//---------------------------------------------------------------------------
+// CAN_ACCFILT_AFMR Bits
+//
+#define AFMR_OFF 0x00000001 // 1 = Acceptance filter is not operational
+#define AFMR_BYPASS 0x00000002 // 1 = all Rx messages are accepted on enabled CAN controllers.
+#define AFMR_FULLCAN 0x00000004 // 1 = FullCAN mode
+#define AFMR_ON 0x00000000 // Acceptance filter on
+#define ACCFILT_RAM_SIZE 2048 // size of acceptance filter ram
+
+
+//---------------------------------------------------------------------------
+// Acceptance filter tool macros
+//
+#define ACCFILT_STD_ID_MASK 0x7FF
+#define ACCFILT_EXT_ID_MASK 0x1FFFFFFF
+#define ACCFILT_STD_DIS 0x1000
+#define ACCFILT_STD_CTRL_MASK 0xE000
+#define ACCFILT_EXT_CTRL_MASK 0xE0000000
+#define ACCFILT_STD_GET_CTRL(_entry_) (((_entry_) >> 13) & 0x7)
+#define ACCFILT_STD_GET_CTRL_LOWER(_entry_) (((_entry_) >> 29) & 0x7)
+#define ACCFILT_STD_GET_CTRL_UPPER(_entry_) (((_entry_) >> 13) & 0x7)
+#define ACCFILT_STD_GET_ID(_entry_) ((_entry_) & ACCFILT_STD_ID_MASK)
+#define ACCFILT_EXT_GET_ID(_entry_) ((_entry_) & ACCFILT_EXT_ID_MASK)
+#define ACCFILT_EXT_GET_CTRL(_entry_) (((_entry_) >> 29) & 0x7)
+#define ACCFILT_EXT_SET_CTRL(_entry_, _ctrl_) ((_entry_ & 0xE0000000) | ((_ctrl_) << 29))
+
+
+//---------------------------------------------------------------------------
+// CAN Central CAN Registers register layout
+//
+#define CAN_CENTRAL_TXSR (CAN_CENTRAL_REG_BASE + 0x0000)
+#define CAN_CENTRAL_RXSR (CAN_CENTRAL_REG_BASE + 0x0004)
+#define CAN_CENTRAL_MSR (CAN_CENTRAL_REG_BASE + 0x0008)
+
+
+//---------------------------------------------------------------------------
+// CAN Controller register offsets
+// Registers are offsets from base CAN module control register
+//
+#define CANREG_MOD 0x0000
+#define CANREG_CMR 0x0004
+#define CANREG_GSR 0x0008
+#define CANREG_ICR 0x000C
+#define CANREG_IER 0x0010
+#define CANREG_BTR 0x0014
+#define CANREG_EWL 0x0018
+#define CANREG_SR 0x001C
+#define CANREG_RFS 0x0020
+#define CANREG_RID 0x0024
+#define CANREG_RDA 0x0028
+#define CANREG_RDB 0x002C
+#define CANREG_TFI1 0x0030
+#define CANREG_TID1 0x0034
+#define CANREG_TDA1 0x0038
+#define CANREG_TDB1 0x003C
+#define CANREG_TFI2 0x0040
+#define CANREG_TID2 0x0044
+#define CANREG_TDA2 0x0048
+#define CANREG_TDB2 0x004C
+#define CANREG_TFI3 0x0050
+#define CANREG_TID3 0x0054
+#define CANREG_TDA3 0x0058
+#define CANREG_TDB3 0x005C
+
+
+//---------------------------------------------------------------------------
+// CAN Controller register layout
+//
+#define CAN_CTRL_MOD(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_MOD)
+#define CAN_CTRL_CMR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_CMR)
+#define CAN_CTRL_GSR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_GSR)
+#define CAN_CTRL_ICR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_ICR)
+#define CAN_CTRL_IER(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_IER)
+#define CAN_CTRL_BTR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_BTR)
+#define CAN_CTRL_EWL(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_EWL)
+#define CAN_CTRL_SR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_SR)
+#define CAN_CTRL_RFS(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RFS)
+#define CAN_CTRL_RID(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RID)
+#define CAN_CTRL_RDA(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RDA)
+#define CAN_CTRL_RDB(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RDB)
+#define CAN_CTRL_TFI1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI1)
+#define CAN_CTRL_TID1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID1)
+#define CAN_CTRL_TDA1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA1)
+#define CAN_CTRL_TDB1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB1)
+#define CAN_CTRL_TFI2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI2)
+#define CAN_CTRL_TID2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID2)
+#define CAN_CTRL_TDA2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA2)
+#define CAN_CTRL_TDB2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB2)
+#define CAN_CTRL_TFI3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI3)
+#define CAN_CTRL_TID3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID3)
+#define CAN_CTRL_TDA3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA3)
+#define CAN_CTRL_TDB3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB3)
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_ICR register bits
+//
+#define ICR_RX 0x00000001
+#define ICR_TX1 0x00000002
+#define ICR_ERR_WARN 0x00000004
+#define ICR_DATA_OVR 0x00000008
+#define ICR_WAKE_UP 0x00000010
+#define ICR_ERR_PASSIVE 0x00000020
+#define ICR_ARBITR_LOST 0x00000040
+#define ICR_BUS_ERR 0x00000080
+#define ICR_ID_READY 0x00000100
+#define ICR_TX2 0x00000200
+#define ICR_TX3 0x00000400
+#define ICR_LUT_ERR 0x00000800
+#define ICR_GET_ERRBIT(_icr_) (((_icr_) >> 16) & 0x1F)
+#define ICR_ERR_DIRECTION 0x00200000
+#define ICR_GET_ERRCODE(_icr_) (((_icr_) >> 22) & 0x03)
+#define ICR_GET_ALCBIT(_icr_) (((_icr_) >> 24) & 0x1F)
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_ALIE
+#define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_ARBITR_LOST | ICR_BUS_ERR | ICR_ERR_WARN)
+#else
+#define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_BUS_ERR | ICR_ERR_WARN)
+#endif
+#define CAN_MISC_INT (CAN_ALL_ERR_INT | ICR_WAKE_UP)
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_ICR register bits
+//
+#define ICR_ERRCODE_BIT_ERR 0x00
+#define ICR_ERRCODE_FORM_ERR 0x01
+#define ICR_ERRCODE_STUFF_ERR 0x02
+#define ICR_ERRCODE_OTHER_ERR 0x03
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_RFS register bits
+//
+#define RFS_ACCFILT_INDEX_MASK 0x000003FF
+#define RFS_RECEIVED_IN_BYPASS_MODE 0x00000400
+#define RFS_DLC_MASK 0x000F0000
+#define RFS_RTR 0x40000000
+#define RFS_EXT 0x80000000
+#define RFS_GET_DLC(_regval_) (((_regval_) >> 16) & 0xF)
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_CMR register bits
+//
+#define CMR_TX_REQ 0x00000001
+#define CMR_TX_ABORT 0x00000002
+#define CMR_RX_RELEASE_BUF 0x00000004
+#define CMR_CLEAR_DATA_OVR 0x00000008
+#define CMR_SELF_RX_REQ 0x00000010
+#define CMR_SEND_TX_BUF1 0x00000020
+#define CMR_SEND_TX_BUF2 0x00000040
+#define CMR_SEND_TX_BUF3 0x00000080
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_TFI register bits
+//
+#define TFI_PRIO_MASK 0x000000FF
+#define TFI_DLC_MASK 0x000F0000
+#define TFI_DLC_RTR 0x40000000
+#define TFI_DLC_EXT 0x80000000
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_MOD register bits
+//
+#define CANMOD_OPERATIONAL 0x00000000
+#define CANMOD_RESET 0x00000001
+#define CANMOD_LISTEN_ONLY 0x00000002
+#define CANMOD_SELF_TEST 0x00000004
+#define CANMOD_TX_BUF_CFG 0x00000008
+#define CANMOD_SLEEP 0x00000010
+#define CANMOD_REV_POLARITY 0x00000020
+#define CANMOD_TEST 0x00000040
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_IER register bits
+//
+#define IER_RX 0x00000001
+#define IER_TX1 0x00000002
+#define IER_ERR_WARN 0x00000004
+#define IER_DATA_OVR 0x00000008
+#define IER_WAKE_UP 0x00000010
+#define IER_ERR_PASSIVE 0x00000020
+#define IER_ARBITR_LOST 0x00000040
+#define IER_BUS_ERR 0x00000080
+#define IER_ID_READY 0x00000100
+#define IER_TX2 0x00000200
+#define IER_TX3 0x00000400
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_GSR register bits
+//
+#define GSR_RX_MSG_AVAILABLE 0x00000001
+#define GSR_DATA_OVR 0x00000002
+#define GSR_TX_NOT_PENDING 0x00000004
+#define GSR_ALL_TX_COMPLETE 0x00000008
+#define GSR_RECEIVING_ACTIVE 0x00000010
+#define GSR_SENDING_ACTIVE 0x00000020
+#define GSR_ERR 0x00000040
+#define GSR_BUS_OFF 0x00000080
+#define GSR_RXERR_CNT(_reg_) (((_reg_) >> 16) & 0xFF)
+#define GSR_TXERR_CNT(_reg_) (((_reg_) >> 24) & 0xFF)
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_SR register bits
+//
+#define SR_RX_MSG_AVAILABLE 0x01
+#define SR_DATA_OVR 0x02
+#define SR_TX_BUF_WRITE_OK 0x04 // TBS1, TBS2, TBS3 (Bit 2, 10, 18)
+#define SR_TX_COMPLETE 0x08 // TCS1, TCS2, TCS3 (Bit 3, 11, 19)
+#define SR_RECEIVING_ACTIVE 0x10
+#define SR_SENDING_ACTIVE 0x20 // TS1, TS2, TS3 (5, 13, 21)
+#define SR_ERR 0x40
+#define SR_BUS_OFF 0x80
+
+
+//---------------------------------------------------------------------------
+// Optimize for the case of a single CAN channel, while still allowing
+// multiple channels.
+//
+#if CYGINT_IO_CAN_CHANNELS == 1
+#define CAN_CTRL_BASE(_extra_) CAN_CTRL_SINGLETON_BASE
+#define CAN_ISRVEC(_extra_) CAN_SINGLETON_ISRVEC
+#define CAN_CHAN_NO(_extra_) CAN_SINGLETON_CHAN_NO
+#define CAN_DECLARE_INFO(_chan_)
+#define CAN_DECLARE_CHAN(_data_)
+#else
+#define CAN_CTRL_BASE(_extra_) ((_extra_)->base)
+#define CAN_ISRVEC(_extra_) ((_extra_)->isrvec)
+#define CAN_CHAN_NO(_extra_) ((_extra_)->chan_no)
+#define CAN_DECLARE_INFO(_chan_) lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+#define CAN_DECLARE_CHAN(_data_) can_channel *chan = (can_channel *)data;
+#endif // CYGINT_IO_CAN_CHANNELS == 1
+
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN0_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN0_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN0_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN1_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN1_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN1_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN2_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN2_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN2_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN3_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN3_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN3_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+//
+// Structure stores LPC2xxx CAN channel related stuff
+//
+
+// If we use Self Reception Request command instead of the Transmission Request
+// we must add last transmit message id in order to reject it in rx_ISR
+// There are two last_tx_id because tx interrupt (and so transmission of next
+// message) happens before rx interrupt (which uses last_tx_id for rejecting))
+
+// Format of last_tx_id:
+// (bits: 28:0-ID, 29-Validation, 30-RTR, 31-EXT)
+// if last_tx_id == 0xFFFFFFFF (Validation == 1) then last id is not valid
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_IDMASK 0x1FFFFFFF
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK 0xC0000000
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID 0xFFFFFFFF
+
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_DECL cyg_uint8 last_tx_index; \
+ cyg_uint32 last_tx_id[2];
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_INIT last_tx_index : 0, \
+ last_tx_id : {LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID, LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID},
+#else
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_DECL
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_INIT
+#endif
+
+typedef struct lpc2xxx_can_info_st
+{
+//
+// Newer LPC2xxx variants like the LPC2468 do not support per channel
+// interrupts. They provide only one single interrupt vector for all
+// CAN interrupts
+//
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_interrupt tx_interrupt;
+ cyg_handle_t tx_interrupt_handle;
+ cyg_uint8 tx_interrupt_priority;
+ cyg_interrupt rx_interrupt;
+ cyg_handle_t rx_interrupt_handle;
+ cyg_uint8 rx_interrupt_priority;
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_can_state state; // state of CAN controller
+ cyg_uint8 flags; // flags indicating several states
+ LPC2XXX_CAN_INFO_LAST_TX_ID_DECL // last transmitted messages ids
+#if CYGINT_IO_CAN_CHANNELS > 1
+ cyg_uint32 base; // Per-bus h/w details
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_uint8 isrvec; // ISR vector (peripheral id)
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_uint8 chan_no; // number of CAN channel
+#endif // CYGINT_IO_CAN_CHANNELS > 1
+} lpc2xxx_can_info_t;
+
+
+#define INFO_FLAG_RX_ALL 0x01 // this bit indicates that channel receives all CAN messages - no filtering active
+#define INFO_FLAG_STARTUP_RX_ALL 0x02 // this bit indicates filter state at startup
+
+
+//
+// lpc2xxx info initialisation
+//
+#define LPC2XXX_CTRL_NOT_INITIALIZED 0xFF
+
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+#if CYGINT_IO_CAN_CHANNELS > 1
+#define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _chan_no_, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : LPC2XXX_CTRL_NOT_INITIALIZED, \
+ base : (_base), \
+ isrvec : (_isrvec), \
+ chan_no : (_chan_no_), \
+ tx_interrupt_priority : (_tx_priority), \
+ rx_interrupt_priority : (_rx_priority), \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#else // CYGINT_IO_CAN_CHANNELS == 1
+#define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+ tx_interrupt_priority : (_tx_priority), \
+ rx_interrupt_priority : (_rx_priority), \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#endif // CYGINT_IO_CAN_CHANNELS == 1
+#else // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+//
+// Newer devices support only one global CAN interrupt. We do not need
+// per channel interrupt data an ignore the values during initialisation
+//
+#if CYGINT_IO_CAN_CHANNELS > 1
+#define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _chan_no_, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : LPC2XXX_CTRL_NOT_INITIALIZED, \
+ base : (_base), \
+ chan_no : (_chan_no_), \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#else // CYGINT_IO_CAN_CHANNELS == 1
+#define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#endif // CYGINT_IO_CAN_CHANNELS == 1
+
+//
+// The following defines are only dummies required for proper
+// initialisation of can channel data structures
+//
+#define CYGNUM_HAL_INTERRUPT_CAN1_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY
+#define CYGNUM_HAL_INTERRUPT_CAN2_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY
+#define CYGNUM_HAL_INTERRUPT_CAN3_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY
+#define CYGNUM_HAL_INTERRUPT_CAN4_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+
+//
+// Acceptance filter data
+//
+typedef struct lpc2xxx_global_can_info_st
+{
+ cyg_interrupt interrupt; // common CAN interrupt
+ cyg_handle_t interrupt_handle; // common CAN interrupt handle
+ cyg_uint16 free_filters; // number of free message filter
+#if CYGINT_IO_CAN_CHANNELS > 1 // optimize for single channel
+ cyg_uint8 init_cnt; // counts number of initialized channels
+ can_channel* active_channels[5]; // stores pointers to active channels - the last entry is just a delimiter
+#else // CYGINT_IO_CAN_CHANNELS > 1
+ can_channel* active_channels[1]; // optimize for one single channel
+#endif // CYGINT_IO_CAN_CHANNELS > 1
+} lpc2xxx_global_can_info_t;
+
+
+#if CYGINT_IO_CAN_CHANNELS > 1
+#define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[_chan_no_])
+#else
+#define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[0])
+#endif
+
+//
+// The number of available message filters depends on the size of the
+// acceptance filter RAM and on the size of one entry. The size of
+// one entry is 4 byte (standard ID only 2 byte, extended groups 8 byte)
+//
+#define ACCFILT_COMMON_ENTRY_SIZE 4
+#define LPC2XXX_CAN_MSG_FILTERS_MAX (ACCFILT_RAM_SIZE / ACCFILT_COMMON_ENTRY_SIZE)
+lpc2xxx_global_can_info_t lpc2xxx_global_can_info =
+{
+ .free_filters = LPC2XXX_CAN_MSG_FILTERS_MAX,
+#if CYGINT_IO_CAN_CHANNELS > 1 // optimize for single channel
+ .init_cnt = 0,
+ .active_channels = {0, 0, 0, 0, 0},
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+};
+
+
+
+//
+// Data type for access of single bytes/words of an dword value
+//
+typedef union lsc_buf_u
+{
+ cyg_uint8 bytes[4];
+ struct
+ {
+ cyg_uint16 low;
+ cyg_uint16 high;
+ } words;
+
+ struct
+ {
+ cyg_uint16 upper; // uppper column of acceptance filter ram
+ cyg_uint16 lower; // lower column of acceptance filter ram
+ } column;
+
+ cyg_uint32 dword;
+} lsc_buf_t;
+
+
+//===========================================================================
+// GLOBAL DATA
+//===========================================================================
+#if CYGINT_IO_CAN_CHANNELS > 1
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
+ CAN_CTRL_1_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN1_TX,
+ 0,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
+ CAN0_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
+ CAN_CTRL_2_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN2_TX,
+ 1,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
+ CAN1_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
+ CAN_CTRL_3_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN3_TX,
+ 2,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
+ CAN2_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
+ CAN_CTRL_4_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN4_TX,
+ 3,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
+ CAN3_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+#else // CYGINT_IO_CAN_CHANNELS == 1
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
+ CAN0_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_1_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN1_TX
+#define CAN_SINGLETON_CHAN_NO 0
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
+ CAN1_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_2_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN2_TX
+#define CAN_SINGLETON_CHAN_NO 1
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
+ CAN2_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_3_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN3_TX
+#define CAN_SINGLETON_CHAN_NO 2
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
+ CAN3_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_4_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN4_TX
+#define CAN_SINGLETON_CHAN_NO 3
+#endif
+
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+
+
+//===========================================================================
+// PROTOTYPES
+//===========================================================================
+
+//--------------------------------------------------------------------------
+// Device driver interface functions
+//
+static bool lpc2xxx_can_init(struct cyg_devtab_entry* devtab_entry);
+static Cyg_ErrNo lpc2xxx_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name);
+static Cyg_ErrNo lpc2xxx_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static Cyg_ErrNo lpc2xxx_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static bool lpc2xxx_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata);
+static bool lpc2xxx_can_getevent(can_channel *priv, CYG_CAN_EVENT_T *pevent, void *pdata);
+static void lpc2xxx_can_start_xmit(can_channel* chan);
+static void lpc2xxx_can_stop_xmit(can_channel* chan);
+
+
+//--------------------------------------------------------------------------
+// ISRs and DSRs
+//
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+static cyg_uint32 lpc2xxx_can_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_can_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_can_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+
+//--------------------------------------------------------------------------
+// Private utility functions
+//
+static bool lpc2xxx_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init);
+static bool lpc2xxx_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate);
+static Cyg_ErrNo lpc2xxx_enter_lowpower_mode(can_channel *chan);
+static void lpc2xxx_start_module(can_channel *chan);
+static cyg_can_state lpc2xxx_get_state(lpc2xxx_can_info_t *info);
+static void lpc2xxx_set_state(lpc2xxx_can_info_t *info, cyg_can_state state);
+
+
+//--------------------------------------------------------------------------
+// Message box configuration
+//
+static void lpc2xxx_can_config_rx_all(can_channel *chan);
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+static void lpc2xxx_can_config_rx_none(can_channel *chan);
+static bool lpc2xxx_can_add_rx_filter(lpc2xxx_can_info_t *info, cyg_can_filter *filter);
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#include "can_accfilt_lpc2xxx.c"
+
+//===========================================================================
+// GENERIC CAN IO DATA INITIALISATION
+//===========================================================================
+CAN_LOWLEVEL_FUNS(lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can_putmsg,
+ lpc2xxx_can_getevent,
+ lpc2xxx_can_get_config,
+ lpc2xxx_can_set_config,
+ lpc2xxx_can_start_xmit,
+ lpc2xxx_can_stop_xmit
+ );
+
+
+//---------------------------------------------------------------------------
+// CAN channel 0
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+CYG_CAN_EVENT_T lpc2xxx_can0_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can0_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can0_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can0_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD),
+ lpc2xxx_can0_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_TX,
+ lpc2xxx_can0_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can0_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can0_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+
+
+//---------------------------------------------------------------------------
+// CAN channel 1
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+CYG_CAN_EVENT_T lpc2xxx_can1_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can1_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can1_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can1_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD),
+ lpc2xxx_can1_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_TX,
+ lpc2xxx_can1_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can1_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can1_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+
+
+//---------------------------------------------------------------------------
+// CAN channel 2
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+CYG_CAN_EVENT_T lpc2xxx_can2_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can2_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can2_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can2_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN2_KBAUD),
+ lpc2xxx_can2_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_TX,
+ lpc2xxx_can2_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can2_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can2_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+
+
+//---------------------------------------------------------------------------
+// CAN channel 3
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+CYG_CAN_EVENT_T lpc2xxx_can3_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can3_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can3_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can3_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN3_KBAUD),
+ lpc2xxx_can3_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_TX,
+ lpc2xxx_can3_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can3_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can3_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+
+
+//===========================================================================
+// IMPLEMENTATION
+//===========================================================================
+
+
+
+//===========================================================================
+/// First initialisation and reset of CAN modul.
+//===========================================================================
+static bool lpc2xxx_can_init(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ bool res;
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("LPC2XXX CAN init\n");
+#endif
+
+ //
+ // Newer LPC2xxx variants do not support individual interrupt
+ // sources for CAN on chip peripherals
+ //
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ //
+ // Create TX interrupt
+ //
+ cyg_drv_interrupt_create(CAN_ISRVEC(info),
+ info->tx_interrupt_priority,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ lpc2xxx_can_tx_ISR,
+ lpc2xxx_can_tx_DSR,
+ &info->tx_interrupt_handle,
+ &info->tx_interrupt);
+ cyg_drv_interrupt_attach(info->tx_interrupt_handle);
+ cyg_drv_interrupt_unmask(CAN_ISRVEC(info));
+
+ //
+ // Create RX interrupt
+ //
+ cyg_drv_interrupt_create(CAN_ISRVEC(info) + 6,
+ info->rx_interrupt_priority,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ lpc2xxx_can_rx_ISR,
+ lpc2xxx_can_rx_DSR,
+ &info->rx_interrupt_handle,
+ &info->rx_interrupt);
+ cyg_drv_interrupt_attach(info->rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(CAN_ISRVEC(info) + 6);
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+ //
+ // Now create and enable global CAN interrupt. This interrupt is
+ // global for all channels and so we need to call it only one times -
+ // when the first channel is initialized
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ if (!lpc2xxx_global_can_info.init_cnt)
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+ {
+ //
+ // Create err interrupt
+ //
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CAN,
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY,
+#else // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY,
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ 0, // Data item passed to interrupt handler
+ lpc2xxx_can_ISR,
+ lpc2xxx_can_DSR,
+ &lpc2xxx_global_can_info.interrupt_handle,
+ &lpc2xxx_global_can_info.interrupt);
+ cyg_drv_interrupt_attach(lpc2xxx_global_can_info.interrupt_handle);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CAN);
+ }
+
+ res = lpc2xxx_can_config_channel(chan, &chan->config, true);
+#if CYGINT_IO_CAN_CHANNELS > 1
+ lpc2xxx_global_can_info.active_channels[lpc2xxx_global_can_info.init_cnt++] = chan;
+#else // CYGINT_IO_CAN_CHANNELS > 1
+ lpc2xxx_global_can_info.active_channels[0] = chan;
+#endif
+ return res;
+}
+
+
+//===========================================================================
+// Configure can channel
+//===========================================================================
+static bool lpc2xxx_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init)
+{
+ CAN_DECLARE_INFO(chan);
+ bool res = true;
+
+ if (init)
+ {
+ //
+ // In case platform needs extra initialization (i.e. setup of
+ // CAN transceivers) it should implement this macro
+ //
+#ifdef CYGPRI_IO_CAN_LPC2XXX_PLF_INIT_HOOK
+ CYGPRI_IO_CAN_LPC2XXX_PLF_INIT_HOOK(chan, config);
+#endif
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF); // Acceptance Filter Mode Register = off
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET); // Go into reset mode
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), 0); // disable all interrupts
+ HAL_WRITE_UINT32(CAN_CTRL_GSR(info), 0); // Clear Status register - clears error counters
+
+ //
+ // Perform platform/variant specific initialisation here.
+ // The variant/ platform should setup the pin configuration to support
+ // CAN here
+ //
+ HAL_LPC2XXX_INIT_CAN(CAN_CHAN_NO(info));
+
+ //
+ // If this is the first channel to initialize then we reset the CAN
+ // registers and setup the CAN I/O pins
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ if (!lpc2xxx_global_can_info.init_cnt)
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+ {
+ lpc2xxx_can_accfilt_reset();
+ }
+ } // if (init)
+
+ res = lpc2xxx_can_set_baud(chan, &config->baud); // set baudrate
+ // $$$$ enable receive interrupt?
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_OPERATIONAL); // enter normal operating mode
+
+ //
+ // store new config values
+ //
+ if (config != &chan->config)
+ {
+ chan->config = *config;
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Set baudrate of certain can channel
+//===========================================================================
+static bool lpc2xxx_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate)
+{
+ bool res = true;
+ cyg_uint32 canbtr;
+ cyg_uint32 canmod;
+ CAN_DECLARE_INFO(chan);
+
+ //
+ // Get bit timings from HAL because bit timings depend on sysclock
+ // If the macro fills the canbtr value with 0 then the baudrate
+ // is not supported and the function returns false
+ //
+ HAL_LPC2XXX_GET_CAN_BR(*baudrate, canbtr);
+ if (0 == canbtr)
+ {
+ return false;
+ }
+
+ //
+ // Any modificatons to the baudrate register must be done while CAN
+ // module is in reset mode. So we first set the CAN module in reset
+ // mode, then we set baudrate and then we restore content of CANMOD
+ // register
+ //
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), canmod); // backup canmod register
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET); // Go into reset mode
+ HAL_WRITE_UINT32(CAN_CTRL_BTR(info), canbtr); // write baudrate value
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), canmod); // restore previous value
+
+ return res;
+}
+
+
+//===========================================================================
+// Lookup the device and return its handle
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
+{
+ can_channel* chan = (can_channel*) (*tab)->priv;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ cyg_uint32 regval;
+
+ chan->callbacks->can_init(chan);
+
+ //
+ // If runtime acceptance filter configuration is supported then we only
+ // configure RX ALL if the user selected the RX ALL setup in config utility
+ //
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ if (info->flags & INFO_FLAG_STARTUP_RX_ALL)
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ {
+ lpc2xxx_can_config_rx_all(chan);
+ }
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_ON); // Activate acceptance filter
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval = regval | IER_RX | CAN_MISC_INT; // enable all interrupts
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+
+ return ENOERR;
+}
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Setup LPC2XXX CAN module in a state where all message boxes are disabled
+// After this call it is possible to add single message buffers and filters
+//===========================================================================
+static void lpc2xxx_can_config_rx_none(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ //
+ // Remove all acceptance filters
+ // $$$$ maybe we should also abort any pending transfers and
+ // disable receive interrupts ?
+ //
+ lpc2xxx_can_accfilt_remove_all_ctrl_entries(info);
+ info->flags &= ~INFO_FLAG_RX_ALL;
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+}
+
+
+//===========================================================================
+// Add one single message filter to acceptance filter
+//===========================================================================
+static bool lpc2xxx_can_add_rx_filter(lpc2xxx_can_info_t *info, cyg_can_filter *filter)
+{
+ bool res;
+
+ res = lpc2xxx_can_accfilt_add(info, filter->msg.id, 0, filter->msg.ext);
+ if (!res)
+ {
+ filter->handle = CYGNUM_CAN_MSGBUF_NA;
+ }
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message buffers
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_config_msgbuf(can_channel *chan, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ cyg_can_msgbuf_cfg *msg_buf = (cyg_can_msgbuf_cfg *)buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_cfg))
+ {
+ return -EINVAL;
+ }
+
+ switch (msg_buf->cfg_id)
+ {
+ //
+ // clear all message filters and remote buffers - prepare for message buffer
+ // configuration
+ //
+ case CYGNUM_CAN_MSGBUF_RESET_ALL :
+ {
+ lpc2xxx_can_config_rx_none(chan);
+ }
+ break;
+
+ //
+ // setup driver for reception of all standard and extended messages
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ALL :
+ {
+ if (!(info->flags & INFO_FLAG_RX_ALL)) // if rx_all is enabled we do not need to do anything
+ {
+ lpc2xxx_can_config_rx_all(chan); // setup RX all state
+ }
+ }
+ break;
+
+ //
+ // add single message filter, message with filter ID will be received
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ADD :
+ {
+ cyg_can_filter *filter = (cyg_can_filter*) buf;
+
+ //
+ // if the acceptance filter is configured to receive all messages then
+ // it is not allowed to add single message filters because then more
+ // than one acceptance filter would receive the same CAN id
+ //
+ if (info->flags & INFO_FLAG_RX_ALL)
+ {
+ return -EPERM;
+ }
+
+ //
+ // try to allocate a free acceptance filter entry - if we have a free one
+ // then we can prepare the acceptance filter table for reception of
+ // this message
+ //
+ if (!lpc2xxx_can_add_rx_filter(info, filter))
+ {
+ return -EPERM;
+ }
+ }
+ break; //CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+
+
+#ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ //
+ // Try to add a new RTR response message buffer for automatic
+ // transmission of data frame on reception of a remote frame
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD :
+ {
+ // $$$$ TODO implement remote response buffers in software
+ return -ENOSUPP;
+ }
+ break;
+
+ //
+ // write data into remote response buffer
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE :
+ {
+ // $$$$ TODO implement remote response buffers in software
+ return -ENOSUPP;
+ }
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ default:
+ return -EINVAL;
+ } // switch (buf->cfg_id)
+
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//===========================================================================
+// Read state of CAN controller
+// The CAN state variable for each channel is modified by DSR so if we
+// read the state we need to lock DSRs to protect the data access
+//===========================================================================
+static cyg_can_state lpc2xxx_get_state(lpc2xxx_can_info_t *info)
+{
+ cyg_can_state result;
+
+ cyg_drv_dsr_lock();
+ result = info->state;
+ cyg_drv_dsr_unlock();
+
+ return result;
+}
+
+
+//===========================================================================
+// Set state of CAN controller
+// The CAN state variable for each channel is modified by DSR so if we
+// write the state we need to lock DSRs to protect the data access
+//===========================================================================
+static void lpc2xxx_set_state(lpc2xxx_can_info_t *info, cyg_can_state state)
+{
+ cyg_drv_dsr_lock();
+ info->state = state;
+ cyg_drv_dsr_unlock();
+}
+
+
+//===========================================================================
+// Enter low power mode
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_enter_lowpower_mode(can_channel *chan)
+{
+ cyg_uint32 regval;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ //
+ // Before we enter low power mode, we have to enable wake up interrupt
+ // Normally this interrupt is always enabled so we do not need to do
+ // anything here
+ //
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), regval);
+
+ //
+ // Software can only set SM when RM in the CAN Mode register is 0
+ //
+ if (regval & CANMOD_RESET)
+ {
+ return -EPERM;
+ }
+
+ //regval &= CANMOD_SLEEP;
+ lpc2xxx_set_state(info, CYGNUM_CAN_STATE_STANDBY);
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_SLEEP);
+ return ENOERR;
+}
+
+
+//===========================================================================
+// Start CAN module - set CANMOD operational and enable all interrupts
+//===========================================================================
+static void lpc2xxx_start_module(can_channel *chan)
+{
+ cyg_uint32 regval;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_OPERATIONAL);
+ //
+ // The interrupt enable register is also modified by ISR and DSR so
+ // we need to protect acces here
+ //
+ cyg_drv_isr_lock();
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval = regval | IER_RX | CAN_MISC_INT; // enable all interrupts
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ cyg_drv_isr_unlock();
+}
+
+
+//===========================================================================
+// Enter reset mode
+//===========================================================================
+static void lpc2xxx_enter_reset_mode(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ info->state = CYGNUM_CAN_STATE_STOPPED;
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET);
+}
+
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+//===========================================================================
+// Add message filter group
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_config_accfilt_group(can_channel *chan, const void* buf, cyg_uint32* len)
+{
+ bool res;
+ cyg_can_filtergroup_cfg *filter_grp = (cyg_can_filtergroup_cfg *)buf;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+
+ if (*len != sizeof(cyg_can_filtergroup_cfg))
+ {
+ return -EINVAL;
+ }
+
+ if (filter_grp->lower_id_bound >= filter_grp->upper_id_bound)
+ {
+ return -EINVAL;
+ }
+
+ //
+ // if the acceptance filter is configured to receive all messages then
+ // it is not allowed to add single message filter groups because then more
+ // than one acceptance filter would receive the same CAN id
+ //
+ if (info->flags & INFO_FLAG_RX_ALL)
+ {
+ return -EPERM;
+ }
+
+ res = lpc2xxx_can_accfilt_add(info,
+ filter_grp->lower_id_bound,
+ filter_grp->upper_id_bound,
+ filter_grp->ext);
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+ return res ? ENOERR : -EPERM;
+}
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+
+
+//===========================================================================
+// Change device configuration
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+
+ switch (key)
+ {
+ //
+ // Setup a new CAN configuration. This will i.e. setup a new baud rate
+ //
+ case CYG_IO_SET_CONFIG_CAN_INFO:
+ {
+ cyg_can_info_t* config = (cyg_can_info_t*) buf;
+ if (*len < sizeof(cyg_can_info_t))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_info_t);
+ if (!lpc2xxx_can_config_channel(chan, config, false))
+ {
+ return -EINVAL;
+ }
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // configure message buffers
+ //
+ case CYG_IO_SET_CONFIG_CAN_MSGBUF :
+ {
+ res = lpc2xxx_can_config_msgbuf(chan, buf, len);
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+ //
+ // Add message filter group to acceptance filter
+ //
+ case CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP :
+ {
+ return lpc2xxx_can_config_accfilt_group(chan, buf, len);
+ }
+ break;
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+
+ //
+ // Change CAN state of CAN module
+ //
+ case CYG_IO_SET_CONFIG_CAN_MODE :
+ {
+ cyg_can_mode *can_mode = (cyg_can_mode*) buf;
+
+ if (*len != sizeof(cyg_can_mode))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_mode);
+
+ //
+ // decide what to do according to mode
+ //
+ switch (*can_mode)
+ {
+ //
+ // The controller does not support a stopped and standby state so we
+ // simply enter the low power state here. This state is also safe for
+ // message buffer configuration
+ //
+ case CYGNUM_CAN_MODE_STOP : lpc2xxx_enter_reset_mode(chan); break;
+ case CYGNUM_CAN_MODE_START : lpc2xxx_start_module(chan); break;
+ case CYGNUM_CAN_MODE_STANDBY : lpc2xxx_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_CONFIG : lpc2xxx_enter_reset_mode(chan); break;
+ }
+ }
+ break; // case CYG_IO_SET_CONFIG_CAN_MODE :
+ //
+ // Unknown config key - indicate this by returning -EINVAL
+ //
+ default:
+ return -EINVAL;
+ } // switch (key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Query device configuration
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ switch(key)
+ {
+ //
+ // query state of CAN controller
+ //
+ case CYG_IO_GET_CONFIG_CAN_STATE :
+ {
+ cyg_can_state *can_state = (cyg_can_state*) buf;
+
+ if (*len != sizeof(cyg_can_state))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_state);
+ *can_state = lpc2xxx_get_state(info);
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // Query message box information - returns available and free message
+ // boxes
+ //
+ case CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO :
+ {
+ cyg_can_msgbuf_info *mbox_info = (cyg_can_msgbuf_info*) buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_info))
+ {
+ return -EINVAL;
+ }
+ cyg_uint32 end_of_table;
+ *len = sizeof(cyg_can_msgbuf_info);
+
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+ mbox_info->count = LPC2XXX_CAN_MSG_FILTERS_MAX;
+ mbox_info->free = (ACCFILT_RAM_SIZE - end_of_table) / ACCFILT_COMMON_ENTRY_SIZE;
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+ //
+ // Query hardware description of FlexCAN device driver
+ //
+ case CYG_IO_GET_CONFIG_CAN_HDI :
+ {
+ cyg_can_hdi *hdi = (cyg_can_hdi *)buf;
+ //
+ // comes from high level driver so we do not need to
+ // check buffer size here
+ //
+ hdi->support_flags = CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE
+ | CYGNUM_CAN_HDI_FULLCAN;
+ }
+ break;
+
+ default :
+ res = -EINVAL;
+ }// switch(key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Send single message
+//===========================================================================
+static bool lpc2xxx_can_putmsg(can_channel *chan, CYG_CAN_MSG_T *pmsg, void *pdata)
+{
+ cyg_uint32 regval;
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *) chan->dev_priv;
+#else
+ CAN_DECLARE_INFO(info);
+#endif
+
+ //
+ // We use only one single transmit buffer of the three available buffers
+ // We use buffer 1 (buffer 2 and 3 are unused)
+ //
+ // The errata sheet tells the following about the transmit buffers:
+ // Problem: The Triple Transmit Buffer function cannot be used.
+ // Work-around: Use any one Transmit buffer only (Use either Transmit Buffer 1,
+ // Transmit Buffer 2 or Transmit Buffer 3 exclusively). The buffer you decided
+ // to use should be loaded only when there is no pending transmission.
+ //
+ HAL_READ_UINT32(CAN_CTRL_SR(info), regval);
+ if (!(regval & SR_TX_BUF_WRITE_OK))
+ {
+ return false;
+ }
+
+ regval = pmsg->dlc << 16;
+ if (pmsg->rtr)
+ {
+ regval |= TFI_DLC_RTR;
+ }
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (pmsg->ext)
+ {
+ regval |= TFI_DLC_EXT;
+ }
+#endif // #define CYGOPT_IO_CAN_EXT_CAN_ID
+ HAL_WRITE_UINT32(CAN_CTRL_TFI1(info), regval); // write DLC
+ HAL_WRITE_UINT32(CAN_CTRL_TID1(info), pmsg->id); // write ID
+ HAL_WRITE_UINT32(CAN_CTRL_TDA1(info), pmsg->data.dwords[0]); // write first 4 data bytes
+ HAL_WRITE_UINT32(CAN_CTRL_TDB1(info), pmsg->data.dwords[1]); // write second 4 data bytes
+
+ //
+ // Request transmission of message
+ // The errata sheet tells the following about tx request:
+ // Introduction: The CAN module can lose arbitration to another CAN node during an
+ // attempt to transmit a CAN message. The message of the CAN node the arbitration was
+ // lost to is supposed to be received correctly by the CAN module.
+ // Problem: Messages might not be received correctly if during a CAN Transmission the
+ // CAN bus arbitration is lost to another CAN node.
+ // Work-around: Use the Self Reception Request command instead of the Transmission
+ // Request command. However, it has to be taken into account that now all transmitted
+ // messages may be received if not prevented by appropriate Acceptance Filter settings.
+ // (Don't set up Acceptance Filter Message Identifiers for the messages you are
+ // transmitting yourself.)
+ //
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ // Calc last_tx_id
+ regval = pmsg->id | (regval & LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK);
+
+ // Save last message id to next last_tx_id
+ info->last_tx_index = info->last_tx_index == 0 ? 1 : 0;
+ info->last_tx_id[info->last_tx_index] = regval;
+
+ // Write self transmission request
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_SELF_RX_REQ | CMR_SEND_TX_BUF1);
+#else
+ // Write transmission request
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_TX_REQ | CMR_SEND_TX_BUF1);
+#endif
+
+ return true;
+}
+
+
+//===========================================================================
+// Read event from device driver
+//===========================================================================
+static bool lpc2xxx_can_getevent(can_channel *chan, CYG_CAN_EVENT_T *pevent, void *pdata)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ bool res = true;
+ cyg_uint32 regval;
+ cyg_uint32 event = *((cyg_uint32*)pdata);
+ lsc_buf_t data;
+
+ //
+ // Handle RX event
+ //
+ if (event & ICR_RX)
+ {
+ cyg_uint32 id;
+
+ pevent->flags |= CYGNUM_CAN_EVENT_RX;
+ HAL_READ_UINT32(CAN_CTRL_RFS(info), regval);
+ HAL_READ_UINT32(CAN_CTRL_RID(info), id);
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (regval & RFS_EXT)
+ {
+ pevent->msg.ext = CYGNUM_CAN_ID_EXT;
+ pevent->msg.id = id & 0x1FFFFFFF;
+ }
+ else
+#endif // #define CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ pevent->msg.ext = CYGNUM_CAN_ID_STD;
+ pevent->msg.id = id & 0x7FF;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ } // if (regval & RFS_EXT)
+
+ if (regval & RFS_RTR)
+ {
+ pevent->msg.rtr = CYGNUM_CAN_FRAME_RTR;
+ }
+ else
+ {
+ pevent->msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ HAL_READ_UINT32(CAN_CTRL_RDA(info), pevent->msg.data.dwords[0]);
+ HAL_READ_UINT32(CAN_CTRL_RDB(info), pevent->msg.data.dwords[1]);
+ } //if (regval & RFS_RTR)
+ pevent->msg.dlc = RFS_GET_DLC(regval);
+ //
+ // Release the message buffer. Now this buffer can receive the next message
+ //
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_RX_RELEASE_BUF);
+
+ //
+ // Now check if an data overrun occurred - a message was lost
+ // because the preceding message to this CAN controller was not read
+ // and released quickly enough. After reading the status we clear
+ // the overrun bit
+ //
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), regval);
+ if (regval & GSR_DATA_OVR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_OVERRUN_RX;
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_CLEAR_DATA_OVR);
+ }
+ }
+
+ //
+ // Handle TX events
+ //
+#ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ if (event & ICR_TX1)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_TX;
+ }
+#endif
+
+ //
+ // Handle all other events
+ //
+ if (event & (CAN_MISC_INT | ICR_LUT_ERR))
+ {
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
+
+ //
+ // 1: Error Warning Interrupt -- this bit is set on every change (set or clear) of the Error
+ // Status or Bus Status bit in CANSR, if the EIE bit in CAN is 1 at the time of the
+ // change.
+ //
+ if (event & ICR_ERR_WARN)
+ {
+ //
+ // If one of the warning counters is above 96 then the controller is in bus warning
+ // state. If both counters are below 96 the this interrupt indicates that the
+ // controller has left the bus warning state and is error active again
+ //
+ if (data.bytes[2] >= 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_RX;
+ info->state = CYGNUM_CAN_STATE_BUS_WARN;
+ }
+ else if (data.bytes[3] >= 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
+ info->state = CYGNUM_CAN_STATE_BUS_WARN;
+ }
+ else
+ {
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ }
+ LPC2XXX_DBG_PRINT("ICR_ERR_WARN (%p)\n", (void*) chan);
+ }
+
+ //
+ // 1: Wake-Up Interrupt: this bit is set if the CAN controller is sleeping and bus activity
+ // is detected, if the WUIE bit in CANIE is 1.
+ //
+ if (event & ICR_WAKE_UP)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_LEAVING_STANDBY;
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ LPC2XXX_DBG_PRINT("ICR_WAKE_UP (%p)\n", (void*) chan);
+ }
+
+ //
+ // Error Passive Interrupt -- this bit is set if the EPIE bit in CANIE is 1, and the CAN
+ // controller switches between Error Passive and Error Active mode in either
+ // direction. We have to check if the ERR bit is set in global status register.
+ // If it is set, then it is a switch to error passive else it is a switch to
+ // error active state
+ //
+ if (event & ICR_ERR_PASSIVE)
+ {
+ if (data.dword & GSR_ERR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ERR_PASSIVE;
+ info->state = CYGNUM_CAN_STATE_ERR_PASSIVE;
+ }
+ else
+ {
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ }
+ LPC2XXX_DBG_PRINT("ICR_ERR_PASSIVE (%p)\n", (void*) chan);
+ }
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_ALIE
+ //
+ // Arbitration Lost Interrupt -- this bit is set if the ALIE bit in CANIE is 1, and the
+ // CAN controller loses arbitration while attempting to transmit.
+ //
+ if (event & ICR_ARBITR_LOST)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ARBITRATION_LOST;
+ LPC2XXX_DBG_PRINT("ICR_ARBITR_LOST (%p)\n", (void*) chan);
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_ALIE
+
+ //
+ // 1: Bus Error Interrupt -- this bit is set if the BEIE bit in CANIE is 1, and the CAN
+ // controller detects an error on the bus.
+ //
+ if (event & ICR_BUS_ERR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_BUS_OFF;
+ LPC2XXX_DBG_PRINT("ICR_BUS_ERR (%p)\n", (void*) chan);
+ }
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ //
+ // LUT error interrupt -- this bit is set if bit 0 in LUTerr is 1 and LUTerrAd
+ // points to entry in filter table for this CAN controller
+ //
+ if(event & ICR_LUT_ERR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_FILTER_ERR;
+ LPC2XXX_DBG_PRINT("ICR_LUT_ERR (%p)\n", (void*) chan);
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+
+ } // if (event & (CAN_MISC_INT | ICR_LUT_ERR))
+
+ return res;
+}
+
+
+//===========================================================================
+// Kick transmitter
+//===========================================================================
+static void lpc2xxx_can_start_xmit(can_channel* chan)
+{
+ cyg_uint32 regval;
+ CAN_DECLARE_INFO(chan);
+
+ LPC2XXX_DBG_PRINT("start_xmit (%p)\n", (void*) chan);
+
+ cyg_drv_dsr_lock();
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval |= IER_TX1; // enable tx interrupt for tx buf 1
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+ cyg_drv_dsr_unlock();
+
+ //
+ // kick transmitter
+ //
+ chan->callbacks->xmt_msg(chan, 0); // Kick transmitter (if necessary)
+}
+
+
+//===========================================================================
+// Stop transmitter
+//===========================================================================
+static void lpc2xxx_can_stop_xmit(can_channel* chan)
+{
+ cyg_uint32 regval;
+ CAN_DECLARE_INFO(chan);
+
+ LPC2XXX_DBG_PRINT("stop_xmit (%p)\n", (void*) chan);
+
+ cyg_drv_dsr_lock();
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval &= ~IER_TX1; // disable tx interrupt for tx buf 1
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+ cyg_drv_dsr_unlock();
+}
+
+
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+//===========================================================================
+// Low level transmit interrupt handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ //
+ // Now read input capture register - this clears all interrupt bits in this
+ // register and also acknowledges the interrupt - any further processing is done
+ // by the DSR
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("tx_ISR (%p)\n", (void*) data);
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// High level transmit interrupt handler
+//===========================================================================
+static void lpc2xxx_can_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ cyg_uint32 regval;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ //
+ // First read the ICR register to acknowledge all interrupts and
+ // get all captured interrupts
+ //
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), regval);
+
+ //
+ // If TX events are supported then only call the rcv_event() callback
+ // if any other event occurred - pass the event field to the getevent function
+ // to indicate the events
+ //
+#ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ if (regval & ~ICR_TX1)
+#endif
+ {
+ chan->callbacks->rcv_event(chan, ®val);
+ }
+
+ //
+ // Now transmit next message and reenable interrupts
+ //
+ chan->callbacks->xmt_msg(chan, 0); // send next message
+ LPC2XXX_DBG_PRINT("tx_DSR (%p)\n", (void*) data);
+ cyg_drv_interrupt_unmask(vector);
+}
+
+
+//===========================================================================
+// Low level receive interrupt handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ cyg_uint32 regval;
+ can_channel* chan = (can_channel*)data;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *) chan->dev_priv;
+ cyg_uint32 id;
+ cyg_uint32 index;
+
+ // We have to reject self tx message, so read message id
+ HAL_READ_UINT32(CAN_CTRL_RID(info), id);
+ HAL_READ_UINT32(CAN_CTRL_RFS(info), regval);
+ id |= (regval & LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK);
+
+ // Test message id
+ for(index = 0; index < 2; index++)
+ {
+ if(id == info->last_tx_id[index])
+ {
+ // Clear last_tx_id
+ info->last_tx_id[index] = LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID;
+
+ // Clear receive buffer
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_RX_RELEASE_BUF);
+
+ // Acknowledge a vector
+ cyg_drv_interrupt_acknowledge(vector);
+
+ // Exit without calling DSR
+ LPC2XXX_DBG_PRINT("self_rx_ISR (%p)\n", (void*) data);
+ return CYG_ISR_HANDLED;
+ }
+ }
+#endif
+
+ //
+ // The ISR only disables and acknowledges the RX interrupt
+ // any further processing is done by DSR. We also need to mask the
+ // global CAN status interrupt here because the interrupt flag
+ // in ICR is not cleared yet and may still cause a status
+ // interrupt
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("rx_ISR (%p)\n", (void*) data);
+
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// High level receive interrupt handler
+//===========================================================================
+static void lpc2xxx_can_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ cyg_uint32 icr = ICR_RX;
+
+ //
+ // Read the event, the receive buffer will be released by the
+ // get_event() function
+ //
+ chan->callbacks->rcv_event(chan, &icr);
+ LPC2XXX_DBG_PRINT("rx_DSR (%p)\n", (void*) data);
+ cyg_drv_interrupt_unmask(vector);
+}
+
+
+
+//===========================================================================
+// status ISR handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ //
+ // Acknowledge and disable the interrupt - any further processing is
+ // done by the DSR
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("err_ISR\n");
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// status ISR handler
+//===========================================================================
+static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // If we use acceptance filter we can get LUT error
+ cyg_uint32 luterr;
+ cyg_uint8 luterr_chan0 = 0; // Init to avoid warnings
+ cyg_uint8 luterr_chan1 = 0; // Init to avoid warnings
+
+ // Read LUT error flag
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, luterr);
+
+ if (luterr & 1)
+ {
+ cyg_uint32 lutaddr;
+ cyg_uint32 eff_sa;
+ lsc_buf_t errentry;
+
+ // Read address of failed entry (it clears interrupt flag)
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, lutaddr);
+
+ // Read address of extended id individual table
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+
+ // Read error entry
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + lutaddr, errentry.dword);
+
+ // If err entry from standard id tables then read two
+ // controllers numbers
+ if(lutaddr < eff_sa)
+ {
+ // Calc CAN controllers numbers
+ luterr_chan0 = (cyg_uint8) ACCFILT_STD_GET_CTRL_UPPER(errentry.dword);
+
+ if(errentry.column.lower & ACCFILT_STD_DIS)
+ {
+ luterr_chan1 = luterr_chan0;
+ }
+ else
+ {
+ luterr_chan1 = (cyg_uint8) ACCFILT_STD_GET_CTRL_LOWER(errentry.dword);
+ }
+ }
+ else
+ {
+ // Calc CAN controller number
+ luterr_chan0 = luterr_chan1 = (cyg_uint8) ACCFILT_EXT_GET_CTRL(errentry.dword);
+ }
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+
+ //
+ // Loop through all channels - we need to do this only if we have more
+ // than one channel so we can optimize here for single channel
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ cyg_uint8 i = 0;
+ while (lpc2xxx_global_can_info.active_channels[i])
+#endif
+ {
+ cyg_uint32 regval;
+ can_channel *chan = LPC2XXX_GET_CAN_CHANNEL(lpc2xxx_global_can_info, i++);
+ CAN_DECLARE_INFO(chan);
+
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), regval);
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // Set ICR_LUT_ERR flag only for controller which cause LUT error
+ if ((luterr & 1) && ((luterr_chan0 == i) || (luterr_chan1 == i)))
+ {
+ regval |= ICR_LUT_ERR;
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ regval &= CAN_MISC_INT; // don't care about RX and TX events here
+ if (regval)
+ {
+ chan->callbacks->rcv_event(chan, ®val);
+ }
+ } // while (lpc2xxx_global_can_info.active_channels[i])
+
+ LPC2XXX_DBG_PRINT("err_DSR\n");
+ cyg_drv_interrupt_unmask(vector);
+}
+#else // #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+
+//===========================================================================
+// Global CAN interrupt handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ //
+ // Disable interrupts, the DSR will enable it as soon as it processed
+ // the current interrupt
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("CAN_ISR\n");
+ return CYG_ISR_CALL_DSR;
+}
+
+//===========================================================================
+// Global CAN DSR
+//===========================================================================
+static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // If we use acceptance filter we can get LUT error
+ cyg_uint32 luterr;
+ cyg_uint8 luterr_chan0 = 0xFF; // Init to avoid warnings
+ cyg_uint8 luterr_chan1 = 0xFF; // Init to avoid warnings
+
+ // Read LUT error flag
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, luterr);
+
+ if (luterr & 1)
+ {
+ cyg_uint32 lutaddr;
+ cyg_uint32 eff_sa;
+ lsc_buf_t errentry;
+
+ // Read address of failed entry (it clears interrupt flag)
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, lutaddr);
+
+ // Read address of extended id individual table
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+
+ // Read error entry
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + lutaddr, errentry.dword);
+
+ // If errentry from standard id tables then read two controllers numbers
+ if(lutaddr < eff_sa)
+ {
+ // Calc CAN controllers numbers
+ luterr_chan0 = (cyg_uint8) ACCFILT_STD_GET_CTRL_UPPER(errentry.dword);
+
+ if(errentry.column.lower & ACCFILT_STD_DIS)
+ {
+ luterr_chan1 = luterr_chan0;
+ }
+ else
+ {
+ luterr_chan1 = (cyg_uint8) ACCFILT_STD_GET_CTRL_LOWER(errentry.dword);
+ }
+ }
+ else
+ {
+ // Calc CAN controller number
+ luterr_chan0 = luterr_chan1 = (cyg_uint8) ACCFILT_EXT_GET_CTRL(errentry.dword);
+ }
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+
+ //
+ // Walk through list of active CAN channels and process interrupts
+ // of all channels - we need to loop only if we have more than one CAN channel so
+ // we can optimize for single CAN channel here
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ cyg_uint8 i = 0;
+ while (lpc2xxx_global_can_info.active_channels[i])
+#endif // CYGINT_IO_CAN_CHANNELS > 1
+ {
+ cyg_uint32 icr;
+ can_channel *chan = LPC2XXX_GET_CAN_CHANNEL(lpc2xxx_global_can_info, i++);
+ CAN_DECLARE_INFO(chan);
+
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), icr); // this read clears ICR
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // Set ICR_LUT_ERR flag only for controller which cause LUT error
+ if ((luterr_chan0 == i) || (luterr_chan1 == i))
+ {
+ icr |= ICR_LUT_ERR;
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ //
+ // If TX events are supported then we simply call the rcv_event()
+ // callback to store the event. If TX events are not supported then
+ // we only call the rcv_event() function if any other interrupt than
+ // the TX interrupt was captured
+ //
+#ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ if (icr & ~ICR_TX1)
+#endif // CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ {
+ chan->callbacks->rcv_event(chan, &icr);
+ }
+ //
+ // If this was an TX interrupt then transmit next message now
+ //
+ if (icr & ICR_TX1)
+ {
+ chan->callbacks->xmt_msg(chan, 0); // send next message
+ }
+ } // while (lpc2xxx_global_can_info.active_channels[i])
+ LPC2XXX_DBG_PRINT("CAN_DSR\n");
+ cyg_drv_interrupt_unmask(vector);
+}
+#endif // #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message boxes for reception of any CAN message
+//===========================================================================
+static void lpc2xxx_can_config_rx_all(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ //
+ // First clear all acceptance filter entries and then insert the
+ // two RX all groups
+ //
+ lpc2xxx_can_config_rx_none(chan);
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ lpc2xxx_can_accfilt_add(info, 0x000, 0x7FF, CYGNUM_CAN_ID_STD);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ lpc2xxx_can_accfilt_add(info, 0x000, 0x1FFFFFFF, CYGNUM_CAN_ID_EXT);
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+ info->flags |= INFO_FLAG_RX_ALL;
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifndef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message boxes for reception of any CAN message
+//===========================================================================
+static void lpc2xxx_can_config_rx_all(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ lpc2xxx_can_accfilt_simple_rx_all();
+ info->flags |= INFO_FLAG_RX_ALL;
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//---------------------------------------------------------------------------
+// EOF can_lpc2xxx.c
--- /dev/null
+//==========================================================================
+//
+// can_baudrates.c
+//
+// CAN test of all supported baudrates
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN LPC2xxx baudrate test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN;
+
+
+//
+// The table of baudrates to test
+//
+static cyg_can_baud_rate_t baudrate_tbl[9] =
+{
+ CYGNUM_CAN_KBAUD_10,
+ CYGNUM_CAN_KBAUD_20,
+ CYGNUM_CAN_KBAUD_50,
+ CYGNUM_CAN_KBAUD_100,
+ CYGNUM_CAN_KBAUD_125,
+ CYGNUM_CAN_KBAUD_250,
+ CYGNUM_CAN_KBAUD_500,
+ CYGNUM_CAN_KBAUD_800,
+ CYGNUM_CAN_KBAUD_1000,
+};
+
+//
+// String table forprinting supported baudrates
+//
+static char* baudrate_strings_tbl[9] =
+{
+ "10",
+ "20",
+ "50",
+ "100",
+ "125",
+ "250",
+ "500",
+ "800",
+ "1000",
+};
+
+
+//===========================================================================
+// Thread 0
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_uint32 i;
+ cyg_can_info_t can_info;
+
+ diag_printf("\n\nWhen the LPC2xxx driver selects a new baudrate then you need\n"
+ "to setup your hardware to the new baudrate and send one CAN\n"
+ "single CAN standard message.\n");
+ //
+ // Test all supported baudrates
+ //
+ for (i = 0; i < 9; ++i)
+ {
+ diag_printf("\n\nBaudrate: %s Kbaud\n", baudrate_strings_tbl[i]);
+ can_info.baud = baudrate_tbl[i];
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ diag_printf("not supported\n");
+ continue;
+ }
+ else
+ {
+ diag_printf("waiting for CAN message...\n");
+ }
+
+ len = sizeof(rx_event);
+ //
+ // First receive CAN event from real CAN hardware
+ //
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel 0");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX chan 1:");
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ CYG_TEST_FAIL_FINISH("Rx message expected");
+ }
+ } // for (i = 0; i < 9; ++i)
+
+ CYG_TEST_PASS_FINISH("CAN baudrate test OK");
+}
+
+
+//===========================================================================
+// Entry point
+//===========================================================================
+void cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(5, can0_thread,
+ (cyg_addrword_t) 0,
+ "can_tx_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_busload.c
--- /dev/null
+//==========================================================================
+//
+// can_busload.c
+//
+// CAN bus load test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN bus load test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// We need two CAN channels
+#if defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+
+
+// The same baud rates are required because we send from one channel to the other one
+#if CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+
+
+// We need a large RX buffer
+#ifdef CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX_1024
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN_Tbl[2];
+
+
+//===========================================================================
+// Thread 0
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_message tx_msg;
+ cyg_can_event rx_event;
+ cyg_uint32 i;
+ cyg_uint32 rx_msg_cnt = 0;
+
+
+ //
+ // Prepeare message - we use a data length of 0 bytes here. Each received message
+ // causes an iterrupt. The shortest message is a 0 data byte message. This will generate
+ // the highest interrupt rate
+ //
+ CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA);
+
+ //
+ // Now send 1024 CAN messages as fast as possible to stress the receiver of CAN
+ // channel 1
+ //
+ for (i = 0; i< 1024; ++i)
+ {
+ tx_msg.id = i;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN_Tbl[1], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to channel 0");
+ }
+ }
+
+ //
+ // Now try to receive all 1024 CAN messages. If all messages are received
+ // and no overrun occured then the message processing is fast enought
+ //
+ while (1)
+ {
+ len = sizeof(rx_event);
+ //
+ // First receive CAN event from real CAN hardware
+ //
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN_Tbl[0], &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX chan 1:");
+ rx_msg_cnt++;
+ if (rx_msg_cnt == 1024)
+ {
+ CYG_TEST_PASS_FINISH("CAN load test OK");
+ }
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX)
+ {
+ CYG_TEST_FAIL_FINISH("RX overrun for channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_ERR_PASSIVE)
+ {
+ CYG_TEST_FAIL_FINISH("Channel 1 error passive event");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_BUS_OFF)
+ {
+ CYG_TEST_FAIL_FINISH("Channel 1 bus off event");
+ }
+ }
+ } // while (1)
+}
+
+
+//===========================================================================
+// Entry point
+//===========================================================================
+void cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+
+
+ //
+ // open CAN device driver channel 2
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(5, can0_thread,
+ (cyg_addrword_t) 0,
+ "can_tx_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX_1024
+#define N_A_MSG "Channel 0 needs RX buffer size for 1024 events"
+#endif
+
+#else // CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+#define N_A_MSG "Baudrate of channel 0 and 1 need to be equal"
+#endif
+
+#else // defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+#define N_A_MSG "Needs support for CAN channel 1 and 2"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_busload.c
--- /dev/null
+//==========================================================================
+//
+// can_extended_cfg.c
+//
+// Test of extended CAN configuration keys for LPC2xxx CAN driver
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2006-06-20
+// Description: LPC2xxx CAN extended configuration test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_RUNTIME_MBOX_CFG)
+#include "can_test_aux.inl"
+
+#if defined(CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS)
+#include <cyg/io/can_lpc2xxx.h>
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN0;
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_can_filtergroup_cfg acc_filt_grp;
+ cyg_can_msgbuf_cfg msgbox_cfg;
+
+ //
+ // First we reset message buffer configuration - this is mandatory bevore starting
+ // message buffer runtime configuration. This call clears/frees all message buffers
+ // The CAN controller cannot receive any further CAN message after this call
+ //
+ msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+ len = sizeof(msgbox_cfg);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0");
+ }
+
+ //
+ // Now we setup two different acceptance filter groups. Acceptance filter
+ // groups are not part of the CAN I/O layer and are a LPC2xxx specific
+ // feature. You should not use appcetance filter groups if you would like
+ // to code portable eCos CAN applications
+ //
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ acc_filt_grp.ext = CYGNUM_CAN_ID_STD;
+ acc_filt_grp.lower_id_bound = 0x100;
+ acc_filt_grp.upper_id_bound = 0x110;
+ len = sizeof(acc_filt_grp);
+
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP ,&acc_filt_grp, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error adding filter group to /dev/can0");
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ acc_filt_grp.ext = CYGNUM_CAN_ID_EXT;
+ acc_filt_grp.lower_id_bound = 0x2000;
+ acc_filt_grp.upper_id_bound = 0x2200;
+ len = sizeof(acc_filt_grp);
+
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP ,&acc_filt_grp, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error adding filter group to /dev/can0");
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+ diag_printf("\n\nNow try to send CAN messages. The device should only\n"
+ "receive standard messages identifiers in the range of 0x100\n"
+ "to 0x110 and/or extended identifiers in the range 0x2000 to\n"
+ "0x2200. As soon as a standard message with ID 0x110 or an\n"
+ "extended message with ID 0x2200 arrives, the test finishes\n\n");
+
+ while (1)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (rx_event.msg.id == 0x110)
+ {
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN message filter group test OK");
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (rx_event.msg.id == 0x2200)
+ {
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN message filter group test OK");
+ }
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+ if (((rx_event.msg.id > 0x110) && (rx_event.msg.id < 0x2000))
+ || (rx_event.msg.id > 0x2200))
+ {
+ CYG_TEST_FAIL_FINISH("Received CAN identifier outside filter group bounds");
+ }
+ }
+ }
+ } // while (1)
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+#define N_A_MSG "Needs support for extended LPC2xxx CAN configuration keys"
+#endif
+
+#else // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+#define N_A_MSG "Needs CAN message box runtime confuguration support"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF flexcan_remote.c
--- /dev/null
+//==========================================================================
+//
+// can_multichan_rx.c
+//
+// CAN RX test for multiple CAN channels
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN RX test for multiple CAN controller channels
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_SUPPORT_NONBLOCKING)
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN_Tbl[4];
+
+
+//===========================================================================
+// Setup acceptance filter
+//===========================================================================
+void can_setup_channel(cyg_io_handle_t hCAN, unsigned char Channel)
+{
+ cyg_uint32 len;
+ cyg_can_msgbuf_cfg msgbox_cfg;
+ cyg_uint8 i;
+ cyg_uint32 blocking;
+
+ //
+ // First we reset message buffer configuration - this is mandatory bevore starting
+ // message buffer runtime configuration. This call clears/frees all message buffers
+ // The CAN controller cannot receive any further CAN message after this call
+ //
+ msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+ len = sizeof(msgbox_cfg);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0");
+ }
+
+ //
+ // Now setup 10 message filters for this channel
+ //
+ for (i = 0; i < 10; ++i)
+ {
+ cyg_can_filter rx_filter;
+
+ rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
+ rx_filter.msg.id = Channel * 0x100 + i;
+ rx_filter.msg.ext = CYGNUM_CAN_ID_STD;
+
+ len = sizeof(rx_filter);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config");
+ }
+ else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+ {
+ CYG_TEST_FAIL_FINISH("Error setting up message filter");
+ }
+ }
+
+ //
+ // Now set driver into nonblocking mode because the receiver thread will
+ // receive the messages from all channels
+ //
+ blocking = 0;
+ len = sizeof(blocking);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_READ_BLOCKING ,&blocking, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error setting channel into nonblocking mode");
+ }
+
+ //
+ // If timeouts are supported we need to setup a timeout value of 0 because
+ // the driver should return immediatelly if no message is available
+ //
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMEOUTS
+ cyg_can_timeout_info_t timeouts;
+
+ timeouts.rx_timeout = 0;
+ timeouts.tx_timeout = 0;
+ len = sizeof(timeouts);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_TIMEOUT ,&timeouts, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error setting timeout for channel");
+ }
+#endif
+}
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_uint8 i = 0;
+
+ //
+ // Check that all cannels have the same baudrate
+ //
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ can_setup_channel(hCAN_Tbl[0], 0);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ can_setup_channel(hCAN_Tbl[1], 1);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ can_setup_channel(hCAN_Tbl[2], 2);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ can_setup_channel(hCAN_Tbl[3], 3);
+#endif
+
+ diag_printf("\n\nThis test uses all available CAN channels for reception\n"
+ "of CAN standard messages. The following messages will be received:\n\n");
+
+ for (i = 0; i < 4; ++i)
+ {
+ if (hCAN_Tbl[i])
+ {
+ diag_printf("CAN channel %d: msg: 0x%03x - 0x%03x\n", i, i * 0x100, i * 0x100 + 9);
+ }
+ }
+
+ diag_printf("\n\nYou can stop this test by sending a message with ID 0xX09\n");
+
+ while (1)
+ {
+ for (i = 0; i < 4; ++i)
+ {
+ if (hCAN_Tbl[i])
+ {
+ Cyg_ErrNo ret;
+ cyg_can_event rx_event;
+
+ len = sizeof(rx_event);
+ ret = cyg_io_read(hCAN_Tbl[i], &rx_event, &len);
+ if ((ret == -EAGAIN) || (ret == -EINTR))
+ {
+ continue;
+ }
+
+ if (ENOERR != ret)
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel");
+ }
+ else
+ {
+ diag_printf("Channel %d events: ", i);
+ print_can_flags(rx_event.flags, "");
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ if ((rx_event.msg.id & 9) == 9)
+ {
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel RX test OK");
+ }
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ }
+ } // if (hCAN_Tbl[i])
+ } // for (i = 0; i < 4; ++i)
+ } // while (1)
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+#else
+ hCAN_Tbl[0] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+#else
+ hCAN_Tbl[1] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME, &hCAN_Tbl[2]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 2");
+ }
+#else
+ hCAN_Tbl[2] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME, &hCAN_Tbl[3]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 3");
+ }
+#else
+ hCAN_Tbl[3] = 0;
+#endif
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGOPT_IO_CAN_SUPPORT_NONBLOCKING
+#define N_A_MSG "Needs support for nonblocking calls"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_multichan_rx.c
--- /dev/null
+//==========================================================================
+//
+// can_multichan_tx.c
+//
+// CAN TX test for multiple CAN channels
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN TX test for multiple CAN controller channels
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN_Tbl[4];
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_message tx_msg;
+ cyg_can_info_t can_info;
+ cyg_can_baud_rate_t baud;
+ cyg_uint8 i = 0;
+ cyg_uint8 j = 0;
+
+ //
+ // Check that all cannels have the same baudrate
+ //
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[0], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 0");
+ }
+ else
+ {
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[1], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 1");
+ }
+ else
+ {
+ if (i && (baud != can_info.baud))
+ {
+ CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 0 and 1");
+ }
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[2], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 2");
+ }
+ else
+ {
+ if (i && (baud != can_info.baud))
+ {
+ CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 1 and 2");
+ }
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[3], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 3");
+ }
+ else
+ {
+ if (i && (baud != can_info.baud))
+ {
+ CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 2 and 3");
+ }
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+ diag_printf("\n\nYou should no receive 4 CAN messages from each active CAN channel\n");
+
+ //
+ // Now each CAN channel sends 10 CAN messages
+ //
+ for (i = 0; i < 4; ++i)
+ {
+ if (hCAN_Tbl[i])
+ {
+ CYG_CAN_MSG_SET_PARAM(tx_msg, i * 0x100, CYGNUM_CAN_ID_STD, 4, CYGNUM_CAN_FRAME_DATA);
+ tx_msg.data.dwords[0] = 0;
+ tx_msg.data.dwords[1] = 0;
+ char err_msg[64];
+ diag_snprintf(err_msg, sizeof(err_msg), "Error sending TX using CAN channel %d", i);
+ for (j = 0; j < 4; ++j)
+ {
+ tx_msg.id = i * 0x100 + j;
+ tx_msg.data.bytes[0] = j;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN_Tbl[i], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH(err_msg);
+ }
+ }
+ } // if (hCAN_Tbl[i])
+ } // for (i = 0; i < 4; ++i)
+
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel TX test OK");
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+#else
+ hCAN_Tbl[0] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+#else
+ hCAN_Tbl[1] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME, &hCAN_Tbl[2]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 2");
+ }
+#else
+ hCAN_Tbl[2] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME, &hCAN_Tbl[3]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 3");
+ }
+#else
+ hCAN_Tbl[3] = 0;
+#endif
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_multichan_tx.c
--- /dev/null
+//==========================================================================
+//
+// can_rx_tx.c
+//
+// CAN RX / TX test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN RX/TX test for 2 CAN channels
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// We need two CAN channels
+#if defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+
+
+// The same baud rates are required because we send from one channel to the other one
+#if CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+
+
+// We need the loop can driver
+#if defined(CYGPKG_DEVS_CAN_LOOP)
+#include <pkgconf/devs_can_loop.h>
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_tx_thread;
+thread_data_t can0_thread_data;
+cyg_thread_entry_t can_rx_thread;
+thread_data_t can1_thread_data;
+cyg_io_handle_t hCAN_Tbl[2];
+cyg_io_handle_t hLoopCAN_Tbl[2];
+
+
+//===========================================================================
+// Thread 0
+//===========================================================================
+void can_rx_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_can_event loop_rx_event;
+ cyg_uint32 msg_cnt = 0;
+ cyg_uint8 i;
+
+ while (msg_cnt < 0xF0)
+ {
+
+ //
+ // First receive CAN event from real CAN hardware
+ //
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN_Tbl[1], &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX chan 1:");
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ }
+
+ //
+ // Now receive CAN event from loop CAN driver
+ //
+ len = sizeof(loop_rx_event);
+ if (ENOERR != cyg_io_read(hLoopCAN_Tbl[1], &loop_rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from loop channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX loop 1:");
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ }
+
+ //
+ // Chaeck message ID and DLC of HW CAN message and CAN message from loop driver
+ // booth should be the same
+ //
+ if (rx_event.msg.id != loop_rx_event.msg.id)
+ {
+ CYG_TEST_FAIL_FINISH("Received message IDs of hw CAN channel and loop CAN channel are not equal");
+ }
+
+ if (rx_event.msg.dlc != loop_rx_event.msg.dlc)
+ {
+ CYG_TEST_FAIL_FINISH("Received DLCs of hw CAN msg and loop CAN msg are not equal");
+ }
+
+ //
+ // Now check each data byte of the receive message
+ //
+ for (i = 0; i < rx_event.msg.dlc; ++i)
+ {
+ if (rx_event.msg.data.bytes[i] != loop_rx_event.msg.data.bytes[i])
+ {
+ CYG_TEST_FAIL_FINISH("Data of hw CAN msg and loop CAN msg are not equal");
+ }
+
+ if (rx_event.msg.data.bytes[i] != (i + msg_cnt))
+ {
+ CYG_TEST_FAIL_FINISH("CAN message contains unexpected data");
+ }
+ }
+
+ msg_cnt++;
+ } // while (1)
+
+ CYG_TEST_PASS_FINISH("CAN rx/tx test OK");
+}
+
+
+//===========================================================================
+// Thread 1
+//===========================================================================
+void can_tx_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_message tx_msg;
+ cyg_uint32 msg_cnt = 0;
+ cyg_uint8 i;
+
+
+ CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA);
+
+ //
+ // Prepare CAN message with a known CAN state
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ tx_msg.data.bytes[i] = i;
+ }
+
+ while (msg_cnt < 0xF0)
+ {
+ tx_msg.id = msg_cnt;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN_Tbl[0], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to channel 0");
+ }
+
+
+ tx_msg.id = msg_cnt;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hLoopCAN_Tbl[0], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to channel 1");
+ }
+
+ //
+ // Increment data in each single data byte
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ tx_msg.data.bytes[i] += 1;
+ }
+
+ msg_cnt++;
+ tx_msg.dlc = (tx_msg.dlc + 1) % 9;
+ } // while (msg_cnt < 0x100)
+}
+
+
+//===========================================================================
+// Entry point
+//===========================================================================
+void cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+
+
+ //
+ // open CAN device driver channel 2
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+
+ //
+ // open Loop CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGDAT_DEVS_CAN_LOOP_CAN0_NAME, &hLoopCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening loop CAN channel 0");
+ }
+
+
+ //
+ // open Loop CAN device driver channel 2
+ //
+ if (ENOERR != cyg_io_lookup(CYGDAT_DEVS_CAN_LOOP_CAN1_NAME, &hLoopCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening loop CAN channel 1");
+ }
+
+
+
+
+
+ //
+ // create the first thread that access the CAN device driver
+ //
+ cyg_thread_create(5, can_tx_thread,
+ (cyg_addrword_t) 0,
+ "can_tx_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ //
+ // create the second thread that access the CAN device driver
+ //
+ cyg_thread_create(4, can_rx_thread,
+ (cyg_addrword_t) 0,
+ "can_rx_thread",
+ (void *) can1_thread_data.stack,
+ 1024 * sizeof(long),
+ &can1_thread_data.hdl,
+ &can1_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+ cyg_thread_resume(can1_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // defined(CYGPKG_DEVS_CAN_LOOP)
+#define N_A_MSG "Needs support for loop CAN device driver"
+#endif
+
+#else // CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+#define N_A_MSG "Baudrate of channel 0 and 1 need to be equal"
+#endif
+
+#else // defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+#define N_A_MSG "Needs support for CAN channel 1 and 2"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_rx_tx.c
--- /dev/null
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
--- /dev/null
+The file synth_test.ecm can be used to configure a synthetic target
+work tree to enable the various options to allow the tests to be run.
\ No newline at end of file
--- /dev/null
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+ description "" ;
+ hardware linux ;
+ template default ;
+ package -hardware CYGPKG_HAL_SYNTH current ;
+ package -hardware CYGPKG_HAL_SYNTH_I386 current ;
+ package -hardware CYGPKG_DEVS_FLASH_SYNTH current ;
+ package -hardware CYGPKG_DEVS_ETH_ECOSYNTH current ;
+ package -hardware CYGPKG_DEVS_WATCHDOG_SYNTH current ;
+ package -hardware CYGPKG_DEVS_WALLCLOCK_SYNTH current ;
+ package -template CYGPKG_HAL current ;
+ package -template CYGPKG_IO current ;
+ package -template CYGPKG_IO_SERIAL current ;
+ package -template CYGPKG_INFRA current ;
+ package -template CYGPKG_KERNEL current ;
+ package -template CYGPKG_MEMALLOC current ;
+ package -template CYGPKG_ISOINFRA current ;
+ package -template CYGPKG_LIBC current ;
+ package -template CYGPKG_LIBC_I18N current ;
+ package -template CYGPKG_LIBC_SETJMP current ;
+ package -template CYGPKG_LIBC_SIGNALS current ;
+ package -template CYGPKG_LIBC_STARTUP current ;
+ package -template CYGPKG_LIBC_STDIO current ;
+ package -template CYGPKG_LIBC_STDLIB current ;
+ package -template CYGPKG_LIBC_STRING current ;
+ package -template CYGPKG_LIBC_TIME current ;
+ package -template CYGPKG_LIBM current ;
+ package -template CYGPKG_IO_WALLCLOCK current ;
+ package -template CYGPKG_ERROR current ;
+ package CYGPKG_IO_CAN current ;
+ package CYGPKG_DEVS_CAN_LOOP current ;
+};
+
+cdl_component CYGPKG_DEVS_CAN_LOOP_CAN0 {
+ user_value 1
+};
+
+cdl_component CYGPKG_DEVS_CAN_LOOP_CAN1 {
+ user_value 1
+};
+
+cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT {
+ user_value 1
+};
+
+cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING {
+ user_value 1
+};
+
+cdl_option CYGOPT_IO_CAN_SUPPORT_CALLBACK {
+ user_value 1
+};
+
+cdl_component CYGOPT_IO_CAN_SUPPORT_TIMEOUTS {
+ user_value 1
+};
+
--- /dev/null
+//==========================================================================
+//
+// can_callback.c
+//
+// CAN driver test of callback on event
+//
+//==========================================================================
+//####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): Uwe Kindler, Alexey Shusharin
+// Contributors: Uwe Kindler, Alexey Shusharin
+// Date: 2007-08-23
+// Description: CAN driver test of callback on event
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_SUPPORT_CALLBACK)
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_thread;
+thread_data_t can_thread_data;
+
+cyg_mutex_t can_lock;
+cyg_cond_t can_wait;
+
+cyg_io_handle_t hCAN0;
+cyg_io_handle_t hCAN1;
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// CALLBACK FUNCTION
+//===========================================================================
+
+static void callback_func(cyg_uint16 flags, CYG_ADDRWORD data)
+{
+ if (data == ((CYG_ADDRWORD) hCAN0) && (flags & CYGNUM_CAN_EVENT_RX))
+ {
+ // Wake up thread
+ cyg_cond_signal(&can_wait);
+ }
+}
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_callback_cfg callback_cfg;
+ cyg_can_message tx_msg;
+ cyg_bool_t wait_res;
+
+ //
+ // open CAN0 device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // open CAN1 device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can1", &hCAN1))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can1");
+ }
+
+ //
+ // configure CAN0 callback
+ //
+ len = sizeof(callback_cfg);
+ callback_cfg.flag_mask = 0xFFFF;
+ callback_cfg.data = (CYG_ADDRWORD) hCAN0;
+ callback_cfg.callback_func = callback_func;
+
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_CALLBACK,
+ &callback_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ //
+ // transmit message from CAN1 to CAN0
+ //
+ tx_msg.id = 0x001;
+ tx_msg.ext = CYGNUM_CAN_ID_STD;
+ tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ tx_msg.dlc = 0;
+ len = sizeof(tx_msg);
+
+ if (ENOERR != cyg_io_write(hCAN1, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing message to /dev/can1");
+ }
+
+ //
+ // Wait CAN0 callback
+ //
+ cyg_mutex_lock(&can_lock);
+
+ wait_res = cyg_cond_timed_wait(&can_wait, 100);
+
+ cyg_mutex_unlock(&can_lock);
+
+ //
+ // If result of wait is a signal operation, test is successed
+ // If timeout - test is failed, because callback_func() hasn't been
+ // called with correct parameters
+ //
+ if(wait_res)
+ {
+ CYG_TEST_PASS_FINISH("can_callback test OK");
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("can_callback test FAILED");
+ }
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ cyg_mutex_init(&can_lock);
+ cyg_cond_init(&can_wait, &can_lock);
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(4, can_thread,
+ (cyg_addrword_t) 0,
+ "can_thread",
+ (void *) can_thread_data.stack,
+ 1024 * sizeof(long),
+ &can_thread_data.hdl,
+ &can_thread_data.obj);
+
+ cyg_thread_resume(can_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // #if defined(CYGOPT_IO_CAN_SUPPORT_CALLBACK)
+#define N_A_MSG "Needs callback support"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_callback.c
--- /dev/null
+//==========================================================================
+//
+// flexcan_wake.c
+//
+// FlexCAN wake test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-09-10
+// Description: FlexCAN test of standby and wake
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+cyg_io_handle_t hDrvFlexCAN;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event1;
+ cyg_can_event rx_event2;
+ cyg_can_msgbuf_info msgbox_info;
+ cyg_can_mode mode;
+ cyg_can_state state;
+
+
+ diag_printf("Test of FlexCAN standby mode with selfwakeup\n"
+ "As soon as a message arrives the FlexCAN modul\n"
+ "will leave standby and generates a leave standby event.\n"
+ "Each time you send a message you should see LSTY first\n"
+ "for \"leaving standby\" and then \"RX\" for the\n"
+ "RX event that caused the leave standby event. You can send\n"
+ "a CAN data frame with any ID\n");
+
+ diag_printf("!!! This test can be stopped by sending a data frame with ID 0x100 !!!\n\n");
+
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+ else
+ {
+ diag_printf("Message boxes available: %d free: %d\n",
+ msgbox_info.count, msgbox_info.free);
+ }
+
+ while (1)
+ {
+ //
+ // now we set FlexCAN into standby mode
+ //
+ mode = CYGNUM_CAN_MODE_STANDBY;
+ len = sizeof(mode);
+ if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MODE ,&mode, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ //
+ // now check if FlexCAN modul is really in standby mode
+ //
+ len = sizeof(state);
+ if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_STATE ,&state, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+
+ if (state != CYGNUM_CAN_STATE_STANDBY)
+ {
+ CYG_TEST_FAIL_FINISH("Error stopping FlexCAN /dev/can0");
+ }
+
+ //
+ // as soon as a message arrives the FlexCAN modul leaves standby mode
+ // and we should receive a CYGNUM_CAN_EVENT_LEAVING_STANDBY event but
+ // we will also receive a RX event because a message arrived
+ //
+ len = sizeof(rx_event1);
+ if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event1, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ len = sizeof(rx_event2);
+ if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event2, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ print_can_flags(rx_event1.flags, "");
+ print_can_flags(rx_event2.flags, "");
+
+ //
+ // The first event we receive should be a leaving standby event because
+ // first flexcan leaves standby and then a message will be received
+ //
+ if (!(rx_event1.flags & CYGNUM_CAN_EVENT_LEAVING_STANDBY))
+ {
+ CYG_TEST_FAIL_FINISH("CYGNUM_CAN_EVENT_LEAVING_STANDBY event expexted /dev/can0");
+ }
+
+ if (rx_event2.msg.id == 0x100)
+ {
+ CYG_TEST_PASS_FINISH("flexcan_wake test OK");
+ }
+ }
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open flexcan device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hDrvFlexCAN))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+
+ //
+ // create the two threads which access the CAN device driver
+ // a reader thread with a higher priority and a writer thread
+ // with a lower priority
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF flexcan_wake.c
--- /dev/null
+2007-05-30 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/mmc_spi.c: Revise debug information with addition.
+ Add idle to operational retry wait.
+ * cdl/devs_disk_mmc.cdl: Add idle to operational retry wait parameter.
+
+2006-09-27 Sergei Gavrikov <sg@sgs.gomel.by>
+
+ * src/mmc_spi.c: (mmc_spi_disk_lookup): just fixed a missed
+ semicolon.
+
+2006-09-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * Contribution of MMC/SPI package from eCosCentric. eCosCentric
+ changes prior to contribution are included below for reference:
+
+ 2006-09-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/mmc_spi.c: DISK_FUNS, DISK_CHANNEL and DISK_CONTROLLER are now
+ implicitly static.
+ Update DISK_CHANNEL for new io/disk macro definition.
+
+ 2006-04-05 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/devs_disk_mmc.cdl: Add reference to package documentation.
+
+ 2006-03-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/mmc_spi.c (struct cyg_mmc_spi_disk_info_t): Store underlying
+ medium's read/write block length.
+ (mmc_spi_check_for_disk): Store underlying medium's
+ read/write block length.
+ (mmc_spi_disk_lookup): Report medium block size to disk layer.
+ (mmc_spi_disk_read): API now requires sector reads to be with length
+ of sectors not bytes.
+ (mmc_spi_disk_write): Ditto.
+
+ 2005-10-28 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/mmc_protocol.h: Move from src/ to here.
+ * src/mmc_spi.c: Reflect above move.
+
+ 2004-08-30 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c (mmc_spi_write_disk_block): disable background
+ writes. Some MMC cards don't seem to implement this correctly so
+ if you are trying to talking to another SPI device the MMC card
+ still replies.
+
+ 2004-07-03 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c (MMC_SPI_READ_DATA_TOKEN_RETRIES): increase the
+ number of iterations. With some cards a read can occasionally take
+ 50* longer than normal.
+
+ 2004-07-01 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c: reorganize write code, to work around problems
+ with some cards.
+
+ 2004-06-29 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c: some cards require an extra delay during a mount
+ sequence, when doing the first read of a data block. Also added
+ some recovery code to the mount code in case a previous session
+ left the card still sending data.
+
+ 2004-06-15 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c (mmc_spi_check_for_disk): allow platform HALs to
+ customize the mount sequence.
+
+ * doc/disk_mmc.sgml: document the above change.
+
+ 2004-04-25 Bart Veer <bartv@ecoscentric.com>
+
+ * MMC package created
+
+ //===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006 eCosCentric Ltd.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# devs_disk_mmc.cdl
+#
+# Support for MMC cards
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2004, 2005, 2006 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv,jlarmour
+# Date: 2004-04-25
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_DISK_MMC {
+ display "Disk driver for MMC cards"
+ doc ecos-ref/devs-disk-mmc-part.html
+
+ include_dir cyg/io
+
+ parent CYGPKG_IO_DISK_DEVICES
+ active_if CYGPKG_IO_DISK
+
+ cdl_interface CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS {
+ active_if CYGPKG_IO_SPI
+ display "Number of MMC connectors accessed via SPI"
+ }
+
+ cdl_component CYGPKG_DEVS_DISK_MMC_SPI {
+ display "Access an MMC card via an SPI bus"
+ default_value { CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS > 0 }
+ compile -library=libextras.a mmc_spi.c
+ requires CYGPKG_ERROR CYGPKG_LIBC_STRING
+ description "
+ This option enables support for accessing an MMC card via an
+ SPI bus."
+
+ define_proc {
+ puts $::cdl_system_header "/***** MMC/SPI disk driver output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_DEVS_DISK_CFG"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_DISK_CFG <pkgconf/devs_disk_mmc.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** MMC/SPI disk driver output end *****/"
+ }
+
+ cdl_option CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME {
+ display "Device name for the MMC/SPI disk 0 device"
+ flavor data
+ default_value { "\"/dev/hd0/\"" }
+ description "
+ This is the device name used to access the raw disk device
+ in eCos, for example for mount operations. Note that the
+ trailing slash must be present."
+
+ # Testing support. For now just hard-code some values for partition 0
+ # on the card.
+ define_proc {
+ puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DEVICE CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME \"1\""
+ puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_MOUNTPOINT \"/dosfs\""
+ puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DIRECTORY \"/test\""
+ }
+ }
+
+ cdl_option CYGIMP_DEVS_DISK_MMC_SPI_POLLED {
+ display "Run the driver in polled mode rather than interrupt-driven"
+ default_value !CYGPKG_KERNEL
+ description "
+ By default the MMC disk driver will operate in interrupt-driven
+ mode if the kernel is present, i.e. if the application is likely
+ to be multi-threaded. Otherwise it will operate in polled mode."
+ }
+ cdl_option CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT {
+ display "Idle to operational retry wait"
+ flavor booldata
+ default_value 10000
+ description "
+ This option sets how long to wait between retries of attempts to change the
+ card state from idle to operational. It is measured in microseconds."
+ }
+}
+
+# EOF devs_disk_mmc.cdl
--- /dev/null
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- disk_mmc.sgml -->
+<!-- -->
+<!-- Documentation for the MMC disk device driver -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN#### -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- -->
+<!-- ####COPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2004/04/25 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-disk-mmc-part"><title>MMC MultiMedia Card Disk Driver</title>
+
+<refentry id="devs-disk-mmc">
+ <refmeta>
+ <refentrytitle>Device Driver for MMC MultiMedia Cards</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVS_DISK_MMC</varname></refname>
+ <refpurpose>eCos Support for MMC MultiMedia Cards</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-disk-mmc-description"><title>Description</title>
+ <para>
+This package provides a disk device driver for MultiMediaCards (MMC).
+A MultiMediaCard provides non-volatile storage in a small footprint
+(24mm * 32mm * 1.4mm), and weighing less than 2 grams. Typical
+card sizes are 16MB to 128MB, with an upper limit of 4GB. It
+should be noted that these sizes are measured in millions of bytes,
+not 2^20. The <ulink url="http://www.mmca.org">MultiMediaCard
+Association</ulink> defines the standard for these cards.
+ </para>
+ <para>
+At the hardware level there are two ways of accessing an MMC card,
+either using a custom interface or via an SPI bus. A card will detect
+the interface in use at run-time. The custom interface allows for
+better performance but requires additional hardware. Currently only
+SPI mode is supported by this package.
+ </para>
+ <para>
+Theoretically an MMC card can be used with any file system. In
+practice all cards are formatted for PC compatibility, with a
+partition table in the first block and a single FAT file system on the
+rest of the card. Currently this package checks the format of the MMC
+card and will only allow access to a card if it is formatted this way.
+ </para>
+ <para>
+An MMC socket allows cards to be removed and inserted at any time. The
+device driver will detect removal events when the next I/O operation
+happens and will report them to higher-level code via an error code
+<literal>ENODEV</literal>. However there are no guarantees that the
+higher-level code will be able to recover from this error. The
+expected usage is that application code will explicitly
+<function>mount</function> the card before attempting any file I/O,
+and will <function>umount</function> the card before it is removed.
+Between these operations the system is likely to keep some disk blocks
+cached, for performance reasons. If the card is removed before the
+<function>umount</function> then it may end up with a corrupted file
+system, and the disk subsystem may be left in an inconsistent state.
+Regular uses of <function>sync</function> will reduce the risk
+of file system corruption.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-disk-mmc-config"><title>Configuration Options</title>
+ <para>
+<varname>CYGPKG_DEVS_DISK_MMC</varname> is a hardware package which
+should get loaded automatically when you configure for a suitable eCos
+target platform. In this case suitable means that the hardware has an
+MMC socket connected to an SPI bus, that an SPI bus driver package
+exists and is also automatically loaded, and that the platform HAL
+provides <link linkend="devs-disk-mmc-porting">information</link>
+on how the card is connected to the SPI bus.
+ </para>
+ <para>
+The package depends on support from the generic disk package
+<varname>CYGPKG_IO_DISK</varname>. That will not be loaded
+automatically: the presence of an MMC socket on the board does not
+mean that the application has any need for a file system. Hence by
+default <varname>CYGPKG_DEVS_DISK_MMC</varname> will be inactive and
+will not contribute any code or data to the application's memory
+footprint. To activate the driver it will be necessary to add one or
+more packages to the configuration using
+<command>ecosconfig add</command> or the graphical configuration
+tool: the generic disk support <varname>CYGPKG_IO_DISK</varname>;
+usually a file system, <varname>CYGPKG_FS_FAT</varname>; support for
+the file I/O API <varname>CYGPKG_IO_FILEIO</varname>; and possibly
+additional support packages that may be needed by the file system, for
+example <varname>CYGPKG_LINUX_COMPAT</varname>. Depending on the
+template used to create the initial configuration some of these may be
+loaded already.
+ </para>
+ <para>
+The package provides two main configuration options.
+<varname>CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME</varname> specifies the
+name of the raw disk device, for example <literal>/dev/hd0</literal>.
+Allowing for partition tables that makes <literal>/dev/hd0/1</literal>
+the first argument that shoul be passed to a
+<function>mount</function> call. If the hardware has multiple disk
+devices then each one will need a unique name.
+<varname>CYGIMP_DEVS_DISK_MMC_SPI_POLLED</varname> controls whether
+the SPI bus will be accessed in interrupt-driven or polled mode. It
+will default to interrupt-driven if the application is multi-threaded,
+which is assumed to be the case if the kernel is present. If the
+kernel is absent, for example in a RedBoot configuration, then the
+driver will default to polled mode. With some hardware polled mode may
+significantly increase disk throughput even in a multi-threaded
+application, but will consume cpu cycles that could be used by other
+threads.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-disk-mmc-extra"><title>Additional Functionality</title>
+ <para>
+The disk driver package exports a variable
+<varname>cyg_mmc_spi_polled</varname>. This defaults to true or false
+depending on the configuration option
+<varname>CYGIMP_DEVS_DISK_MMC_SPI_POLLED</varname>. If the default
+mode is interrupt-driven then file I/O, including mount operations,
+are only allowed when the scheduler has started and interrupts have
+been enabled. Any attempts at file I/O earlier during system
+initialization, for example inside a C++ static constructor, will lock
+up. If it is necessary to perform file I/O at this time then the
+driver can be temporarily switched to polling mode before the I/O
+operation by setting <varname>cyg_mmc_spi_polled</varname>, and
+clearing it again after the I/O. Alternatively the default mode can be
+changed to polling by editing the configuration, and then the
+<function>main()</function> thread can change the mode to
+interrupt-driven once the scheduler has started.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-disk-mmc-porting"><title>Porting to New Hardware</title>
+ <para>
+Assuming that the MMC connector is hooked up to a standard SPI bus and
+that there is already an eCos SPI bus driver, porting the MMC disk
+driver package should be straightforward. Some other package, usually
+the platform HAL, should provide a <type>cyg_spi_device</type>
+structure <varname>cyg_spi_mmc_dev0</varname>. That structure contains
+the information needed by this package to interact with the MMC card
+via the usual SPI interface, for example how to activate the
+appropriate chip select. The platform HAL should also implement the
+CDL interface <varname>CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS</varname>.
+ </para>
+ <para>
+When defining <varname>cyg_spi_mmc_dev0</varname> special care must be
+taken with the chip select. The MMC protocol is transaction-oriented.
+For example a read operation involves an initial command sent to the
+card, then a reply, then the actual data, and finally a checksum. The
+card's chip select must be kept asserted for the entire operation, and
+there can be no interactions with other devices on the same SPI bus
+during this time.
+ </para>
+ <para>
+Optionally the platform HAL may define a macro
+<function>HAL_MMC_SPI_INIT</function> which will be invoked during a
+mount operation. This can take any hardware-specific actions that may
+be necessary, for example manipulating GPIO pins. Usually no such
+macro is needed because the hardware is set up during platform
+initialization.
+ </para>
+ <para>
+Currently the package does not provide any support for accessing MMC
+cards using an interface other than SPI. On some targets there may be
+additional hardware to detect events such as card insertion or
+removal, but there is no support for exploiting such hardware at
+present.
+ </para>
+ <para>
+Only a single MMC socket is supported. Extending the package to
+support multiple sockets would be straightforward but it seems
+unlikely that any hardware would come with multiple MMC sockets. Given
+the nature of SPI buses there is a problem if the MMC socket is hooked
+up via an expansion connector rather than being attached to the main
+board. The platform HAL would not know about the socket so would not
+implement the CDL interface
+<varname>CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS</varname>, and the
+<database>ecos.db</database> target entry would not include
+<varname>CYGPKG_DEVS_DISK_MMC</varname>. Because this is a hardware
+package it cannot easily be added by hand. Instead this scenario would
+require some editing of the existing platform HAL and target entry.
+ </para>
+ </refsect1>
+
+</refentry>
+</part>
--- /dev/null
+#ifndef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+#define CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+//==========================================================================
+//
+// mmc_protocol.h
+//
+// Define the protocol used for interacting with MMC cards
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005 eCosCentric Limited
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: bartv
+// Contributors: jlarmour
+// Date: 2004-04-25
+// Usage: Only this package and implementing device drivers should
+// include this header file.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h> /* Common types */
+
+// The MMC command set. A request is a six-byte sequence. First a
+// single command byte, one of the following with bit 6 (0x40) or'd in
+// and bit 7 clear as a start bit. Then a four-byte argument, usually
+// a 32-bit integer most significant byte first. Finally a 7-bit CRC
+// and a stop bit. In SPI mode the CRC is usually optional, except for
+// the GO_IDLE_STATE command.
+//
+// Commands ALL_SEND_CID, SEND_RELATIVE_ADDR, SET_DSR,
+// SELECT_DESELECT, READ_DATA_UNTIL_STOP, STOP_TRANSMISSION,
+// GO_INACTIVE, READ_MULTIPLE_BLOCK, WRITE_DATA_UNTIL_STOP,
+// WRITE_MULTIPLE_BLOCK, and PROGRAM_CID are MMC only, and not
+// available in SPI mode.
+//
+// Device drivers may use values with bit 7 set to indicate
+// driver-specific commands.
+
+#define MMC_REQUEST_GO_IDLE_STATE 0x00
+#define MMC_REQUEST_SEND_OP_COND 0x01
+#define MMC_REQUEST_ALL_SEND_CID 0x02
+#define MMC_REQUEST_SEND_RELATIVE_ADDR 0x03
+#define MMC_REQUEST_SET_DSR 0x04
+#define MMC_REQUEST_SELECT_DESELECT 0x07
+#define MMC_REQUEST_SEND_CSD 0x09
+#define MMC_REQUEST_SEND_CID 0x0A
+#define MMC_REQUEST_READ_DATA_UNTIL_STOP 0x0B
+#define MMC_REQUEST_STOP_TRANSMISSION 0x0C
+#define MMC_REQUEST_SEND_STATUS 0x0D
+#define MMC_REQUEST_GO_INACTIVE 0x0F
+#define MMC_REQUEST_SET_BLOCKLEN 0x10
+#define MMC_REQUEST_READ_SINGLE_BLOCK 0x11
+#define MMC_REQUEST_READ_MULTIPLE_BLOCK 0x12
+#define MMC_REQUEST_WRITE_DATA_UNTIL_STOP 0x14
+#define MMC_REQUEST_WRITE_BLOCK 0x18
+#define MMC_REQUEST_WRITE_MULTIPLE_BLOCK 0x19
+#define MMC_REQUEST_PROGRAM_CID 0x1A
+#define MMC_REQUEST_PROGRAM_CSD 0x1B
+#define MMC_REQUEST_SET_WRITE_PROT 0x1C
+#define MMC_REQUEST_CLR_WRITE_PROT 0x1D
+#define MMC_REQUEST_SEND_WRITE_PROT 0x1E
+#define MMC_REQUEST_TAG_SECTOR_START 0x20
+#define MMC_REQUEST_TAG_SECTOR_END 0x21
+#define MMC_REQUEST_UNTAG_SECTOR 0x22
+#define MMC_REQUEST_TAG_ERASE_GROUP_START 0x23
+#define MMC_REQUEST_TAG_ERASE_GROUP_END 0x24
+#define MMC_REQUEST_UNTAG_ERASE_GROUP 0x25
+#define MMC_REQUEST_ERASE 0x26
+#define MMC_REQUEST_LOCK_UNLOCK 0x2A
+#define MMC_REQUEST_READ_OCR 0x3A
+#define MMC_REQUEST_CRC_ON_OFF 0x3B
+
+// Response formats are different for MMC vs. SPI mode, so are defined
+// in the appropriate source files.
+
+// The CID register is generally treated as an opaque data structure
+// used only for unique identification of cards.
+typedef struct mmc_cid_register {
+ cyg_uint8 cid_data[16];
+} mmc_cid_register;
+
+#define MMC_CID_REGISTER_MID(_data_) ((_data_)->cid_data[0])
+#define MMC_CID_REGISTER_OID(_data_) (((_data_)->cid_data[1] << 8) | \
+ ((_data_)->cid_data[2]))
+#define MMC_CID_REGISTER_PNM(_data_) ((const char*)&((_data_)->cid_data[3]))
+#define MMC_CID_REGISTER_PRV(_data_) ((_data_)->cid_data[9])
+#define MMC_CID_REGISTER_PSN(_data_) (((_data_)->cid_data[10] << 24) | \
+ ((_data_)->cid_data[11] << 16) | \
+ ((_data_)->cid_data[12] << 8) | \
+ ((_data_)->cid_data[13]))
+#define MMC_CID_REGISTER_MDT(_data_) ((_data_)->cid_data[14])
+#define MMC_CID_REGISTER_CRC(_data_) ((_data_)->cid_data[15] >> 1)
+
+
+// The CSD register is just lots of small bitfields. For now keep it
+// as an array of 16 bytes and provide macros to read the fields.
+typedef struct mmc_csd_register {
+ cyg_uint8 csd_data[16];
+} mmc_csd_register;
+
+#define MMC_CSD_REGISTER_CSD_STRUCTURE(_data_) (((_data_)->csd_data[0] & 0x00C0) >> 6)
+#define MMC_CSD_REGISTER_SPEC_VERS(_data_) (((_data_)->csd_data[0] & 0x003C) >> 2)
+#define MMC_CSD_REGISTER_TAAC_MANTISSA(_data_) (((_data_)->csd_data[1] & 0x0078) >> 3)
+#define MMC_CSD_REGISTER_TAAC_EXPONENT(_data_) ((_data_)->csd_data[1] & 0x0007)
+#define MMC_CSD_REGISTER_NSAC(_data_) ((_data_)->csd_data[2])
+#define MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(_data_) (((_data_)->csd_data[3] & 0x0078) >> 3)
+#define MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(_data_) ((_data_)->csd_data[3] & 0x0007)
+#define MMC_CSD_REGISTER_CCC(_data_) (((_data_)->csd_data[4] << 4) | (((_data_)->csd_data[5] & 0x00F0) >> 4))
+#define MMC_CSD_REGISTER_READ_BL_LEN(_data_) ((_data_)->csd_data[5] & 0x000F)
+#define MMC_CSD_REGISTER_READ_BL_PARTIAL(_data_) (((_data_)->csd_data[6] & 0x0080) >> 7)
+#define MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0040) >> 6)
+#define MMC_CSD_REGISTER_READ_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0020) >> 5)
+#define MMC_CSD_REGISTER_DSR_IMP(_data_) (((_data_)->csd_data[6] & 0x0010) >> 4)
+#define MMC_CSD_REGISTER_C_SIZE(_data_) ((((_data_)->csd_data[6] & 0x0003) << 10) | \
+ ((_data_)->csd_data[7] << 2) | \
+ (((_data_)->csd_data[8] & 0x00C0) >> 6))
+#define MMC_CSD_REGISTER_VDD_R_CURR_MIN(_data_) (((_data_)->csd_data[8] & 0x0038) >> 3)
+#define MMC_CSD_REGISTER_VDD_R_CURR_MAX(_data_) ((_data_)->csd_data[8] & 0x0007)
+#define MMC_CSD_REGISTER_VDD_W_CURR_MIN(_data_) (((_data_)->csd_data[9] & 0x00E0) >> 5)
+#define MMC_CSD_REGISTER_VDD_W_CURR_MAX(_data_) (((_data_)->csd_data[9] & 0x001C) >> 2)
+#define MMC_CSD_REGISTER_C_SIZE_MULT(_data_) ((((_data_)->csd_data[9] & 0x0003) << 1) | \
+ (((_data_)->csd_data[10] & 0x0080) >> 7))
+#define MMC_CSD_REGISTER_SECTOR_SIZE(_data_) (((_data_)->csd_data[10] & 0x007C) >> 2)
+#define MMC_CSD_REGISTER_ERASE_GRP_SIZE(_data_) ((((_data_)->csd_data[10] & 0x0003) << 3) | \
+ (((_data_)->csd_data[11] & 0x00E0) >> 5))
+#define MMC_CSD_REGISTER_WR_GRP_SIZE(_data_) ((_data_)->csd_data[11] & 0x001F)
+#define MMC_CSD_REGISTER_WR_GRP_ENABLE(_data_) (((_data_)->csd_data[12] & 0x0080) >> 7)
+#define MMC_CSD_REGISTER_DEFAULT_ECC(_data_) (((_data_)->csd_data[12] & 0x0060) >> 5)
+#define MMC_CSD_REGISTER_R2W_FACTOR(_data_) (((_data_)->csd_data[12] & 0x001C) >> 2)
+#define MMC_CSD_REGISTER_WRITE_BL_LEN(_data_) ((((_data_)->csd_data[12] & 0x0003) << 2) | \
+ (((_data_)->csd_data[13] & 0x00C0) >> 6))
+#define MMC_CSD_REGISTER_WR_BL_PARTIAL(_data_) (((_data_)->csd_data[13] & 0x0020) >> 5)
+#define MMC_CSD_REGISTER_FILE_FORMAT_GROUP(_data_) (((_data_)->csd_data[14] & 0x0080) >> 7)
+#define MMC_CSD_REGISTER_COPY(_data_) (((_data_)->csd_data[14] & 0x0040) >> 6)
+#define MMC_CSD_REGISTER_PERM_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0020) >> 5)
+#define MMC_CSD_REGISTER_TMP_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0010) >> 4)
+#define MMC_CSD_REGISTER_FILE_FORMAT(_data_) (((_data_)->csd_data[14] & 0x000C) >> 2)
+#define MMC_CSD_REGISTER_ECC(_data_) ((_data_)->csd_data[14] & 0x0003)
+#define MMC_CSD_REGISTER_CRC(_data_) (((_data_)->csd_data[15] & 0xFE) >> 1)
+
+
+#endif // ifdef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+
+/* EOF mmc_protocol.h */
--- /dev/null
+//==========================================================================
+//
+// mmc_spi.c
+//
+// Provide a disk device driver for MMC cards over SPI
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2006 eCosCentric Limited
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: bartv
+// Date: 2004-04-25
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_disk_mmc.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_if.h> // delays
+#include <cyg/hal/hal_intr.h>
+#include <string.h>
+#include <errno.h>
+#include <cyg/io/io.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/disk.h>
+#include <cyg/io/mmc_protocol.h>
+
+// Communication parameters. First some debug support
+#define DEBUG 0
+#if DEBUG > 0
+# define DEBUG1(format, ...) diag_printf(format, ## __VA_ARGS__)
+#else
+# define DEBUG1(format, ...)
+#endif
+#if DEBUG > 1
+# define DEBUG2(format, ...) diag_printf(format, ## __VA_ARGS__)
+#else
+# define DEBUG2(format, ...)
+#endif
+
+// Should the SPI operations run in polled or interrupt-driven mode?
+// The default value is determined by CDL, but can be overridden at
+// run-time if necessary. For example if configured for
+// interrupt-driven I/O then it will be impossible to perform disk
+// operations during system initialization, e.g. from a static
+// constructor, unless this flag is changed for the duration.
+#ifdef CYGIMP_DEVS_DISK_MMC_SPI_POLLED
+cyg_bool cyg_mmc_spi_polled = true;
+#else
+cyg_bool cyg_mmc_spi_polled = false;
+#endif
+
+// Should write operations be allowed to complete in the background,
+// or must the operation complete in the foreground. The latter
+// requires polling for potentially a long time, up to some 100's of
+// milliseconds, but the former appears unreliable if there are other
+// devices on the SPI bus. In theory the MMC card should detect that
+// the chip select line is dropped and tristate the output line, but
+// in practice this does not always happen.
+#undef MMC_SPI_BACKGROUND_WRITES
+
+// The size of each disk block
+#define MMC_SPI_BLOCK_SIZE 512
+// The number of retries during a mount operation when switching to
+// IDLE mode.
+#define MMC_SPI_GO_IDLE_RETRIES 16
+// The number of retries during a mount operation when switching from
+// idle to operational
+#define MMC_SPI_OP_COND_RETRIES 128
+// The number of retries when waiting for a response to any command
+#define MMC_SPI_COMMAND_RETRIES 32
+// Retries when waiting for a data response token during a read
+#define MMC_SPI_READ_DATA_TOKEN_RETRIES 32768
+// Retries during a write while waiting for completion
+#define MMC_SPI_WRITE_BUSY_RETRIES 32768
+
+// ----------------------------------------------------------------------------
+// SPI-specific parts of the MMC protocol.
+//
+// The main response byte. 0 indicates success, other bits
+// indicate various error conditions.
+#define MMC_REPLY_SUCCESS 0x00
+#define MMC_REPLY_PARAMETER_ERROR (0x01 << 6)
+#define MMC_REPLY_ADDRESS_ERROR (0x01 << 5)
+#define MMC_REPLY_ERASE_SEQUENCE_ERROR (0x01 << 4)
+#define MMC_REPLY_COM_CRC_ERROR (0x01 << 3)
+#define MMC_REPLY_ILLEGAL_COMMAND (0x01 << 2)
+#define MMC_REPLY_ERASE_RESET (0x01 << 1)
+#define MMC_REPLY_IN_IDLE_STATE (0x01 << 0)
+
+// A send-status command generates a second response byte
+#define MMC_REPLY2_OUT_OF_RANGE (0x01 << 7)
+#define MMC_REPLY2_ERASE_PARAM (0x01 << 6)
+#define MMC_REPLY2_WP_VIOLATION (0x01 << 5)
+#define MMC_REPLY2_CARD_ECC_FAILED (0x01 << 4)
+#define MMC_REPLY2_CC_ERROR (0x01 << 3)
+#define MMC_REPLY2_ERROR (0x01 << 2)
+#define MMC_REPLY2_WP_ERASE_SKIP (0x01 << 1)
+// Alias for the above
+#define MMC_REPLY2_LOCK_UNLOCK_FAILED (0x01 << 1)
+#define MMC_REPLY2_CARD_LOCKED (0x01 << 0)
+
+// The data error token byte which may get sent if a read
+// operation fails. The top 3 bits will be 0. A successful
+// response will have these bits 1.
+#define MMC_DATA_TOKEN_SUCCESS (0x00FE)
+#define MMC_DATA_ERROR_TOKEN_CARD_LOCKED (0x01 << 4)
+#define MMC_DATA_ERROR_TOKEN_OUT_OF_RANGE (0x01 << 3)
+#define MMC_DATA_ERROR_TOKEN_CARD_ECC_FAILED (0x01 << 2)
+#define MMC_DATA_ERROR_TOKEN_CC_ERROR (0x01 << 1)
+#define MMC_DATA_ERROR_TOKEN_ERROR (0x01 << 0)
+
+// ----------------------------------------------------------------------------
+// Structures and statics.
+//
+// There should be an SPI device cyg_spi_mmc_dev0, probably provided by
+// the HAL, possibly by the application. Because of the latter we cannot
+// assume the variable will be defined in a header.
+extern cyg_spi_device cyg_spi_mmc_dev0;
+
+// When retrieving data it is necessary to send an 0xff byte stream,
+// which the card will not confuse with further commands. The largest
+// transfer is 512 bytes, too large a buffer to place on the stack.
+static cyg_uint8 mmc_spi_ff_data[512];
+#define MMC_SPI_INIT_FF_DATA() \
+ CYG_MACRO_START \
+ memset(mmc_spi_ff_data, 0x00FF, 512); \
+ CYG_MACRO_END
+
+// Details of a specific MMC card
+typedef struct cyg_mmc_spi_disk_info_t {
+ cyg_spi_device* mmc_spi_dev;
+ cyg_uint32 mmc_saved_baudrate;
+ cyg_uint32 mmc_block_count;
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ cyg_bool mmc_writing;
+#endif
+ cyg_bool mmc_read_only;
+ cyg_bool mmc_connected;
+ cyg_uint32 mmc_heads_per_cylinder;
+ cyg_uint32 mmc_sectors_per_head;
+ cyg_uint32 mmc_read_block_length;
+ cyg_uint32 mmc_write_block_length;
+ mmc_cid_register mmc_id;
+} cyg_mmc_spi_disk_info_t;
+
+// There is no need for a hardware-specific disk controller structure.
+// The closest equivalent is probably an SPI bus, i.e. if there were
+// MMC connectors attached to different SPI buses then these would
+// have separate controllers with independent locking. However that
+// can be handled without a cyg_mmc_spi_controller_info_t structure.
+
+// ----------------------------------------------------------------------------
+// The low-level MMC operations
+
+// After power-on an MMC card is in idle state and needs at least 74
+// clock cycles before any communication. These might be supplied
+// courtesy of another SPI device, but no guarantees, so generate some
+// ticks.
+static void
+mmc_spi_send_init(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_spi_bus *bus;
+ cyg_spi_device *dev;
+
+ DEBUG2("mmc_spi_send_init(): dev pointer 0x%p, %d\n", disk->mmc_spi_dev, cyg_mmc_spi_polled );
+ dev = disk->mmc_spi_dev;
+ bus = dev->spi_bus;
+ DEBUG2(" : begin pointer %p\n", bus->spi_transaction_begin );
+ cyg_spi_tick(disk->mmc_spi_dev, cyg_mmc_spi_polled, 10);
+}
+
+// Send the first part of a command sequence. This consists of the
+// command itself, an argument, a CRC, and then waiting for a
+// reply byte from the card.
+static cyg_uint32
+mmc_spi_send_command_start(cyg_mmc_spi_disk_info_t* disk, cyg_uint32 command, cyg_uint32 arg)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ cyg_uint8 request[7];
+ cyg_uint8 response[7];
+ cyg_uint8 reply;
+ int i;
+
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ // If the last operation was a block write, those can take a while
+ // to complete. Rather than wait at the end of the write(), do so
+ // at the beginning of the next operation i.e. here. This also
+ // allows the chip select to be dropped while the write comples,
+ // so communication is possible with other devices. The polling is
+ // done as a sequence of transactions rather than in a single
+ // transaction, again to let other threads in to communicate with
+ // other devices.
+ //
+ // The card will send a stream of 0x00 bytes while the write
+ // completes. Some cards have been observed to send a byte 0x03 at
+ // the end, Either way, when the card sends a byte 0xff it should
+ // be ready for the next command.
+ if (disk->mmc_writing) {
+ DEBUG2("mmc_spi_send_command_start(): polling for completion of previous write\n");
+ disk->mmc_writing = 0;
+ response[0] = 0x00;
+ for (i = 0; (i < MMC_SPI_WRITE_BUSY_RETRIES) && (0x00FF != response[0]); i++) {
+ cyg_spi_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, response);
+ }
+ }
+#endif
+
+ request[0] = command | 0x0040;
+ request[1] = (arg >> 24) & 0x00FF;
+ request[2] = (arg >> 16) & 0x00FF;
+ request[3] = (arg >> 8) & 0x00FF;
+ request[4] = arg & 0x00FF;
+ // A CRC is needed for the go-idle-state command, because that
+ // command switches the device from MMC to SPI mode. That CRC is
+ // well-known. Once in SPI mode the card will not use CRCs by
+ // default.
+ request[5] = (command == 0x00) ? 0x0095 : 0x00ff;
+ // There will need to be at least one extra byte transfer to get
+ // the card's response, so send that straightaway. Extra
+ // outgoing data like this should be 0xff so that the card
+ // does not confuse it with a new incoming command.
+ request[6] = 0x00ff;
+
+ // Lock the SPI bus. It remains locked until a subsequent call to
+ // mmc_spi_end_command().
+ cyg_spi_transaction_begin(dev);
+
+ // Transfer the whole command, and try to read the response back
+ // immediately.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 7, request, response, 0);
+ DEBUG2("Sent command %02x %d: reply bytes %02x %02x %02x %02x %02x %02x %02x\n", command, arg, \
+ response[0], response[1], response[2], response[3], response[4], response[5], response[6]);
+
+ // The response will be a single byte with the top bit clear.
+ // The remaining bits are error/status flags. If the command
+ // involves an additional response then that will be handled
+ // by the calling code.
+ reply = response[6];
+ for (i = 0; (i < MMC_SPI_COMMAND_RETRIES) && (0 != (reply & 0x0080)); i++) {
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, response, 0);
+ reply = response[0];
+ DEBUG2(" loop %d, additional reply %02x\n", i, reply);
+ }
+
+ // Leave the interpretation of the reply code to the caller
+ return (cyg_uint32) reply;
+}
+
+// At the end of each command the card needs eight clocks to finish
+// its processing. A tick() call takes care of that, and will have
+// the side effect of dropping the chip select. Ending the transaction
+// unlocks the bus for other SPI I/O operations
+static void
+mmc_spi_end_command(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ cyg_spi_transaction_tick(dev, cyg_mmc_spi_polled, 1);
+ cyg_spi_transaction_end(dev);
+}
+
+// A utility combination of the above two for simple commands which do
+// not involve any other data.
+static cyg_uint32
+mmc_spi_send_command(cyg_mmc_spi_disk_info_t* disk, cyg_uint32 command, cyg_uint32 arg)
+{
+ cyg_uint32 reply;
+ reply = mmc_spi_send_command_start(disk, command, arg);
+ mmc_spi_end_command(disk);
+ return reply;
+}
+
+// The card will return a data block when reading a disk block, or
+// for certain other commands like reading card registers. Each
+// data block consists of:
+// 1) some number of padding bytes 0xff while the card is still
+// processing the command and preparing the data
+// 2) a data token byte, usually 0xFE for success
+// 3) n bytes of data
+// 4) two bytes of crc, which can be ignored.
+//
+// The data token byte is the only indication of success or failure,
+// so that gets returned.
+//
+// When mounting certain types of card an extra delay may be needed
+// before reading the first data block. This is handled by the
+// extra_delay argument.
+static cyg_uint32
+mmc_spi_read_data(cyg_mmc_spi_disk_info_t* disk, cyg_uint8* buf, cyg_uint32 count, cyg_bool extra_delay)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ int i;
+ cyg_uint8 response[2];
+ cyg_uint32 retries;
+
+ if (extra_delay) {
+ retries = MMC_SPI_READ_DATA_TOKEN_RETRIES * 100;
+ } else {
+ retries = MMC_SPI_READ_DATA_TOKEN_RETRIES;
+ }
+
+ response[0] = 0x00FF;
+ for (i = 0; (i < retries) && (0x00FF == response[0]); i++) {
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, response, 0);
+ }
+
+ if (MMC_DATA_TOKEN_SUCCESS != response[0]) {
+ DEBUG1("mmc_spi_read_data(): got error response %02x after %d iterations\n", response[0], i);
+ return response[0];
+ }
+
+ // Now for the actual data. There is no way of detecting a failure from
+ // this point on.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, count, mmc_spi_ff_data, buf, 0);
+ // And the CRC, which can be ignored
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 2, mmc_spi_ff_data, response, 0);
+ DEBUG2("mmc_spi_read_data(): got data and CRC %02x %02x\n", response[0], response[1]);
+
+ return MMC_DATA_TOKEN_SUCCESS;
+}
+
+// Read one of the card registers, e.g. CSD or CID
+static Cyg_ErrNo
+mmc_spi_read_register(cyg_mmc_spi_disk_info_t* disk, cyg_uint32 command, cyg_uint8* buf, cyg_uint32 count)
+{
+ cyg_uint32 reply;
+
+ reply = mmc_spi_send_command_start(disk, command, 0);
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("mmc_spi_read_register(): unexpected response to command %02x, reply code %02x\n", command, reply);
+ mmc_spi_end_command(disk);
+ return (0x00FF == reply) ? -ENODEV : -EIO;
+ }
+ reply = mmc_spi_read_data(disk, buf, count, false);
+ mmc_spi_end_command(disk);
+ if (MMC_DATA_TOKEN_SUCCESS != reply) {
+ DEBUG1("mmc_spi_read_register(): unexpected response to command %02x, expected 0x00FE data token, got %02x\n", command, reply);
+ return -EIO;
+ }
+ return ENOERR;
+}
+
+// Reading a disk block is just a combination of the above utilities.
+// This code is also responsible for translating error codes, since
+// higher-level code does not get to see the initial response vs. the
+// data token byte.
+static Cyg_ErrNo
+mmc_spi_read_disk_block(cyg_mmc_spi_disk_info_t* disk, cyg_uint8* buf, cyg_uint32 block, cyg_bool extra_delay)
+{
+ cyg_uint32 reply;
+
+ // First the command itself.
+ DEBUG2("mmc_spi_read_disk_block(%d): sending command\n", block);
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_READ_SINGLE_BLOCK, block * MMC_SPI_BLOCK_SIZE);
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("mmc_spi_read_disk_block(%d): unexpected response to READ_SINGLE_BLOCK command, code %02x\n", block, reply);
+ mmc_spi_end_command(disk);
+ // A byte 0xFF indicates the card has been removed.
+ if (0x00FF == reply) {
+ return -ENODEV;
+ }
+ // Parameter or address error should not occur, higher-level
+ // code should have checked the block to ensure that it is
+ // in range.
+ if (0 != (reply & (MMC_REPLY_PARAMETER_ERROR | MMC_REPLY_ADDRESS_ERROR))) {
+ return -EINVAL;
+ }
+ // The disk should not be in idle state or in an erase sequence. The
+ // command is definitely legal and CRCs should be disabled. So everything
+ // else is an I/O error.
+ return -EIO;
+ }
+
+ // Now read back the data block. That code can be shared with other read
+ // operations, e.g. for retrieving registers.
+ DEBUG2("mmc_spi_read_disk_block(%d): reading data token/data/crc\n", block);
+ reply = mmc_spi_read_data(disk, buf, MMC_SPI_BLOCK_SIZE, extra_delay);
+ mmc_spi_end_command(disk);
+ if (MMC_DATA_TOKEN_SUCCESS != reply) {
+ DEBUG1("mmc_spi_read_disk_block(%d): failed to retrieve data, error token %02x\n", block, reply);
+
+ // Possibilities are password-locked, range error, ECC failure
+ // if the raw data is corrupt, CC error for an internal card
+ // error, or some other error. A byte 0xFF indicates the card
+ // has been removed.
+ if (0x00FF == reply) {
+ return -ENODEV;
+ } else if (0 != (MMC_DATA_ERROR_TOKEN_CARD_LOCKED & reply)) {
+ // This should have been caught by a mount operation.
+ return -EPERM;
+ } else if (0 != (MMC_DATA_ERROR_TOKEN_OUT_OF_RANGE & reply)) {
+ return -EINVAL;
+ } else {
+ return -EIO;
+ }
+ }
+ return ENOERR;
+}
+
+// Writing a block involves a bit more work. Some of this could be
+// moved into a utility routine if necessary, shared with code for
+// e.g. updating the CSD register, but for now that other functionality
+// is not needed.
+static Cyg_ErrNo
+mmc_spi_write_disk_block(cyg_mmc_spi_disk_info_t* disk, const cyg_uint8* buf, cyg_uint32 block)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ cyg_uint32 reply;
+ cyg_uint8 extra[4];
+ int i;
+
+ // First, send the command itself and get the initial response
+ DEBUG2("mmc_spi_write_disk_block(), sending command\n");
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_WRITE_BLOCK, block * MMC_SPI_BLOCK_SIZE);
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("mmc_spi_write_disk_block(): unexpected response to WRITE_BLOCK command, code %02x\n", reply);
+ mmc_spi_end_command(disk);
+ if (0x00FF == reply) {
+ return -ENODEV;
+ }
+ // Parameter or address error should not occur, higher-level
+ // code should have checked the block to ensure that it is
+ // in range.
+ if (0 != (reply & (MMC_REPLY_PARAMETER_ERROR | MMC_REPLY_ADDRESS_ERROR))) {
+ return -EINVAL;
+ }
+ // The disk should not be in idle state or in an erase sequence. The
+ // command is definitely legal and CRCs should be disabled. So everything
+ // else is an I/O error.
+ return -EIO;
+ }
+
+ // The card is now expecting a data block. This consists of a single byte
+ // 0x00FE, then the data itself, and a dummy CRC. The reply from the card
+ // does not contain any useful information.
+ DEBUG2("mmc_spi_write_disk_block(): sending data token/data/crc\n");
+ extra[0] = 0x00FE;
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, extra, (cyg_uint8*)0, 0);
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, MMC_SPI_BLOCK_SIZE, buf, (cyg_uint8*)0, 0);
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 2, mmc_spi_ff_data, (cyg_uint8*)0, 0);
+
+ // The card should respond immediately with a data response token.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, extra, 0);
+ DEBUG2("mmc_spi_write_disk_block(): got data response token %02x\n", extra[0]);
+
+ // The bottom five bits contain the response. 00101 indicates success,
+ // anything else is a CRC error. Everything else will have been checked
+ // before the data got transferred.
+ if (0x05 != (extra[0] & 0x1F)) {
+ DEBUG1("mmc_spi_write_disk_block(): invalid data response token %02x\n", extra[0]);
+ mmc_spi_end_command(disk);
+ if (0x00FF == extra[0]) {
+ return -ENODEV;
+ }
+ return -EIO;
+ }
+
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ // Mark the card as writing. The next operation will poll for completion.
+ disk->mmc_writing = true;
+#else
+ // The card is now busy doing the write and will output a stream of 0's
+ // while busy. The timeout should really be calculated using the CSD
+ // register settings.
+ //
+ // It should be legal to drop the chip select here, i.e. to end
+ // the current transaction and start a new one for each poll
+ // operation. That would allow other SPI devices to be accessed.
+ // However it appears that this does not work with all MMC cards.
+ extra[0] = 0x00;
+ for (i = 0; (i < MMC_SPI_WRITE_BUSY_RETRIES) && (0x00 == extra[0]); i++) {
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, extra, 0);
+ DEBUG2("mmc_spi_write_disk_block(), polling for ! busy, got response %02x\n", extra[0]);
+ }
+#endif
+
+ // Assume that the loop did in fact terminate.
+ mmc_spi_end_command(disk);
+ return ENOERR;
+}
+
+// MMC sockets will default to a slow clockrate. During a successful mount
+// the SPI device settings will be changed to the fastest supported by the
+// card, as per the CSD register. This will need to be undone during an
+// unmount, or if the final stages of a mount are unsuccessful.
+static void
+mmc_spi_restore_baud(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_uint32 len = sizeof(cyg_uint32);
+ (void) cyg_spi_set_config(disk->mmc_spi_dev, CYG_IO_SET_CONFIG_SPI_CLOCKRATE, (void*) &(disk->mmc_saved_baudrate), &len);
+}
+
+// check_for_disk() tries to communicate with an MMC card that is not
+// currently mounted. It performs the appropriate initialization so
+// that read and write operations are possible, checks the disk format,
+// distinguishes between read-only and read-write cards, calculates the
+// card size, stores the unique id, etc.
+//
+// The main error conditions are ENODEV (no card), EIO (card not
+// responding sensibly to requests), ENOTDIR (wrong format), or EPERM
+// (card is password-locked).
+static Cyg_ErrNo
+mmc_spi_check_for_disk(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ int i;
+ cyg_uint32 reply;
+ Cyg_ErrNo code;
+ mmc_csd_register csd;
+
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ // If we have unmounted a disk and are remounting it, assume that
+ // any writes have completed.
+ disk->mmc_writing = false;
+#endif
+ reply = 0x00ff;
+
+ for (i = 0; (i < MMC_SPI_GO_IDLE_RETRIES) && (0x01 != reply); i++) {
+ // Allow platform HALs to provide additional initialization,
+ // if the hardware needs it.
+#ifdef HAL_MMC_SPI_INIT
+ HAL_MMC_SPI_INIT(dev, reply);
+ if (! reply) {
+ return -ENODEV;
+ }
+#endif
+ // MMC cards generic initialization. The card may have just
+ // been plugged in so there is no guarantee that any previous
+ // init() calls or other traffic will have affected this card.
+ mmc_spi_send_init(disk);
+
+ // Now set the card to idle state. This involves the GO_IDLE_STATE
+ // command which will be accepted irrespective of whether the card is
+ // currently in MMC or SPI mode, and will leave the card in SPI mode.
+ reply = mmc_spi_send_command(disk, MMC_REQUEST_GO_IDLE_STATE, 0);
+
+ // The card should reply with 0x01. FF suggests that there is
+ // no card. Any other response indicates some synchronization
+ // problem. For example the card might still be responding to
+ // some request from a previous session which aborted at an
+ // inconvenient moment. Some dummy traffic is generated in the
+ // hope that this gets things back in sync.
+ if (0x01 != reply) {
+ DEBUG1("mmc_spi_check_for_disk(): loop %d, card did not enter idle state, code %02x\n", i, reply);
+ if (0x0ff != reply) {
+ cyg_spi_transfer(dev, cyg_mmc_spi_polled, 128, mmc_spi_ff_data, (cyg_uint8*) 0);
+ }
+ }
+ }
+ if (0x0ff == reply) {
+ DEBUG1("mmc_spi_check_for_disk(): unable to get a response from the MMC card: code %02x\n", reply);
+ // A working card should be returning some data
+ return -ENODEV;
+ }
+ if (0x01 != reply) {
+ DEBUG1("mmc_spi_check_for_disk(): card did not enter idle state, code %02x\n", reply);
+ return -EIO;
+ }
+
+ // Next, wait for the card to initialize. This involves repeatedly
+ // trying the SEND_OP_COND command until we get a reply that is
+ // not idle
+ reply = 0x00ff;
+ for (i = 0; (i < MMC_SPI_OP_COND_RETRIES) && ((0x00ff == reply) || (0 != (MMC_REPLY_IN_IDLE_STATE & reply))); i++) {
+#ifdef CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT
+ CYGACC_CALL_IF_DELAY_US(CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT);
+#endif
+ reply = mmc_spi_send_command(disk, MMC_REQUEST_SEND_OP_COND, 0);
+ }
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("mmc_spi_check_for_disk(): card has not entered operational state: reply code %02x\n", reply);
+ return (0x00FF == reply) ? -ENODEV : -EIO;
+ }
+
+ // The card has now generated sufficient responses that we don't need to
+ // worry about a missing card anymore.
+ // Get hold of the card's unique ID and store it, to allow disk changes
+ // to be detected.
+ code = mmc_spi_read_register(disk, MMC_REQUEST_SEND_CID, (cyg_uint8*) &(disk->mmc_id), 16);
+ if (code) {
+ mmc_spi_end_command(disk);
+ return code;
+ }
+ DEBUG2("CID data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", \
+ disk->mmc_id.cid_data[ 0], disk->mmc_id.cid_data[ 1], disk->mmc_id.cid_data[ 2], disk->mmc_id.cid_data[ 3], \
+ disk->mmc_id.cid_data[ 4], disk->mmc_id.cid_data[ 5], disk->mmc_id.cid_data[ 6], disk->mmc_id.cid_data[ 7], \
+ disk->mmc_id.cid_data[ 8], disk->mmc_id.cid_data[ 9], disk->mmc_id.cid_data[10], disk->mmc_id.cid_data[11], \
+ disk->mmc_id.cid_data[12], disk->mmc_id.cid_data[13], disk->mmc_id.cid_data[14], disk->mmc_id.cid_data[15]);
+#if DEBUG > 0
+ DEBUG1("CID data: register\n");
+ DEBUG1(" : Manufacturer ID : MID = 0x%02x\n", MMC_CID_REGISTER_MID(&(disk->mmc_id)) & 0xff);
+ DEBUG1(" : OEM/Application ID : OID = 0x%04x\n", MMC_CID_REGISTER_OID(&(disk->mmc_id)) & 0xffff);
+ DEBUG1(" : Product name : PNM = 0x%02x%02x%02x%02x%02x%02x\n",
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[0] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[1] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[2] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[3] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[4] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[5] & 0xff);
+ DEBUG1(" : Product revision : PRV = 0x%02x\n", MMC_CID_REGISTER_PRV(&(disk->mmc_id)) & 0xff);
+ DEBUG1(" : Product serial number : PSN = 0x%08x\n", MMC_CID_REGISTER_PSN(&(disk->mmc_id)) & 0xffffffff);
+ DEBUG1(" : Manufacturing date : MDT = 0x%02x\n", MMC_CID_REGISTER_MDT(&(disk->mmc_id)) & 0xff);
+ DEBUG1(" : 7-bit CRC checksum : CRC = 0x%02x\n", MMC_CID_REGISTER_CRC(&(disk->mmc_id)) & 0xff);
+#endif
+
+ // And retrieve the card's configuration data.
+ code = mmc_spi_read_register(disk, MMC_REQUEST_SEND_CSD, (cyg_uint8*) &csd, 16);
+ if (code) {
+ mmc_spi_end_command(disk);
+ return code;
+ }
+ DEBUG2("CSD data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", \
+ csd.csd_data[ 0], csd.csd_data[ 1], csd.csd_data[ 2], csd.csd_data[3], \
+ csd.csd_data[ 4], csd.csd_data[ 5], csd.csd_data[ 6], csd.csd_data[7], \
+ csd.csd_data[ 8], csd.csd_data[ 9], csd.csd_data[10], csd.csd_data[11], \
+ csd.csd_data[12], csd.csd_data[13], csd.csd_data[14], csd.csd_data[15]);
+
+ // Optionally dump the whole CSD register. This takes a lot of
+ // code but gives a lot of info about the card. If the info looks
+ // correct then we really are interacting properly with an MMC card.
+#if DEBUG > 0
+ DEBUG1("CSD data: structure 0x%02x, version 0x%02x\n", MMC_CSD_REGISTER_CSD_STRUCTURE(&csd), MMC_CSD_REGISTER_SPEC_VERS(&csd));
+ if (0 != MMC_CSD_REGISTER_FILE_FORMAT_GROUP(&csd)) {
+ DEBUG1(" : Reserved (unknown), FILE_FORMAT_GROUP %d, FILE_FORMAT %d\n", \
+ MMC_CSD_REGISTER_FILE_FORMAT_GROUP(&csd), MMC_CSD_REGISTER_FILE_FORMAT(&csd));
+ } else if (0 == MMC_CSD_REGISTER_FILE_FORMAT(&csd)) {
+ DEBUG1(" : Partioned disk, FILE_FORMAT_GROUP 0, FILE_FORMAT 0\n");
+ } else if (1 == MMC_CSD_REGISTER_FILE_FORMAT(&csd)) {
+ DEBUG1(" : FAT disk, FILE_FORMAT_GROUP 0, FILE_FORMAT 1\n");
+ } else if (2 == MMC_CSD_REGISTER_FILE_FORMAT(&csd)) {
+ DEBUG1(" : Universal File format, FILE_FORMAT_GROUP 0, FILE_FORMAT 2\n");
+ } else {
+ DEBUG1(" : Others/Unknown disk, FILE_FORMAT_GROUP 0, FILE_FORMAT 3\n");
+ }
+ {
+ static const cyg_uint32 mantissa_speeds_x10[16] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+ static const cyg_uint32 exponent_speeds_div10[8] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+ cyg_uint32 speed = mantissa_speeds_x10[MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(&csd)] *
+ exponent_speeds_div10[MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(&csd)];
+ speed /= 1000;
+ DEBUG1(" : TRAN_SPEED %d %d -> %d kbit/s\n", \
+ MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(&csd), MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(&csd), speed);
+ }
+ DEBUG1(" : READ_BL_LEN block length 2^%d (%d)\n", MMC_CSD_REGISTER_READ_BL_LEN(&csd), \
+ 0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd));
+ DEBUG1(" : C_SIZE %d, C_SIZE_MULT %d\n", MMC_CSD_REGISTER_C_SIZE(&csd), MMC_CSD_REGISTER_C_SIZE_MULT(&csd));
+ {
+ cyg_uint32 block_len = 0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd);
+ cyg_uint32 mult = 0x01 << (MMC_CSD_REGISTER_C_SIZE_MULT(&csd) + 2);
+ cyg_uint32 size = block_len * mult * (MMC_CSD_REGISTER_C_SIZE(&csd) + 1);
+ cyg_uint32 sizeK = (cyg_uint32) (size / 1024);
+ cyg_uint32 sizeM = sizeK / 1024;
+ sizeK -= (sizeM * 1024);
+ DEBUG1(" : total card size %dM%dK\n", sizeM, sizeK);
+ }
+ DEBUG1(" : WR_BL_LEN block length 2^%d (%d)\n", \
+ MMC_CSD_REGISTER_WRITE_BL_LEN(&csd), 0x01 << MMC_CSD_REGISTER_WRITE_BL_LEN(&csd));
+ {
+ static cyg_uint32 taac_mantissa_speeds_x10[16] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+ static cyg_uint32 taac_exponent_speeds_div10[8] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
+ cyg_uint32 taac_speed = taac_mantissa_speeds_x10[MMC_CSD_REGISTER_TAAC_MANTISSA(&csd)] *
+ taac_exponent_speeds_div10[MMC_CSD_REGISTER_TAAC_EXPONENT(&csd)];
+ taac_speed /= 100;
+ DEBUG1(" : asynchronous read access time TAAC %d %d -> %d ns\n", \
+ MMC_CSD_REGISTER_TAAC_MANTISSA(&csd), MMC_CSD_REGISTER_TAAC_EXPONENT(&csd), taac_speed);
+ }
+ DEBUG1(" : synchronous read access time NSAC %d * 100 cycles\n", \
+ MMC_CSD_REGISTER_NSAC(&csd));
+ DEBUG1(" : typical write program time %d * read time\n", MMC_CSD_REGISTER_R2W_FACTOR(&csd));
+ DEBUG1(" : CCC command classes 0x%04x\n", MMC_CSD_REGISTER_CCC(&csd));
+ DEBUG1(" : READ_BL_PARTIAL %d, WRITE_BLK_MISALIGN %d, READ_BLK_MISALIGN %d, DSR_IMP %d\n", \
+ MMC_CSD_REGISTER_READ_BL_PARTIAL(&csd), MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(&csd), \
+ MMC_CSD_REGISTER_READ_BLK_MISALIGN(&csd), MMC_CSD_REGISTER_DSR_IMP(&csd));
+ DEBUG1(" : WR_BL_PARTIAL %d\n", MMC_CSD_REGISTER_WR_BL_PARTIAL(&csd));
+ {
+ static cyg_uint8 min_currents[8] = { 1, 1, 5, 10, 25, 35, 60, 100 };
+ static cyg_uint8 max_currents[8] = { 1, 5, 10, 25, 35, 45, 80, 200 };
+ DEBUG1(" : read current min %dmA, max %dmA\n", \
+ min_currents[MMC_CSD_REGISTER_VDD_R_CURR_MIN(&csd)], \
+ max_currents[MMC_CSD_REGISTER_VDD_R_CURR_MAX(&csd)]);
+ DEBUG1(" : write current min %dmA, max %dmA\n", \
+ min_currents[MMC_CSD_REGISTER_VDD_W_CURR_MIN(&csd)], \
+ max_currents[MMC_CSD_REGISTER_VDD_W_CURR_MAX(&csd)]);
+ }
+ DEBUG1(" : erase sector size %d, erase group size %d\n", \
+ MMC_CSD_REGISTER_SECTOR_SIZE(&csd) + 1, MMC_CSD_REGISTER_ERASE_GRP_SIZE(&csd) + 1);
+ DEBUG1(" : write group enable %d, write group size %d\n", \
+ MMC_CSD_REGISTER_WR_GRP_ENABLE(&csd), MMC_CSD_REGISTER_WR_GRP_SIZE(&csd) + 1);
+ DEBUG1(" : copy bit %d\n", MMC_CSD_REGISTER_COPY(&csd));
+ DEBUG1(" : permanent write protect %d, temporary write protect %d\n", \
+ MMC_CSD_REGISTER_PERM_WRITE_PROTECT(&csd), MMC_CSD_REGISTER_TMP_WRITE_PROTECT(&csd));
+ DEBUG1(" : ecc %d, default ecc %d\n", MMC_CSD_REGISTER_ECC(&csd), MMC_CSD_REGISTER_DEFAULT_ECC(&csd));
+ DEBUG1(" : crc 0x%08x\n", MMC_CSD_REGISTER_CRC(&csd));
+#endif
+
+ // There is information available about the file format, e.g.
+ // partitioned vs. simple FAT. With the current version of the
+ // generic disk code this needs to be known statically, via
+ // the mbr field of the disk channel structure. If the card
+ // is inappropriately formatted, reject the mount request.
+ if ((0 != MMC_CSD_REGISTER_FILE_FORMAT_GROUP(&csd)) ||
+ (0 != MMC_CSD_REGISTER_FILE_FORMAT(&csd))) {
+ return -ENOTDIR;
+ }
+
+ // Look for a write-protect bit (permanent or temporary), and set
+ // the disk as read-only or read-write as appropriate. The
+ // temporary write-protect could be cleared by rewriting the CSD
+ // register (including recalculating the CRC) but the effort
+ // involves does not seem worth-while.
+ if ((0 != MMC_CSD_REGISTER_PERM_WRITE_PROTECT(&csd)) || (0 != MMC_CSD_REGISTER_TMP_WRITE_PROTECT(&csd))) {
+ disk->mmc_read_only = true;
+ } else {
+ disk->mmc_read_only = false;
+ }
+ DEBUG1("Disk read-only flag %d\n", disk->mmc_read_only);
+
+ // Calculate the disk size, primarily for assertion purposes.
+ // By design MMC cards are limited to 4GB, which still doesn't
+ // quite fit into 32 bits.
+ disk->mmc_block_count = (((cyg_uint64)(0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd))) *
+ ((cyg_uint64)(0x01 << (MMC_CSD_REGISTER_C_SIZE_MULT(&csd) + 2))) *
+ ((cyg_uint64)(MMC_CSD_REGISTER_C_SIZE(&csd) + 1))) / (cyg_uint64)MMC_SPI_BLOCK_SIZE;
+ DEBUG1("Disk blockcount %d (0x%08x)\n", disk->mmc_block_count, disk->mmc_block_count);
+
+ // Assume for now that the block length is 512 bytes. This is
+ // probably a safe assumption since we have just got the card
+ // initialized out of idle state. If it ever proves to be a problem
+ // the SET_BLOCK_LEN command can be used.
+ // Nevertheless store the underlying block sizes
+ disk->mmc_read_block_length = 0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd);
+ disk->mmc_write_block_length = 0x01 << MMC_CSD_REGISTER_WRITE_BL_LEN(&csd);
+
+ // The CSD contains the maximum supported transfer speed. Adjust
+ // the SPI device to match, saving the old value for an unmount
+ // operation. It is assumed that the SPI bus driver will munge
+ // the supplied speed to something appropriate.
+ {
+ static const cyg_uint32 mantissa_speeds_x10[16] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+ static const cyg_uint32 exponent_speeds_div10[8] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+ cyg_uint32 speed, len;
+
+ len = sizeof(cyg_uint32);
+ if (cyg_spi_get_config(dev, CYG_IO_GET_CONFIG_SPI_CLOCKRATE, (void*) &disk->mmc_saved_baudrate, &len)) {
+ DEBUG1("Failed to retrieve current SPI device clockrate\n");
+ return -EIO;
+ }
+ speed = mantissa_speeds_x10[MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(&csd)] * exponent_speeds_div10[MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(&csd)];
+ if (speed > disk->mmc_saved_baudrate) {
+ DEBUG1("Old SPI speed %d, switching to %d\n", disk->mmc_saved_baudrate, speed);
+ cyg_spi_set_config(dev, CYG_IO_SET_CONFIG_SPI_CLOCKRATE, (void*) &speed, &len);
+ } else {
+ DEBUG1("Old SPI speed %d already greater than max speed %d, leaving it alone\n",
+ disk->mmc_saved_baudrate, speed);
+ }
+ }
+
+ // Read the partition table off the card. This is a way of
+ // checking that the card is not password-locked. It also
+ // provides information about the "disk geometry" which is
+ // needed by higher-level code.
+ // FIXME: the higher-level code should be made to use LBA
+ // addressing instead.
+ {
+ cyg_uint8 data[MMC_SPI_BLOCK_SIZE];
+ cyg_uint8* partition;
+ cyg_uint32 lba_first, lba_size, lba_end, head, cylinder, sector;
+
+ code = mmc_spi_read_disk_block(disk, data, 0, true);
+ if (code) {
+ mmc_spi_restore_baud(disk);
+ return code;
+ }
+#if DEBUG > 1
+ {
+ cyg_uint8 *ptr_data;
+
+ DEBUG2("MBR dump\n");
+ for (i = 0; i < MMC_SPI_BLOCK_SIZE; i += 16) {
+ ptr_data = &data[i];
+ DEBUG2(" %04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ i,
+ ptr_data[ 0], ptr_data[ 1], ptr_data[ 2], ptr_data[ 3],
+ ptr_data[ 4], ptr_data[ 5], ptr_data[ 6], ptr_data[ 7],
+ ptr_data[ 8], ptr_data[ 9], ptr_data[10], ptr_data[11],
+ ptr_data[12], ptr_data[13], ptr_data[14], ptr_data[15]);
+ }
+ }
+#endif
+#if DEBUG > 0
+ DEBUG1("Read block 0 (partition table)\n");
+ DEBUG1("Signature 0x%02x 0x%02x, should be 0x55 0xaa\n", data[0x1fe], data[0x1ff]);
+ // There should be four 16-byte partition table entries at offsets
+ // 0x1be, 0x1ce, 0x1de and 0x1ee. The numbers are stored little-endian
+ for (i = 0; i < 4; i++) {
+ partition = &(data[0x1be + (0x10 * i)]);
+ DEBUG1("Partition %d: boot %02x, first sector %02x %02x %02x, file system %02x, last sector %02x %02x %02x\n", i, \
+ partition[0], partition[1], partition[2], partition[3], partition[4], \
+ partition[5], partition[6], partition[7]);
+ DEBUG1(" : first sector (linear) %02x %02x %02x %02x, sector count %02x %02x %02x %02x\n", \
+ partition[11], partition[10], partition[9], partition[8], \
+ partition[15], partition[14], partition[13], partition[12]);
+ }
+#endif
+ if ((0x0055 != data[0x1fe]) || (0x00aa != data[0x1ff])) {
+ mmc_spi_restore_baud(disk);
+ return -ENOTDIR;
+ }
+ partition = &(data[0x1be]);
+ lba_first = (partition[11] << 24) | (partition[10] << 16) | (partition[9] << 8) | partition[8];
+ lba_size = (partition[15] << 24) | (partition[14] << 16) | (partition[13] << 8) | partition[12];
+ lba_end = lba_first + lba_size - 1;
+
+ // First sector in c/h/s format
+ cylinder = ((partition[2] & 0xC0) << 2) | partition[3];
+ head = partition[1];
+ sector = partition[2] & 0x3F;
+
+ // lba_start == (((cylinder * Nh) + head) * Ns) + sector - 1, where (Nh == heads/cylinder) and (Ns == sectors/head)
+ // Strictly speaking we should be solving some simultaneous
+ // equations here for lba_start/lba_end, but that gets messy.
+ // The first partition is at the start of the card so cylinder will be 0,
+ // and we can ignore Nh.
+ CYG_ASSERT(0 == cylinder, "Driver assumption - partition 0 is at start of card\n");
+ CYG_ASSERT(0 != head, "Driver assumption - partition table is sensible\n");
+ disk->mmc_sectors_per_head = ((lba_first + 1) - sector) / head;
+
+ // Now for lba_end.
+ cylinder = ((partition[6] & 0xC0) << 2) | partition[7];
+ head = partition[5];
+ sector = partition[6] & 0x3F;
+ disk->mmc_heads_per_cylinder = ((((lba_end + 1) - sector) / disk->mmc_sectors_per_head) - head) / cylinder;
+ }
+
+ return ENOERR;
+}
+
+// Check that the current card is the one that was previously
+// accessed. This may fail if the card has been removed and the
+// slot is empty, or if the card has been removed and a different
+// one inserted. It may pass incorrectly if a card is removed,
+// modified elsewhere, and reinserted without eCos noticing.
+// There is no way around that without some way of detecting
+// disk removal in hardware.
+//
+// Re-reading the cid may actually be overkill. If a new card
+// has been plugged in then it will not have been initialized so
+// it will respond with 0xff anyway. It is very unlikely that
+// an init sequence will have happened by accident.
+static cyg_bool
+mmc_spi_disk_changed(cyg_mmc_spi_disk_info_t* disk)
+{
+ mmc_cid_register cid;
+ Cyg_ErrNo code;
+
+ code = mmc_spi_read_register(disk, MMC_REQUEST_SEND_CID, (cyg_uint8*) &cid, 16);
+ if (-ENODEV == code) {
+ return true;
+ }
+
+ if (0 != memcmp(&cid, &(disk->mmc_id), sizeof(mmc_cid_register))) {
+ return true;
+ }
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+// No hardware initialization is performed here. Even if a card is
+// currently plugged in it may get removed before it gets mounted, so
+// there is no point looking at the card here. It is still necessary
+// to invoke the callback init function so that higher-level code gets
+// a chance to do its bit.
+static cyg_bool
+mmc_spi_disk_init(struct cyg_devtab_entry* tab)
+{
+ disk_channel* chan = (disk_channel*) tab->priv;
+ MMC_SPI_INIT_FF_DATA();
+ return (*chan->callbacks->disk_init)(tab);
+}
+
+// lookup() is called during a mount() operation, so this is the right
+// place to check whether or not there is a card.
+
+static char*
+mmc_spi_disk_lookup_itoa(cyg_uint32 num, char* where)
+{
+ if (0 == num) {
+ *where++ = '0';
+ } else {
+ char local[10]; // 2^32 just fits into 10 places
+ int index = 9;
+ while (num > 0) {
+ local[index--] = (num % 10) + '0';
+ num /= 10;
+ }
+ for (index += 1; index < 10; index++) {
+ *where++ = local[index];
+ }
+ }
+ return where;
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry *sub_tab, const char* name)
+{
+ disk_channel* chan = (disk_channel*) (*tab)->priv;
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+ Cyg_ErrNo result;
+
+ DEBUG2("mmc_spi_disk_lookup(): target name=%s\n", name );
+ DEBUG2(" : device name=%s dep_name=%s\n", tab[0]->name, tab[0]->dep_name );
+ DEBUG2(" : sub name=%s dep_name=%s\n", sub_tab->name, sub_tab->dep_name );
+
+ if (disk->mmc_connected) {
+ // There was a card plugged in last time we looked. Is it still there?
+ if (mmc_spi_disk_changed(disk)) {
+ // The old card is gone. Either there is no card plugged in, or
+ // it has been replaced with a different one. If the latter the
+ // existing mounts must be removed before anything sensible
+ // can be done.
+ disk->mmc_connected = false;
+ (*chan->callbacks->disk_disconnected)(chan);
+ if (0 != chan->info->mounts) {
+ return -ENODEV;
+ }
+ }
+ }
+
+ if ((0 != chan->info->mounts) && !disk->mmc_connected) {
+ // There are still mount points to an old card. We cannot accept
+ // new mount requests until those have been cleaned out.
+ return -ENODEV;
+ }
+
+ if (!disk->mmc_connected) {
+ cyg_disk_identify_t ident;
+ cyg_uint32 id_data;
+ char* where;
+ int i;
+
+ // The world is consistent and the higher-level code does not
+ // know anything about the current card, if any. Is there a
+ // card?
+ result = mmc_spi_check_for_disk(disk);
+ if (ENOERR != result) {
+ return result;
+ }
+ // A card has been found. Tell the higher-level code about it.
+ // This requires an identify structure, although it is not
+ // entirely clear what purpose that serves.
+ disk->mmc_connected = true;
+ // Serial number, up to 20 characters; The CID register contains
+ // various fields which can be used for this.
+ where = &(ident.serial[0]);
+ id_data = disk->mmc_id.cid_data[0]; // 1-byte manufacturer id -> 3 chars, 17 left
+ where = mmc_spi_disk_lookup_itoa(id_data, where);
+ id_data = (disk->mmc_id.cid_data[1] << 8) + disk->mmc_id.cid_data[2]; // 2-byte OEM ID, 5 chars, 12 left
+ where = mmc_spi_disk_lookup_itoa(id_data, where);
+ id_data = (disk->mmc_id.cid_data[10] << 24) + (disk->mmc_id.cid_data[11] << 16) +
+ (disk->mmc_id.cid_data[12] << 8) + disk->mmc_id.cid_data[13];
+ where = mmc_spi_disk_lookup_itoa(id_data, where); // 4-byte OEM ID, 10 chars, 2 left
+ // And terminate the string with a couple of places to spare.
+ *where = '\0';
+
+ // Firmware revision number. There is a one-byte product
+ // revision number in the CID, BCD-encoded
+ id_data = disk->mmc_id.cid_data[9] >> 4;
+ if (id_data <= 9) {
+ ident.firmware_rev[0] = id_data + '0';
+ } else {
+ ident.firmware_rev[0] = id_data - 10 + 'A';
+ }
+ id_data = disk->mmc_id.cid_data[9] & 0x0F;
+ if (id_data <= 9) {
+ ident.firmware_rev[1] = id_data + '0';
+ } else {
+ ident.firmware_rev[1] = id_data - 10 + 'A';
+ }
+ ident.firmware_rev[2] = '\0';
+
+ // Model number. There is a six-byte product name in the CID.
+ for (i = 0; i < 6; i++) {
+ if ((disk->mmc_id.cid_data[i + 3] >= 0x20) && (disk->mmc_id.cid_data[i+3] <= 0x7E)) {
+ ident.model_num[i] = disk->mmc_id.cid_data[i + 3];
+ } else {
+ break;
+ }
+ }
+ ident.model_num[i] = '\0';
+
+ // We don't have no cylinders, heads, or sectors, but
+ // higher-level code may interpret partition data using C/H/S
+ // addressing rather than LBA. Hence values for some of these
+ // settings were calculated above.
+ ident.cylinders_num = 1;
+ ident.heads_num = disk->mmc_heads_per_cylinder;
+ ident.sectors_num = disk->mmc_sectors_per_head;
+ ident.lba_sectors_num = disk->mmc_block_count;
+ ident.phys_block_size = disk->mmc_write_block_length/512;
+ ident.max_transfer = disk->mmc_write_block_length;
+
+ DEBUG1("Calling disk_connected(): serial %s, firmware %s, model %s, heads %d, sectors %d, lba_sectors_num %d, phys_block_size %d\n", \
+ ident.serial, ident.firmware_rev, ident.model_num, ident.heads_num, ident.sectors_num,
+ ident.lba_sectors_num, ident.phys_block_size);
+ (*chan->callbacks->disk_connected)(*tab, &ident);
+
+ // We now have a valid card and higher-level code knows about it. Fall through.
+ }
+
+ // And leave it to higher-level code to finish the lookup, taking
+ // into accounts partitions etc.
+ return (*chan->callbacks->disk_lookup)(tab, sub_tab, name);
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_read(disk_channel* chan, void* buf_arg, cyg_uint32 blocks, cyg_uint32 first_block)
+{
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+ cyg_uint32 i;
+ cyg_uint8* buf = (cyg_uint8*) buf_arg;
+ Cyg_ErrNo code = ENOERR;
+
+ DEBUG1("mmc_spi_disk_read(): first block %d, buf %p, len %lu blocks (%lu bytes)\n",
+ first_block, buf, (unsigned long)blocks, (unsigned long)blocks*512);
+
+ if (! disk->mmc_connected) {
+ return -ENODEV;
+ }
+ if ((first_block + blocks) >= disk->mmc_block_count) {
+ return -EINVAL;
+ }
+
+ for (i = 0; (i < blocks) && (ENOERR == code); i++) {
+ code = mmc_spi_read_disk_block(disk, buf, first_block + i, false);
+ buf += MMC_SPI_BLOCK_SIZE;
+ }
+ return code;
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_write(disk_channel* chan, const void* buf_arg, cyg_uint32 blocks, cyg_uint32 first_block)
+{
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+ cyg_uint32 i;
+ const cyg_uint8* buf = (cyg_uint8*) buf_arg;
+ Cyg_ErrNo code = ENOERR;
+
+ DEBUG1("mmc_spi_disk_write(): first block %d, buf %p, len %lu blocks (%lu bytes)\n",
+ first_block, buf, (unsigned long)blocks, (unsigned long)blocks*512);
+
+ if (! disk->mmc_connected) {
+ return -ENODEV;
+ }
+ if (disk->mmc_read_only) {
+ return -EROFS;
+ }
+ if ((first_block + blocks) >= disk->mmc_block_count) {
+ return -EINVAL;
+ }
+
+ for (i = 0; (i < blocks) && (ENOERR == code); i++) {
+ code = mmc_spi_write_disk_block(disk, buf, first_block + i);
+ buf += MMC_SPI_BLOCK_SIZE;
+ }
+ return code;
+}
+
+// get_config() and set_config(). There are no supported get_config() operations
+// at this time.
+static Cyg_ErrNo
+mmc_spi_disk_get_config(disk_channel* chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ CYG_UNUSED_PARAM(disk_channel*, chan);
+ CYG_UNUSED_PARAM(cyg_uint32, key);
+ CYG_UNUSED_PARAM(const void*, buf);
+ CYG_UNUSED_PARAM(cyg_uint32*, len);
+
+ return -EINVAL;
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_set_config(disk_channel* chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo result = ENOERR;
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+
+ switch(key) {
+ case CYG_IO_SET_CONFIG_DISK_MOUNT:
+ // There will have been a successful lookup(), so there's
+ // little point in checking the disk again.
+ break;
+
+ case CYG_IO_SET_CONFIG_DISK_UMOUNT:
+ if (0 == chan->info->mounts) {
+ // If this is the last unmount of the card, mark it as
+ // disconnected. If the user then removes the card and
+ // plugs in a new one everything works cleanly. Also
+ // reset the SPI device's clockrate.
+ disk->mmc_connected = false;
+ mmc_spi_restore_baud(disk);
+ result = (chan->callbacks->disk_disconnected)(chan);
+ }
+ break;
+ }
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// And finally the data structures that define this disk. Some of this
+// should be moved into an exported header file so that applications can
+// define additional disks.
+//
+// It is not obvious why there are quite so many structures. Apart
+// from the devtab entries there are no tables involved, so there is
+// no need to keep everything the same size. The cyg_disk_info_t could
+// be the common part of a h/w info_t. The channel structure is
+// redundant and its fields could be merged into the cyg_disk_info_t
+// structure. That would leave a devtab entry, a disk info structure
+// (h/w specific but with a common base), and a disk controller
+// structure (ditto).
+
+DISK_FUNS(cyg_mmc_spi_disk_funs,
+ mmc_spi_disk_read,
+ mmc_spi_disk_write,
+ mmc_spi_disk_get_config,
+ mmc_spi_disk_set_config
+ );
+
+static cyg_mmc_spi_disk_info_t cyg_mmc_spi_disk0_hwinfo = {
+ .mmc_spi_dev = &cyg_spi_mmc_dev0,
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ .mmc_writing = 0,
+#endif
+ .mmc_connected = 0
+};
+
+// No h/w controller structure is needed, but the address of the
+// second argument is taken anyway.
+DISK_CONTROLLER(cyg_mmc_spi_disk_controller_0, cyg_mmc_spi_disk0_hwinfo);
+
+DISK_CHANNEL(cyg_mmc_spi_disk0_channel,
+ cyg_mmc_spi_disk_funs,
+ cyg_mmc_spi_disk0_hwinfo,
+ cyg_mmc_spi_disk_controller_0,
+ true, /* MBR support */
+ 1 /* Number of partitions supported */
+ );
+
+BLOCK_DEVTAB_ENTRY(cyg_mmc_spi_disk0_devtab_entry,
+ CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME,
+ 0,
+ &cyg_io_disk_devio,
+ &mmc_spi_disk_init,
+ &mmc_spi_disk_lookup,
+ &cyg_mmc_spi_disk0_channel);
+
+// EOF mmc_spi.c
--- /dev/null
+2007-04-08 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/at91_eth.cdl: Fixed typo. (Removed AT91RM9200 from
+ CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL)
+
+2007-03-23 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * src/if_at91.c: Added support for the ETH_DRV_SET_MAC_ADDRESS
+ control key. Added functionality to clear the transmit buffer
+ ownershiop bits when the TXCOMP status is detected.
+
+2007-01-17 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * src/if_at91.c * include/at91_eth.cdl: Working implementation
+ of a device driver for the AT91 EMAC device.
+
+2006-06-02 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_at91.c * include/at91_eth.cdl: Partially implementation
+ of a device driver for the AT91 EMAC device.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright 2006 Andrew Lunn
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+#==========================================================================
+#
+# at91_eth.cdl
+#
+# Ethernet drivers for Atmel AT91 Cores
+#
+#==========================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2002 Jonathan Larmour
+## Copyright (C) 2006 Andrew Lunn
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Andrew Lunn
+# Contributors:
+# Date: 2006-05-10
+# Purpose:
+# Description:
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================*/
+
+cdl_package CYGPKG_DEVS_ETH_ARM_AT91 {
+ display "Atmel AT91 ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ include_dir net
+ description "
+ Ethernet driver for Atmel AT91 core. This has been tested with the
+ AT91SAM7X, but should be easy to get to work on other AT91 cores that
+ have the EMAC core."
+
+ compile -library=libextras.a if_at91.c
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1 2}
+ default_value 1
+ description "
+ This option specifies the level of debug data output by
+ the AT91 ethernet device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output; and 2 signifies maximum debug data output (not
+ suitable when GDB and application are sharing an ethernet
+ port)."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS {
+ display "Number of RX buffers"
+ flavor data
+ default_value 32
+ description "
+ Number of receive buffers. Each buffer is 128 bytes in size"
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS {
+ display "Number of TX buffers"
+ flavor data
+ default_value 10
+ description "
+ Number of transmit buffer descriptors. We need one descriptor
+ for each element in the scatter/gather list."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_PHYADDR {
+ display "PHY MII address"
+ flavor data
+ legal_values 0 to 31
+ default_value 1
+ description "This option specifies the MII address of the PHY"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ active_if (CYGPKG_REDBOOT || CYGSEM_HAL_USE_ROM_MONITOR)
+
+ description "
+ Enabling this option will allow the ethernet station
+ address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually
+ by the 'Set the ethernet station address' option for each
+ interface."
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA_VARS {
+ display "Export RedBoot command to set ESA in FLASH config"
+ flavor none
+ no_define
+ description "
+ This component contains options which, when enabled, allow
+ RedBoot to support the setting of the ESA in the FLASH
+ configuration. This can then subsequently be accessed by
+ applications using virtual vector calls if those applications
+ are also built with
+ CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA enabled."
+
+ cdl_option CYGSEM_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+ }
+ }
+ }
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_MACADDR {
+ display "Ethernet station (MAC) address for eth0"
+ flavor data
+ default_value {"0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC"}
+ description "The default ethernet station address. This is the
+ MAC address used when no value is found in the
+ RedBoot FLASH configuration field."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Atmel AT91 ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+}
+
+# EOF at91_eth.cdl
--- /dev/null
+//==========================================================================
+//
+// if_at91.c
+//
+//
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew Lunn, John Eigelaar
+// Contributors:
+// Date: 2006-05-10
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_eth_arm_at91.h>
+#include <pkgconf/io_eth_drivers.h>
+#if defined(CYGPKG_REDBOOT)
+ #include <pkgconf/redboot.h>
+#endif
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/io/eth_phy.h>
+#include <errno.h>
+#include <string.h>
+
+// Set up the level of debug output
+#if CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL > 0
+ #define debug1_printf(args...) diag_printf(args)
+#else
+ #define debug1_printf(args...)
+#endif
+#if CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL > 1
+ #define debug2_printf(args...) diag_printf(args)
+#else
+ #define debug2_printf(args...)
+#endif
+
+//Driver interface callbacks
+#define _eth_drv_init(sc,mac) \
+ (sc->funs->eth_drv->init)(sc,(unsigned char *)mac)
+#define _eth_drv_tx_done(sc,key,status) \
+ (sc->funs->eth_drv->tx_done)(sc,key,status)
+#define _eth_drv_recv(sc,len) \
+ (sc->funs->eth_drv->recv)(sc,len)
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+at91_eth_isr (cyg_vector_t vector, cyg_addrword_t data);
+#endif
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)
+ #include <redboot.h>
+ #include <flash_config.h>
+
+ #ifdef CYGSEM_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa_data,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0);
+ #endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA
+
+ #include <cyg/hal/hal_if.h>
+
+ #ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+ #endif
+
+ #define CYGHWR_DEVS_ETH_ARM_AT91_GET_ESA( mac_address, ok ) \
+ CYG_MACRO_START \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa_data", \
+ mac_address, \
+ CONFIG_ESA); \
+ CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_AT91_ETH_REDBOOT_HOLDS_ESA
+
+//============================================================================
+
+// Private Data structures
+
+#ifndef AT91_EMAC_RX_BUFF_SIZE
+#define AT91_EMAC_RX_BUFF_SIZE 128
+#endif
+
+// Receive Buffer Descriptor
+typedef struct rbd_s
+{
+ cyg_uint32 addr;
+ cyg_uint32 sr;
+} rbd_t;
+
+// Receive Buffer
+typedef struct rb_s
+{
+ cyg_uint8 rb[AT91_EMAC_RX_BUFF_SIZE];
+} rb_t;
+
+// Transmit Buffer Descriptor
+typedef struct tbd_s
+{
+ cyg_uint32 addr;
+ cyg_uint32 sr;
+} tbd_t;
+
+// AT91 Ethernet private data
+typedef struct at91_eth_priv_s
+{
+ cyg_uint32 intr_vector;
+ char *esa_key; // RedBoot 'key' for device ESA
+ cyg_uint8 *enaddr;
+ cyg_uint32 base; // Base address of device
+ eth_phy_access_t *phy;
+ rbd_t rbd[CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS];
+ rb_t rb[CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS];
+ tbd_t tbd[CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS];
+ unsigned long curr_tx_key;
+ cyg_bool tx_busy;
+ cyg_uint32 last_tbd_idx;
+ cyg_uint32 curr_tbd_idx;
+ cyg_uint32 curr_rbd_idx;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt intr;
+ cyg_handle_t intr_handle;
+#endif
+} at91_eth_priv_t;
+
+//============================================================================
+// PHY access bits and pieces
+//
+
+static void
+at91_mdio_enable(void)
+{
+ cyg_uint32 val;
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+ val |= AT91_EMAC_NCR_MPE; /* enable management port */
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+}
+
+static void
+at91_mdio_disable(void)
+{
+ cyg_uint32 val;
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+ val &= ~AT91_EMAC_NCR_MPE; /* disable management port */
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+}
+
+// Write one of the PHY registers via the MII bus
+static void
+at91_write_phy(int reg_addr, int phy_addr, unsigned short data)
+{
+ cyg_uint32 val, cnt=0;
+
+ CYG_ASSERTC(reg_addr >= 0 && reg_addr <= AT91_EMAC_MAN_REGA_MASK);
+ CYG_ASSERTC(phy_addr >= 0 && phy_addr <= AT91_EMAC_MAN_PHY_MASK);
+
+ val = (AT91_EMAC_MAN_SOF |
+ AT91_EMAC_MAN_WR |
+ AT91_EMAC_MAN_CODE |
+ AT91_EMAC_MAN_PHYA(phy_addr) |
+ AT91_EMAC_MAN_REGA(reg_addr) |
+ AT91_EMAC_MAN_DATA(data));
+
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_MAN, val);
+
+ /* Wait until IDLE bit in Network Status register is cleared */
+ while (cnt < 1000000)
+ {
+ HAL_READ_UINT32((AT91_EMAC + AT91_EMAC_NSR), val);
+ if (!(val & AT91_EMAC_NSR_IDLE))
+ break;
+ }
+ CYG_ASSERTC(cnt < 1000000);
+}
+
+
+// Read one of the PHY registers via the MII bus
+static bool
+at91_read_phy(int reg_addr, int phy_addr, unsigned short *data)
+{
+ cyg_uint32 val;
+
+ CYG_ASSERTC(reg_addr >= 0 && reg_addr <= AT91_EMAC_MAN_REGA_MASK);
+ CYG_ASSERTC(phy_addr >= 0 && phy_addr <= AT91_EMAC_MAN_PHY_MASK);
+
+ val = (AT91_EMAC_MAN_SOF |
+ AT91_EMAC_MAN_RD |
+ AT91_EMAC_MAN_CODE |
+ AT91_EMAC_MAN_PHYA(phy_addr) |
+ AT91_EMAC_MAN_REGA(reg_addr));
+
+
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_MAN, val);
+ /* Wait until IDLE bit in Network Status register is cleared */
+ do
+ {
+ HAL_READ_UINT32((AT91_EMAC + AT91_EMAC_NSR), val);
+ }while(val & AT91_EMAC_NSR_IDLE);
+
+ HAL_DELAY_US(50);
+
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_MAN, val);
+ *data = val & AT91_EMAC_MAN_DATA_MASK;
+
+ return (true);
+}
+
+// Enable the MDIO bit in MAC control register so that we can talk to
+// the PHY. Also set the clock divider so that MDC is less than 2.5MHz.
+static void
+at91_init_phy(void)
+{
+ cyg_uint32 cfg;
+ cyg_uint32 div;
+
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_NCFG, cfg);
+ cfg &=~ AT91_EMAC_NCFG_CLK_MASK;
+
+ div = (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / 2500000);
+ if (div < 8)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_8;
+ }
+ else if (div < 16)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_16;
+ }
+ else if (div < 32)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_32;
+ }
+ else if (div < 64)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_64;
+ }
+ else
+ {
+ CYG_FAIL("Unable to program MII clock");
+ }
+
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_NCFG, cfg);
+}
+
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(at91_phy,
+ at91_init_phy,
+ NULL,
+ at91_write_phy,
+ at91_read_phy);
+
+//======================================================================
+// Receiver buffer handling
+
+// Initialize the receiver buffers and descriptors
+static void
+at91_rb_init(at91_eth_priv_t *priv)
+{
+ int i;
+ for (i = 0 ; i < CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS; i++)
+ {
+ priv->rbd[i].addr = ((cyg_uint32)&priv->rb[i]) & AT91_EMAC_RBD_ADDR_MASK;
+ priv->rbd[i].sr = 0;
+ }
+ // Set the wrap bit on the last entry
+ priv->rbd[CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS-1].addr |=
+ AT91_EMAC_RBD_ADDR_WRAP;
+}
+
+//======================================================================
+// Transmit buffer handling
+
+// Initialize the transmit buffer descriptors
+static void
+at91_tb_init(at91_eth_priv_t *priv)
+{
+ int i;
+ for (i = 0 ; i < CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS; i++)
+ {
+ priv->tbd[i].addr = 0;
+ priv->tbd[i].sr = AT91_EMAC_TBD_SR_USED;
+ }
+ // Set the wrap bit on the last entry
+ priv->tbd[CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1].sr |= AT91_EMAC_TBD_SR_WRAP;
+}
+
+//======================================================================
+// Enable and Disable of the receiver and transmitter.
+
+static void
+at91_disable_rx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl &= ~AT91_EMAC_NCR_RE;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_disable_tx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl &= ~AT91_EMAC_NCR_TX;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_enable_rx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_RE;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_enable_tx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_TX;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_enable(at91_eth_priv_t *priv)
+{
+ at91_enable_tx(priv);
+ at91_enable_rx(priv);
+}
+
+static void
+at91_disable(at91_eth_priv_t *priv)
+{
+ at91_disable_tx(priv);
+ at91_disable_rx(priv);
+}
+
+static void
+at91_start_transmitter(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_TSTART;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+
+//======================================================================
+// Initialization code
+
+// Configure the pins so that the EMAC has control of them. This
+// assumes the MII is used, not the RMII
+static void
+at91_cfg_pins(void)
+{
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_EREFCK);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ECRS);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ECOL);
+
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERXDV);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX0);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX1);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX2);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX3);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERXER);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERXCK);
+
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETXEN);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX0);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX1);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX2);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX3);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETXER);
+
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_EMDC);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_EMDIO);
+}
+
+// Set a specific address match to a given address. Packets received which
+// match this address will be passed on.
+static void
+at91_set_mac(at91_eth_priv_t * priv, cyg_uint8 * enaddr, int sa)
+{
+ cyg_uint32 hi, lo;
+
+ CYG_ASSERTC(sa > 0 && sa < 5);
+ sa--;
+
+ lo = ((enaddr[3] << 24) |
+ (enaddr[2] << 16) |
+ (enaddr[1] << 8) |
+ (enaddr[0]));
+
+ hi = ((enaddr[5] << 8) |
+ (enaddr[4]));
+
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_SA1L + (8*sa), lo);
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_SA1H + (8*sa), hi);
+}
+
+static void
+at91_clear_stats(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_CSR;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+// Enable and Disable of the receiver and transmitter.
+// Initialize the interface. This configures the interface ready for use.
+// Interrupts are grabbed etc. This means the start function has
+// little to do except enable the receiver
+static bool
+at91_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ bool esa_ok = false;
+ unsigned char enaddr[6] = { CYGPKG_DEVS_ETH_ARM_AT91_MACADDR};
+ unsigned char enzero[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ unsigned short phy_state = 0;
+ cyg_uint32 ncfg = 0;
+
+ debug1_printf("\nAT91_ETH: Initialising @ %x\n",priv->base);
+
+ priv->tx_busy = false;
+ priv->curr_tbd_idx = 0;
+ priv->curr_rbd_idx = 0;
+
+ // Enable the clock to the EMAC
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_EMAC);
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOB);
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOA);
+
+ //at91_disable(priv);
+ at91_cfg_pins();
+
+ /* Enable IO Clock */
+ HAL_WRITE_UINT32(priv->base+AT91_EMAC_USRIO,AT91_EMAC_USRIO_CLKEN);
+
+ /* Disable all the interrupts for the moment */
+ /* The Start function actually enables all that we need */
+ //HAL_WRITE_UINT32(priv->base + AT91_EMAC_IDR, 0x3FFF);
+
+ // If we are building an interrupt enabled version, install the
+ // interrupt handler
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ debug1_printf("AT91_ETH: Installing Interrupts on IRQ %d\n",
+ priv->intr_vector);
+ cyg_drv_interrupt_create(priv->intr_vector,
+ 4,
+ (cyg_addrword_t)sc,
+ at91_eth_isr,
+ eth_drv_dsr,
+ &priv->intr_handle,
+ &priv->intr);
+
+ cyg_drv_interrupt_attach(priv->intr_handle);
+ cyg_drv_interrupt_unmask(priv->intr_vector);
+#endif
+
+#ifdef CYGHWR_DEVS_ETH_ARM_AT91_GET_ESA
+ // Get MAC address from RedBoot configuration variables
+ CYGHWR_DEVS_ETH_ARM_AT91_GET_ESA(&enaddr[0], esa_ok);
+ // If this call fails myMacAddr is unchanged and MAC address from
+ // CDL is used
+#endif
+
+ if (!esa_ok)
+ {
+ // Can't figure out ESA
+ debug1_printf("AT91_ETH - Warning! ESA unknown\n");
+ }
+ debug1_printf("AT91_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ // Give the EMAC its address
+ at91_set_mac(priv, enaddr, 1);
+ at91_set_mac(priv, enzero, 2);
+ at91_set_mac(priv, enzero, 3);
+ at91_set_mac(priv, enzero, 4);
+
+ // Setup the receiver buffers and descriptors
+ at91_rb_init(priv);
+
+ // And tell the EMAC where the first receive buffer descriptor is
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_RBQP, (cyg_uint32)priv->rbd);
+
+ // Setup the transmit descriptors
+ at91_tb_init(priv);
+
+ // And tell the EMAC where the first transmit buffer descriptor is
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_TBQP, (cyg_uint32)priv->tbd);
+
+ // Setup the PHY
+ CYG_ASSERTC(priv->phy);
+
+ at91_mdio_enable();
+ if (!_eth_phy_init(priv->phy))
+ {
+ at91_mdio_disable();
+ return (false);
+ }
+
+ // Get the current mode and print it
+ phy_state = _eth_phy_state(priv->phy);
+ at91_mdio_disable();
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCFG,ncfg);
+
+
+ if ((phy_state & ETH_PHY_STAT_LINK) != 0)
+ {
+ if (((phy_state & ETH_PHY_STAT_100MB) != 0))
+ {
+ debug1_printf("AT91_ETH: 100Mbyte/s");
+ ncfg |= AT91_EMAC_NCFG_SPD_100Mbps;
+ }
+ else
+ {
+ debug1_printf("AT91_ETH: 10Mbyte/s");
+ ncfg &= ~(AT91_EMAC_NCFG_SPD_100Mbps);
+ }
+ if((phy_state & ETH_PHY_STAT_FDX))
+ {
+ debug1_printf(" Full Duplex\n");
+ ncfg |= AT91_EMAC_NCFG_FD;
+ }
+ else
+ {
+ debug1_printf(" Half Duplex\n");
+ ncfg &= ~(AT91_EMAC_NCFG_FD);
+ }
+ }
+ else
+ {
+ debug1_printf("AT91_ETH: No Link\n");
+ }
+
+
+ //Setup the network configuration
+ ncfg |= (AT91_EMAC_NCFG_RLCE);
+
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCFG,ncfg);
+
+ // Clear the Statistics counters;
+ at91_clear_stats(priv);
+
+
+ /* Clear the status registers */
+ HAL_READ_UINT32(priv->base + AT91_EMAC_ISR,ncfg);
+ HAL_READ_UINT32(priv->base + AT91_EMAC_RSR,ncfg);
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_RSR,ncfg);
+ HAL_READ_UINT32(priv->base + AT91_EMAC_TSR,ncfg);
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_TSR,ncfg);
+
+ // Initialize the upper layer driver
+ _eth_drv_init(sc,enaddr);
+
+ return (true);
+}
+
+// This function is called to stop the interface.
+static void
+at91_eth_stop(struct eth_drv_sc *sc)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+
+ at91_disable(priv);
+}
+
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running.
+static void
+at91_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ cyg_uint32 bits;
+
+ // Enable the interrupts we are interested in
+ // TODO: We probably need to add at least the RBNA interrupt here
+ // as well in order to do some error handling
+ bits = (AT91_EMAC_ISR_RCOM | AT91_EMAC_ISR_TCOM);
+
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_IER, bits);
+
+ // Enable the receiver and transmitter
+ at91_enable(priv);
+}
+
+// This function is called for low level "control" operations
+static int
+at91_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ {
+ if(length >= ETHER_ADDR_LEN)
+ {
+ at91_eth_stop(sc);
+
+ cyg_uint8 * enaddr = (cyg_uint8 *)data;
+ debug1_printf("AT91_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ at91_set_mac((at91_eth_priv_t *)sc->driver_private,enaddr,1);
+ at91_eth_start(sc,enaddr,0);
+ return 0;
+ }
+ return 1;
+ }
+ default:
+ {
+ diag_printf("%s.%d: key %lx\n", __FUNCTION__, __LINE__, key);
+ return (1);
+ }
+ }
+
+}
+
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send
+// any more.
+//
+// We allocate one buffer descriptor per scatter/gather entry. We assume that
+// a typical packet will not have more than 3 such entries, and so we say we
+// can send a packet when we have 3 or more buffer descriptors free
+//
+// TODO: Implement what the comment actually says!
+static int
+at91_eth_can_send(struct eth_drv_sc *sc)
+{
+ int can_send;
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ if(priv->tx_busy)
+ {
+ can_send = 0;
+ }
+ else
+ {
+ can_send = 1;
+ }
+ return (can_send);
+}
+
+// This routine is called to send data to the hardware
+static void
+at91_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ int i;
+ cyg_uint32 sr;
+
+ priv->tx_busy = true;
+
+ priv->last_tbd_idx = priv->curr_tbd_idx;
+
+ for(i = 0;i<sg_len;i++)
+ {
+ priv->tbd[priv->curr_tbd_idx].addr = sg_list[i].buf;
+
+ sr = (sg_list[i].len & AT91_EMAC_TBD_SR_LEN_MASK);
+ // Set the End Of Frame bit in the last descriptor
+ if(i == (sg_len-1))
+ {
+ sr |= AT91_EMAC_TBD_SR_EOF;
+ }
+
+ if(priv->curr_tbd_idx < (CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1))
+ {
+ priv->tbd[priv->curr_tbd_idx].sr = sr;
+ priv->curr_tbd_idx++;
+ }
+ else
+ {
+ priv->tbd[priv->curr_tbd_idx].sr = (sr | AT91_EMAC_TBD_SR_WRAP);
+ priv->curr_tbd_idx = 0;
+ }
+ }
+
+ // Store away the key for when the transmit has completed
+ // and we need to tell the stack which transmit has completed.
+ priv->curr_tx_key = key;
+
+ at91_start_transmitter(priv);
+}
+
+static void at91_reset_tbd(at91_eth_priv_t *priv)
+{
+ while(priv->curr_tbd_idx != priv->last_tbd_idx)
+ {
+ if(priv->last_tbd_idx == (CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1))
+ {
+ priv->tbd[priv->last_tbd_idx].sr =
+ (AT91_EMAC_TBD_SR_USED|AT91_EMAC_TBD_SR_WRAP);
+ priv->last_tbd_idx = 0;
+ }
+ else
+ {
+ priv->tbd[priv->last_tbd_idx].sr = AT91_EMAC_TBD_SR_USED;
+ priv->last_tbd_idx++;
+ }
+ }
+}
+
+
+//======================================================================
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+at91_eth_isr (cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ cyg_uint32 ret;
+ cyg_uint32 isr;
+
+ /* Get the interrupt status */
+ HAL_READ_UINT32(priv->base+AT91_EMAC_ISR,isr);
+
+ ret = CYG_ISR_HANDLED;
+
+ //TODO: We should probably be handling some of the error interrupts as well
+ if(isr & AT91_EMAC_ISR_TCOM)
+ {
+ ret = CYG_ISR_CALL_DSR;
+ }
+
+ if(isr & AT91_EMAC_ISR_RCOM)
+ {
+ ret = CYG_ISR_CALL_DSR;
+ }
+ cyg_interrupt_acknowledge(vector);
+ return(ret);
+}
+#endif
+
+static void
+at91_eth_deliver(struct eth_drv_sc *sc)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+
+ cyg_uint32 tsr;
+ cyg_uint32 rsr;
+
+ cyg_uint32 ctr;
+ cyg_uint32 cnt;
+ cyg_uint32 idx;
+
+ /* Get the Transmit Status */
+ HAL_READ_UINT32(priv->base+AT91_EMAC_TSR,tsr);
+ HAL_WRITE_UINT32(priv->base+AT91_EMAC_TSR,tsr);
+
+ /* Get the Receive Status */
+ HAL_READ_UINT32(priv->base+AT91_EMAC_RSR,rsr);
+ HAL_WRITE_UINT32(priv->base+AT91_EMAC_RSR,rsr);
+
+
+ //TODO: The interrupts other than RCOMP and TCOMP needs to be
+ // handled properly especially stuff like RBNA which could have
+ // serious effects on driver performance
+
+ /* Service the TX buffers */
+ if (tsr&AT91_EMAC_TSR_COL) //1
+ {
+ debug1_printf("AT91_ETH: Tx COL\n");
+ }
+
+ if (tsr&AT91_EMAC_TSR_RLE) //2
+ {
+ debug1_printf("AT91_ETH: Tx RLE\n");
+ }
+
+ if (tsr&AT91_EMAC_TSR_BNQ) //4
+ {
+ debug1_printf("AT91_ETH: Tx BEX\n");
+ }
+
+ if (tsr&AT91_EMAC_TSR_UND) //6
+ {
+ debug1_printf("AT91_ETH: Tx UND\n");
+ }
+
+ /* Check that the last transmission is completed */
+ if (tsr&AT91_EMAC_TSR_COMP) //5
+ {
+ at91_reset_tbd(priv);
+ _eth_drv_tx_done(sc,priv->curr_tx_key,0);
+ priv->tx_busy = false;
+ }
+
+ /* Service the RX buffers when we get something */
+ if (rsr&AT91_EMAC_RSR_REC)
+ {
+ /* Do this all until we find the first EMAC Buffer */
+ while (priv->rbd[priv->curr_rbd_idx].addr & AT91_EMAC_RBD_ADDR_OWNER_SW)
+ {
+
+ //Firstly walk through to either the first buffer that belongs
+ // to the controller or the first SOF
+ while ((priv->rbd[priv->curr_rbd_idx].addr &
+ AT91_EMAC_RBD_ADDR_OWNER_SW) &&
+ !(priv->rbd[priv->curr_rbd_idx].sr &
+ AT91_EMAC_RBD_SR_SOF))
+ {
+ priv->rbd[priv->curr_rbd_idx].addr &=
+ ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
+ priv->curr_rbd_idx++;
+ if (priv->curr_rbd_idx >= CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS)
+ {
+ priv->curr_rbd_idx = 0;
+ }
+ }
+
+ /* Check that we did find a SOF*/
+ if ((priv->rbd[priv->curr_rbd_idx].addr &
+ AT91_EMAC_RBD_ADDR_OWNER_SW) &&
+ (priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_SOF))
+ {
+ cnt = 0;
+ for (ctr=0;ctr<CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS;ctr++)
+ {
+ idx = (ctr+priv->curr_rbd_idx)%CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS;
+ cnt += (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_LEN_MASK);
+ if (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_EOF)
+ {
+ /* The recv function will adjust the current buffer idx
+ after the buffer has been cleared
+ */
+ if (cnt)
+ _eth_drv_recv(sc,cnt);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (rsr&AT91_EMAC_RSR_BNA)
+ {
+ debug1_printf("AT91_ETH: Rx BNA\n");
+ }
+ if (rsr&AT91_EMAC_RSR_OVR)
+ {
+ debug1_printf("AT91_ETH: Rx OVR\n");
+ }
+
+}
+
+static void
+at91_eth_recv(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ int i;
+ cyg_uint32 bytes_in_buffer;
+ cyg_uint32 bytes_in_list = 0;
+ cyg_uint32 bytes_needed_list = 0;
+ cyg_uint32 buffer_pos = 0;
+ cyg_uint8 * sg_buf;
+ cyg_uint32 total_bytes = 0;
+
+ for(i = 0;i<sg_len;i++)
+ {
+ while(bytes_in_list < sg_list[i].len)
+ {
+ bytes_needed_list = sg_list[i].len - bytes_in_list;
+
+ if(priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_EOF)
+ {
+ bytes_in_buffer =
+ ((priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_LEN_MASK)
+ - total_bytes) - buffer_pos;
+ }
+ else
+ {
+ bytes_in_buffer = AT91_EMAC_RX_BUFF_SIZE - buffer_pos;
+ }
+
+ sg_buf = (cyg_uint8 *)(sg_list[i].buf);
+
+ if(bytes_needed_list < bytes_in_buffer)
+ {
+ if(sg_buf != NULL)
+ memcpy(&sg_buf[bytes_in_list],
+ &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
+ bytes_needed_list);
+ bytes_in_list += bytes_needed_list;
+ buffer_pos += bytes_needed_list;
+ total_bytes += bytes_needed_list;
+ }
+ else
+ {
+ if(sg_buf != NULL)
+ memcpy(&sg_buf[bytes_in_list],
+ &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
+ bytes_in_buffer);
+ bytes_in_list += bytes_in_buffer;
+ total_bytes += bytes_in_buffer;
+
+ /* Step our buffer on one */
+ priv->rbd[priv->curr_rbd_idx].addr &=
+ ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
+ priv->curr_rbd_idx++;
+ if(priv->curr_rbd_idx >= CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS)
+ {
+ priv->curr_rbd_idx = 0;
+ }
+ buffer_pos = 0;
+ }
+ }
+ }
+}
+
+// routine called to handle ethernet controller in polled mode
+static void
+at91_eth_poll(struct eth_drv_sc *sc)
+{
+ /* Service the buffers */
+ at91_eth_deliver(sc);
+}
+
+static int
+at91_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return(CYGNUM_HAL_INTERRUPT_EMAC);
+}
+
+at91_eth_priv_t at91_priv_data =
+{
+ .intr_vector = CYGNUM_HAL_INTERRUPT_EMAC,
+ .base = AT91_EMAC,
+ .phy = &at91_phy
+};
+
+ETH_DRV_SC(at91_sc,
+ &at91_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ at91_eth_start,
+ at91_eth_stop,
+ at91_eth_control,
+ at91_eth_can_send,
+ at91_eth_send,
+ at91_eth_recv,
+ at91_eth_deliver,
+ at91_eth_poll,
+ at91_eth_int_vector);
+
+NETDEVTAB_ENTRY(at91_netdev,
+ "at91",
+ at91_eth_init,
+ &at91_sc);
+
+// EOF if_at91.c
--- /dev/null
+2008-01-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/phycore229x_eth_drivers.cdl:
+ * include/devs_eth_phycore229x.inl:
+ release of phyCORE-LPC229x ethernet driver package
+
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 eCosCentric Ltd.
+##
+## 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.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
--- /dev/null
+# ====================================================================
+#
+# phycore229x_eth_drivers.cdl
+#
+# Ethernet drivers - platform support for phyCORE-LPC229x
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2007-11-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_PHYCORE229X {
+ display "LAN ethernet driver for phyCORE-LPC229x"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_LPC2XXX_PHYCORE229X
+
+ include_dir cyg/io
+
+ # 32-bit mode, with EEPROM
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+
+ requires CYGPKG_DEVS_ETH_SMSC_LAN91CXX
+ requires CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO == CYGHWR_HAL_ARM_PHYCORE229X_ETH_INT_PRIO
+
+ description "This option includes the ethernet device driver for the
+ phyCORE-LPC229x board."
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_phycore229x.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_arm_phycore229x.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_PHYCORE229X_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "
+ Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA. The phyCORE
+ board contains an EEPROM so setting the ESA here is not
+ required. If RedBoot supports FLASH configuration then
+ the MAC address is configurable and a static MAC address
+ is not required."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_PHYCORE229X_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "
+ A static ethernet station address. Caution: Booting two systems
+ with the same MAC on the same network, will cause severe conflicts."
+ }
+ }
+}
+
+# EOF phycore229x_eth_drivers.cdl
--- /dev/null
+#ifndef CYGONCE_DEVS_ETH_PHYCORE229X_INL
+#define CYGONCE_DEVS_ETH_PHYCORE229X_INL
+//==========================================================================
+//
+// devs_eth_phycore_229x.inl
+//
+// phyCORE-LPC229x ethernet I/O definitions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2007-11-24
+// Purpose:
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_phycore229x.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+ #include <pkgconf/redboot.h>
+ #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ #include <redboot.h>
+ #include <flash_config.h>
+ #endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+
+
+
+//--------------------------------------------------------------------------
+// Configure LAN91CXX driver
+//
+#define LAN91CXX_IS_LAN91C111 1
+#define LAN91CXX_FORCE_10MHZ 1 // due a PCB tracking problem only
+ // 10 MHz is possible
+#define LAN91CXX_32BIT_RX 1 // 32 bit access
+
+
+//--------------------------------------------------------------------------
+// RedBoot ESA Flash configuration options
+// When this option is enabled, RedBoot will keep configuration
+// data in a separate block of FLASH memory.
+//
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+
+//--------------------------------------------------------------------------
+// Application ESA Flash configuration options
+// Note that this section *is* active in an application, outside
+// RedBoot, where the above section is not included.
+//
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+#endif
+#ifndef CONFIG_BOOL
+ #define CONFIG_BOOL (1)
+#endif
+
+
+//--------------------------------------------------------------------------
+// Provide ESA function
+// Returns true if ESA is configured by flash, else false
+//
+cyg_bool phycore229x_provide_esa(struct lan91cxx_priv_data *cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+
+
+ //
+ // first we check, if the ESA should be set according to flash
+ // configuration
+ //
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa",
+ &set_esa,
+ CONFIG_BOOL);
+ //
+ // if esa should be set by flash configuration, then we store the
+ // esa from flash in driver configuration data and return true
+ //
+ if (ok && set_esa)
+ {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data",
+ cpd->enaddr,
+ CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+
+//---------------------------------------------------------------------------
+// Stores configuration data for generic smsc91xxx driver
+//
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+ base : (unsigned short *)(CYGHWR_HAL_ARM_PHYCORE229X_ETH_MEM_AREA
+ + 0x0300),
+ interrupt : ( CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT +
+ CYGNUM_HAL_INTERRUPT_EINT0) ,
+ //
+ // if user selects a hardwired ESA in configuration then
+ // we fill the ESA here
+ //
+#ifdef CYGSEM_DEVS_ETH_PHYCORE229X_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_PHYCORE229X_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &phycore229x_provide_esa,
+#else
+ provide_esa : NULL, // read MAC from associated EEPROM
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+}; // lan91cxx_priv_data
+
+
+//---------------------------------------------------------------------------
+// Driver configuration
+//
+ETH_DRV_SC(
+ lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // driver specific data
+ CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME, // device name
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+
+//---------------------------------------------------------------------------
+// Entry into net device table
+//
+NETDEVTAB_ENTRY(
+ lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc
+);
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_PHYCORE229X_INL
--- /dev/null
+//==========================================================================
+//
+// dev/DM9161A.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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): John Eigelaar
+// Contributors: Gary Thomas
+// Date: 2006-12-07
+// Purpose:
+// Description: Support for Davicom DM9161A PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#define DM9161A_BMSR 0x01
+#define DM9161A_BMSR_ANEG_COMP (1<<5)
+#define DM9161A_BMSR_LINK (1<<2)
+
+#define DM9161A_BMCR 0x00
+
+#define DM9161A_DSCSR 17
+#define DM9161A_DSCSR_100FDX (1<<15)
+#define DM9161A_DSCSR_100HDX (1<<14)
+#define DM9161A_DSCSR_10FDX (1<<13)
+#define DM9161A_DSCSR_10HDX (1<<12)
+
+static bool dm9161a_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ *state = 0;
+ // Read negotiated state
+
+ if (_eth_phy_read(f, DM9161A_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & DM9161A_BMSR_ANEG_COMP) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME;
+ tries++)
+ {
+ if (_eth_phy_read(f, DM9161A_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & DM9161A_BMSR_ANEG_COMP) != 0)
+ {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & DM9161A_BMSR_ANEG_COMP) != 0)
+ {
+ *state = 0;
+ if (!_eth_phy_read(f, DM9161A_DSCSR, f->phy_addr, &phy_state))
+ return false;
+
+ if (phy_state & 0xF000)
+ {
+ *state |= ETH_PHY_STAT_LINK;
+ }
+ if ((phy_state & DM9161A_DSCSR_100FDX) ||
+ (phy_state & DM9161A_DSCSR_100HDX))
+ {
+ *state |= ETH_PHY_STAT_100MB;
+ }
+ if ((phy_state & DM9161A_DSCSR_100FDX) ||
+ (phy_state & DM9161A_DSCSR_10FDX))
+ {
+ *state |= ETH_PHY_STAT_FDX;
+ }
+
+ return (true);
+ }
+ }
+ return (false);
+}
+
+_eth_phy_dev("Davicom DM9161A", 0x0181B8A0, dm9161a_stat)
--- /dev/null
+//==========================================================================
+//
+// dev/KS8721.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Gary Thomas
+//
+// 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): Uwe Kindler <uwe_kindler@web.de>
+// Contributors: Markus Schade <marks@peppercon.de>
+// Date: 2007-04-04
+// Purpose:
+// Description: Support for ethernet Micrel KS8721 PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+
+static bool ks8721_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ unsigned short phy_anadv_reg;
+ int tries;
+ int ms;
+
+ // Read negotiated state
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0)
+ {
+ break;
+ }
+ }
+
+ //
+ // Wait for 1 second
+ //
+ for (ms = 0; ms < 1000; ++ms)
+ {
+ CYGACC_CALL_IF_DELAY_US(1000); // 1 ms
+ }
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0)
+ {
+ _eth_phy_read(f, PHY_AN_ADV, f->phy_addr, &phy_anadv_reg);
+ eth_phy_printf("\nAuto negotiation advertisement: %x\n", phy_anadv_reg);
+ *state = 0;
+ if ((phy_state & PHY_BMSR_LINK) != 0) *state |= ETH_PHY_STAT_LINK;
+ if ((phy_anadv_reg & PHY_AN_ADV_100FDX) != 0) *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ return true;
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev("Micrel KS8721", 0x00221619, ks8721_stat)
--- /dev/null
+//==========================================================================
+//
+// ics189x.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Gary Thomas
+//
+// 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): gthomas
+// Contributors: Jay Foster
+// Date: 2006-03-17
+// Purpose:
+// Description: Support for ethernet ICS 189x PHYs
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#define Bit(n) (1<<(n))
+
+static bool ics189x_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ // Read negotiated state from the Quick Poll Detailed Status Register
+ if (_eth_phy_read(f, 17, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & Bit(4)) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, 17, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & Bit(4)) != 0)
+ {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & Bit(4)) != 0)
+ {
+ *state = 0;
+ if (phy_state & Bit(0))
+ *state |= ETH_PHY_STAT_LINK;
+ if (phy_state & Bit(14))
+ *state |= ETH_PHY_STAT_FDX;
+ if (phy_state & Bit(15))
+ *state |= ETH_PHY_STAT_100MB;
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef CYGHWR_DEVS_ETH_PHY_ICS1890
+_eth_phy_dev("ICS 1890", 0x0015F422, ics189x_stat) // 1st general release
+_eth_phy_dev("ICS 1890", 0x0015F423, ics189x_stat) // 1890 "J" release
+#endif
+#ifdef CYGHWR_DEVS_ETH_PHY_ICS1892
+_eth_phy_dev("ICS 1892", 0x0015F430, ics189x_stat)
+#endif
+#ifdef CYGHWR_DEVS_ETH_PHY_ICS1893
+_eth_phy_dev("ICS 1893", 0x0015F441, ics189x_stat)
+#endif
+
--- /dev/null
+2008-07-08 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/flash_ea2468.c:
+ * cdl/flash_ea2468.cdl: New package/file(s).
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# flash_ea2468.cdl
+#
+# FLASH memory - Hardware support on EA LPC2468 OEM board
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Andrew Lunn
+##
+## 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): Uwe Kindler
+# Contributors:
+# Date: 2008-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EA2468 {
+ display "EA LPC2468 OEM board FLASH memory support"
+ description "FLASH memory device support for Embedded Artists LPC2468 OEM board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_LPC24XX
+
+ compile -library=libextras.a flash_ea2468.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED {
+ display "Generic SST 39VFXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+}
+
+# EOF flash_ea2468.cdl
\ No newline at end of file
--- /dev/null
+//==========================================================================
+//
+// flash_ea2468.c
+//
+// Flash programming for SST Flash device on EA LPC2468 OEM board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Andrew Lunn
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2008-07-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+#include <pkgconf/devs_flash_ea2468.h>
+
+
+// The EA LPC2468 OEM board has one SST 39VF3201 part
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGPKG_DEVS_FLASH_SST_39VF3201
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_sst_39vfxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF flash_ea2468.c
--- /dev/null
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip flash memory
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# flash_arm_lpc2xxx.cdl
+#
+# Philips LPC2XXX flash memory package
+#
+# ====================================================================
+#####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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:
+# Date: 2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_LPC2XXX {
+ display "LPC2xxx internal FLASH memory support"
+ description "Support for the internal FLASH memory of LPC2xxx controllers"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_LPC2XXX
+ implements CYGHWR_IO_FLASH_DEVICE
+
+ # These chips use two erase block sizes, the access to flash is
+ # limited to the last few of the 8k blocks. I don't have a chip
+ # using only 8k block sizes, so I can't test and therefore won't
+ # implement support for these devices.
+ active_if {
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2124" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2129" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2194" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2214" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2292" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2294"
+ }
+
+ compile flash_arm_lpc2xxx.c
+ include_dir .
+
+ cdl_option CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE {
+ display "copy buffer size"
+ description "
+ Size of the buffer reserved at the end of the internal
+ SRAM area for flash writing (copy) operations. Additional
+ 32 bytes are reserved for use by the IAP routine."
+ flavor data
+ legal_values 512 1024 4096 8192
+ default_value 8192
+ }
+}
--- /dev/null
+#ifndef CYGONCE_FLASH_ARM_LPC2XXX_H
+#define CYGONCE_FLASH_ARM_LPC2XXX_H
+
+//==========================================================================
+//
+// flash_arm_lpc2xxx.h
+//
+// Flash programming for LPC2xxx
+//
+//==========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+struct iap_param {
+ cyg_uint32 code;
+ cyg_uint32 p[4];
+};
+
+#define IAP_PREPARE 50
+#define IAP_COPY 51
+#define IAP_ERASE 52
+#define IAP_CHECK 53
+#define IAP_PARTID 54
+#define IAP_VERSION 55
+#define IAP_COMPARE 56
+
+#define IAP_CMD_SUCCESS 0
+#define IAP_CMD_INVALID 1
+#define IAP_SRC_ADDRERR 2
+#define IAP_DST_ADDRERR 3
+#define IAP_SRC_ADDRMAP 4
+#define IAP_DST_ADDRMAP 5
+#define IAP_CNT_INVALID 6
+#define IAP_SEC_INVALID 7
+#define IAP_SEC_NOTBLNK 8
+#define IAP_SEC_NOTPREP 9
+#define IAP_CMP_INEQUAL 10
+#define IAP_BSY 11
+
+#define IAP_LOCATION 0x7ffffff1
+
+#endif
--- /dev/null
+//==========================================================================
+//
+// flash_arm_lpc2xxx.c
+//
+// Flash programming for LPC2xxx
+//
+//==========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_flash_arm_lpc2xxx.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm.h>
+#include <cyg/hal/hal_intr.h>
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+#include "flash_arm_lpc2xxx.h"
+
+/* gcc builtins */
+extern void* memcpy(void *, const void *, size_t);
+extern void* memset(void *, int, size_t);
+
+/* wrapper for simpler IAP access */
+static void
+iap(struct iap_param *param, struct iap_param *result)
+{
+ static void (* const iap)(struct iap_param *, struct iap_param *)
+ = (void (*)(struct iap_param *, struct iap_param *)) IAP_LOCATION;
+ cyg_uint32 cpsr;
+
+ HAL_DISABLE_INTERRUPTS(cpsr);
+ iap(param, result);
+ HAL_RESTORE_INTERRUPTS(cpsr);
+}
+
+void
+flash_query(void *data)
+{
+ /* nothing to do here */
+}
+
+/*
+ * 248k in 31 blocks by 8k there actually less blocks since two of
+ * them are 64k, but accessing anything but the last few 8k blocks is
+ * not supported anyway
+ */
+int
+flash_hwr_init(void)
+{
+ flash_info.block_size = 8 * 1024;
+ flash_info.blocks = 31;
+ flash_info.start = (void *) 0;
+ flash_info.end = (void *) (248 * 1024);
+
+ return FLASH_ERR_OK;
+}
+
+
+static const cyg_uint8 flash_errors[12] = {
+ FLASH_ERR_OK, /* IAP_CMD_SUCCESS */
+ FLASH_ERR_PROTOCOL, /* IAP_INV_COMMAND */
+ FLASH_ERR_INVALID, /* IAP_SRC_ADDRERR */
+ FLASH_ERR_INVALID, /* IAP_DST_ADDRERR */
+ FLASH_ERR_INVALID, /* IAP_SRC_ADDRMAP */
+ FLASH_ERR_INVALID, /* IAP_DST_ADDRMAP */
+ FLASH_ERR_INVALID, /* IAP_CNT_INVALID */
+ FLASH_ERR_INVALID, /* IAP_SEC_INVALID */
+ FLASH_ERR_PROTOCOL, /* IAP_SEC_NOTBLNK */
+ FLASH_ERR_PROTOCOL, /* IAP_SEC_NOTPREP */
+ FLASH_ERR_DRV_VERIFY, /* IAP_CMP_INEQUAL */
+ FLASH_ERR_DRV_TIMEOUT, /* IAP_BSY */
+};
+
+int
+flash_hwr_map_error(e)
+{
+ if(e > 11)
+ return FLASH_ERR_PROTOCOL;
+ return flash_errors[e];
+}
+
+/* this will not work for flash addresses < 0x30000 */
+static int
+block_by_addr(cyg_uint32 addr)
+{
+ int block;
+
+ block = (addr >> 13) & 0x1f;
+ block -= 14;
+
+ return block;
+}
+
+int
+flash_erase_block(void *block, unsigned int size)
+{
+ struct iap_param param, result;
+
+ param.code = IAP_PREPARE;
+
+ param.p[0] = param.p[1] = block_by_addr((cyg_uint32) block);
+ if(param.p[0] < 10)
+ return FLASH_ERR_INVALID;
+
+ /* prepare sector(s) */
+ iap(¶m, &result);
+ if(result.code != IAP_CMD_SUCCESS)
+ return result.code;
+
+ param.code = IAP_ERASE;
+ param.p[2] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
+
+ /* erase sector(s) */
+ iap(¶m, &result);
+ return result.code;
+}
+
+int
+flash_program_buf(void *addr, void *data, int len)
+{
+ static const int size = CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE;
+ static const cyg_uint32 b = (0x40004000 - 32 -
+ CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
+ static void * const buf = (void *) (0x40004000 - 32 -
+ CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
+ cyg_uint32 a = (cyg_uint32) addr;
+ char *d = (char *) data;
+ struct iap_param param, result;
+
+ param.code = IAP_PREPARE;
+ param.p[0] = block_by_addr(a);
+ param.p[1] = block_by_addr(a + len - 1);
+ if(param.p[0] < 10 || param.p[1] > 16)
+ return FLASH_ERR_INVALID;
+
+ do {
+ /* prepare sector(s) */
+ iap(¶m, &result);
+ if(result.code != IAP_CMD_SUCCESS)
+ return result.code;
+
+ if(len < size)
+ memset(buf, 0xff, size);
+ memcpy(buf, d, size);
+
+ param.code = IAP_COPY;
+ param.p[0] = a;
+ param.p[1] = b;
+ param.p[2] = size;
+ param.p[3] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
+
+ /* copy ram to flash */
+ iap(¶m, &result);
+ if(result.code != IAP_CMD_SUCCESS)
+ return result.code;
+
+ len -= size;
+ a += size;
+ d += size;
+ } while(len > 0);
+
+ return(result.code);
+}
+
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
--- /dev/null
+2007-11-24 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/flash_phycore229x.c:
+ * cdl/flash_phycore229x.cdl:
+ Initial release of FLASH driver for Phytec phyCORE-LPC229x board.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+//
+// 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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# flash_phycore229x.cdl
+#
+# FLASH memory - Hardware support on Phytec phyCORE LPC229x board
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+##
+## 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): Uwe Kindler
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2007-11-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_PHYCORE229X {
+ display "phyCORE-LPC229x board FLASH memory support"
+ description "FLASH memory device support for Phytec phyCORE-LPC229x board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_LPC2XXX
+
+ compile -library=libextras.a flash_phycore229x.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29XXXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29DL800 {
+ display "AMD AM29DL800 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29DL800" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL800
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29DL800" ? 1 : 0 }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29LV800 {
+ display "AMD AM29LV800 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV800" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV800" ? 1 : 0 }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29LV160 {
+ display "AMD AM29LV160 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV160" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV160" ? 1 : 0 }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29LV320 {
+ display "AMD AM29LV320 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV320" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV320" ? 1 : 0 }
+ }
+}
+
+# EOF flash_phycore229x.cdl
--- /dev/null
+//==========================================================================
+//
+// flash_phycore229x.c
+//
+// Flash programming for AMD device on Phytec phyCORE-LPC229x board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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): Uwe Kindler
+// Contributors: jskov, nickg,jlarmour, block
+// Date: 2007-11-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+#include <pkgconf/devs_flash_phycore229x.h>
+
+//
+// There are pairs of
+//
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (CYGHWR_HAL_ARM_PHYCORE229X_FLASH_CNT >> 1)
+#define CYGNUM_FLASH_BASE (0x80000000u)
+
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF phycore_flash.c
--- /dev/null
+2008-07-01 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/skmb91302_flash.c: Changed CYGNUM_FLASH_BASE to 0x1000000
+ for real flash support
+
+2007-07-09 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/skmb91302_flash.c:
+ * cdl/flash_skmb91302.cdl: New package - platform specifics.
+
+//===========================================================================
+//####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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# flash_skmb91302.cdl
+#
+# FLASH memory - Hardware support on Fujitsu Starterkit MB91302
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2002 Gary Thomas
+##
+## 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): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2002-09-03
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_FR30_SKMB91302 {
+ display "Fujitsu Starterkit MB91302 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_FR30_MB91301_SKMB91302
+
+ implements CYGHWR_IO_FLASH_DEVICE
+
+ compile skmb91302_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL640D
+
+}
+
--- /dev/null
+//==========================================================================
+//
+// skmb91302_flash.c
+//
+// Flash programming support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// 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): gthomas
+// Contributors: gthomas
+// Date: 2000-10-20
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x1000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF skmb91302_flash.c
--- /dev/null
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip I2C unit
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# i2c_lpc2xxx.cdl
+#
+# I2C driver for LPC2xxx
+#
+# ====================================================================
+#####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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:
+# Date: 2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_I2C_ARM_LPC2XXX {
+ display "I2C driver for LPC2xxx family of ARM controllers"
+
+ parent CYGPKG_IO_I2C
+ active_if CYGPKG_IO_I2C
+ active_if CYGPKG_HAL_ARM_LPC2XXX
+
+ description "This package provides a driver for the I2C module found in
+ Philips LPC2xxx controllers."
+
+ compile i2c_lpc2xxx.c
+}
\ No newline at end of file
--- /dev/null
+//==========================================================================
+//
+// i2c_lpc2xxx.c
+//
+// I2C driver for LPC2xxx
+//
+//==========================================================================
+//####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): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_i2c_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+/*
+ * According to the Users Manual the LPC2xxx I2C module is very
+ * similar to the I2C module of the Philips 8xC552/556 controllers. I
+ * guess it is used in other Philips/NXP controllers, too. Using these
+ * macros should make it easier to split off the common parts of the
+ * driver once it's necessary.
+ */
+
+#define I2C_XFER 8
+#define I2C_INTR CYGNUM_HAL_INTERRUPT_I2C
+#define I2C_FREQ (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / \
+ CYGNUM_HAL_ARM_LPC2XXX_VPBDIV)
+#define I2C_BASE CYGARC_HAL_LPC2XXX_REG_I2_BASE
+
+#define I2C_CONSET CYGARC_HAL_LPC2XXX_REG_I2CONSET
+#define I2C_CONCLR CYGARC_HAL_LPC2XXX_REG_I2CONCLR
+#define I2C_CON I2C_CONSET
+#define I2C_STAT CYGARC_HAL_LPC2XXX_REG_I2STAT
+#define I2C_DAT CYGARC_HAL_LPC2XXX_REG_I2DAT
+#define I2C_ADR CYGARC_HAL_LPC2XXX_REG_I2ADR
+#define I2C_SCLH CYGARC_HAL_LPC2XXX_REG_I2SCLH
+#define I2C_SCLL CYGARC_HAL_LPC2XXX_REG_I2SCLL
+
+#define I2C_R8(r, x) HAL_READ_UINT8 (I2C_BASE + (r), (x))
+#define I2C_W8(r, x) HAL_WRITE_UINT8 (I2C_BASE + (r), (x))
+#define I2C_R16(r, x) HAL_READ_UINT16 (I2C_BASE + (r), (x))
+#define I2C_W16(r, x) HAL_WRITE_UINT16(I2C_BASE + (r), (x))
+
+/* Special case for setting/clearing bits in I2C_CON */
+#define SET_CON(x) I2C_W8(I2C_CONSET, (x))
+#define CLR_CON(x) I2C_W8(I2C_CONCLR, (x))
+
+#define CON_EN CYGARC_HAL_LPC2XXX_REG_I2CONSET_I2EN
+#define CON_STA CYGARC_HAL_LPC2XXX_REG_I2CONSET_STA
+#define CON_STO CYGARC_HAL_LPC2XXX_REG_I2CONSET_STO
+#define CON_SI CYGARC_HAL_LPC2XXX_REG_I2CONSET_SI
+#define CON_AA CYGARC_HAL_LPC2XXX_REG_I2CONSET_AA
+
+static cyg_uint8 i2c_addr;
+static cyg_uint32 i2c_count = 0;
+static const cyg_uint8* i2c_txbuf = NULL;
+static cyg_uint8* i2c_rxbuf = NULL;
+static cyg_bool i2c_rxnak;
+
+volatile
+static cyg_uint32 i2c_flag = 0;
+static cyg_uint32 i2c_delay;
+
+static cyg_drv_mutex_t i2c_lock;
+static cyg_drv_cond_t i2c_wait;
+static cyg_handle_t i2c_hand;
+static cyg_interrupt i2c_data;
+
+#define I2C_FLAG_FINISH 1 /* transfer finished */
+#define I2C_FLAG_ACT 2 /* bus still active, no STOP condition sent */
+#define I2C_FLAG_ERROR (1<<31) /* one of the following errors occured: */
+#define I2C_FLAG_ADDR (1<<30) /* - address was not ACKed */
+#define I2C_FLAG_DATA (1<<29) /* - data was not ACKed */
+#define I2C_FLAG_LOST (1<<28) /* - bus arbitration was lost */
+#define I2C_FLAG_BUF (1<<27) /* - no buffer for reading or writing */
+#define I2C_FLAG_UNK (1<<26) /* - unknown I2C status */
+
+/*
+ * set up I2C bus timing
+ * I2C clock period is in PCLK ticks
+ */
+static void
+i2c_lpc2xxx_delay(cyg_uint32 delay)
+{
+ cyg_uint32 period;
+
+ if(delay == i2c_delay)
+ return;
+
+ period = I2C_FREQ / (1000000000 / delay);
+ period /= 2;
+
+ I2C_W16(I2C_SCLL, period);
+ I2C_W16(I2C_SCLH, period);
+ i2c_delay = delay;
+}
+
+/*
+ * The ISR does the actual work. It is not that much work to justify
+ * putting it in the DSR, and it is also not clear whether this would
+ * even work. If an error occurs we try to leave the bus in the same
+ * state as we would if there was no error.
+ */
+static cyg_uint32
+i2c_lpc2xxx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ cyg_uint8 status;
+ I2C_R8(I2C_STAT, status);
+
+ switch(status) {
+ case 0x08: /* START sent, send Addr+R/W */
+ case 0x10: /* ReSTART sent, send Addr+R/W */
+ CLR_CON(CON_STA);
+ I2C_W8(I2C_DAT, i2c_addr);
+ break;
+
+ case 0x18: /* Addr ACKed, send data */
+ case 0x28: /* Data ACKed, send more */
+ if(i2c_count == 0) {
+ i2c_flag = I2C_FLAG_FINISH;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ if(i2c_txbuf == NULL) {
+ i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUF;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ I2C_W8(I2C_DAT, *i2c_txbuf);
+ i2c_txbuf++;
+ i2c_count--;
+ break;
+
+ case 0x50: /* Data ACKed, receive more */
+ case 0x58: /* Data not ACKed, end reception */
+ if(i2c_rxbuf == NULL) {
+ i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUF;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ I2C_R8(I2C_DAT, *i2c_rxbuf);
+ i2c_rxbuf++;
+ i2c_count--;
+ case 0x40: /* Addr ACKed, receive data */
+ if(status == 0x58 || i2c_count == 0) {
+ i2c_flag = I2C_FLAG_FINISH;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ if(i2c_count == 1 && i2c_rxnak)
+ CLR_CON(CON_AA);
+ else
+ SET_CON(CON_AA);
+ break;
+
+ case 0x20: /* Addr not ACKed */
+ case 0x48:
+ i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_ADDR;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ break;
+ case 0x30: /* Data not ACKed */
+ i2c_count++;
+ i2c_txbuf--;
+ i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_DATA;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ break;
+ case 0x38: /* Arbitration lost */
+ i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_LOST;
+ break;
+ default: /* lots of unused states... */
+ i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_UNK;
+ break;
+ }
+
+ CLR_CON(CON_SI);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+static void
+i2c_lpc2xxx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ if(i2c_flag)
+ cyg_drv_cond_signal(&i2c_wait);
+}
+
+/*
+ * Initialize driver & hardware state
+ */
+static void
+i2c_lpc2xxx_init(struct cyg_i2c_bus *bus)
+{
+ cyg_uint32 addr, tmp;
+
+ /* enable I2C pins */
+ addr = CYGARC_HAL_LPC2XXX_REG_PIN_BASE + CYGARC_HAL_LPC2XXX_REG_PINSEL0;
+ HAL_READ_UINT32(addr, tmp);
+ tmp |= 0x50;
+ HAL_WRITE_UINT32(addr, tmp);
+
+ cyg_drv_mutex_init(&i2c_lock);
+ cyg_drv_cond_init(&i2c_wait, &i2c_lock);
+ cyg_drv_interrupt_create(I2C_INTR, 0, (cyg_addrword_t) 0, &i2c_lpc2xxx_isr,
+ &i2c_lpc2xxx_dsr, &i2c_hand, &i2c_data);
+ cyg_drv_interrupt_attach(i2c_hand);
+
+ CLR_CON(CON_EN | CON_STA | CON_SI | CON_AA);
+ I2C_W8(I2C_ADR, 0);
+ SET_CON(CON_EN);
+}
+
+/*
+ * transmit a buffer to a device
+ */
+static cyg_uint32
+i2c_lpc2xxx_tx(const cyg_i2c_device *dev,
+ cyg_bool send_start,
+ const cyg_uint8 *tx_data,
+ cyg_uint32 count,
+ cyg_bool send_stop)
+{
+ i2c_lpc2xxx_delay(dev->i2c_delay);
+
+ i2c_addr = dev->i2c_address << 1;
+ i2c_count = count;
+ i2c_txbuf = tx_data;
+
+ /*
+ * for a repeated start the SI bit has to be reset
+ * if we continue a previous transfer, load the next byte
+ */
+ if(send_start && i2c_flag == I2C_FLAG_ACT) {
+ SET_CON(CON_STA);
+ CLR_CON(CON_SI);
+ } else if(send_start) {
+ SET_CON(CON_STA);
+ } else {
+ I2C_W8(I2C_DAT, *i2c_txbuf);
+ i2c_txbuf++;
+ i2c_count--;
+ CLR_CON(CON_SI);
+ }
+
+ i2c_flag = 0;
+
+ /*
+ * the isr will do most of the work, and the dsr will signal when an
+ * error occured or the transfer finished
+ */
+ cyg_drv_mutex_lock(&i2c_lock);
+ cyg_drv_dsr_lock();
+ cyg_drv_interrupt_unmask(I2C_INTR);
+ while(!(i2c_flag & (I2C_FLAG_FINISH|I2C_FLAG_ERROR)))
+ cyg_drv_cond_wait(&i2c_wait);
+ cyg_drv_interrupt_mask(I2C_INTR);
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&i2c_lock);
+
+ /* too bad we have no way to tell the caller */
+ if(i2c_flag & I2C_FLAG_ERROR)
+ diag_printf("I2C TX error flag: %x\n", i2c_flag);
+
+ if(send_stop) {
+ SET_CON(CON_STO);
+ CLR_CON(CON_SI | CON_STA);
+ } else i2c_flag = I2C_FLAG_ACT;
+
+ count -= i2c_count;
+
+ i2c_addr = 0;
+ i2c_count = 0;
+ i2c_txbuf = NULL;
+
+ return count;
+}
+
+/*
+ * receive into a buffer from a device
+ */
+static cyg_uint32
+i2c_lpc2xxx_rx(const cyg_i2c_device *dev,
+ cyg_bool send_start,
+ cyg_uint8 *rx_data,
+ cyg_uint32 count,
+ cyg_bool send_nak,
+ cyg_bool send_stop)
+{
+ i2c_lpc2xxx_delay(dev->i2c_delay);
+
+ i2c_addr = dev->i2c_address << 1 | 1;
+ i2c_count = count;
+ i2c_rxbuf = rx_data;
+ i2c_rxnak = send_nak;
+
+ /*
+ * for a repeated start the SI bit has to be reset
+ * if we continue a previous transfer, start reception
+ */
+ if(send_start && i2c_flag == I2C_FLAG_ACT) {
+ SET_CON(CON_STA);
+ CLR_CON(CON_SI);
+ } else if(send_start)
+ SET_CON(CON_STA);
+
+ i2c_flag = 0;
+
+ /*
+ * the isr will do most of the work, and the dsr will signal when an
+ * error occured or the transfer finished
+ */
+ cyg_drv_mutex_lock(&i2c_lock);
+ cyg_drv_dsr_lock();
+ cyg_drv_interrupt_unmask(I2C_INTR);
+ while(!(i2c_flag & (I2C_FLAG_FINISH|I2C_FLAG_ERROR)))
+ cyg_drv_cond_wait(&i2c_wait);
+ cyg_drv_interrupt_mask(I2C_INTR);
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&i2c_lock);
+
+ /* too bad we have no way to tell the caller */
+ if(i2c_flag & I2C_FLAG_ERROR)
+ diag_printf("I2C RX error flag: %x\n", i2c_flag);
+
+ if(send_stop) {
+ SET_CON(CON_STO);
+ CLR_CON(CON_SI | CON_STA);
+ } else i2c_flag = I2C_FLAG_ACT;
+
+ count -= i2c_count;
+
+ i2c_addr = 0;
+ i2c_count = 0;
+ i2c_rxbuf = NULL;
+
+ return count;
+
+}
+
+
+/*
+ * generate a STOP
+ */
+static void
+i2c_lpc2xxx_stop(const cyg_i2c_device *dev)
+{
+ SET_CON(CON_STO);
+}
+
+CYG_I2C_BUS(cyg_i2c_lpc2xxx_bus,
+ &i2c_lpc2xxx_init,
+ &i2c_lpc2xxx_tx,
+ &i2c_lpc2xxx_rx,
+ &i2c_lpc2xxx_stop,
+ (void *) 0);
--- /dev/null
+2006-02-28 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_i2c.sgml, include/i2c_mcf52xx.h: new files
+
+ * src/i2c_mcf52xx.c, cdl/i2c_mcf52xx.cdl: various clean-ups
+
+2005-10-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * mcf52xx I2C driver package created
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# i2c_mcf52xx.cdl
+#
+# eCos MCF52xx I2C configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2005, 2006 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors: Bart Veer
+# Date: 2005-10-23
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_I2C_MCF52xx {
+ display "I2C driver for coldfire MCF52xx family"
+
+ parent CYGPKG_IO_I2C
+ active_if CYGPKG_IO_I2C
+ active_if CYGPKG_HAL_M68K_MCF52xx
+
+ description "
+ This package provides a generic I2C device driver for the on-chip
+ I2C modules in MCF52xx ColdFire processors."
+
+ include_dir cyg/io
+ compile i2c_mcf52xx.c
+
+ cdl_option CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES {
+ display "Target hardware may have multiple MCF52xx I2C buses"
+ flavor bool
+ default_value 0
+ description "
+ The MCF52xx I2C driver can support multiple I2C bus devices, but
+ typically the coldfire processor only provides a single device. By
+ default the driver assumes only a single device is present and will
+ optimize for that case, using constant definitions provided by the
+ platform HAL rather than per-device structure fields. If the hardware
+ has multiple I2C bus devices, or if a singleton bus is instantiated
+ by some other package and hence the platform HAL cannot provide the
+ necessary definitions, then this option should be enabled."
+ }
+
+ cdl_component CYGPKG_DEVS_I2C_MCF52xx_OPTIONS {
+ display "I2C driver build options"
+ flavor none
+ active_if { CYGINT_DEVS_I2C_MCF52xx_BUS_DEVICES > 0 }
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the MCF52xx I2C
+ bus driver."
+
+ cdl_option CYGPKG_DEVS_I2C_MCF52xx_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MCF52xx I2C bus driver. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_MCF52xx_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MCF52xx I2C bus driver. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
--- /dev/null
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- mcf52xx_i2c.sgml -->
+<!-- -->
+<!-- Documentation for the mcf52xx I2C bus driver -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN#### -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2006 eCosCentric Limited -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- -->
+<!-- ####COPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2006/02/19 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-i2c-m68k-mcf52xx-part"><title>Motorola MCF52xx ColdFire I<superscript>2</superscript>C Bus Driver</title>
+
+<refentry id="devs-i2c-m68k-mcf52xx">
+ <refmeta>
+ <refentrytitle>Motorola MCF52xx Coldfire I<superscript>2</superscript>C Bus Driver</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVS_I2C_MCF52xx</varname></refname>
+ <refpurpose>eCos Support for the Motorola Coldfire I<superscript>2</superscript>C Bus</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-i2c-m68k-mcf52xx-description"><title>Description</title>
+ <para>
+Several processors in the Motorola ColdFire family come with one or
+more on-chip I<superscript>2</superscript>C bus devices. This package
+provides an eCos I<superscript>2</superscript>C bus driver. It was
+originally developed on an MCF5280 but should work with any ColdFire
+processor that uses a compatible bus device. The driver implements the
+functionality defined by the generic I<superscript>2</superscript>C
+package <varname>CYGPKG_IO_I2C</varname>.
+ </para>
+ <caution><para>
+The hardware does not support DMA or fifos, so usually a transfer will
+involve an interrupt for every byte transferred. Since the
+I<superscript>2</superscript>C bus typically runs at 100KHz large
+transfers will consume much of the available cpu time.
+ </para></caution>
+ <para>
+This package does not provide any <structname>cyg_i2c_bus</structname>
+structures. The number of I<superscript>2</superscript>C buses varies
+between ColdFire processors. If multiple buses are available then
+exactly which one(s) are in use on a given hardware platform depends
+entirely on that platform. The desired I<superscript>2</superscript>C
+bus speed also depends on the platform, and there may be other issues
+such as how the processor pins should be set up. Hence it is left to
+other code, usually the platform HAL, to instantiate the bus
+structure(s). This driver package supplies the necessary functions and
+utility macros. Similarly this package does not provide any
+<structname>cyg_i2c_device</structname> structures. Which
+I<superscript>2</superscript>C devices are hooked up to which
+I<superscript>2</superscript>C bus is entirely a characteristic of the
+hardware platform, so again it is up to the platform HAL to
+instantiate the necessary structures.
+ </para>
+ <para>
+The driver will operate in interrupt-driven mode if interrupts are
+enabled when a transfer is initiated. Otherwise it will operate in
+polled mode. This allows the driver to be used in a variety of
+configurations including inside RedBoot.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-i2c-m68k-mcf52xx-config"><title>Configuration Options</title>
+ <para>
+The I<superscript>2</superscript>C bus driver package should be loaded
+automatically when selecting a target containing a suitable ColdFire
+processor, and it should never be necessary to load the package
+explicitly. If the application does not use any of the
+I<superscript>2</superscript>C functionality, directly or indirectly,
+then all the I<superscript>2</superscript>C code should be removed at
+link-time and the application does not suffer any overheads.
+ </para>
+ <para>
+By default the driver assumes a single I<superscript>2</superscript>C
+bus and optimizes for that case. For example options like the ISR
+vector and priority are handled by compile-time
+<literal>#define</literal>'s in the platform HAL's exported header
+files rather than by per-bus structure fields. This helps to reduce
+both code and data overheads. If the driver should support multiple
+I<superscript>2</superscript>C buses then
+<varname>CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES</varname> should be
+enabled. Typically this will be done by the platform HAL using a CDL
+<property>requires</property> property. If bus instantiation happens
+outside the platform HAL and hence the HAL's header files do not
+provide the appropriate definitions, then this configuration option
+should also be defined.
+ </para>
+ <para>
+The only other configuration options in this package provide control
+over the compiler flags used to build the driver code.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-i2c-m68k-mcf52xx-bus-devices"><title>Defining the Bus and Devices</title>
+ <para>
+For most hardware targets the platform HAL will instantiate the
+<structname>cyg_i2c_bus</structname> and
+<structname>cyg_i2c_device</structname> structures, and it will also
+initialize the hardware so that the
+I<superscript>2</superscript>C-related pins are connected
+appropriately. Some development boards have no
+I<superscript>2</superscript>C devices, but the
+I<superscript>2</superscript>C bus signals are accessible via an
+expansion connector and I<superscript>2</superscript>C devices can be
+put on a daughter board. In such cases it may be necessary for the
+application to instantiate both the bus and all the device structures.
+Alternatively the platform HAL may provide a configuration option to
+enable just the bus, with the devices still left to application code.
+ </para>
+ <para>
+To facilitate bus instantiation the header file <filename
+class="headerfile">cyg/io/i2c_mcf52xx.h</filename> provides a utility
+macro <function>CYG_MCF52xx_I2C_BUS</function>. This takes six
+parameters:
+ </para>
+ <orderedlist>
+ <listitem><para>
+The name of the bus, for example
+<varname>hal_dnp5280_i2c_bus</varname>. This name will be used when
+instantiating the I<superscript>2</superscript>C devices.
+ </para></listitem>
+ <listitem><para>
+An initialization function. If no platform-specific initialization is
+needed then this can be the <function>cyg_mcf52xx_i2c_init</function>
+function exported by this driver. Otherwise it can be a
+platform-specific function which, for example, sets up the relevant
+pins appropriately and then chains into
+<function>cyg_mcf52xx_i2c_init</function>.
+ </para></listitem>
+ <listitem><para>
+The base address of the I<superscript>2</superscript>C bus. For
+example on an MCF5282 with the IPSBAR set to its usual value of
+0x40000000, the I<superscript>2</superscript>C bus is at location
+0x40000300.
+ </para></listitem>
+ <listitem><para>
+The interrupt vector, for example
+<varname>CYGNUM_HAL_ISR_I2C_IIF</varname> on an MCF5282.
+ </para></listitem>
+ <listitem><para>
+The interrupt priority. Typically this will be a configurable option
+within the platform HAL.
+ </para></listitem>
+ <listitem><para>
+A value for the I<superscript>2</superscript>C bus's I2FDR register.
+That register controls the bus speed. Typical bus speeds are 100KHz
+and 400KHz, depending on the capabilities of the attached devices.
+There is no simple relationship between the system clock speed, the
+desired bus speed, and the FDR register. Although the driver could
+determine the FDR setting using a lookup table and appropriate code,
+it is better to determine the correct value once during the porting
+process and avoid unnecessary run-time overheads.
+ </para></listitem>
+ </orderedlist>
+ <para>
+For the common case where only a single I<superscript>2</superscript>C
+bus should be supported
+(<varname>CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES</varname> is
+disabled), the last four parameters should be provided by preprocessor
+<literal>#define</literal>'s, typically in <filename
+class="headerfile">cyg/hal/plf_io.h</filename> which gets
+<literal>#include</literal>'d automatically via
+<filename>cyg/hal/hal_io.h</filename>. This header can also define the
+<varname>HAL_I2C_EXPORTED_DEVICES</varname> macro as per the generic
+I<superscript>2</superscript>C package:
+ </para>
+ <programlisting width=72>
+#include <pkgconf/hal_m68k_dnp5280.h>
+…
+#ifdef CYGHWR_HAL_M68K_DNP5280_I2C
+#define HAL_MCF52xx_I2C_SINGLETON_BASE (HAL_MCF52xx_MBAR+HAL_MCF5282_I2C0_BASE)
+#define HAL_MCF52xx_I2C_SINGLETON_ISRVEC CYGNUM_HAL_ISR_I2C_IIF
+#define HAL_MCF52xx_I2C_SINGLETON_ISRPRI CYGNUM_HAL_M68K_DNP5280_I2C_ISRPRI
+#define HAL_MCF52xx_I2C_SINGLETON_FDR CYGNUM_HAL_M68K_DNP5280_I2C_FDR
+
+#define HAL_I2C_EXPORTED_DEVICES \
+ extern cyg_i2c_bus hal_dnp5280_i2c_bus;
+#endif
+ </programlisting>
+ <para>
+On this particular platform the I<superscript>2</superscript>C bus is
+only accessible on an expansion connector so the support is
+conditional on a configuration option
+<varname>CYGHWR_HAL_M68K_DNP5280_I2C</varname>. The interrupt priority
+and I2FDR values are also controlled by configuration options. On
+other platforms the I<superscript>2</superscript>C support may not be
+conditional and the priority and/or FDR values may be hard-wired.
+ </para>
+ <para>
+The I<superscript>2</superscript>C bus instantiation should happen in
+an ordinary C or C++ file, typically in the platform HAL. The
+corresponding object file should go into
+<filename>libtarget.a</filename> and the file should only contain
+I<superscript>2</superscript>C-related code to get the maximum benefit
+of linker garbage collection.
+ </para>
+ <programlisting width=72>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_mcf52xx.h>
+
+static void
+dnp5280_i2c_init(struct cyg_i2c_bus* bus)
+{
+ cyg_uint16 paspar;
+ // Reset GPIO pins PAS0/1 to their alternative SCL/SDA settings
+ HAL_READ_UINT16(HAL_MCF5282_IPSBAR + HAL_MCF5282_GPIO_PASPAR, paspar);
+ paspar &= ~(HAL_MCF5282_GPIO_PASPAR_A0_MASK | HAL_MCF5282_GPIO_PASPAR_A1_MASK);
+ paspar |= (HAL_MCF5282_GPIO_PASPAR_A0_SCL | HAL_MCF5282_GPIO_PASPAR_A1_SDA);
+ HAL_WRITE_UINT16(HAL_MCF5282_IPSBAR + HAL_MCF5282_GPIO_PASPAR, paspar);
+
+ // And leave the driver to take care of the rest.
+ cyg_mcf52xx_i2c_init(bus);
+}
+
+CYG_MCF52xx_I2C_BUS(hal_dnp5280_i2c_bus,
+ &dnp5280_i2c_init,
+ HAL_MCF52xx_I2C_SINGLETON_BASE,
+ HAL_MCF52xx_I2C_SINGLETON_ISRVEC,
+ HAL_MCF52xx_I2C_SINGLETON_ISRPRI,
+ HAL_MCF52xx_I2C_SINGLETON_FDR);
+
+ </programlisting>
+ <para>
+Obviously if <varname>CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES</varname>
+is enabled then the singleton macros may not be defined and the
+appropriate numbers should be used directly. This example uses a
+custom initialization function which sets up the relevant pins and
+then chains into the I<superscript>2</superscript>C drivers'
+<function>cyg_mcf52xx_i2c_init</function> function. If the platform
+HAL has already set up the pins correctly then
+<function>cyg_mcf52xx_i2c_init</function> could be used directly in
+the bus instantiation, saving a small amount of code for the custom
+initialization function.
+ </para>
+ <para>
+I<superscript>2</superscript>C device structures can be instantiated
+in the usual way, for example:
+ </para>
+ <programlisting width=72>
+CYG_I2C_DEVICE(cyg_i2c_wallclock_ds1307,
+ &hal_dnp5280_i2c_bus,
+ 0x68,
+ 0x00,
+ CYG_I2C_DEFAULT_DELAY);
+ </programlisting>
+ </refsect1>
+
+</refentry>
+</part>
--- /dev/null
+//==========================================================================
+//
+// devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.h
+//
+// I2C driver for Motorola coldfire processors
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bart Veer
+// Contributors:
+// Date: 2005-11-20
+// Description: I2C driver for motorola coldfire processor
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/devs_i2c_mcf52xx.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+
+typedef enum cyg_mcf52xx_i2c_xfer_mode {
+ CYG_MCF52xx_I2C_XFER_MODE_INVALID = 0x00,
+ CYG_MCF52xx_I2C_XFER_MODE_TX = 0x01,
+ CYG_MCF52xx_I2C_XFER_MODE_RX = 0x02,
+ CYG_MCF52xx_I2C_XFER_MODE_STARTRX = 0x03
+} cyg_mcf52xx_i2c_xfer_mode;
+
+typedef struct cyg_mcf52xx_i2c_extra {
+#ifdef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
+ // Put statically initialized fields first.
+ cyg_uint8* i2c_base; // Per-bus h/w details
+ cyg_vector_t i2c_isrvec;
+ int i2c_isrpri;
+ int i2c_fdr;
+#endif
+
+ cyg_uint8 i2c_owner; // We have bus ownership
+ cyg_uint8 i2c_lost_arb; // Error condition leading to loss of bus ownership
+ cyg_uint8 i2c_send_nack; // As per rx send_nack argument
+ cyg_uint8 i2c_got_nack; // The last tx resulted in a nack
+ cyg_uint8 i2c_completed; // Set by DSR, checked by thread
+
+ union {
+ const cyg_uint8* i2c_tx_data;
+ cyg_uint8* i2c_rx_data;
+ } i2c_data; // The current buffer for rx or tx
+ cyg_uint32 i2c_count; // Number of bytes left in buffer
+ cyg_mcf52xx_i2c_xfer_mode i2c_mode; // TX, RX, ...
+
+
+ cyg_drv_mutex_t i2c_lock; // For synchronizing between DSR and foreground
+ cyg_drv_cond_t i2c_wait;
+ cyg_handle_t i2c_interrupt_handle; // For initializing the interrupt
+ cyg_interrupt i2c_interrupt_data;
+} cyg_mcf52xx_i2c_extra;
+
+externC void cyg_mcf52xx_i2c_init(struct cyg_i2c_bus*);
+externC cyg_uint32 cyg_mcf52xx_i2c_tx(const cyg_i2c_device*, cyg_bool, const cyg_uint8*, cyg_uint32, cyg_bool);
+externC cyg_uint32 cyg_mcf52xx_i2c_rx(const cyg_i2c_device*, cyg_bool, cyg_uint8*, cyg_uint32, cyg_bool, cyg_bool);
+externC void cyg_mcf52xx_i2c_stop(const cyg_i2c_device*);
+
+#ifdef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
+# define CYG_MCF52xx_I2C_BUS(_name_, _init_fn_, _base_, _isr_vec_, _isr_pri_, _fdr_) \
+ static cyg_mcf52xx_i2c_extra _name_ ## _extra = { \
+ _base_, \
+ _isr_vec_, \
+ _isr_pri_, \
+ _fdr_ \
+ } ; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ &cyg_mcf52xx_i2c_tx, \
+ &cyg_mcf52xx_i2c_rx, \
+ &cyg_mcf52xx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+
+#else
+# define CYG_MCF52xx_I2C_BUS(_name_, _init_fn_, _base_, _isr_vec_, _isr_pri_, _fdr_) \
+ static cyg_mcf52xx_i2c_extra _name_ ## _extra; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ cyg_mcf52xx_i2c_tx, \
+ cyg_mcf52xx_i2c_rx, \
+ cyg_mcf52xx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+#endif
+
--- /dev/null
+//==========================================================================
+//
+// devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c
+//
+// I2C driver for Motorola coldfire processors
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler, Bart Veer
+// Contributors:
+// Date: 2005-10-23
+// Description: I2C driver for motorola coldfire processor
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_i2c_mcf52xx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_mcf52xx.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+// Optimize for the case of a single bus device, while still allowing
+// multiple devices.
+#ifndef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
+# define I2C_BASE(_extra_) (cyg_uint8*)HAL_MCF52xx_I2C_SINGLETON_BASE
+# define I2C_ISRVEC(_extra_) HAL_MCF52xx_I2C_SINGLETON_ISRVEC
+# define I2C_ISRPRI(_extra_) HAL_MCF52xx_I2C_SINGLETON_ISRPRI
+# define I2C_FDR(_extra_) HAL_MCF52xx_I2C_SINGLETON_FDR
+#else
+# define I2C_BASE(_extra_) ((_extra_)->i2c_base)
+# define I2C_ISRVEC(_extra_) ((_extra_)->i2c_isrvec)
+# define I2C_ISRPRI(_extra_) ((_extra_)->i2c_isrpri)
+# define I2C_FDR(_extra_) ((_extra_)->i2c_fdr)
+#endif
+
+// If building for a singleton but the macros are no defined, assume
+// the I2C support is conditional on a disabled platform HAL
+// configuration option. This handles the common case of an I2C bus
+// accessed only via an expansion connector.
+#if defined(CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES) || defined(HAL_MCF52xx_I2C_SINGLETON_BASE)
+
+// ----------------------------------------------------------------------------
+// Interrupt handling and polling
+//
+// The MCF52xx I2C bus device does not have a fifo or any kind of DMA
+// capability, so can generate interrupts at a very high rate: ~10K
+// interrupts per second if the bus is running at the standard 100KHz,
+// or 50K for a high-speed 400KHz bus. To keep the cpu load down to
+// something vaguely reasonable as much work as possible has to be
+// done in the ISR, with the DSR used only for completion.
+static cyg_uint32
+mcf52xx_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)data;
+ cyg_uint8 sr, dr;
+ cyg_uint8* base = I2C_BASE(extra);
+ cyg_uint32 result = CYG_ISR_HANDLED;
+
+ // Read the current status, then clear the interrupt and
+ // arbitration-lost flags. No later code will look at the
+ // SR register again.
+ HAL_READ_UINT8( base + HAL_MCF52xx_I2C_SR_OFF, sr);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0x00);
+
+ // What to do next depends on the current transfer mode.
+ if (CYG_MCF52xx_I2C_XFER_MODE_TX == extra->i2c_mode) {
+ // We are in a transmit, or sending the address byte just
+ // before a transmit.
+ if (sr & HAL_MCF52xx_I2C_SR_IAL) {
+ // Lost the bus, abort the transfer. count has already been
+ // decremented. Assume the byte did not actually arrive.
+ extra->i2c_count += 1;
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else if (sr & HAL_MCF52xx_I2C_SR_RXAK) {
+ // This byte has been sent but the device cannot accept
+ // any more. The nack must be remembered. Otherwise if
+ // we got a nack for the last byte in a tx then the
+ // calling code will think the entire tx succeeded,
+ // and there will be problems if the next call is
+ // another tx without a repeated start.
+ extra->i2c_got_nack = 1;
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else if (0 == extra->i2c_count) {
+ // No more bytes to send.
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, *(extra->i2c_data.i2c_tx_data));
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+ }
+ } else if (CYG_MCF52xx_I2C_XFER_MODE_RX == extra->i2c_mode) {
+ if (sr & HAL_MCF52xx_I2C_SR_IAL) {
+ // Lost the bus? Maybe a spurious stop
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ if (extra->i2c_send_nack && (2 == extra->i2c_count)) {
+ // Received one, one more to go, and that one should be nacked.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_TXAK);
+ } else if (1 == extra->i2c_count) {
+ // Received the last byte. The docs say to send a stop,
+ // but there may be another transaction_rx() call. We
+ // cannot just read DR again, that would trigger another
+ // read. So instead switch to transmit mode for now,
+ // which should cause the h/w to wait until a byte is
+ // written to DR.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_MTX);
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, dr);
+ *(extra->i2c_data.i2c_rx_data) = dr;
+ extra->i2c_data.i2c_rx_data += 1;
+ extra->i2c_count -= 1;
+ }
+ } else if (CYG_MCF52xx_I2C_XFER_MODE_STARTRX == extra->i2c_mode) {
+ // Start followed by RX. The address byte has been sent, we
+ // need to switch to receiving.
+ if (sr & HAL_MCF52xx_I2C_SR_IAL) {
+ // Looks like no device acknowledged the address.
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_RX;
+ if (extra->i2c_send_nack && (1 == extra->i2c_count)) {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_TXAK);
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA);
+ }
+ // This dummy read causes the next rx to start
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, dr);
+ }
+ } else {
+ // Invalid state? Some kind of spurious interrupt? Just ignore
+ // it.
+ CYG_FAIL("I2C spurious interrupt");
+ }
+
+ // NOTE: this will acknowledge the interrupt even in polled mode.
+ // Probably harmless. Using I2C_ISRVEC rather than the vec arg
+ // means a constant number for the singleton case, which may
+ // allow the HAL to optimize the acknowledge away completely.
+ HAL_INTERRUPT_ACKNOWLEDGE(I2C_ISRVEC(extra));
+ return result;
+}
+
+static void
+mcf52xx_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)data;
+ extra->i2c_completed = 1;
+ cyg_drv_cond_signal(&(extra->i2c_wait));
+}
+
+// A transfer has been started. Wait for completion, allowing for both
+// polled and interrupt-driven mode.
+static inline void
+mcf52xx_i2c_doit(cyg_mcf52xx_i2c_extra* extra)
+{
+ cyg_uint8* base = I2C_BASE(extra);
+ int ints_state;
+ int sr;
+
+ HAL_QUERY_INTERRUPTS(ints_state);
+ if (((ints_state >> 8) & 0x07) > CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL) {
+ // Interrupts are currently disabled. We'll have to poll.
+ for ( ; ; ) {
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, sr);
+ if (sr & HAL_MCF52xx_I2C_SR_IIF) {
+ if (CYG_ISR_CALL_DSR & mcf52xx_i2c_isr(I2C_ISRVEC(extra), (cyg_addrword_t)extra)) {
+ break;
+ }
+ }
+ }
+ } else {
+ cyg_drv_mutex_lock(&(extra->i2c_lock));
+ cyg_drv_dsr_lock();
+ while (! extra->i2c_completed) {
+ cyg_drv_cond_wait(&(extra->i2c_wait));
+ }
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&(extra->i2c_lock));
+ }
+}
+
+static cyg_bool
+mcf52xx_i2c_send_start(cyg_mcf52xx_i2c_extra* extra, int address)
+{
+ cyg_uint8* base = I2C_BASE(extra);
+ cyg_uint8 sr;
+
+ // This may be a repeated start or the beginning of a transaction.
+ // If the former then we still own the bus.
+ if (!extra->i2c_owner) {
+ // The bus is currently in slave mode. See if another master
+ // currently owns the bus and if so fail immediately. It is up
+ // to higher level code to decide when to retry. Alternatively
+ // if the bus has somehow got stuck in busy mode it is again
+ // up to higher level code to sort things out.
+ HAL_READ_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_SR_OFF, sr);
+ if (sr & HAL_MCF52xx_I2C_SR_IBB) {
+ return 0;
+ }
+
+ // Now we can put the bus into master mode
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA | // This implicitly generates the start
+ HAL_MCF52xx_I2C_CR_MTX); // The address byte needs to be transmitted.
+ extra->i2c_owner = 1;
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA | // Already set so no start generated by this
+ HAL_MCF52xx_I2C_CR_MTX |
+ HAL_MCF52xx_I2C_CR_RSTA); // Repeated start
+ }
+
+ // Any previous nack is no longer relevant. If the device cannot accept
+ // more data it will nack the address.
+ extra->i2c_got_nack = 0;
+ // Now send the address. The rest of the transfer is handled by the
+ // interrupt/polling code.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, address);
+ return 1;
+}
+
+static inline void
+mcf52xx_i2c_stopit(cyg_mcf52xx_i2c_extra* extra)
+{
+ // If we still own the bus this releases it (by clearing MSTA) and
+ // generating a stop. If we have lost arbitration then this write
+ // has no effect (other than disabling interrupts). Either way the
+ // bus should end up in a consistent state.
+ HAL_WRITE_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
+ extra->i2c_lost_arb = 0;
+ extra->i2c_owner = 0;
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_INVALID;
+}
+
+// ----------------------------------------------------------------------------
+// The functions needed for all I2C devices.
+
+void
+cyg_mcf52xx_i2c_init(struct cyg_i2c_bus* bus)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)bus->i2c_extra;
+ cyg_uint8 reg;
+ cyg_uint8* base = I2C_BASE(extra);
+
+ cyg_drv_mutex_init(&extra->i2c_lock);
+ cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
+ cyg_drv_interrupt_create(I2C_ISRVEC(extra),
+ I2C_ISRPRI(extra),
+ (cyg_addrword_t) extra,
+ &mcf52xx_i2c_isr,
+ &mcf52xx_i2c_dsr,
+ &(extra->i2c_interrupt_handle),
+ &(extra->i2c_interrupt_data));
+ cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
+
+ // Before unmasking the interrupt sort out the hardware.
+ //
+ // The bus frequency is set by the platform HAL or user, since
+ // it depends on what mixture of devices are present on the bus.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_FDR_OFF, I2C_FDR(extra));
+ // The device will operate in slave mode when idle. If there is
+ // another bus master then the coldfire might accidentally accept
+ // requests intended for another device. Address 0 is installed
+ // as the slave address. This is the General Call address, used
+ // for broadcasting. It might be better to use another address
+ // like an Hs-mode one, but conflicts are still possible.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_ADR_OFF, 0x0);
+ // Enable the I2C device but do not start any transfers and
+ // leave interrupts disabled.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
+
+ // As per the documentation, if IBB is set then issue a stop. It
+ // is not really clear this is the right thing to do in
+ // multimaster setups, if another master happens to start a
+ // transfer at this exact time. Presumably it solves more problems
+ // than it might cause.
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, reg);
+ if (reg & HAL_MCF52xx_I2C_SR_IBB) {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x0000);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x00A0);
+ HAL_READ_UINT8( base + HAL_MCF52xx_I2C_DR_OFF, reg);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0x0000);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x0000);
+
+ // Don't forget to reenable the device.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
+ }
+
+ // Clear any pending conditions including interrupts.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0);
+
+ // Interrupts can now be safely unmasked
+ HAL_INTERRUPT_UNMASK(I2C_ISRVEC(extra));
+}
+
+cyg_uint32
+cyg_mcf52xx_i2c_tx(const cyg_i2c_device* dev, cyg_bool send_start, const cyg_uint8* tx_data, cyg_uint32 count, cyg_bool send_stop)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
+
+ extra->i2c_count = count;
+ if (! extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_TX;
+
+ if (send_start) {
+ extra->i2c_data.i2c_tx_data = tx_data;
+ if (! mcf52xx_i2c_send_start(extra, (dev->i2c_address << 1) | 0x00)) {
+ diag_printf("send_start failed\n");
+ return 0;
+ }
+ mcf52xx_i2c_doit(extra);
+ } else if ( !extra->i2c_got_nack) {
+ // We are in the middle of a transaction and not
+ // generating a repeated start, so the device must already
+ // be set up for writes.
+ extra->i2c_data.i2c_tx_data = &(tx_data[1]);
+ extra->i2c_count = count - 1;
+ HAL_WRITE_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_DR_OFF, *tx_data);
+ mcf52xx_i2c_doit(extra);
+ }
+ }
+ if (send_stop) {
+ mcf52xx_i2c_stopit(extra);
+ }
+
+ // tx() should return the number of bytes actually transmitted.
+ // ISR() increments extra->count after a failure, which leads to
+ // an edge condition when send_start and there is no acknowledgment
+ // of the address byte.
+ if (extra->i2c_count > count) {
+ return 0;
+ }
+ return count - extra->i2c_count;
+}
+
+cyg_uint32
+cyg_mcf52xx_i2c_rx(const cyg_i2c_device* dev, cyg_bool send_start, cyg_uint8* rx_data, cyg_uint32 count, cyg_bool send_nack, cyg_bool send_stop)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ cyg_uint8* base = I2C_BASE(extra);
+ cyg_uint8 discard;
+
+ extra->i2c_count = count;
+ extra->i2c_send_nack = send_nack;
+
+ if (! extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_data.i2c_rx_data = rx_data;
+ if (send_start) {
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_STARTRX;
+ if (! mcf52xx_i2c_send_start(extra, (dev->i2c_address << 1) | 0x01) ) {
+ return 0;
+ }
+ } else {
+ // In the middle of a transaction. The previous transfer
+ // will have left the device in tx mode.
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_RX;
+ if (send_nack && (1 == count)) {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_TXAK);
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA);
+ }
+ // So reading the data register here should get the device
+ // reading the next byte.
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, discard);
+ }
+ mcf52xx_i2c_doit(extra);
+ }
+ if (send_stop) {
+ mcf52xx_i2c_stopit(extra);
+ }
+ return count - extra->i2c_count;
+}
+
+void
+cyg_mcf52xx_i2c_stop(const cyg_i2c_device* dev)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ mcf52xx_i2c_stopit(extra);
+}
+
+#endif // defined(CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES) || defined(HAL_MCF52xx_I2C_SINGLETON_BASE)
+//---------------------------------------------------------------------------
+// EOF i2c_mcf52xx.c
--- /dev/null
+2008-07-07 Uwe Kindler <uwe_kindler@web.de>
+
+ * include/arm_lpc24xx_ser.inl:
+ Serial driver for ARM LPC24XX, using generic 16X5X driver.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# ser_arm_lpc24xx.cdl
+#
+# eCos serial ARM/LPC24XX configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2004 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Original data: gthomas, jskov
+# Contributors:
+# Date: 2008-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_ARM_LPC24XX {
+ display "ARM LPC24xx serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_LPC24XX
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ ARM LPC24xx."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_lpc24xx_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_lpc24xx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ # Support up to 4 on-chip UART modules. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::channel 0 } { $::channel < 4 } { incr ::channel } {
+
+ cdl_interface CYGINT_IO_SERIAL_LPC24XX_UART[set ::channel] {
+ display "Platform provides UART [set ::channel]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific LPC24xx
+ processor being used has on-chip UART [set ::channel], and if
+ that UART is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel] {
+ display "ARM LPC24cxx UART [set ::channel] driver"
+ flavor bool
+ active_if CYGINT_IO_SERIAL_LPC24XX_UART[set ::channel]
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the ARM
+ LPC24xx UART [set ::channel]."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_NAME {
+ display "Device name for UART [set ::channel]"
+ flavor data
+ default_value [format {"\"/dev/ser%d\""} $::channel]
+ description "
+ This option specifies the name of the serial device
+ for the ARM LPC24xx UART [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_BAUD {
+ display "Baud rate for UART [set ::channel]"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800
+ 2400 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the ARM LPC24xx UART [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_BUFSIZE {
+ display "Buffer size for the UART [set ::channel]"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the ARM LPC24xx UART [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_INTPRIO {
+ display "Interrupt priority of UART [set ::channel]"
+ flavor data
+ legal_values 0 to 15
+ default_value 15
+ description "
+ This option selects the interupt priority for the
+ UART [set ::channel] interrupts. There are 16
+ priority levels corresponding to the values 0
+ through 15 decimal, of which 15 is the lowest
+ priority. The reset value of these registers
+ defaults all interrupt to the lowest priority,
+ allowing a single write to elevate the priority of
+ an individual interrupt."
+ }
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC24XX_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armlpc24xx\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_lpc24xx.cdl
--- /dev/null
+//==========================================================================
+//
+// io/serial/arm/arm_lpc24xx_ser.inl
+//
+// ARM LPC24XX Serial I/O definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: gthomas, jlarmour
+// Date: 2008-06-07
+// Purpose: LPC24XX Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/lpc24xx_misc.h>
+
+
+//==========================================================================
+// STATIC DATA
+//==========================================================================
+// Baud rate specification
+static const unsigned int select_baud[] =
+{
+ 9999, // Unused
+ 50,
+ 75,
+ 110,
+ 134.5,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 3600,
+ 4800,
+ 7200,
+ 9600,
+ 14400,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+};
+
+
+//==========================================================================
+// Return baudrate devisor for certain baudrate
+//==========================================================================
+unsigned short lpc24xx_baud_generator(pc_serial_info *ser_chan,
+ cyg_serial_baud_rate_t baud)
+{
+ cyg_uint8 pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART0;
+ switch (ser_chan->base)
+ {
+ case CYGARC_HAL_LPC24XX_REG_UART0_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART0;
+ break;
+
+ case CYGARC_HAL_LPC24XX_REG_UART1_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART1;
+ break;
+
+ case CYGARC_HAL_LPC24XX_REG_UART2_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART2;
+ break;
+
+ case CYGARC_HAL_LPC24XX_REG_UART3_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART3;
+ break;
+
+ default:
+ CYG_FAIL("Invalid UART base address");
+ } // (ser_chan->base)
+
+ return CYG_HAL_ARM_LPC24XX_BAUD_GENERATOR(pclk_id, select_baud[baud]);
+}
+
+
+#define CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR(_ser_chan_, _baud_) \
+ lpc24xx_baud_generator((_ser_chan_), (_baud_))
+
+
+
+//==========================================================================
+// SERIAL CHANNEL 0
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL0
+static pc_serial_info lpc24xx_serial_info0 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART0_BASE,
+ CYGNUM_HAL_INTERRUPT_UART0,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel0,
+ pc_serial_funs,
+ lpc24xx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf0[0],
+ sizeof(lpc24xx_serial_out_buf0),
+ &lpc24xx_serial_in_buf0[0],
+ sizeof(lpc24xx_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel0,
+ pc_serial_funs,
+ lpc24xx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL0_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL0
+
+
+//==========================================================================
+// SERIAL CHANNEL 1
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL1
+static pc_serial_info lpc24xx_serial_info1 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART1_BASE,
+ CYGNUM_HAL_INTERRUPT_UART1,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel1,
+ pc_serial_funs,
+ lpc24xx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf1[0],
+ sizeof(lpc24xx_serial_out_buf1),
+ &lpc24xx_serial_in_buf1[0],
+ sizeof(lpc24xx_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel1,
+ pc_serial_funs,
+ lpc24xx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL1_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL1
+
+
+//==========================================================================
+// SERIAL CHANNEL 2
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL2
+static pc_serial_info lpc24xx_serial_info2 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART2_BASE,
+ CYGNUM_HAL_INTERRUPT_UART2,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel2,
+ pc_serial_funs,
+ lpc24xx_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf2[0],
+ sizeof(lpc24xx_serial_out_buf2),
+ &lpc24xx_serial_in_buf2[0],
+ sizeof(lpc24xx_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel2,
+ pc_serial_funs,
+ lpc24xx_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io2,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL2_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL2
+
+
+//==========================================================================
+// SERIAL CHANNEL 3
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL3
+static pc_serial_info lpc24xx_serial_info3 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART3_BASE,
+ CYGNUM_HAL_INTERRUPT_UART3,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf3[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf3[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel3,
+ pc_serial_funs,
+ lpc24xx_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf3[0],
+ sizeof(lpc24xx_serial_out_buf3),
+ &lpc24xx_serial_in_buf3[0],
+ sizeof(lpc24xx_serial_in_buf3)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel3,
+ pc_serial_funs,
+ lpc24xx_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io3,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL3_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel3
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL3
+
+
+//----------------------------------------------------------------------------
+// EOF arm_lpc2xxx_ser.inl
--- /dev/null
+2006-11-21 Alexander Neundorf <alexander.neundorf@jenoptik.com>
+
+ * generic PXA 2X0 serial IO support, based on the IQ80321 driver
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_iq80321.cdl: Remove irrelevant doc link.
+
+2002-01-25 Nick Garnett <nickg@redhat.com>
+
+ * include/arm_iq80321_ser.inl:
+ * cdl/ser_arm_iq80321.cdl:
+ IQ80321 files created, by copying the IQ80310 versions and editing.
+
+//===========================================================================
+//####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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# ser_arm_xscale_pxa2x0.cdl
+#
+# eCos serial PXA 2X0 configuration data
+#
+# ====================================================================
+#####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): msalter
+# Original data: msalter
+# Contributors: Alexander Neundorf
+# Date: 21st November 2006 (last modification)
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0 {
+ display "PXA2X0 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_XSCALE_PXA2X0
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for pxa."
+ doc redirect/ecos-device-drivers.html
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_xscale_pxa2x0_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_xscale_pxa2x0.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0 {
+ display "ARM XSCALE PXA2X0 serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+ implements CYGNUM_SERIAL_FLOW_RTSCTS_RX
+ implements CYGNUM_SERIAL_FLOW_RTSCTS_TX
+
+
+ description "
+ This option includes the serial device driver for the PXA 2X0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_NAME {
+ display "Device name for PXA 2X0 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the PXA 2X0 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BAUD {
+ display "Baud rate for the PXA2X0 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed)
+ for the PXA2X0 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE {
+ display "Buffer size for the serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for port 0."
+ }
+ }
+
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"pxa2x0\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+
+}
+
+# EOF ser_arm_xscale_pxa2x0.cdl
--- /dev/null
+//==========================================================================
+//
+// io/serial/arm/arm_xscale_pxa2x0_ser.inl
+//
+// Generic PXA 2X0 Serial I/O definitions
+//
+//==========================================================================
+//#####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): msalter
+// Contributors: msalter, Alexander Neundorf
+// Date: 21st November 2006
+// Purpose: PXA2X0 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned short select_baud[] = {
+ 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
+ 0, // 9600
+ 64, // 14400
+ 48, // 19200
+ 24, // 38400
+ 16, // 57600
+ 8, // 115200
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0
+static pc_serial_info pxa2x0_serial_info0 = {PXA2X0_FFUART_BASE,
+ CYGNUM_HAL_INTERRUPT_FFUART};
+#if CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE > 0
+static unsigned char pxa2x0_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE];
+static unsigned char pxa2x0_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pxa2x0_serial_channel0,
+ pc_serial_funs,
+ pxa2x0_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pxa2x0_serial_out_buf0[0], sizeof(pxa2x0_serial_out_buf0),
+ &pxa2x0_serial_in_buf0[0], sizeof(pxa2x0_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(pxa2x0_serial_channel0,
+ pc_serial_funs,
+ pxa2x0_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pxa2x0_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pxa2x0_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0
+
+
+// EOF arm_xscale_pxa2x0_ser.inl
--- /dev/null
+2006-05-09 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/mcf5272_serial.c (MCF5272_uart_init): Fix compiler warning
+ with diag_printf().
+
+2005-06-24 Enrico Piria <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+ * src/mcf5272_serial.c:
+ * src/mcf5272_serial.h:
+ * cdl/mcf5272_serial.cdl:
+ Rework of the original driver contributed by Wade Jensen.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mcf5272_uart.cdl: Remove irrelevant doc link.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# ser_MCF5272_uart.cdl
+#
+# eCos serial driver for MCF5272 UART
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_COLDFIRE_MCF5272 {
+ display "Serial driver for MCF5272 UART"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the serial device drivers for the
+ ColdFire MCF5272."
+
+ compile -library=libextras.a mcf5272_serial.c
+
+ cdl_component CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0 {
+ display "MCF5272 UART serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "This option includes the serial device driver
+ for the MCF5272 UART port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_NAME {
+ display "Device name for the MCF5272 UART serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of serial device for the
+ MCF5272 UART port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BAUD {
+ display "Baud rate for the MCF5272 UART serial port 0"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 19200
+ description "
+ This option specifies the default baud rate (speed) for the
+ MCF5272 UART port 0."
+ }
+
+ cdl_option CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_AUTOBAUD {
+ display "Enable automatic baud rate detection for the MCF5272 UART serial port 0."
+ flavor bool
+ default_value 0
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE > 0
+ description "
+ This option enables automatic baud rate detection for
+ MCF5272 UART port 0. Sending a BREAK character on the
+ line will start the detection. The first character following
+ the BREAK should occupy an odd position in the character table
+ (like \'a\'). This option requires interrupts to be enabled
+ for the port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE {
+ display "Buffer size for the MCF5272 UART serial port 0"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MCF5272 UART port 0. If the size specified is 0, the
+ driver will not use interrupts."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_PRIORITY {
+ display "Interrupt priority level for MCF5272 UART serial port 0"
+ flavor data
+ legal_values 1 to 6
+ default_value 2
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE > 0
+ description "
+ This option specifies the priority associated to interrupts
+ coming from the MCF5272 UART port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1 {
+ display "MCF5272 UART serial port 1 driver"
+ flavor bool
+ default_value 0
+
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "This option includes the serial device driver for the
+ MCF5272 UART port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_NAME {
+ display "Device name for the MCF5272 UART serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ MCF5272 UART port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BAUD {
+ display "Baud rate for the MCF5272 UART serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 19200
+ description "
+ This option specifies the default baud rate (speed) for the
+ MCF5272 UART port 1."
+ }
+
+ cdl_option CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_AUTOBAUD {
+ display "Enable automatic baud rate detection for the MCF5272 UART serial port 1."
+ flavor bool
+ default_value 0
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE > 0
+ description "
+ This option enables automatic baud rate detection for
+ MCF5272 UART port 1. Sending a BREAK character on the
+ line will start the detection. The first character following
+ the BREAK should occupy an odd position in the character table
+ (like \'a\'). This option requires interrupts to be enabled
+ for the port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE {
+ display "Buffer size for the MCF5272 UART serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MCF5272 UART port 1. If the size specified is 0, the
+ driver will not use interrupts."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_PRIORITY {
+ display "Interrupt priority level for MCF5272 UART serial port 1"
+ flavor data
+ legal_values 1 to 6
+ default_value 2
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE > 0
+ description "
+ This option specifies the priority associated to interrupts
+ coming from the MCF5272 UART port 1."
+ }
+ }
+}
+
--- /dev/null
+//==========================================================================
+//
+// devs/serial/coldfire/mcf5272/mcf5272_serial.c
+//
+// ColdFire MCF5272 UART Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Wade Jensen, Enrico Piria
+// Contributors:
+// Date: 2005-06-25
+// Purpose: MCF5272 Serial I/O module (interrupt driven version).
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <string.h> // memset, strcmp
+
+#include "mcf5272_serial.h"
+
+
+// Use this macro to determine if at least one of the ports uses
+// autobaud detection.
+#if defined(CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_AUTOBAUD) || \
+ defined(CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_AUTOBAUD)
+#define REQUESTED_AUTOBAUD
+#endif
+
+// Autobaud states
+typedef enum autobaud_states_t
+{
+ AB_IDLE = 0, // Normal state. Autobaud process hasn't been initiated yet.
+ AB_BEGIN_BREAK, // Detected a start of the break.
+ AB_BEGIN, // Detected the end of the break and has set up the autobaud.
+ AB_DISABLED // Autobaud detection disabled for this port.
+} autobaud_states_t;
+
+typedef struct MCF5272_uart_info_t
+{
+ volatile mcf5272_uart_t *base; // Base address of the UART registers
+ cyg_uint32 uart_vector; // UART interrupt vector number
+
+ cyg_interrupt serial_interrupt; // Interrupt context
+ cyg_handle_t serial_interrupt_handle; // Interrupt handle
+
+ volatile cyg_uint8 imr_mirror; // Interrupt mask register mirror
+
+ cyg_serial_info_t config; // The channel configuration
+
+ autobaud_states_t autobaud_state; // The autobaud state
+
+
+} MCF5272_uart_info_t;
+
+// Function prototypes for the MCF5272 UART ISR and DSR.
+static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+// Function prototypes for the serial functions.
+static bool MCF5272_uart_init(struct cyg_devtab_entry * tab);
+static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab, const char *name);
+static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c);
+static unsigned char MCF5272_uart_getc(serial_channel *chan);
+Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void MCF5272_uart_start_xmit(serial_channel *chan);
+static void MCF5272_uart_stop_xmit(serial_channel * chan);
+
+// Declare the serial functions that are called by the common serial
+// driver layer.
+static SERIAL_FUNS
+(
+ MCF5272_uart_funs,
+ MCF5272_uart_putc,
+ MCF5272_uart_getc,
+ MCF5272_uart_set_config,
+ MCF5272_uart_start_xmit,
+ MCF5272_uart_stop_xmit
+);
+
+
+// Definition for channel 0 UART configuration.
+//***********************************************
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+// Data structure contains channel information.
+static MCF5272_uart_info_t MCF5272_uart_channel_info_0;
+
+// If the channel buffer size is zero, do not include interrupt UART processing
+#if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE > 0
+
+// Allocate receive and transmit buffer. The size of the buffer is
+// configured by the configtool.
+static unsigned char
+MCF5272_uart_out_buf0[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE];
+static unsigned char
+MCF5272_uart_in_buf0[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE];
+
+// Channel function table. We register the UART functions here so
+// that uppper serial drivers can call the serial driver's routines.
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ MCF5272_uart_channel_0,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ MCF5272_uart_out_buf0, sizeof(MCF5272_uart_out_buf0),
+ MCF5272_uart_in_buf0, sizeof(MCF5272_uart_in_buf0)
+);
+
+#else
+
+// Don't use interrupt processing for the UART.
+static SERIAL_CHANNEL(
+ MCF5272_uart_channel_0,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+);
+#endif
+
+DEVTAB_ENTRY(
+ MCF5272_uart_io0,
+ CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio, // The table of I/O functions.
+ MCF5272_uart_init, // UART initialization function.
+ MCF5272_uart_lookup, // The UART lookup function. This
+ // function typically sets
+ // up the device for actual use,
+ // turning on interrupts,
+ // configuring the port, etc.
+ &MCF5272_uart_channel_0
+);
+#endif // ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+
+// Definition for channel 1 UART configuration.
+//***********************************************
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+// Data structure contains channel informtion.
+static MCF5272_uart_info_t MCF5272_uart_channel_info_1;
+
+// If the channel buffer size is zero, do not include interrupt UART processing
+#if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE > 0
+
+// Allocate receive and transmit buffer. The size of the buffer is
+// configured by the configtool.
+static unsigned char
+MCF5272_uart_out_buf1[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE];
+static unsigned char
+MCF5272_uart_in_buf1[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE];
+
+// Channel function table. We register the UART functions here so
+// that uppper serial drivers can call the serial driver's routines.
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ MCF5272_uart_channel_1,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ MCF5272_uart_out_buf1, sizeof(MCF5272_uart_out_buf1),
+ MCF5272_uart_in_buf1, sizeof(MCF5272_uart_in_buf1)
+);
+
+#else
+
+static SERIAL_CHANNEL(
+ MCF5272_uart_channel_1,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+);
+#endif
+
+DEVTAB_ENTRY(
+ MCF5272_uart_io1,
+ CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio, // The table of I/O functions.
+ MCF5272_uart_init, // UART initialization function.
+ MCF5272_uart_lookup, // The UART lookup function. This function
+ // typically sets up the device for actual use,
+ // turing on interrupts, configuring the port, etc.
+ &MCF5272_uart_channel_1
+);
+#endif // ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+
+// Function Prototypes
+
+// Internal function to actually configure the hardware to desired
+// baud rate, etc.
+static bool MCF5272_uart_config_port(serial_channel*, cyg_serial_info_t*);
+static void MCF5272_uart_start_xmit(serial_channel*);
+
+
+// The table contains dividers to divide the clock to configure an
+// approppriate baud rate for the UART.
+
+#define DIVIDER(_baudrate_) \
+ ((CYGHWR_HAL_SYSTEM_CLOCK_MHZ * 1000000) / ((_baudrate_) * 32))
+
+static unsigned long dividers_table[]=
+{
+ 0,
+ DIVIDER(50), // CYGNUM_SERIAL_BAUD_50 = 1
+ DIVIDER(75), // CYGNUM_SERIAL_BAUD_75
+ DIVIDER(110), // CYGNUM_SERIAL_BAUD_110
+ DIVIDER(134.5), // CYGNUM_SERIAL_BAUD_134_5
+ DIVIDER(150), // CYGNUM_SERIAL_BAUD_150
+ DIVIDER(200), // CYGNUM_SERIAL_BAUD_200
+ DIVIDER(300), // CYGNUM_SERIAL_BAUD_300
+ DIVIDER(600), // CYGNUM_SERIAL_BAUD_600
+ DIVIDER(1200), // CYGNUM_SERIAL_BAUD_1200
+ DIVIDER(1800), // CYGNUM_SERIAL_BAUD_1800
+ DIVIDER(2400), // CYGNUM_SERIAL_BAUD_2400
+ DIVIDER(3600), // CYGNUM_SERIAL_BAUD_3600
+ DIVIDER(4800), // CYGNUM_SERIAL_BAUD_4800
+ DIVIDER(7200), // CYGNUM_SERIAL_BAUD_7200
+ DIVIDER(9600), // CYGNUM_SERIAL_BAUD_9600
+ DIVIDER(14400), // CYGNUM_SERIAL_BAUD_14400
+ DIVIDER(19200), // CYGNUM_SERIAL_BAUD_19200
+ DIVIDER(38400), // CYGNUM_SERIAL_BAUD_38400
+ DIVIDER(57600), // CYGNUM_SERIAL_BAUD_57600
+ DIVIDER(115200), // CYGNUM_SERIAL_BAUD_115200
+ DIVIDER(230400) // CYGNUM_SERIAL_BAUD_230400
+};
+
+
+// ****************************************************************************
+// MCF5272_uart_init() - This routine is called during bootstrap to set up the
+// UART driver.
+//
+// INPUT:
+// Pointer to the the device table.
+//
+// RETURN:
+// Returns true if the initialization is successful. Otherwise, it retuns
+// false.
+
+static bool MCF5272_uart_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel *chan = (serial_channel *) tab->priv;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ int priority_level = 0;
+
+
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+ // Instantiation of the UART channel 0 data structure. This data
+ // structure contains channel information.
+ if (strcmp(tab->name, CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_NAME)
+ == 0)
+ {
+
+ cyg_uint32 pbcnt;
+
+ // A priority makes sense only if interrupts are enabled
+#ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_PRIORITY
+ priority_level = CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_PRIORITY;
+#else
+ priority_level = 0;
+#endif
+
+ // Initialize the UART information data to all zeros
+ memset(port, sizeof(MCF5272_uart_info_t), 0);
+
+ // Set the base address of the UART registers to differentiate
+ // itself from the different registers for the other UART port.
+ port->base = (mcf5272_uart_t *) &MCF5272_DEVS->uart[0];
+
+ // Set the UART interrupt vector number
+ port->uart_vector = CYGNUM_HAL_INTERRUPT_UART1;
+
+#ifdef CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_AUTOBAUD
+
+ // Set the autobaud state to idle
+ port->autobaud_state = AB_IDLE;
+#else
+ // Disable autobaud detection for this port
+ port->autobaud_state = AB_DISABLED;
+#endif
+
+ // Initialize the UART 0 output pins
+ HAL_READ_UINT32(&MCF5272_DEVS->gpio.pbcnt, pbcnt);
+ HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pbcnt,
+ MCF5272_GPIO_PBCNT_URT0_EN |
+ (pbcnt & ~MCF5272_GPIO_PBCNT_URT0_MSK));
+ }
+#endif // CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+ // Instantiation of the UART channel 1 data strucutre. This data
+ // structure contains channel information.
+ if (strcmp(tab->name, CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_NAME)
+ == 0)
+ {
+ cyg_uint32 pdcnt;
+
+ // A priority makes sense only if interrupts are enabled
+#ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_PRIORITY
+ priority_level = CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_PRIORITY;
+#else
+ priority_level = 0;
+#endif
+
+ // Initialize the UART information data to all zeros
+ memset(port, sizeof(MCF5272_uart_info_t), 0);
+
+ // Set the base address of the UART registers to differentiate
+ // itself from the different regusters for the other UART port.
+ port->base = (mcf5272_uart_t *) &MCF5272_DEVS->uart[1];
+
+ // Set the UART interrupt vector number
+ port->uart_vector = CYGNUM_HAL_INTERRUPT_UART2;
+
+#ifdef CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_AUTOBAUD
+
+ // Set the autobaud state to idle
+ port->autobaud_state = AB_IDLE;
+#else
+ // Disable autobaud detection for this port
+ port->autobaud_state = AB_DISABLED;
+#endif
+
+ // Initialize the UART 1 output pins
+ HAL_READ_UINT32(&MCF5272_DEVS->gpio.pdcnt, pdcnt);
+ HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pdcnt,
+ MCF5272_GPIO_PDCNT_URT1_EN |
+ (pdcnt & ~MCF5272_GPIO_PDCNT_URT1_MSK));
+
+ }
+#endif // CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+
+ if (chan->out_cbuf.len > 0)
+ {
+ // If the the buffer is greater than zero, then the driver will
+ // use interrupt driven I/O. Hence, the driver creates an
+ // interrupt context for the UART device.
+
+ cyg_drv_interrupt_create(port->uart_vector,
+ priority_level, // Priority
+ (cyg_addrword_t)chan, // Data item passed
+ // to interrupt handler
+ MCF5272_uart_ISR,
+ MCF5272_uart_DSR,
+ &port->serial_interrupt_handle,
+ &port->serial_interrupt);
+
+ cyg_drv_interrupt_attach(port->serial_interrupt_handle);
+
+ cyg_drv_interrupt_unmask(port->uart_vector);
+ }
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("MCF5272 UART init - dev: %p.%d\n", port->base,
+ port->uart_vector);
+#endif
+
+ // Configure Serial device
+ return (MCF5272_uart_config_port(chan, &chan->config));
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_config_port() - Configure the UART port.
+//
+// Internal function to actually configure the hardware to desired baud rate,
+// etc.
+//
+// INPUT:
+// chan - The channel information.
+// new_confg - The port configuration which include the desired
+// baud rate, etc.
+//
+// RETURN:
+// Returns true if the port configuration is successful. Otherwise,
+// it retuns false.
+
+static bool MCF5272_uart_config_port(serial_channel *chan,
+ cyg_serial_info_t *new_config)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ cyg_uint8 mode_reg = 0;
+ cyg_uint32 ubgs;
+
+
+ // If we are configuring the port once again, disable all interrupts
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, 0);
+
+ // If the baud rate is null, we don't configure the port
+ if (new_config->baud == 0) return false;
+
+ // Get the divider from the baudrate table which will use to
+ // configure the port's baud rate.
+ ubgs = (cyg_uint16) dividers_table[new_config->baud];
+
+ // Save the configuration value for later use
+ port->config = *new_config;
+
+ // We first write the reset values into the device and then configure
+ // the device the way we want to use it.
+
+ // Reset Transmitter
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_TX);
+
+ // Reset Receiver
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_RX);
+
+ // Reset Mode Register
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ // Translate the parity configuration to UART mode bits
+ switch(port->config.parity)
+ {
+ default:
+ case CYGNUM_SERIAL_PARITY_NONE:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_NONE;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_EVEN;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_ODD:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_ODD;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_MARK:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_HI;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_SPACE:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_LO;
+ break;
+ }
+
+ // Translate the number of bits per character configuration to
+ // UART mode bits
+ switch(port->config.word_length)
+ {
+ case CYGNUM_SERIAL_WORD_LENGTH_5:
+ mode_reg |= MCF5272_UART_UMR1_BC_5;
+ break;
+
+ case CYGNUM_SERIAL_WORD_LENGTH_6:
+ mode_reg |= MCF5272_UART_UMR1_BC_6;
+ break;
+
+ case CYGNUM_SERIAL_WORD_LENGTH_7:
+ mode_reg |= MCF5272_UART_UMR1_BC_7;
+ break;
+
+ default:
+ case CYGNUM_SERIAL_WORD_LENGTH_8:
+ mode_reg |= MCF5272_UART_UMR1_BC_8;
+ break;
+ }
+
+ // Enable HW flow control for receiver
+ if(port->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX)
+ mode_reg |= MCF5272_UART_UMR1_RXRTS;
+
+ // Configure the parity, HW flow control and the bits per character.
+ // After this write MR pointer points to mode register 2.
+ HAL_WRITE_UINT8(&port->base->umr, mode_reg);
+
+ // Translate the stop bit length to UART mode bits
+ switch(port->config.stop)
+ {
+ default:
+ case CYGNUM_SERIAL_STOP_1:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_1;
+ break;
+
+ case CYGNUM_SERIAL_STOP_1_5:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_15;
+ break;
+
+ case CYGNUM_SERIAL_STOP_2:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_2;
+ break;
+ }
+
+ // Enable HW flow control for transmitter
+ if(port->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX)
+ mode_reg |= MCF5272_UART_UMR2_TXCTS;
+
+ // No echo or loopback
+ mode_reg |= MCF5272_UART_UMR2_CM_NORMAL;
+
+ // Write to mode register 2
+ HAL_WRITE_UINT8(&port->base->umr, mode_reg);
+
+ // Set Rx and Tx baud by timer
+ HAL_WRITE_UINT8(&port->base->usr_ucsr, 0 | MCF5272_UART_UCSR_RCS(0xD) |
+ MCF5272_UART_UCSR_TCS(0xD));
+
+ // Mask all UART interrupts
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, 0);
+
+ // Program the baud settings to the device
+ HAL_WRITE_UINT8(&port->base->udu, (cyg_uint8)((ubgs & 0xFF00) >> 8));
+ HAL_WRITE_UINT8(&port->base->udl, (cyg_uint8)(ubgs & 0x00FF));
+
+ // Enable receiver and transmitter
+ HAL_WRITE_UINT8(&port->base->ucr, 0 | MCF5272_UART_UCR_TXRXEN);
+
+ // Enable both transmit and receive interrupt
+ port->imr_mirror = MCF5272_UART_UIMR_TXRDY | MCF5272_UART_UIMR_FFULL_RXRDY;
+
+ // Enable break interrupt only if autobaud is enabled
+ if (port->autobaud_state != AB_DISABLED)
+ port->imr_mirror |= MCF5272_UART_UIMR_DB;
+
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+
+ // Return true to indicate a successful configuration
+ return true;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_lookup() - This routine is called when the device is "looked"
+// up (i.e. attached)
+//
+// INPUT:
+// tab - pointer to a pointer of the device table.
+// sub_tab - Pointer to the sub device table.
+// name - name of the device.
+//
+// RETURN:
+// Always return ENOERR.
+
+static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_putc() - Send a character to the device output buffer.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+// c - the character to output.
+//
+// RETURN:
+// 'true' if character is sent to device, return 'false' when we've
+// ran out of buffer space in the device itself.
+
+static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ cyg_uint8 usr_ucsr;
+
+ // Make sure the transmitter is not full. If it is full, return false.
+ HAL_READ_UINT8(&port->base->usr_ucsr, usr_ucsr);
+ if (!(usr_ucsr & MCF5272_UART_USR_TXRDY))
+ return false;
+
+ // Send the character
+ HAL_WRITE_UINT8(&port->base->urb_utb, c);
+
+ return true ;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_getc() - Fetch a character from the device input buffer and
+// return it to the calling routine. Wait until there
+// is a character ready.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+//
+// RETURN:
+// the character read from the UART.
+
+static unsigned char MCF5272_uart_getc(serial_channel *chan)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ cyg_uint8 usr_ucsr, urb_utb;
+
+ // Wait until character has been received
+ do
+ {
+ HAL_READ_UINT8(&port->base->usr_ucsr, usr_ucsr);
+ }
+ while (!(usr_ucsr & MCF5272_UART_USR_RXRDY)) ;
+
+ // Read the character from the FIFO queue
+ HAL_READ_UINT8(&port->base->urb_utb, urb_utb);
+
+ return urb_utb;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_set_config() - Set up the device characteristics; baud rate,
+// etc.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+// key - configuration key (command).
+// xbuf - pointer to the configuration buffer.
+// len - the length of the configuration buffer.
+//
+// RETURN:
+// NOERR - If the configuration is successful.
+// EINVAL - If the argument is invalid.
+
+Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ cyg_serial_info_t *config = (cyg_serial_info_t *) xbuf;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+ switch (key)
+ {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ // Set serial configuration
+ if (*len < sizeof(cyg_serial_info_t))
+ return EINVAL;
+
+ *len = sizeof(cyg_serial_info_t);
+
+ if (!MCF5272_uart_config_port(chan, config))
+ return EINVAL;
+ }
+ break;
+
+ case CYG_IO_GET_CONFIG_SERIAL_INFO:
+ // Retrieve UART configuration
+ *config = port->config;
+ break;
+
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ cyg_uint32 *f = (cyg_uint32 *)xbuf;
+
+ if (*len < sizeof(*f))
+ return -EINVAL;
+
+ // we should throttle
+ if (*f) HAL_WRITE_UINT8(&port->base->uop0, MCF5272_UART_UOP0_RTS);
+ // we should no longer throttle
+ else HAL_WRITE_UINT8(&port->base->uop1, MCF5272_UART_UOP1_RTS);
+ }
+ break;
+
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ // We only support RTSCTS (and software) flow control.
+ // We clear any unsupported flags here and
+ // then return -ENOSUPP - the higher layer can then query
+ // what flags are set and decide what to do.
+ {
+ unsigned int flags_mask;
+ cyg_uint8 umr1_mask, umr2_mask;
+
+ // These are the control flow modes we support
+ flags_mask = (CYGNUM_SERIAL_FLOW_RTSCTS_RX |
+ CYGNUM_SERIAL_FLOW_RTSCTS_RX);
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
+ flags_mask |= (CYGNUM_SERIAL_FLOW_XONXOFF_RX |
+ CYGNUM_SERIAL_FLOW_XONXOFF_TX);
+#endif
+ if (chan->config.flags & ~flags_mask)
+ {
+ chan->config.flags &= flags_mask;
+ return -ENOSUPP;
+ }
+
+ // For security, mask UART interrupt while we change configuration
+ cyg_drv_interrupt_mask(port->uart_vector);
+
+ // Reset mode register pointer
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ // Read mode register 1
+ HAL_READ_UINT8(&port->base->umr, umr1_mask);
+
+ // Read mode register 2
+ HAL_READ_UINT8(&port->base->umr, umr2_mask);
+
+ if (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX)
+ umr1_mask |= MCF5272_UART_UMR1_RXRTS;
+ else umr1_mask &= ~MCF5272_UART_UMR1_RXRTS;
+
+ if (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX)
+ umr2_mask |= MCF5272_UART_UMR2_TXCTS;
+ else umr2_mask &= ~MCF5272_UART_UMR2_TXCTS;
+
+ // Reset mode register pointer
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ // Write mode register 1
+ HAL_WRITE_UINT8(&port->base->umr, umr1_mask);
+
+ // Write mode register 2
+ HAL_WRITE_UINT8(&port->base->umr, umr2_mask);
+
+ // Unmask UART interrupt
+ cyg_drv_interrupt_unmask(port->uart_vector);
+ }
+ break;
+#endif // CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+
+ default:
+ return EINVAL;
+ }
+
+ return ENOERR;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_start_xmit() - Enable the transmitter on the device.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+
+static void MCF5272_uart_start_xmit(serial_channel *chan)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ // Mask UART interrupt to prevent race conditions
+ cyg_drv_interrupt_mask(port->uart_vector);
+
+ // Enable the UART transmitter.
+ // Eventually, preserve the ongoing autobaud calculation.
+#ifdef REQUESTED_AUTOBAUD
+ if(port->autobaud_state == AB_BEGIN)
+ HAL_WRITE_UINT8(&port->base->ucr, (MCF5272_UART_UCR_TX_ENABLED |
+ MCF5272_UART_UCR_ENAB));
+ else
+#endif
+ {
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_TX_ENABLED);
+ }
+
+ // Enable transmitter interrupt
+ port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+
+ // Unmask UART interrupt
+ cyg_drv_interrupt_unmask(port->uart_vector);
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_stop_xmit() - Disable the transmitter on the device
+//
+// INPUT:
+// chan - pointer to the serial private data.
+
+static void MCF5272_uart_stop_xmit(serial_channel * chan)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ // Mask UART interrupt to prevent race conditions
+ cyg_drv_interrupt_mask(port->uart_vector);
+
+ // Disable transmitter interrupt
+ port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+
+ // Disable the UART transmitter.
+ // Eventually, preserve the ongoing autobaud calculation.
+ // !!!!!!!!!!!!!
+ // !!!WARNING!!!
+ // !!!!!!!!!!!!!
+ // If the transmitter is disabled
+ // the diag_printf routines will poll forever to transmit the
+ // a character. Hence, don't ever disable the transmitter if
+ // you want it to work with diag_printf.
+#ifdef REQUESTED_AUTOBAUD
+ if(port->autobaud_state == AB_BEGIN)
+ HAL_WRITE_UINT8(&port->base->ucr, (MCF5272_UART_UCR_TX_DISABLED |
+ MCF5272_UART_UCR_ENAB));
+ else
+#endif
+ {
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_TX_DISABLED);
+ }
+
+ // Unmask UART interrupt
+ cyg_drv_interrupt_unmask(port->uart_vector);
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR).
+//
+// INPUT:
+// vector - the interrupt vector number.
+// data - user parameter.
+//
+// RETURN:
+// returns CYG_ISR_CALL_DSR to call the DSR.
+
+static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *) data;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ // Write the value in the interrupt status register back
+ // to the mask register to disable the interrupt temporarily.
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, 0);
+
+ // Cause DSR to run
+ return CYG_ISR_CALL_DSR;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes
+// the interrupt from the device.
+//
+// INPUT:
+// vector - The interrupt vector number.
+// count - The nunber of DSR requests.
+// data - Device specific information.
+//
+// The autobaud feature is implemented by means of a simple finite state
+// machine which can take the following states:
+// AB_DISABLED: autobaud is disabled.
+// AB_IDLE: no autobaud calculation is in progress. If autobaud calculation
+// has completed, retrieve the new baud rate.
+// AB_BEGIN_BREAK: the start of a break character was detected.
+// AB_BEGIN: the end of a break character was detected. Start autobaud
+// calculation.
+//
+// The state diagram is the following:
+// AB_IDLE --> AB_BEGIN_BREAK --> AB_BEGIN --> Back to AB_IDLE
+// The state AB_DISABLED is isolated and means that the autobaud feature is
+// not active for that port.
+
+static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *) data;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ volatile cyg_uint8 isr;
+ cyg_uint8 uisr_uimr;
+
+
+ while (1)
+ {
+ // First of all, the exit condition
+
+ // Retrieve the interrupt status bits. We use these status bits to
+ // figure out what process should we perform: read from the UART or
+ // inform of a completion of a data transmission.
+ HAL_READ_UINT8(&port->base->uisr_uimr, uisr_uimr);
+ isr = uisr_uimr & port->imr_mirror;
+
+ // If there are no more events pending, exit the loop
+ if (!isr) break;
+
+#ifdef REQUESTED_AUTOBAUD
+ switch (port->autobaud_state)
+ {
+ case AB_DISABLED:
+ // Nothing to check for
+ break;
+
+ case AB_BEGIN_BREAK:
+ if (isr & MCF5272_UART_UISR_DB)
+ {
+ // Detected the end of a break, set the state to
+ // AB_BEGIN, and setup autobaud detection.
+ port->autobaud_state = AB_BEGIN;
+
+ // Initialize divider
+ HAL_WRITE_UINT8(&port->base->udu, 0);
+ HAL_WRITE_UINT8(&port->base->udl, 0);
+
+ // Reset the Delta Break bit in the UISR and
+ //Enable autobaud
+ HAL_WRITE_UINT8(&port->base->ucr,
+ MCF5272_UART_UCR_RESET_BKCHGINT);
+
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_ENAB);
+
+ // Enable autobaud completion interrupt
+ port->imr_mirror |= MCF5272_UART_UIMR_ABC;
+
+ // Disable the delta break interrupt so we can't receive
+ // anymore break interrupt.
+ port->imr_mirror &= ~MCF5272_UART_UIMR_DB;
+
+ }
+ break;
+
+ case AB_BEGIN:
+ if (isr & MCF5272_UART_UISR_ABC)
+ {
+ int count;
+ unsigned int threshold;
+ cyg_uint8 uabu, uabl;
+
+ // Retrieve the detected baud rate
+ HAL_READ_UINT8(&port->base->uabu, uabu);
+ HAL_READ_UINT8(&port->base->uabl, uabl);
+
+ cyg_uint16 divider = (uabu << 8) + uabl;
+
+ // Search in the list to find a match
+ for (count = sizeof(dividers_table)/
+ sizeof(unsigned long) - 1;
+ count > 1; count--)
+ {
+ if (divider < dividers_table[count - 1]) break;
+ }
+
+ // Modify baud rate only if it is in range
+ if (count > 1)
+ {
+ // Set the baud rate to the nearest standard rate
+ threshold = (dividers_table[count] +
+ dividers_table[count - 1]) / 2;
+ port->config.baud = (divider < threshold) ? count :
+ count - 1;
+ }
+
+ divider = dividers_table[port->config.baud];
+
+ // Program the baud settings to the device
+ HAL_WRITE_UINT8(&port->base->udu,
+ (cyg_uint8)((divider & 0xFF00) >> 8));
+ HAL_WRITE_UINT8(&port->base->udl,
+ (cyg_uint8)(divider & 0x00FF));
+
+ // Autobaud completion
+ port->autobaud_state = AB_IDLE;
+
+ // Disable autobaud
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_NONE);
+
+#if 0
+ // In case patch submitted July 11, 2005 gets committed
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Inform upper layers of the new baud rate
+ {
+ cyg_serial_line_status_t stat;
+
+ stat.which = CYGNUM_SERIAL_STATUS_NEWBAUDRATE;
+ stat.value = port->config.baud;
+
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+#endif
+ // Ignore autobaud completion interrupt
+ port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;
+
+ // Reenable delta break interrupt
+ port->imr_mirror |= MCF5272_UART_UIMR_DB;
+
+ }
+ break;
+
+ default:
+ case AB_IDLE:
+ if (isr & MCF5272_UART_UISR_DB)
+ {
+ // Detected the begin of a break, set the state to
+ // AB_BEGIN_BREAK
+ port->autobaud_state = AB_BEGIN_BREAK;
+
+ // Reset the delta break bit in the UISR
+ HAL_WRITE_UINT8(&port->base->ucr,
+ MCF5272_UART_UCR_RESET_BKCHGINT);
+ }
+ break;
+ }
+#endif // REQUESTED_AUTOBAUD
+
+ // Receive character interrupt
+ if ((isr & MCF5272_UART_UISR_RXRDY))
+ {
+ char c;
+ cyg_uint8 usr_ucsr;
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ cyg_serial_line_status_t stat;
+#endif
+
+ // Read all the characters in the fifo
+ while (1)
+ {
+ // First of all, the exit condition
+
+ // If there are no more characters waiting, exit the loop
+ HAL_READ_UINT8(&port->base->uisr_uimr, uisr_uimr);
+ if (!(uisr_uimr & MCF5272_UART_UISR_RXRDY)) break;
+
+ // Read port status
+ HAL_READ_UINT8(&port->base->usr_ucsr, usr_ucsr);
+
+ // Received break
+ if (usr_ucsr & MCF5272_UART_USR_RB)
+ {
+ // Ignore break character
+ HAL_READ_UINT8(&port->base->urb_utb, c);
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ stat.which = CYGNUM_SERIAL_STATUS_BREAK;
+ (chan->callbacks->indicate_status)(chan, &stat);
+#endif
+ continue;
+ }
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Overrun error
+ if (usr_ucsr & MCF5272_UART_USR_OE)
+ {
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Framing error
+ if (usr_ucsr & MCF5272_UART_USR_FE)
+ {
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Parity error
+ if (usr_ucsr & MCF5272_UART_USR_PE)
+ {
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+ // Read the character from the UART
+ HAL_READ_UINT8(&port->base->urb_utb, c);
+
+ // Pass the read character to the upper layer
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+ }
+
+ // Transmit complete interrupt
+ if ((isr & MCF5272_UART_UISR_TXRDY))
+ {
+ // Transmit holding register is empty
+ (chan->callbacks->xmt_char)(chan);
+ }
+ }
+
+ // Unmask all the UART interrupts that were masked in the ISR, so
+ // that we can receive the next interrupt.
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+}
--- /dev/null
+#ifndef CYGONCE_MCF5272_SERIAL_H
+#define CYGONCE_MCF5272_SERIAL_H
+
+//==========================================================================
+//
+// devs/serial/coldfire/mcf5272/mcf5272_serial.h
+//
+// ColdFire MCF5272 serial I/O module definitions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria, Wade Jensen
+// Contributors:
+// Date: 2005-06-25
+// Purpose: MCF5272 serial I/O module definitions.
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <pkgconf/io_serial_coldfire_mcf5272.h>
+
+// Bit level definitions and macros
+#define MCF5272_UART_UMR1_RXRTS (0x80)
+#define MCF5272_UART_UMR1_RXIRQ (0x40)
+#define MCF5272_UART_UMR1_ERR (0x20)
+#define MCF5272_UART_UMR1_PM_MULTI_ADDR (0x1C)
+#define MCF5272_UART_UMR1_PM_MULTI_DATA (0x18)
+#define MCF5272_UART_UMR1_PM_NONE (0x10)
+#define MCF5272_UART_UMR1_PM_FORCE_HI (0x0C)
+#define MCF5272_UART_UMR1_PM_FORCE_LO (0x08)
+#define MCF5272_UART_UMR1_PM_ODD (0x04)
+#define MCF5272_UART_UMR1_PM_EVEN (0x00)
+#define MCF5272_UART_UMR1_BC_5 (0x00)
+#define MCF5272_UART_UMR1_BC_6 (0x01)
+#define MCF5272_UART_UMR1_BC_7 (0x02)
+#define MCF5272_UART_UMR1_BC_8 (0x03)
+
+#define MCF5272_UART_UMR2_CM_NORMAL (0x00)
+#define MCF5272_UART_UMR2_CM_ECHO (0x40)
+#define MCF5272_UART_UMR2_CM_LOCAL_LOOP (0x80)
+#define MCF5272_UART_UMR2_CM_REMOTE_LOO (0xC0)
+#define MCF5272_UART_UMR2_TXRTS (0x20)
+#define MCF5272_UART_UMR2_TXCTS (0x10)
+#define MCF5272_UART_UMR2_STOP_BITS_1 (0x07)
+#define MCF5272_UART_UMR2_STOP_BITS_15 (0x08)
+#define MCF5272_UART_UMR2_STOP_BITS_2 (0x0F)
+// Stop Bit Length
+#define MCF5272_UART_UMR2_STOP_BITS(a) ((a)&0x0f)
+
+#define MCF5272_UART_USR_RB (0x80)
+#define MCF5272_UART_USR_FE (0x40)
+#define MCF5272_UART_USR_PE (0x20)
+#define MCF5272_UART_USR_OE (0x10)
+#define MCF5272_UART_USR_TXEMP (0x08)
+#define MCF5272_UART_USR_TXRDY (0x04)
+#define MCF5272_UART_USR_FFULL (0x02)
+#define MCF5272_UART_USR_RXRDY (0x01)
+
+// Rx Clk Select
+#define MCF5272_UART_UCSR_RCS(a) (((a) & 0x0f) << 4)
+// Tx Clk Select
+#define MCF5272_UART_UCSR_TCS(a) ((a) & 0x0f)
+
+
+#define MCF5272_UART_UCR_NONE (0x00)
+#define MCF5272_UART_UCR_ENAB (0x80)
+#define MCF5272_UART_UCR_STOP_BREAK (0x70)
+#define MCF5272_UART_UCR_START_BREAK (0x60)
+#define MCF5272_UART_UCR_RESET_BKCHGINT (0x50)
+#define MCF5272_UART_UCR_RESET_ERROR (0x40)
+#define MCF5272_UART_UCR_RESET_TX (0x30)
+#define MCF5272_UART_UCR_RESET_RX (0x20)
+#define MCF5272_UART_UCR_RESET_MR (0x10)
+#define MCF5272_UART_UCR_TX_DISABLED (0x08)
+#define MCF5272_UART_UCR_TX_ENABLED (0x04)
+#define MCF5272_UART_UCR_RX_DISABLED (0x02)
+#define MCF5272_UART_UCR_RX_ENABLED (0x01)
+
+#define MCF5272_UART_UCR_TXRXEN \
+ (MCF5272_UART_UCR_TX_ENABLED | MCF5272_UART_UCR_RX_ENABLED)
+
+#define MCF5272_UART_UCCR_COS (0x10)
+#define MCF5272_UART_UCCR_CTS (0x01)
+
+#define MCF5272_UART_UACR_BRG (0x80)
+#define MCF5272_UART_UACR_CTMS_TIMER (0x60)
+#define MCF5272_UART_UACR_IEC (0x01)
+
+#define MCF5272_UART_UISR_COS (0x80)
+#define MCF5272_UART_UISR_ABC (0x40)
+#define MCF5272_UART_UISR_DB (0x04)
+#define MCF5272_UART_UISR_RXRDY (0x02)
+#define MCF5272_UART_UISR_TXRDY (0x01)
+
+#define MCF5272_UART_UIMR_COS (0x80)
+#define MCF5272_UART_UIMR_ABC (0x40)
+#define MCF5272_UART_UIMR_DB (0x04)
+#define MCF5272_UART_UIMR_FFULL_RXRDY (0x02)
+#define MCF5272_UART_UIMR_TXRDY (0x01)
+
+#define MCF5272_UART_UOP0_RTS (0x01)
+#define MCF5272_UART_UOP1_RTS (0x01)
+
+// ---------------------------------------------------------------------------
+// End of mcf5272_serial.h
+#endif // CYGONCE_MCF5272_SERIAL_H
--- /dev/null
+2007-01-10 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci_h.cdl: CYGPKG_IO_SERIAL_FREESCALE_ESCI_H
+ moved in a new directory due ecosadmin.tcl issue
+ reported by John Dallaway
+
+2006-08-31 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci.cdl: driver now requires at least 1 selected
+ channel
+
+2006-08-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_esci.h : platform dependent clock related macros
+ removed and placed in platform/var header
+
+2006-05-24 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_esci.cdl:
+ * include/ser_esci.h:
+ * src/ser_esci.c
+ New package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# ser_freescale_esci.cdl
+#
+# eCos serial Freescale/esci configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Original data:
+# Contributors:
+# Date: 2006-04-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_FREESCALE_ESCI {
+ display "eSCI device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+
+ requires CYGPKG_IO_SERIAL_FREESCALE_ESCI_H
+
+ requires (CYGPKG_ERROR && (CYGPKG_IO_SERIAL_FREESCALE_ESCI_A || \
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_B || \
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_C || \
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_D) \
+ )
+
+ include_dir cyg/devs
+
+ description "
+ This option enables the serial device drivers for the
+ Freescale eSCI - Enhanced Serial Communication Interface.
+ eSCI is on-chip serial controller found on some freescale
+ microcontrollers such as: MAC7100 familly, etc.
+ "
+ compile -library=libextras.a ser_esci.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_freescale_esci.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_A {
+ display "eSCI port A driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port A."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_A_NAME {
+ display "Device name for eSCI port A"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name for the eSCI port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_PRIORITY {
+ display "eSCI port A INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 7
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_B {
+ display "eSCI port B driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port B."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_B_NAME {
+ display "Device name for eSCI port B"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the eSCI port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_PRIORITY {
+ display "eSCI prot B INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 7
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_C {
+ display "eSCI port C driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port C."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_C_NAME {
+ display "Device name for eSCI port C"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the eSCI port C."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port C."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port C."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_PRIORITY {
+ display "eSCI prot B INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 6
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_D {
+ display "eSCI port D driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port D."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_D_NAME {
+ display "Device name for eSCI port D"
+ flavor data
+ default_value {"\"/dev/ser3\""}
+ description "
+ This option specifies the device name for the eSCI port D."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port D."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port D."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_PRIORITY {
+ display "eSCI prot B INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 6
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+ }
+
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_FREESCALE_ESCI_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_FREESCALE_ESCI_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_freescale_esci.cdl
--- /dev/null
+//==========================================================================
+//
+// ser_esci.c
+//
+// Freescale sSCI Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2996 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-20
+// Purpose: eSCI Serial I/O module (interrupt driven version)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arbiter.h>
+#include <cyg/hal/var_io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+#include <cyg/devs/ser_esci.h>
+
+// Only build this driver for if ESCI is needed.
+#ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI
+
+typedef struct esci_serial_info {
+ CYG_ADDRWORD esci_base; // Base address of the esci port
+ CYG_WORD interrupt_num; // INTC interrupt vector
+ cyg_priority_t interrupt_priority; // INTC interupt priority
+ cyg_interrupt interrupt_obj; // Interrupt object
+ cyg_handle_t interrupt_handle; // Interrupt handle
+} esci_serial_info;
+
+static bool esci_serial_init(struct cyg_devtab_entry * tab);
+static bool esci_serial_putc(serial_channel * chan, unsigned char c);
+static Cyg_ErrNo esci_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name);
+static unsigned char esci_serial_getc(serial_channel *chan);
+static Cyg_ErrNo esci_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void esci_serial_start_xmit(serial_channel *chan);
+static void esci_serial_stop_xmit(serial_channel *chan);
+
+// Interrupt servers
+static cyg_uint32 esci_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void esci_serial_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(esci_serial_funs,
+ esci_serial_putc,
+ esci_serial_getc,
+ esci_serial_set_config,
+ esci_serial_start_xmit,
+ esci_serial_stop_xmit);
+
+// Available baud rates
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50 bps unsupported
+ 0, // 75 bps unsupported
+ 0, // 110 bps unsupported
+ 0, // 134_5 bps unsupported
+ 0, // 150 bps unsupported
+ 0, // 200 bps unsupported
+ FREESCALE_ESCI_BAUD(300), // 300 bps
+ FREESCALE_ESCI_BAUD(600), // 600 bps
+ FREESCALE_ESCI_BAUD(1200), // 1200 bps
+ 0, // 1800 bps unsupported
+ FREESCALE_ESCI_BAUD(2400), // 2400 bps
+ 0, // 3600 bps unsupported
+ FREESCALE_ESCI_BAUD(4800), // 4800 bps
+ 0, // 7200 bps unsupported
+ FREESCALE_ESCI_BAUD(9600), // 9600 bps
+ FREESCALE_ESCI_BAUD(14400), // 14400 bps
+ FREESCALE_ESCI_BAUD(19200), // 19200 bps
+ FREESCALE_ESCI_BAUD(38400), // 38400 bps
+ FREESCALE_ESCI_BAUD(57600), // 57600 bps
+ FREESCALE_ESCI_BAUD(115200), // 115200 bps
+ 0 // 230400 bps unsupported
+};
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_A
+static esci_serial_info esci_serial_info0 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf0[CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf0[CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(
+ esci_serial_channel0,
+ esci_serial_funs,
+ esci_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf0[0],
+ sizeof(esci_serial_out_buf0),
+ &esci_serial_in_buf0[0],
+ sizeof(esci_serial_in_buf0));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel0,
+ esci_serial_funs,
+ esci_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io0,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_A_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel0);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_A
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_B
+static esci_serial_info esci_serial_info1 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf1[CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf1[CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(esci_serial_channel1,
+ esci_serial_funs,
+ esci_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf1[0],
+ sizeof(esci_serial_out_buf1),
+ &esci_serial_in_buf1[0],
+ sizeof(esci_serial_in_buf1));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel1,
+ esci_serial_funs,
+ esci_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io1,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_B_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel1);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_B
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
+static esci_serial_info esci_serial_info2 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf2[CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf2[CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(esci_serial_channel2,
+ esci_serial_funs,
+ esci_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf2[0],
+ sizeof(esci_serial_out_buf2),
+ &esci_serial_in_buf2[0],
+ sizeof(esci_serial_in_buf2));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel2,
+ esci_serial_funs,
+ esci_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io2,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_C_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel2);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
+
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
+static esci_serial_info esci_serial_info3 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf3[CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf3[CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(esci_serial_channel3,
+ esci_serial_funs,
+ esci_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf3[0],
+ sizeof(esci_serial_out_buf3),
+ &esci_serial_in_buf3[0],
+ sizeof(esci_serial_in_buf3));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel3,
+ esci_serial_funs,
+ esci_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io3,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_D_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel3);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
+
+//----------------------------------------------------------------------------
+// Internal function to actually configure the hardware to desired
+// baud rate, etc.
+//----------------------------------------------------------------------------
+static bool
+esci_serial_config_port(serial_channel * chan, cyg_serial_info_t * new_config,
+ bool init)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)(chan->dev_priv);
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 baud_rate = ((new_config->baud >= 0) &&
+ (new_config->baud < (sizeof(select_baud)/
+ sizeof(select_baud[0]))))
+ ? select_baud[new_config->baud] : 0;
+
+ cyg_uint16 esci_cr12=0, esci_cr12_old;
+
+ HAL_WRITE_UINT8(FREESCALE_ESCI_CR3(esci_base), 0);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_LINCTRL(esci_base), 0);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), 0);
+
+ if(!baud_rate) return false; // Invalid baud rate selected
+
+ switch(new_config->word_length){
+ case 8: break;
+ default: return false;
+ }
+
+ switch(new_config->parity){
+ case CYGNUM_SERIAL_PARITY_ODD:
+ esci_cr12 |= FREESCALE_ESCI_CR12_PT;
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ esci_cr12 |= FREESCALE_ESCI_CR12_PE;
+ case CYGNUM_SERIAL_PARITY_NONE:
+ break;
+ default: return false;
+ }
+
+ if(new_config->stop!=CYGNUM_SERIAL_STOP_1) return false;
+
+ // Enable the device
+ esci_cr12 |= FREESCALE_ESCI_CR12_TE | FREESCALE_ESCI_CR12_RE;
+
+ if(init){ // Enable the receiver interrupt
+ esci_cr12 |= FREESCALE_ESCI_CR12_RIE;
+ }else{ // Restore the old interrupt state
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12_old);
+ esci_cr12 |= (esci_cr12_old & FREESCALE_ESCI_CR12_RIE);
+ }
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+
+ if(new_config != &chan->config)
+ chan->config = *new_config;
+
+ return true;
+}
+
+//--------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+//--------------------------------------------------------------
+static bool
+esci_serial_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel * chan = (serial_channel *)tab->priv;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ if(chan->out_cbuf.len != 0){
+ cyg_drv_interrupt_create(esci_chan->interrupt_num,
+ esci_chan->interrupt_priority,
+ // Data item passed to interrupt handler
+ (cyg_addrword_t)chan,
+ esci_serial_ISR,
+ esci_serial_DSR,
+ &esci_chan->interrupt_handle,
+ &esci_chan->interrupt_obj);
+
+ cyg_drv_interrupt_attach(esci_chan->interrupt_handle);
+ cyg_drv_interrupt_unmask(esci_chan->interrupt_num);
+ }
+ return esci_serial_config_port(chan, &chan->config, true);
+}
+
+//----------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+//----------------------------------------------------------------------
+static Cyg_ErrNo
+esci_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab, const char * name)
+{
+ serial_channel * chan = (serial_channel *)(*tab)->priv;
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ return ENOERR;
+}
+
+//-----------------------------------------------------------------
+// Send a character to Tx
+//-----------------------------------------------------------------
+static bool
+esci_serial_putc(serial_channel * chan, unsigned char ch_out)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_sr;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ if(esci_sr & FREESCALE_ESCI_SR_TDRE){
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_TDRE);
+ HAL_WRITE_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_out);
+ return true;
+ }else
+ return false;
+}
+
+//---------------------------------------------------------------------
+// Fetch a character Rx (for polled operation only)
+//---------------------------------------------------------------------
+static unsigned char
+esci_serial_getc(serial_channel * chan)
+{
+ cyg_uint8 ch_in;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+
+ cyg_uint16 esci_sr;
+
+ do{
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ }while(esci_sr & FREESCALE_ESCI_SR_RDRF);
+
+ HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+
+ return ch_in;
+}
+
+//---------------------------------------------------
+// Set up the device characteristics; baud rate, etc.
+//---------------------------------------------------
+static bool
+esci_serial_set_config(serial_channel * chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 * len)
+{
+ switch(key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:{
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if(*len < sizeof(cyg_serial_info_t)) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if(true != esci_serial_config_port(chan, config, false))
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------
+// Enable the transmitter on the device
+//-------------------------------------
+static void esci_serial_start_xmit(serial_channel * chan)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_cr12;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+ esci_cr12 |= FREESCALE_ESCI_CR12_TIE;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+}
+
+//--------------------------------------
+// Disable the transmitter on the device
+//--------------------------------------
+static void esci_serial_stop_xmit(serial_channel * chan)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_cr12;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+ esci_cr12 &= ~FREESCALE_ESCI_CR12_TIE;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+}
+
+//-----------------------------------------
+// The low level interrupt handler
+//-----------------------------------------
+static
+cyg_uint32 esci_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(esci_chan->interrupt_num);
+ cyg_drv_interrupt_acknowledge(esci_chan->interrupt_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+
+//------------------------------------------
+// The high level interrupt handler
+//------------------------------------------
+
+#define FREESCALE_ESCI_SR_ERRORS (FREESCALE_ESCI_SR_OR | \
+ FREESCALE_ESCI_SR_NF | \
+ FREESCALE_ESCI_SR_FE | \
+ FREESCALE_ESCI_SR_PF)
+
+static void
+esci_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_sr;
+ cyg_uint8 esci_dr;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ if(esci_sr & FREESCALE_ESCI_SR_RDRF){ // Receiver full
+ HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), esci_dr);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+ if(esci_sr &= (cyg_uint16)FREESCALE_ESCI_SR_ERRORS){
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ }else{
+ (chan->callbacks->rcv_char)(chan, (cyg_uint8)esci_dr);
+ }
+ }else if(esci_sr & FREESCALE_ESCI_SR_TDRE){ //Transmitter empty
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ cyg_drv_interrupt_unmask(esci_chan->interrupt_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_FREESCALE_ESCI_[ABCD]
+// EOF ser_esci.c
--- /dev/null
+2007-01-10 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci_h.cdl: moved in a newly created directory for
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_H due ecosadmin.tcl issue
+ reported by John Dallaway
+
+
+2006-08-31 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci.cdl: driver now requires at least 1 selected
+ channel
+
+2006-08-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_esci.h : platform dependent clock related macros
+ removed and placed in platform/var header
+
+2006-05-24 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_esci.cdl:
+ * include/ser_esci.h:
+ * src/ser_esci.c
+ New package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# ser_freescale_esci_h.cdl
+#
+# eCos serial Freescale/esci configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Original data:
+# Contributors:
+# Date: 2006-05-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_FREESCALE_ESCI_H {
+ display "eSCI header"
+
+ include_dir cyg/devs
+ description "
+ This option provides header for Freescale eSCI - Enhanced
+ Serial Communication Interface. eSCI is on-chip serial
+ controller found on some Freescale micro controllers such as:
+ MAC7100 familly, etc. "
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_freescale_esci.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+}
+
+# EOF ser_freescale_esci_h.cdl
--- /dev/null
+#ifndef CYGONCE_DEVS_SERIAL_FREESCALE_ESCI_H
+#define CYGONCE_DEVS_SERIAL_FREESCALE_ESCI_H
+//==========================================================================
+//
+// ser_esci.h
+//
+// Freescale eSCI Serial I/O definitions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-20
+// Purpose: eSCI Serial I/O definitions.
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Note: Following macros are platform dependent
+// and have to be defined in var_io.h or plf_io.h
+// Macros referenced by serial driver:
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE
+// CYGNUM_DEV_SER_FREESCALE_ESCI_SYSTEM_CLOCK
+// FREESCALE_ESCI_BAUD(baud_rate)
+
+// Macros not referenced by serial driver
+// but by interrupt controller
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_VECTOR
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_VECTOR
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_VECTOR
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_VECTOR
+// MAC7100_ESCI_A_IV
+// MAC7100_ESCI_B_IV
+// MAC7100_ESCI_C_IV
+// MAC7100_ESCI_D_IV
+//
+
+#define FREESCALE_ESCI_A_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE)
+#define FREESCALE_ESCI_B_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE)
+#define FREESCALE_ESCI_C_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE)
+#define FREESCALE_ESCI_D_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE)
+
+#define FREESCALE_ESCI_A_I 0
+#define FREESCALE_ESCI_B_I 1
+#define FREESCALE_ESCI_C_I 2
+#define FREESCALE_ESCI_D_I 3
+
+#define FREESCALE_ESCI_BD(esci_base) \
+ (esci_base + FREESCALE_ESCI_BD_OFFSET) //short
+#define FREESCALE_ESCI_CR12(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR12_OFFSET) //short
+#define FREESCALE_ESCI_CR34(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR34_OFFSET) //short
+#define FREESCALE_ESCI_CR1(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR1_OFFSET) //char
+#define FREESCALE_ESCI_CR2(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR2_OFFSET) //char
+#define FREESCALE_ESCI_CR3(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR3_OFFSET) //char
+#define FREESCALE_ESCI_CR4(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR4_OFFSET) //short
+#define FREESCALE_ESCI_LINCTRL(esci_base) \
+ (esci_base + FREESCALE_ESCI_LINCTRL_OFFSET) //short
+#define FREESCALE_ESCI_LINCRCP(esci_base) \
+ (esci_base + FREESCALE_ESCI_LINCRCP_OFFSET) //short
+#define FREESCALE_ESCI_SR(esci_base) \
+ (esci_base + FREESCALE_ESCI_SR_OFFSET) //short
+#define FREESCALE_ESCI_DRL(esci_base) \
+ (esci_base + FREESCALE_ESCI_DRL_OFFSET) //char
+
+#define FREESCALE_ESCI_BD_OFFSET (0x0000)
+#define FREESCALE_ESCI_CR12_OFFSET (0x0002)
+#define FREESCALE_ESCI_CR34_OFFSET (0x0002)
+#define FREESCALE_ESCI_CR1_OFFSET (0x0002)
+#define FREESCALE_ESCI_CR2_OFFSET (0x0003)
+#define FREESCALE_ESCI_CR3_OFFSET (0x0004)
+#define FREESCALE_ESCI_CR4_OFFSET (0x0005)
+#define FREESCALE_ESCI_DRL_OFFSET (0x0007)
+#define FREESCALE_ESCI_SR_OFFSET (0x0008)
+#define FREESCALE_ESCI_LINSTAT_OFFSET (0x000A)
+#define FREESCALE_ESCI_LINCTRL_OFFSET (0x000C)
+#define FREESCALE_ESCI_LINRX_OFFSET (0x0010)
+#define FREESCALE_ESCI_LINTX_OFFSET (0x0014)
+#define FREESCALE_ESCI_LINCRCP_OFFSET (0x0018)
+
+#define FREESCALE_ESCI_CR12_LOOPS (0x8000)
+#define FREESCALE_ESCI_CR12_SCISDOZ (0x4000)
+#define FREESCALE_ESCI_CR12_RSRC (0x2000)
+#define FREESCALE_ESCI_CR12_M (0x1000)
+#define FREESCALE_ESCI_CR12_WAKE (0x0800)
+#define FREESCALE_ESCI_CR12_ILT (0x0400)
+#define FREESCALE_ESCI_CR12_PE (0x0200)
+#define FREESCALE_ESCI_CR12_PT (0x0100)
+#define FREESCALE_ESCI_CR12_TIE (0x0080)
+#define FREESCALE_ESCI_CR12_TCIE (0x0040)
+#define FREESCALE_ESCI_CR12_RIE (0x0020)
+#define FREESCALE_ESCI_CR12_ILIE (0x0010)
+#define FREESCALE_ESCI_CR12_TE (0x0008)
+#define FREESCALE_ESCI_CR12_RE (0x0004)
+#define FREESCALE_ESCI_CR12_RWU (0x0002)
+#define FREESCALE_ESCI_CR12_SBK (0x0001)
+
+#define FREESCALE_ESCI_CR3_MDIS (0x80)
+#define FREESCALE_ESCI_CR3_FBR (0x40)
+#define FREESCALE_ESCI_CR3_BSTP (0x20)
+#define FREESCALE_ESCI_CR3_IEBERR (0x10)
+#define FREESCALE_ESCI_CR3_RXDMA (0x08)
+#define FREESCALE_ESCI_CR3_TXDMA (0x04)
+#define FREESCALE_ESCI_CR3_BRK13 (0x02)
+#define FREESCALE_ESCI_CR3_TXDIR (0x01)
+
+#define FREESCALE_ESCI_SR_TDRE (0x8000)
+#define FREESCALE_ESCI_SR_TC (0x4000)
+#define FREESCALE_ESCI_SR_RDRF (0x2000)
+#define FREESCALE_ESCI_SR_IDLE (0x1000)
+#define FREESCALE_ESCI_SR_OR (0x0800)
+#define FREESCALE_ESCI_SR_NF (0x0400)
+#define FREESCALE_ESCI_SR_FE (0x0200)
+#define FREESCALE_ESCI_SR_PF (0x0100)
+#define FREESCALE_ESCI_SR_BERR (0x0010)
+#define FREESCALE_ESCI_SR_RAF (0x0001)
+
+#endif // CYGONCE_DEVS_SERIAL_FREESCALE_ESCI_H
+// EOF ser_esci.h
--- /dev/null
+2008-04-06 Steven Clugston <steven.clugston@ncl.ac.uk>
+
+ * Refactored cme555 package to more generic mpc555
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_powerpc_cme555.cdl: Remove irrelevant doc link.
+
+2002-11-11 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * src/cme555_serial_with_ints.c:
+ interrupt arbiter slightly modified to make GDB CTRL-C work
+
+2002-04-24 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * New package.
+
+//===========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# ser_powerpc_mpc555.cdl
+#
+# eCos serial PowerPC/mpc555 configuration data
+#
+# ====================================================================
+#####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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Original data:
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_MPC555 {
+ display "mpc555 PowerPC serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_MPC555
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ mpc555 mpc555 development board."
+
+ compile -library=libextras.a mpc555_serial_with_ints.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_mpc555.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A {
+ display "mpc555 PowerPC serial port A driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the mpc555
+ PowerPC port A."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_NAME {
+ display "Device name for mpc555 PowerPC serial port A"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the mpc555 PowerPC
+ port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD {
+ display "Baud rate for the mpc555 PowerPC serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ mpc555 PowerPC port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE {
+ display "Buffer size for the mpc555 PowerPC serial port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the mpc555 PowerPC port A."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B {
+ display "mpc555 PowerPC serial port B driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the mpc555
+ PowerPC port B."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_B_NAME {
+ display "Device name for mpc555 PowerPC serial port B"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the mpc555 PowerPC
+ port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BAUD {
+ display "Baud rate for the mpc555 PowerPC serial port B driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ mpc555 PowerPC port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE {
+ display "Buffer size for the mpc555 PowerPC serial port B driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the mpc555 PowerPC port B."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC555_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC555_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC555_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+}
+
+# EOF ser_powerpc_mpc555.cdl
--- /dev/null
+#ifndef CYGONCE_DEVS_SERIAL_POWERPC_MPC555_SERIAL_H
+#define CYGONCE_DEVS_SERIAL_POWERPC_MPC555_SERIAL_H
+//==========================================================================
+//
+// mpc555_serial.h
+//
+// PowerPC 5xx MPC555 Serial I/O definitions.
+//
+//==========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors:
+// Date: 2002-04-25
+// Purpose: MPC555 Serial I/O definitions.
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+//----------------------------------
+// Includes and forward declarations
+//----------------------------------
+
+//----------------------
+// Constants definitions
+//----------------------
+// Base addresses for the two serial ports
+#define MPC555_SERIAL_BASE_A 0x305008
+#define MPC555_SERIAL_BASE_B 0x305020
+
+// The offset from the base for all serial registers
+#define MPC555_SERIAL_SCCxR0 0
+#define MPC555_SERIAL_SCCxR1 2
+#define MPC555_SERIAL_SCxSR 4
+#define MPC555_SERIAL_SCxDR 6
+
+// The bits in the serial registers
+#define MPC555_SERIAL_SCCxR0_OTHR 0x8000
+#define MPC555_SERIAL_SCCxR0_LINKBD 0x4000
+#define MPC555_SERIAL_SCCxR0_SCxBR 0x1fff
+
+#define MPC555_SERIAL_SCCxR1_LOOPS 0x4000
+#define MPC555_SERIAL_SCCxR1_WOMS 0x2000
+#define MPC555_SERIAL_SCCxR1_ILT 0x1000
+#define MPC555_SERIAL_SCCxR1_PT 0x0800
+#define MPC555_SERIAL_SCCxR1_PE 0x0400
+#define MPC555_SERIAL_SCCxR1_M 0x0200
+#define MPC555_SERIAL_SCCxR1_WAKE 0x0100
+#define MPC555_SERIAL_SCCxR1_TIE 0x0080
+#define MPC555_SERIAL_SCCxR1_TCIE 0x0040
+#define MPC555_SERIAL_SCCxR1_RIE 0x0020
+#define MPC555_SERIAL_SCCxR1_ILIE 0x0010
+#define MPC555_SERIAL_SCCxR1_TE 0x0008
+#define MPC555_SERIAL_SCCxR1_RE 0x0004
+#define MPC555_SERIAL_SCCxR1_RWU 0x0002
+#define MPC555_SERIAL_SCCxR1_SBK 0x0001
+
+#define MPC555_SERIAL_SCxSR_TDRE 0x0100
+#define MPC555_SERIAL_SCxSR_TC 0x0080
+#define MPC555_SERIAL_SCxSR_RDRF 0x0040
+#define MPC555_SERIAL_SCxSR_RAF 0x0020
+#define MPC555_SERIAL_SCxSR_IDLE 0x0010
+#define MPC555_SERIAL_SCxSR_OR 0x0008
+#define MPC555_SERIAL_SCxSR_NF 0x0004
+#define MPC555_SERIAL_SCxSR_FE 0x0002
+#define MPC555_SERIAL_SCxSR_PF 0x0001
+
+// The available baud rates
+// These are calculated for a busclock of 40 MHz
+// It is not necessary to let the compiler calculate these
+// values, we did not provide clockfrequency as a configuarion
+// option anyway.
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50 bps unsupported
+ 0, // 75 bps unsupported
+ 0, // 110 bps unsupported
+ 0, // 134_5 bps unsupported
+ 0, // 150 bps unsupported
+ 0, // 200 bps unsupported
+ 4167, // 300 bps
+ 2083, // 600 bps
+ 1042, // 1200 bps
+ 0, // 1800 bps unsupported
+ 521, // 2400 bps
+ 0, // 3600 bps unsupported
+ 260, // 4800 bps
+ 0, // 7200 bps unsupported
+ 130, // 9600 bps
+ 87, // 14400 bps
+ 65, // 19200 bps
+ 33, // 38400 bps
+ 22, // 57600 bps
+ 11, // 115200 bps
+ 0 // 230400 bps unsupported
+};
+
+static unsigned char select_word_length[] = {
+ 0, // 5 bits / word (char) not supported
+ 0, // 6 bits / word (char) not supported
+ 7, // 7 bits / word (char) ->> 7 bits per frame
+ 8 // 8 bits / word (char) ->> 8 bits per frame
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ 1, // 1 stop bit ->> 1 bit per frame
+ 0, // 1.5 stop bit not supported
+ 2 // 2 stop bits ->> 2 bits per frame
+};
+
+static unsigned char select_parity[] = {
+ 0, // No parity ->> 0 bits per frame
+ 1, // Even parity ->> 1 bit per frame
+ 1, // Odd parityv ->> 1 bit per frame
+ 0, // Mark parity not supported
+ 0, // Space parity not supported
+};
+
+#endif // CYGONCE_DEVS_SERIAL_POWERPC_MPC555_SERIAL_H
+
+// EOF mpc555_serial.h
--- /dev/null
+//==========================================================================
+//
+// mpc555_serial_with_ints.c
+//
+// PowerPC 5xx MPC555 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors:
+// Date: 2002-04-25
+// Purpose: MPC555 Serial I/O module (interrupt driven version)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+//----------------------------------
+// Includes and forward declarations
+//----------------------------------
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arbiter.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+// Only build this driver for the MPC555 based boards
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555
+
+#include "mpc555_serial.h"
+
+//-----------------
+// Type definitions
+//-----------------
+typedef struct mpc555_serial_info {
+ CYG_ADDRWORD base; // The base address of the serial port
+ CYG_WORD tx_interrupt_num; // trivial
+ CYG_WORD rx_interrupt_num; // trivial
+ cyg_priority_t tx_interrupt_priority; // trivial
+ cyg_priority_t rx_interrupt_priority; // trivial
+ bool tx_interrupt_enable; // tells if the transmit interrupt may be re-enabled
+ cyg_interrupt tx_interrupt; // the tx interrupt object
+ cyg_handle_t tx_interrupt_handle; // the tx interrupt handle
+ cyg_interrupt rx_interrupt; // the rx interrupt object
+ cyg_handle_t rx_interrupt_handle; // the rx interrupt handle
+} mpc555_serial_info;
+
+//--------------------
+// Function prototypes
+//--------------------
+static bool mpc555_serial_init(struct cyg_devtab_entry * tab);
+static bool mpc555_serial_putc(serial_channel * chan, unsigned char c);
+static Cyg_ErrNo mpc555_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name);
+static unsigned char mpc555_serial_getc(serial_channel *chan);
+static Cyg_ErrNo mpc555_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void mpc555_serial_start_xmit(serial_channel *chan);
+static void mpc555_serial_stop_xmit(serial_channel *chan);
+
+// The interrupt servers
+static cyg_uint32 mpc555_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static cyg_uint32 mpc555_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void mpc555_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static void mpc555_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+//-------------------------------------------
+// Register the device driver with the kernel
+//-------------------------------------------
+static SERIAL_FUNS(mpc555_serial_funs,
+ mpc555_serial_putc,
+ mpc555_serial_getc,
+ mpc555_serial_set_config,
+ mpc555_serial_start_xmit,
+ mpc555_serial_stop_xmit);
+
+//-------------------
+// Device driver data
+//-------------------
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+static mpc555_serial_info mpc555_serial_info0 = {MPC555_SERIAL_BASE_A,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI0_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI0_RX_PRIORITY,
+ false};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE > 0
+static unsigned char mpc555_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE];
+static unsigned char mpc555_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc555_serial_channel0,
+ mpc555_serial_funs,
+ mpc555_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc555_serial_out_buf0[0],
+ sizeof(mpc555_serial_out_buf0),
+ &mpc555_serial_in_buf0[0],
+ sizeof(mpc555_serial_in_buf0));
+#else
+static SERIAL_CHANNEL(mpc555_serial_channel0,
+ mpc555_serial_funs,
+ mpc555_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(mpc555_serial_io0,
+ CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ mpc555_serial_init,
+ mpc555_serial_lookup,
+ &mpc555_serial_channel0);
+#endif // ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B
+static mpc555_serial_info mpc555_serial_info1 = {MPC555_SERIAL_BASE_B,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX_PRIORITY,
+ false};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE > 0
+static unsigned char mpc555_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE];
+static unsigned char mpc555_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc555_serial_channel1,
+ mpc555_serial_funs,
+ mpc555_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc555_serial_out_buf1[0],
+ sizeof(mpc555_serial_out_buf1),
+ &mpc555_serial_in_buf1[0],
+ sizeof(mpc555_serial_in_buf1));
+#else
+static SERIAL_CHANNEL(mpc555_serial_channel1,
+ mpc555_serial_funs,
+ mpc555_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(mpc555_serial_io1,
+ CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_B_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ mpc555_serial_init,
+ mpc555_serial_lookup,
+ &mpc555_serial_channel1);
+#endif // ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B
+
+//-----------------------------
+// Device driver implementation
+//-----------------------------
+
+// The arbitration isr.
+// I think this is the best place to implement it. The device driver is the only place
+// in the code where the knowledge is present about how the hardware is used
+//
+// Always check receive interrupts. Some rom monitor might be waiting for CTRL-C
+static cyg_uint32 hal_arbitration_isr_qsci(CYG_ADDRWORD a_vector, CYG_ADDRWORD a_data)
+{
+ cyg_uint16 status;
+ cyg_uint16 control;
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SC1SR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCC1R1, control);
+ if((status & CYGARC_REG_IMM_SCxSR_RDRF) && (control & CYGARC_REG_IMM_SCCxR1_RIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_RX);
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A // Do not waist time on unused hardware
+ if((status & CYGARC_REG_IMM_SCxSR_TDRE) && (control & CYGARC_REG_IMM_SCCxR1_TIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TX);
+// Don't waist time on unused interrupts
+// if((status & CYGARC_REG_IMM_SCxSR_TC) && (control & CYGARC_REG_IMM_SCCxR1_TCIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_TXC);
+// Don't waist time on unused interrupts
+// if((status & CYGARC_REG_IMM_SCxSR_IDLE) && (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI0_IDLE);
+#endif
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SC2SR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCC2R1, control);
+ if((status & CYGARC_REG_IMM_SCxSR_RDRF) && (control & CYGARC_REG_IMM_SCCxR1_RIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX);
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B // Do not waist time on unused hardware
+ if((status & CYGARC_REG_IMM_SCxSR_TDRE) && (control & CYGARC_REG_IMM_SCCxR1_TIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX);
+// Don't waist time on unused interrupts
+// if((status & CYGARC_REG_IMM_SCxSR_TC) && (control & CYGARC_REG_IMM_SCCxR1_TCIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXC);
+// Don't waist time on unused interrupts
+// if((status & CYGARC_REG_IMM_SCxSR_IDLE) && (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_IDLE);
+
+#if 0
+ // The driver doesn't use the queue operation of the hardware (It would need different code for serial 1 and 2
+ // since oly one port supports queue mode). So the following is not needed.
+ // Leave it there. It is easyer for later implementations to remove the comments than finding
+ // out how the hardware works again.
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1SR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1CR, control);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QTHF) && (control & CYGARC_REG_IMM_QSCI1CR_QTHFI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQTHF);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QBHF) && (control & CYGARC_REG_IMM_QSCI1CR_QBHFI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQBHF);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QTHE) && (control & CYGARC_REG_IMM_QSCI1CR_QTHEI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQTHE);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QBHE) && (control & CYGARC_REG_IMM_QSCI1CR_QBHEI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQBHE);
+
+ cyg_uint16 status;
+ cyg_uint16 control;
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SPSR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_SPCR2, control);
+ if((status & CYGARC_REG_IMM_SPSR_SPIF) && (control & CYGARC_REG_IMM_SPCR2_SPIFIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SPI_FI);
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SPCR3, control);
+ if((status & CYGARC_REG_IMM_SPSR_MODF) && (control & CYGARC_REG_IMM_SPCR3_HMIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SPI_MODF);
+
+ if((status & CYGARC_REG_IMM_SPSR_HALTA) && (control & CYGARC_REG_IMM_SPCR3_HMIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SPI_HALTA);
+#endif
+
+#endif
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------------
+// Internal function to actually configure the hardware to desired baud rate, etc.
+//--------------------------------------------------------------------------------
+static bool mpc555_serial_config_port(serial_channel * chan, cyg_serial_info_t * new_config, bool init)
+{
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)(chan->dev_priv);
+
+ cyg_addrword_t port = mpc555_chan->base;
+ cyg_uint16 baud_rate = select_baud[new_config->baud];
+ unsigned char frame_length = 1; // The start bit
+
+ cyg_uint16 old_isrstate;
+ cyg_uint16 sccxr;
+
+ if(!baud_rate)
+ return false; // Invalid baud rate selected
+
+ if((new_config->word_length != CYGNUM_SERIAL_WORD_LENGTH_7) &&
+ (new_config->word_length != CYGNUM_SERIAL_WORD_LENGTH_8))
+ return false; // Invalid word length selected
+
+ if((new_config->parity != CYGNUM_SERIAL_PARITY_NONE) &&
+ (new_config->parity != CYGNUM_SERIAL_PARITY_EVEN) &&
+ (new_config->parity != CYGNUM_SERIAL_PARITY_ODD))
+ return false; // Invalid parity selected
+
+ if((new_config->stop != CYGNUM_SERIAL_STOP_1) &&
+ (new_config->stop != CYGNUM_SERIAL_STOP_2))
+ return false; // Invalid stop bits selected
+
+ frame_length += select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+ frame_length += select_stop_bits[new_config->stop];
+ frame_length += select_parity[new_config->parity];
+
+ if((frame_length != 10) && (frame_length != 11))
+ return false; // Invalid frame format selected
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ old_isrstate = sccxr;
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_LOOPS);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_WOMS);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_ILT);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PT);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_M);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_WAKE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_TE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_RE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_RWU);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_SBK);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_TIE);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_TCIE);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_RIE);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_ILIE);
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ // Set databits, stopbits and parity.
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ if(frame_length == 11)
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_M;
+ else
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_M);
+
+ switch(new_config->parity)
+ {
+ case CYGNUM_SERIAL_PARITY_NONE:
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PE);
+ break;
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_PE;
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PT);
+ break;
+ case CYGNUM_SERIAL_PARITY_ODD:
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_PE;
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_PT;
+ break;
+ default:
+ break;
+ }
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ // Set baud rate.
+ baud_rate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR0_OTHR);
+ baud_rate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR0_LINKBD);
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR0, sccxr);
+ sccxr &= ~(MPC555_SERIAL_SCCxR0_SCxBR);
+ sccxr |= baud_rate;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR0, sccxr);
+
+ // Enable the device
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ sccxr |= MPC555_SERIAL_SCCxR1_TE;
+ sccxr |= MPC555_SERIAL_SCCxR1_RE;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ if(init)
+ { // enable the receiver interrupt
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ sccxr |= MPC555_SERIAL_SCCxR1_RIE;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ }
+ else // Restore the old interrupt state
+ {
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ sccxr |= old_isrstate;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ }
+
+ if(new_config != &chan->config)
+ chan->config = *new_config;
+
+ return true;
+}
+
+//--------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+//--------------------------------------------------------------
+static hal_mpc5xx_arbitration_data arbiter;
+
+static bool mpc555_serial_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel * chan = (serial_channel *)tab->priv;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ if(!mpc555_serial_config_port(chan, &chan->config, true))
+ return false;
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if(chan->out_cbuf.len != 0)
+ {
+ arbiter.priority = CYGNUM_HAL_ISR_SOURCE_PRIORITY_QSCI;
+ arbiter.data = 0;
+ arbiter.arbiter = hal_arbitration_isr_qsci;
+
+ // Install the arbitration isr, Make sure that is is not installed twice
+ hal_mpc5xx_remove_arbitration_isr(CYGNUM_HAL_ISR_SOURCE_PRIORITY_QSCI);
+ hal_mpc5xx_install_arbitration_isr(&arbiter);
+
+ // Create the Tx interrupt, do not enable it yet
+ cyg_drv_interrupt_create(mpc555_chan->tx_interrupt_num,
+ mpc555_chan->tx_interrupt_priority,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ mpc555_serial_tx_ISR,
+ mpc555_serial_tx_DSR,
+ &mpc555_chan->tx_interrupt_handle,
+ &mpc555_chan->tx_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->tx_interrupt_handle);
+
+ // Create the Rx interrupt, this can be safely unmasked now
+ cyg_drv_interrupt_create(mpc555_chan->rx_interrupt_num,
+ mpc555_chan->rx_interrupt_priority,
+ (cyg_addrword_t)chan,
+ mpc555_serial_rx_ISR,
+ mpc555_serial_rx_DSR,
+ &mpc555_chan->rx_interrupt_handle,
+ &mpc555_chan->rx_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_num);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+//----------------------------------------------------------------------
+static Cyg_ErrNo mpc555_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name)
+{
+ serial_channel * chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+
+ return ENOERR;
+}
+
+//----------------------------------------------
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+//----------------------------------------------
+static bool mpc555_serial_putc(serial_channel * chan, unsigned char c)
+{
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mpc555_chan->base;
+
+ cyg_uint16 scsr;
+ cyg_uint16 scdr;
+
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ if(scsr & MPC555_SERIAL_SCxSR_TDRE)
+ { // Ok, we have space, write the character and return success
+ scdr = (cyg_uint16)c;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+ return true;
+ }
+ else
+ // We cannot write to the transmitter, return failure
+ return false;
+}
+
+//---------------------------------------------------------------------
+// Fetch a character from the device input buffer, waiting if necessary
+//---------------------------------------------------------------------
+static unsigned char mpc555_serial_getc(serial_channel * chan)
+{
+ unsigned char c;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mpc555_chan->base;
+
+ cyg_uint16 scsr;
+ cyg_uint16 scdr;
+
+ do {
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ } while(!(scsr & MPC555_SERIAL_SCxSR_RDRF));
+
+ // Ok, data is received, read it out and return
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+ c = (unsigned char)scdr;
+
+ return c;
+}
+
+//---------------------------------------------------
+// Set up the device characteristics; baud rate, etc.
+//---------------------------------------------------
+static bool mpc555_serial_set_config(serial_channel * chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 * len)
+{
+ switch(key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if(*len < sizeof(cyg_serial_info_t)) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if(true != mpc555_serial_config_port(chan, config, false))
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------
+// Enable the transmitter on the device
+//-------------------------------------
+static void mpc555_serial_start_xmit(serial_channel * chan)
+{
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ mpc555_chan->tx_interrupt_enable = true;
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_num);
+
+ // No need to call xmt_char, this will generate an interrupt immediately.
+}
+
+//--------------------------------------
+// Disable the transmitter on the device
+//--------------------------------------
+static void mpc555_serial_stop_xmit(serial_channel * chan)
+{
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_dsr_lock();
+ mpc555_chan->tx_interrupt_enable = false;
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_num);
+ cyg_drv_dsr_unlock();
+}
+
+//-----------------------------------------
+// The low level transmit interrupt handler
+//-----------------------------------------
+static cyg_uint32 mpc555_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->tx_interrupt_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+//----------------------------------------
+// The low level receive interrupt handler
+//----------------------------------------
+static cyg_uint32 mpc555_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->rx_interrupt_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->rx_interrupt_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+//------------------------------------------
+// The high level transmit interrupt handler
+//------------------------------------------
+static void mpc555_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ (chan->callbacks->xmt_char)(chan);
+ if(mpc555_chan->tx_interrupt_enable)
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_num);
+}
+
+//-----------------------------------------
+// The high level receive interrupt handler
+//-----------------------------------------
+#define MPC555_SERIAL_SCxSR_ERRORS (MPC555_SERIAL_SCxSR_OR | \
+ MPC555_SERIAL_SCxSR_NF | \
+ MPC555_SERIAL_SCxSR_FE | \
+ MPC555_SERIAL_SCxSR_PF)
+
+static void mpc555_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mpc555_chan->base;
+ cyg_uint16 scdr;
+ cyg_uint16 scsr;
+
+ // Allways read out the received character, in order to clear receiver flags
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ if(scsr & (cyg_uint16)MPC555_SERIAL_SCxSR_ERRORS)
+ {
+ scsr &= ~((cyg_uint16)MPC555_SERIAL_SCxSR_ERRORS);
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ }
+ else
+ {
+ (chan->callbacks->rcv_char)(chan, (cyg_uint8)scdr);
+ }
+
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC555
+
+// EOF mpc555_serial_with_ints.c
--- /dev/null
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip SPI units
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# spi_lpc2xxx.cdl
+#
+# SPI driver for LPC2xxx
+#
+# ====================================================================
+#####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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:
+# Date: 2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_SPI_ARM_LPC2XXX {
+ display "LPC2xxx SPI driver"
+ requires CYGPKG_HAL_ARM_LPC2XXX
+
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+
+ include_dir cyg/io
+ compile spi_lpc2xxx.cxx
+
+ cdl_option CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0 {
+ display "Enable SPI interface 0"
+ flavor bool
+ default_value 1
+ description "The LPC2xxx controllers contain two SPI interfaces.
+ Enable this option to get support for SPI interface 0."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1 {
+ display "Enable SPI interface 1"
+ flavor bool
+ default_value 1
+ description "The LPC2xxx controllers contain two SPI interfaces.
+ Enable this option to get support for SPI interface 1."
+ }
+}
\ No newline at end of file
--- /dev/null
+#ifndef CYGONCE_DEVS_SPI_ARM_LPC2XXX_H
+#define CYGONCE_DEVS_SPI_ARM_LPC2XXX_H
+
+//==========================================================================
+//
+// spi_lpc2xxx.h
+//
+// SPI driver for LPC2xxx
+//
+//==========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+struct spi_dev {
+ volatile cyg_uint32 spcr;
+ volatile cyg_uint32 spsr;
+ volatile cyg_uint32 spdr;
+ volatile cyg_uint32 spccr;
+ cyg_uint32 d1, d2, d3;
+ volatile cyg_uint32 spint;
+};
+
+typedef struct {
+ cyg_spi_bus spi_bus;
+
+ cyg_interrupt spi_intr;
+ cyg_handle_t spi_hand;
+ cyg_vector_t spi_vect;
+ cyg_drv_mutex_t spi_lock;
+ cyg_drv_cond_t spi_wait;
+
+ struct spi_dev *spi_dev;
+
+ volatile cyg_uint32 count;
+ volatile const cyg_uint8 *tx;
+ volatile cyg_uint8 *rx;
+} cyg_spi_lpc2xxx_bus_t;
+
+typedef struct {
+ cyg_spi_device spi_device;
+
+ cyg_uint8 spi_cpha;
+ cyg_uint8 spi_cpol;
+ cyg_uint8 spi_lsbf;
+ cyg_uint32 spi_baud;
+
+ void (*spi_cs)(int);
+} cyg_spi_lpc2xxx_dev_t;
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+externC cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus0;
+#endif
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+externC cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus1;
+#endif
+
+#endif
--- /dev/null
+//==========================================================================
+//
+// spi_lpc2xxx.cxx
+//
+// SPI driver for LPC2xxx
+//
+//==========================================================================
+//####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): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_lpc2xxx.h>
+#include <cyg/error/codes.h>
+
+#define SPI_SPCR_SPIE 0x80
+#define SPI_SPCR_LSBF 0x40
+#define SPI_SPCR_MSTR 0x20
+#define SPI_SPCR_CPOL 0x10
+#define SPI_SPCR_CPHA 0x08
+
+#define SPI_SPSR_SPIF 0x80
+#define SPI_SPSR_WCOL 0x40
+#define SPI_SPSR_ROVR 0x20
+#define SPI_SPSR_MODF 0x10
+#define SPI_SPSR_ABRT 0x08
+
+#define SPI_SPINT 0x01
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus0;
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_lpc2xxx_dev_t, 0);
+#endif
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus1;
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_lpc2xxx_dev_t, 1);
+#endif
+
+/*
+ * Interrupt routine
+ * read & write the next byte until count reaches zero
+ */
+static cyg_uint32
+spi_lpc2xxx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ cyg_spi_lpc2xxx_bus_t *bus = (cyg_spi_lpc2xxx_bus_t *) data;
+ cyg_uint8 tmp;
+
+ tmp = bus->spi_dev->spsr;
+
+ if(tmp & SPI_SPSR_MODF)
+ bus->spi_dev->spcr = bus->spi_dev->spcr | SPI_SPCR_MSTR;
+
+ tmp = bus->spi_dev->spdr;
+
+ if(bus->count) {
+ if(bus->rx)
+ *bus->rx++ = tmp;
+ if(--bus->count) {
+ bus->spi_dev->spint = SPI_SPINT;
+ bus->spi_dev->spdr = bus->tx ? *bus->tx++ : 0;
+ cyg_drv_interrupt_acknowledge(bus->spi_vect);
+ return CYG_ISR_HANDLED;
+ }
+ }
+
+ bus->count = 0;
+ bus->tx = NULL;
+ bus->rx = NULL;
+
+ bus->spi_dev->spint = SPI_SPINT;
+ cyg_drv_interrupt_acknowledge(bus->spi_vect);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+static void
+spi_lpc2xxx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_drv_cond_signal(&((cyg_spi_lpc2xxx_bus_t *) data)->spi_wait);
+}
+
+
+/*
+ * Configure bus for a specific baud rate
+ */
+static void
+spi_lpc2xxx_baud(cyg_spi_lpc2xxx_bus_t *bus, cyg_uint32 baud)
+{
+ cyg_uint32 ccr = 8;
+
+ if(baud) {
+ ccr = (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED
+ / CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / baud;
+ if(((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED
+ / CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / ccr) > baud)
+ ccr++;
+ ccr++;
+ ccr &= 0xfe;
+ }
+
+ bus->spi_dev->spccr = ccr < 8 ? 8 : ccr;
+}
+
+/*
+ * get/set configuration
+ */
+static int
+spi_lpc2xxx_get_config(cyg_spi_device *device, cyg_uint32 key, void *buf,
+ cyg_uint32 *len)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+
+ switch(key) {
+ case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
+ if(*len == sizeof(cyg_uint32)) {
+ cyg_uint32 *b = (cyg_uint32 *) buf;
+ *b = dev->spi_baud;
+ } else return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ENOERR;
+}
+
+static int
+spi_lpc2xxx_set_config(cyg_spi_device *device, cyg_uint32 key, const void *buf,
+ cyg_uint32 *len)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+
+ switch(key) {
+ case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
+ if(*len == sizeof(cyg_uint32)) {
+ dev->spi_baud = * (cyg_uint32 *) buf;
+ spi_lpc2xxx_baud((cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus,
+ dev->spi_baud);
+ }
+ else return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ENOERR;
+}
+
+
+/*
+ * Begin transaction
+ * configure bus for device and drive CS by calling device cs() function
+ */
+static void
+spi_lpc2xxx_begin(cyg_spi_device *device)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+ cyg_spi_lpc2xxx_bus_t *bus =
+ (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+
+ cyg_uint8 cr =
+ (dev->spi_cpha ? SPI_SPCR_CPHA : 0) |
+ (dev->spi_cpol ? SPI_SPCR_CPOL : 0) |
+ (dev->spi_lsbf ? SPI_SPCR_LSBF : 0);
+
+ bus->spi_dev->spcr = SPI_SPCR_MSTR | cr;
+
+ spi_lpc2xxx_baud(bus, dev->spi_baud);
+
+ dev->spi_cs(1);
+}
+
+
+/*
+ * Transfer a buffer to a device,
+ * fill another buffer with data from the device
+ */
+static void
+spi_lpc2xxx_transfer(cyg_spi_device *device, cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8 *tx_data, cyg_uint8 *rx_data,
+ cyg_bool drop_cs)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+ cyg_spi_lpc2xxx_bus_t *bus =
+ (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+ cyg_uint8 tmp;
+
+ if(!count) return;
+
+ if(!polled) {
+ bus->count = count;
+ bus->tx = tx_data;
+ bus->rx = rx_data;
+
+ bus->spi_dev->spcr |= SPI_SPCR_SPIE;
+ bus->spi_dev->spdr = bus->tx ? *bus->tx++ : 0;
+
+ cyg_drv_mutex_lock(&bus->spi_lock);
+ cyg_drv_dsr_lock();
+ cyg_drv_interrupt_unmask(bus->spi_vect);
+ while(bus->count)
+ cyg_drv_cond_wait(&bus->spi_wait);
+ cyg_drv_interrupt_mask(bus->spi_vect);
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&bus->spi_lock);
+ } else do {
+ bus->spi_dev->spdr = tx_data ? *tx_data++ : 0;
+ while(!(bus->spi_dev->spsr & SPI_SPSR_SPIF));
+ tmp = bus->spi_dev->spdr;
+ if(rx_data)
+ *rx_data++ = tmp;
+ count--;
+ } while(count);
+
+ if(drop_cs)
+ dev->spi_cs(0);
+
+ return;
+}
+
+
+/*
+ * Tick
+ */
+static void
+spi_lpc2xxx_tick(cyg_spi_device *device, cyg_bool polled, cyg_uint32 count)
+{
+ spi_lpc2xxx_transfer(device, polled, count, NULL, NULL, false);
+}
+
+
+/*
+ * End transaction
+ * disable SPI bus, drop CS, reset transfer variables
+ */
+static void
+spi_lpc2xxx_end(cyg_spi_device *device)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+ cyg_spi_lpc2xxx_bus_t *bus =
+ (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+
+ bus->spi_dev->spcr = 0;
+ dev->spi_cs(0);
+
+ bus->count = 0;
+ bus->tx = NULL;
+ bus->rx = NULL;
+}
+
+
+/*
+ * Driver & bus initialization
+ */
+static void
+spi_lpc2xxx_init_bus(cyg_spi_lpc2xxx_bus_t *bus,
+ cyg_addrword_t dev,
+ cyg_vector_t vec)
+{
+ bus->spi_bus.spi_transaction_begin = spi_lpc2xxx_begin;
+ bus->spi_bus.spi_transaction_transfer = spi_lpc2xxx_transfer;
+ bus->spi_bus.spi_transaction_tick = spi_lpc2xxx_tick;
+ bus->spi_bus.spi_transaction_end = spi_lpc2xxx_end;
+ bus->spi_bus.spi_get_config = spi_lpc2xxx_get_config;
+ bus->spi_bus.spi_set_config = spi_lpc2xxx_set_config;
+ CYG_SPI_BUS_COMMON_INIT(&bus->spi_bus);
+
+ cyg_drv_mutex_init(&bus->spi_lock);
+ cyg_drv_cond_init(&bus->spi_wait, &bus->spi_lock);
+
+ bus->spi_dev = (struct spi_dev *) dev;
+ bus->spi_vect = vec;
+ cyg_drv_interrupt_create(
+ vec, 0, (cyg_addrword_t) bus,
+ &spi_lpc2xxx_isr, &spi_lpc2xxx_dsr,
+ &bus->spi_hand, &bus->spi_intr);
+ cyg_drv_interrupt_attach(bus->spi_hand);
+}
+
+/*
+ * initialization class
+ */
+class cyg_spi_lpc2xxx_init_class {
+public:
+ cyg_spi_lpc2xxx_init_class(void) {
+ cyg_uint32 addr, tmp;
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+ addr = (CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ + CYGARC_HAL_LPC2XXX_REG_PINSEL0);
+ HAL_READ_UINT32(addr, tmp);
+ tmp |= 0x5500;
+ HAL_WRITE_UINT32(addr, tmp);
+
+ spi_lpc2xxx_init_bus(&cyg_spi_lpc2xxx_bus0,
+ CYGARC_HAL_LPC2XXX_REG_SPI0_BASE,
+ CYGNUM_HAL_INTERRUPT_SPI0);
+#endif
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+ addr = (CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ + CYGARC_HAL_LPC2XXX_REG_PINSEL1);
+ HAL_READ_UINT32(addr, tmp);
+ tmp |= 0x2a8;
+ HAL_WRITE_UINT32(addr, tmp);
+ spi_lpc2xxx_init_bus(&cyg_spi_lpc2xxx_bus1,
+ CYGARC_HAL_LPC2XXX_REG_SPI1_BASE,
+ CYGNUM_HAL_INTERRUPT_SPI1);
+#endif
+ }
+};
+
+static cyg_spi_lpc2xxx_init_class spi_lpc2xxx_init
+ CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+
--- /dev/null
+2007-11-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/usbs_at91.cdl: Fixed typos in
+ CYGNUM_DEVS_USB_AT91_GPIO_PULLUP_INVERTED and
+ CYGNUM_DEVS_USB_AT91_GPIO_READ_POWER_INVERTED. Fixing the typo.
+
+ * src/usbs_at91.c (usbs_at91_set_pullup): Change the logic so that
+ CYGNUM_DEVS_USB_AT91_GPIO_PULLUP_INVERTED does actually cause an
+ invert when set true.
+
+2006-09-07 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * cdl/usbs_at91.c: Read actual EP addresses from the EP configuartion
+ rather than relying on the order in the configuration list.
+
+2006-06-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/usbs_at91.cdl: Allow EP0 to be enabled when there are no
+ slave clients.
+
+2006-05-25 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91_data.cxx: Change the initialization priority. The
+ USB tty driver is initialized at priority CYG_INIT_IO, so the USB
+ device has to be initialized before that.
+
+2006-05-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c: Rework pullup and power dectect to use the AT91
+ GPIO macros.
+
+2006-05-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * Included into eCos anonymous CVS.
+
+ Note: There appears to be a hardware bug with OUT transfers. It
+ appears that after resetting the endpoint, the first OUT transfer
+ does not trigger a receive interrupt. The BK0 bit is not set,
+ however the number of bytes in the receiver FIFO is correct. The
+ second OUT transfer causes both BK0 and BK1 bits to be set and an
+ interrupt generated. Currently no workaround is used to correct
+ this behavoiour.
+
+2006-04-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c: Endpoint 3 can send upto 64 bytes at a time,
+ not 8.
+
+2006-04-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c (usbs_at91_control_data_sent): Send a zero byte
+ packet when the transfer is an exact multiple of the endpoint
+ buffer size.
+
+2006-04-16 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c (usbs_testing_endpoints): Added support for the
+ USB testcase framework by exporting what endpoint we have.
+ * src/usbs_at91.c (usbs_at91_control_setup): Make requests other
+ than standard requests work, eg CLASS, VENDOR etc.
+ * src/usbs_at91.c (usbs_at91_handle_reset): Configure the endpoint
+ hardware using the configuration information.
+ * src/usbs_at91.c (usbs_at91_control_data_sent): Transaction is
+ complete when the buffer is empty _and_ there is no refill
+ function defined.
+
+2006-03-10 Oliver Munz <oli@snr.ch>
+
+ * CDL-Update for PLL-Freuenzy.
+
+2006-03-06 Oliver Munz <oli@snr.ch>
+
+ * USB device driver work finished - haha.
+
+ What's missing:
+ The set_... and get_freature-host-commands are not implemented yet.
+ The dynamical configuration of the data-endpoints is not reflectet in
+ the "usbs.h" API.
+ Isochronus transfer is not implemented.
+ Polling routines are not implemented.
+ USB-Tests are not done.
+ The PowerDetectPin is not used for the state.
+ AT91SAM7X's are not supported at the moment.
+
+ But it works for me...
+
+//===========================================================================
+//####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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# usbs_at91.cdl
+#
+# USB device driver for the ATMEL AT91 family of processors.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2006 eCosCentric
+## Copyright (C) 2006 Andrew Lunn
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Oliver Munz, Andrew Lunn
+# Original data: bartv
+# Contributors:
+# Date: 2006-02-25
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_AT91 {
+ display "Atmel AT91 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_IO_USB
+ implements CYGHWR_IO_USB_SLAVE
+
+ cdl_interface CYGINT_DEVS_USB_AT91_HAS_USB {
+ description "
+ This interface is implemented by HALs for devices which have
+ the USB hardware."
+ }
+
+ description "
+ This package provides a suitable eCos device driver
+ for AT91 USB.
+ In this version the driver will support the AT91SAM7S.
+ Other AT92 devices may work, but have not been tested.
+ The Driver needs 48, 96 or 192MHz plus minus 0.25%.
+ Buffers are allocated only in the higher level. There
+ is no need to configure the endpoints in this CDL, because
+ they will be configured dynamical at the set_configuration
+ call from the host...
+ The endpoints 1..3 can be configured as bulk or interrupt
+ IN or OUT endpoint. Isochronous transfer is not supported."
+
+ cdl_component CYGFUN_DEVS_USB_AT91_EP0 {
+ display "Support the control endpoint 0"
+ flavor bool
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ requires CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE
+ requires {
+ ((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 48120000 &&
+ CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 47880000) ||
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 96240000 &&
+ CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 95760000))
+ }
+
+ active_if CYGINT_DEVS_USB_AT91_HAS_USB
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+
+ compile usbs_at91.c
+ compile -library=libextras.a usbs_at91_data.cxx
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable."
+
+ cdl_option CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN {
+ display "PIO-Pin who controls the pullup resistor"
+ flavor data
+ default_value { "AT91_GPIO_PA16" }
+ description "
+ Every GPIO pin is able to do it. If you don't need
+ a pin because your HW has the pullup fixed wired
+ then select NONE"
+ }
+
+ cdl_option CYGNUM_DEVS_USB_AT91_GPIO_SET_PULLUP_INVERTED {
+ display "Has the signal to be inverted?"
+ flavor bool
+ default_value 1
+ description "
+ This option indicates that the pullup pin should
+ be inverted. ie VDD is active, VCC is inactive. For the
+ AT91SAM7SEK it needs to be inverted, hence this default."
+ }
+
+ cdl_option CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN {
+ display "PIO-Pin who see the USB-Power"
+ flavor data
+ default_value { "AT91_GPIO_PA13"}
+ description "
+ Every GPIO pin is able to do it. If you don't need
+ a pin then select NONE"
+ }
+
+ cdl_option CYGNUM_DEVS_USB_AT91_GPIO_READ_POWER_INVERTED {
+ display "Has the signal to be inverted?"
+ flavor bool
+ default_value 0
+ description "
+ This option indicates that the power detect pin should
+ be inverted. ie VDD is active, VCC is inactive."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_AT91_DEVTAB_ENTRIES {
+ display "Provide a devtab entry for endpoints"
+ active_if CYGFUN_DEVS_USB_AT91_EP0
+ default_value 0
+ description "
+ This component controls if /dev/usb entries will be created."
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 0"
+ flavor bool
+ default_value 0
+ requires CYGPKG_IO
+ description "
+ If endpoint 0 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and ioctl calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 1"
+ flavor bool
+ default_value 1
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 2"
+ flavor bool
+ default_value 1
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 3"
+ flavor bool
+ default_value 1
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME {
+ display "Base name for devtab entries"
+ flavor data
+ default_value { "\"/dev/usbs\"" }
+ description "
+ If the uAT91 USB device driver package provides devtab
+ entries for any of the endpoints then this option gives
+ control over the names of these entries. By default the
+ endpoints will be called \"/dev/usbs0c\", \"/dev/usbs3w\"
+ and \"/dev/usbs4r\" (assuming all three endpoints are
+ enabled. The common part \"/dev/usbs\" is determined
+ by this configuration option. It may be necessary to
+ change this if there are multiple USB slave-side
+ devices on the target hardware to prevent a name clash."
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_USBS_AT91_H
+#define CYGONCE_USBS_AT91_H
+//==========================================================================
+//
+// include/usbs_at91.h
+//
+// The interface exported by the AT91 USB device driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2007 Andrew Lunn
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: bartv
+// Date: 2006-02-25
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/usb/usbs.h>
+#include <pkgconf/devs_usb_at91.h>
+
+#define AT91_USB_ENDPOINTS 4
+
+extern usbs_control_endpoint usbs_at91_ep0;
+extern usbs_rx_endpoint usbs_at91_ep1;
+extern usbs_rx_endpoint usbs_at91_ep2;
+extern usbs_rx_endpoint usbs_at91_ep3;
+
+extern void usbs_at91_endpoint_init(usbs_rx_endpoint * pep,
+ cyg_uint8 endpoint_type, cyg_bool enable);
+#endif /* CYGONCE_USBS_AT91_H */
--- /dev/null
+#ifndef CYGONCE_USBS_AT91_BITOPS_H
+#define CYGONCE_USBS_AT91_BITOPS_H
+
+//==========================================================================
+//
+// bitops.h
+//
+// Hardware Bit manipulation macros for the AT91 USB device
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002 Bart Veer
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: bartv
+// Date: 2006-02-22
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Set the given bits in a device register
+#define SET_BITS(_register_, _bits_) \
+ CYG_MACRO_START \
+ cyg_uint32 _value_; \
+ HAL_READ_UINT32(_register_, _value_); \
+ _value_ |= _bits_; \
+ HAL_WRITE_UINT32(_register_, _value_); \
+ CYG_MACRO_END
+
+// Clear the given bits in a device register
+#define CLEAR_BITS(_register_, _bits_) \
+ CYG_MACRO_START \
+ cyg_uint32 _value_; \
+ HAL_READ_UINT32(_register_, _value_); \
+ _value_ &= ~_bits_; \
+ HAL_WRITE_UINT32(_register_, _value_); \
+ CYG_MACRO_END
+
+#define BITS_ARE_SET(_register_, _bits) \
+ bits_are_set(_register_, _bits)
+
+#define BITS_ARE_CLEARED(_register_, _bits) \
+ bits_are_cleared(_register_, _bits)
+
+static inline cyg_bool
+bits_are_set (cyg_addrword_t addr, cyg_uint32 bits)
+{
+ cyg_uint32 read;
+
+ HAL_READ_UINT32 (addr, read);
+
+ return (read & bits) == bits;
+}
+
+static inline cyg_bool
+bits_are_cleared (cyg_addrword_t addr, cyg_uint32 bits)
+{
+ cyg_uint32 read;
+
+ HAL_READ_UINT32 (addr, read);
+
+ return (read | ~bits) == ~bits;
+}
+
+
+#endif // CYGONCE_USBS_AT91_BITOPS_H
+
--- /dev/null
+//==========================================================================
+//
+// usbs_at91.c
+//
+// Driver for the AT91 USB device
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric
+// Copyright (C) 2006 Andrew Lunn
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz,
+// Contributors: Andrew Lunn, bartv
+// Date: 2006-02-22
+//
+// This code implements support for the on-chip USB port on the AT91
+// family of processors. The code has been developed on the AT91SAM7S
+// and may or may not work on other members of the AT91 family.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/devs_usb_at91.h>
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+#include <cyg/io/usb/usbs_at91.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include "bitops.h"
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define AT91_UDP_CSR0 (AT91_UDP_CSR)
+#define AT91_UDP_FDR0 (AT91_UDP_FDR)
+
+#define pIER (AT91_UDP + AT91_UDP_IER)
+#define pIDR (AT91_UDP + AT91_UDP_IDR)
+#define pISR (AT91_UDP + AT91_UDP_ISR)
+#define pIMR (AT91_UDP + AT91_UDP_IMR)
+#define pICR (AT91_UDP + AT91_UDP_ICR)
+
+#define pCSR0 (AT91_UDP + AT91_UDP_CSR0)
+#define pFDR0 (AT91_UDP + AT91_UDP_FDR0)
+
+#define pCSRn(N) (pCSR0 + (N * 4))
+#define pFDRn(N) (pFDR0 + (N * 4))
+
+#define AT91_UDP_ALLOWED_IRQs \
+ (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
+ AT91_UDP_RXRSM | AT91_UDP_RXSUSP | AT91_UDP_EPINT0 | \
+ AT91_UDP_EPINT1 | AT91_UDP_EPINT2 | AT91_UDP_EPINT3)
+
+#define THERE_IS_A_NEW_PACKET_IN_THE_UDP 0xffff
+
+// Fifo size for each end point.
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+ 8,
+ 64,
+ 64,
+ 64,
+};
+
+// Does an endpoint support ping pong buffering?
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+ false,
+ true,
+ true,
+ false
+};
+
+static cyg_uint8 *usbs_at91_endpoint_pbegin[AT91_USB_ENDPOINTS] =
+ { 0, 0, 0, 0 };
+static cyg_uint8 *usbs_at91_endpoint_pend[AT91_USB_ENDPOINTS] =
+ { 0, 0 ,0, 0 };
+static bool usbs_at91_endpoint_bank1[AT91_USB_ENDPOINTS] =
+ { false, false, false, false };
+static cyg_uint16 usbs_at91_endpoint_bytes_in_fifo[AT91_USB_ENDPOINTS] =
+ { 0, 0, 0, 0 };
+static cyg_uint16 usbs_at91_endpoint_bytes_received[AT91_USB_ENDPOINTS] =
+ { THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+ THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP};
+
+static cyg_interrupt usbs_at91_intr_data;
+static cyg_handle_t usbs_at91_intr_handle;
+
+static void usbs_at91_ep0_start(usbs_control_endpoint *);
+static void usbs_at91_poll(usbs_control_endpoint *);
+
+static void usbs_at91_endpoint_start(usbs_rx_endpoint * pep);
+static void usbs_at91_endpoint_set_halted(usbs_rx_endpoint * pep,
+ cyg_bool new_value);
+void usbs_at91_endpoint_init(usbs_rx_endpoint * pep,
+ cyg_uint8 endpoint_type,
+ cyg_bool enable);
+
+// Endpoint 0, the control endpoint, structure.
+usbs_control_endpoint usbs_at91_ep0 = {
+ // The hardware does not distinguish between detached, attached and powered.
+ state: USBS_STATE_POWERED,
+ enumeration_data: (usbs_enumeration_data *) 0,
+ start_fn: usbs_at91_ep0_start,
+ poll_fn: usbs_at91_poll,
+ interrupt_vector: CYGNUM_HAL_INTERRUPT_UDP,
+ control_buffer: {0, 0, 0, 0, 0, 0, 0, 0},
+ state_change_fn: (void (*) (usbs_control_endpoint *,
+ void *, usbs_state_change, int)) 0,
+ state_change_data: (void *) 0,
+ standard_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ standard_control_data: (void *) 0,
+ class_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ class_control_data: (void *) 0,
+ vendor_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ vendor_control_data: (void *) 0,
+ reserved_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ reserved_control_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ fill_buffer_fn: (void (*)(usbs_control_endpoint *)) 0,
+ fill_data: (void *) 0,
+ fill_index: 0,
+ complete_fn: (usbs_control_return (*)(usbs_control_endpoint *,
+ int)) 0
+};
+
+// Endpoint 1 receive control structure
+usbs_rx_endpoint usbs_at91_ep1 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+
+// Endpoint 2 Receive control structure
+usbs_rx_endpoint usbs_at91_ep2 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+
+// Endpoint 3 Receive control structure
+usbs_rx_endpoint usbs_at91_ep3 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+
+// Array of end points. Used for translating end point pointer to an
+// end point number
+static const void *usbs_at91_endpoints[AT91_USB_ENDPOINTS] = {
+ (void *) &usbs_at91_ep0,
+ (void *) &usbs_at91_ep1,
+ (void *) &usbs_at91_ep2,
+ (void *) &usbs_at91_ep3
+};
+
+// Convert an endpoint pointer to an endpoint number, using the array
+// of endpoint structures
+static int
+usbs_at91_pep_to_number(const usbs_rx_endpoint * pep)
+{
+ int epn;
+
+ for(epn=0; epn < AT91_USB_ENDPOINTS; epn++) {
+ if (pep == usbs_at91_endpoints[epn])
+ return epn;
+ }
+ CYG_FAIL("Unknown endpoint");
+ return 0;
+}
+
+typedef enum ep0_low_level_status_t {
+ EP0_LL_IDLE = 0,
+ EP0_LL_REQUEST,
+ EP0_LL_SEND_READY,
+ EP0_LL_ACK,
+ EP0_LL_RECEIVE_READY,
+ EP0_LL_ISOERROR,
+ EP0_LL_STALL,
+ EP0_LL_SET_ADDRESS,
+} ep0_low_level_status_t;
+
+// Enable/Disable interrupts for a specific endpoint.
+static void
+usbs_at91_endpoint_interrupt_enable (cyg_uint8 epn, bool enable)
+{
+ CYG_ASSERT (epn < AT91_USB_ENDPOINTS, "Invalid endpoint");
+
+ if (enable) {
+ HAL_WRITE_UINT32 (pIER, 1 << epn);
+ } else {
+ HAL_WRITE_UINT32 (pIDR, 1 << epn);
+ }
+}
+
+static cyg_uint8 *
+read_fifo_uint8 (cyg_uint8 * pdest, cyg_addrword_t psource, cyg_uint32 size)
+{
+ cyg_uint8 *preqbyte = pdest;
+ cyg_uint8 reqbyte;
+
+ while (size--) {
+ HAL_READ_UINT8 (psource, reqbyte);
+ *preqbyte = reqbyte;
+ preqbyte++;
+ }
+
+ return preqbyte;
+}
+
+static cyg_uint8 *
+write_fifo_uint8 (cyg_addrword_t pdest, cyg_uint8 * psource,
+ cyg_uint8 * psource_end)
+{
+ cyg_uint8 *preqbyte;
+
+ for (preqbyte = psource; preqbyte < psource_end; preqbyte++) {
+ HAL_WRITE_UINT8 (pdest, (*preqbyte));
+ }
+
+ return preqbyte;
+}
+
+/* Tell the host that the device is ready to start communication */
+static void
+usbs_at91_set_pullup (bool set)
+{
+
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN_NONE
+ if (
+#ifdef CYGNUM_DEVS_USB_AT91_GPIO_SET_PULLUP_INVERTED
+ !set
+#else
+ set
+#endif
+ ) {
+ HAL_ARM_AT91_GPIO_SET(CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN);
+ } else {
+ HAL_ARM_AT91_GPIO_RESET(CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN);
+ }
+#endif
+}
+
+/* Is the USB powered? */
+bool
+usbs_at91_read_power (void)
+{
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN_NONE
+ cyg_bool state;
+
+ HAL_ARM_AT91_GPIO_GET(CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN, state);
+#ifdef CYGNUM_DEVS_USB_AT91_GPIO_READ_POWER_INVERTED
+ return !state;
+#else
+ return state;
+#endif
+#endif
+ return true;
+}
+
+// Stop all transfers that are currently active.
+static void
+usbs_end_all_transfers (usbs_control_return returncode)
+{
+ cyg_uint32 epn;
+ usbs_rx_endpoint *pep;
+
+ for (epn = 1; epn < AT91_USB_ENDPOINTS; epn++) {
+ if (BITS_ARE_SET (pIMR, 1 << epn)) {
+ // If the end point is transmitting, call the complete function
+ // to terminate to transfer
+ pep = (usbs_rx_endpoint *) usbs_at91_endpoints[epn];
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, returncode);
+ }
+ // Disable interrupts from the endpoint
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ }
+ }
+}
+
+// There has been a change in state. Update the end point.
+static void
+usbs_state_notify (usbs_control_endpoint * pcep)
+{
+ static int old_state = USBS_STATE_CHANGE_POWERED;
+ int state = pcep->state & USBS_STATE_MASK;
+
+ if (pcep->state != old_state) {
+ usbs_end_all_transfers (-EPIPE);
+ switch (state) {
+ case USBS_STATE_DETACHED:
+ case USBS_STATE_ATTACHED:
+ case USBS_STATE_POWERED:
+ // Nothing to do
+ break;
+ case USBS_STATE_DEFAULT:
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_GLB_STATE, 0);
+ break;
+ case USBS_STATE_ADDRESSED:
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_GLB_STATE, AT91_UDP_GLB_FADDEN);
+ break;
+ case USBS_STATE_CONFIGURED:
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_GLB_STATE, AT91_UDP_GLB_CONFG);
+ break;
+ default:
+ CYG_FAIL("Unknown endpoint state");
+ }
+
+ if (pcep->state_change_fn) {
+ (*pcep->state_change_fn) (pcep, 0, pcep->state, old_state);
+ }
+
+ old_state = pcep->state;
+ }
+}
+
+static usbs_control_return
+usbs_parse_host_get_command (usbs_control_endpoint * pcep)
+{
+ usbs_control_return retcode;
+ cyg_uint8 dev_req_type =
+ (((usb_devreq *) pcep->control_buffer)->type) & USB_DEVREQ_TYPE_MASK;
+
+ switch (dev_req_type) {
+ case USB_DEVREQ_TYPE_STANDARD:
+ if (!pcep->standard_control_fn) {
+ return usbs_handle_standard_control (pcep);
+ }
+
+ retcode =
+ (*pcep->standard_control_fn) (pcep, pcep->standard_control_data);
+
+ if (retcode == USBS_CONTROL_RETURN_UNKNOWN) {
+ return usbs_handle_standard_control (pcep);
+ }
+ return retcode;
+
+ case USB_DEVREQ_TYPE_CLASS:
+ if (!pcep->class_control_fn) {
+ return USBS_CONTROL_RETURN_STALL;
+ }
+ return (*pcep->class_control_fn) (pcep, pcep->class_control_data);
+
+ case USB_DEVREQ_TYPE_VENDOR:
+ if (!pcep->class_control_fn) {
+ return USBS_CONTROL_RETURN_STALL;
+ }
+ return (*pcep->class_control_fn) (pcep, pcep->vendor_control_data);
+
+ case USB_DEVREQ_TYPE_RESERVED:
+ if (!pcep->reserved_control_fn) {
+ return USBS_CONTROL_RETURN_STALL;
+ }
+ return (*pcep->reserved_control_fn) (pcep, pcep->reserved_control_data);
+ default:
+ return USBS_CONTROL_RETURN_STALL;
+ }
+}
+
+static void
+usbs_at91_endpoint_set_halted (usbs_rx_endpoint * pep, cyg_bool new_value)
+{
+ int epn = usbs_at91_pep_to_number(pep);
+ cyg_addrword_t pCSR = pCSRn(epn);
+
+ cyg_drv_dsr_lock ();
+
+ if (pep->halted != new_value) {
+ /* There is something is to do */
+ pep->halted = new_value;
+
+ if (new_value && BITS_ARE_SET (pIMR, 1 << epn)) {
+ /* Ready to transmit */
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, -EAGAIN);
+ }
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ SET_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
+ } else {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
+ }
+ }
+ cyg_drv_dsr_unlock ();
+}
+
+void
+usbs_at91_endpoint_init (usbs_rx_endpoint * pep, cyg_uint8 endpoint_type,
+ cyg_bool enable)
+{
+ int epn = usbs_at91_pep_to_number(pep);
+ cyg_addrword_t pCSR = pCSRn(epn);
+
+ CYG_ASSERT (AT91_USB_ENDPOINTS > epn, "Invalid end point");
+
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ /* Reset endpoint */
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 1 << epn);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 0);
+
+ pep->halted = false;
+
+ /* Type | In */
+ HAL_WRITE_UINT32 (pCSR, (((((cyg_uint32) endpoint_type) & 0x03) << 8) |
+ ((((cyg_uint32) endpoint_type) & 0x80) << 3)));
+
+ usbs_at91_endpoint_bytes_in_fifo[epn] = 0;
+ usbs_at91_endpoint_bytes_received[epn] = THERE_IS_A_NEW_PACKET_IN_THE_UDP;
+ usbs_at91_endpoint_bank1[epn] = false;
+
+ if (enable) {
+ SET_BITS (pCSR, AT91_UDP_CSR_EPEDS);
+ }
+}
+
+static void
+usbs_at91_handle_reset (void)
+{
+ int epn;
+ const usb_endpoint_descriptor *usb_endpoints;
+ cyg_uint8 endpoint_type;
+
+ cyg_uint8 endpoint_number;
+
+ usbs_end_all_transfers (-EPIPE);
+
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_IDR, 0xffffffff);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_ICR, 0xffffffff);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 0xffffffff);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 0x00000000);
+
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_FADDR, AT91_UDP_FADDR_FEN);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_CSR0,
+ AT91_UDP_CSR_EPEDS | AT91_UDP_CSR_EPTYPE_CTRL);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_IER, AT91_UDP_ALLOWED_IRQs);
+
+ for (epn=1; epn < AT91_USB_ENDPOINTS; epn++) {
+ usbs_at91_endpoint_init ((usbs_rx_endpoint *)usbs_at91_endpoints[epn],
+ 0, false);
+ }
+
+ // Now walk the endpoints configuring them correctly. This only
+ // works if there is one interface.
+ usb_endpoints = usbs_at91_ep0.enumeration_data->endpoints;
+
+ for (epn = 1;
+ epn <= usbs_at91_ep0.enumeration_data->total_number_endpoints;
+ epn++) {
+
+ endpoint_type = (usb_endpoints[epn-1].attributes |
+ (usb_endpoints[epn-1].endpoint &
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN ?
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN :
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT));
+ endpoint_number = usb_endpoints[epn-1].endpoint & ~(USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN);
+ if ( endpoint_number < AT91_USB_ENDPOINTS )
+ {
+ usbs_at91_endpoint_init((usbs_rx_endpoint *)usbs_at91_endpoints[endpoint_number],
+ endpoint_type,
+ true);
+ }
+ }
+}
+
+static void
+usbs_at91_ep0_start (usbs_control_endpoint * endpoint)
+{
+ usbs_at91_handle_reset ();
+
+ // If there is additional platform-specific initialization to
+ // perform, do it now. This macro can come from the platform HAL,
+ // but may not be available on all platforms.
+#ifdef AT91_USB_PLATFORM_INIT
+ AT91_USB_PLATFORM_INIT ();
+#endif
+
+ usbs_at91_set_pullup (true);
+}
+
+static void
+usbs_at91_endpoint_start (usbs_rx_endpoint * pep)
+{
+ int epn = usbs_at91_pep_to_number(pep);
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_addrword_t pFDR = pFDRn(epn);
+ cyg_uint16 space = 0;
+ cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+
+ CYG_ASSERT (pep->complete_fn, "No complete_fn()");
+
+ cyg_drv_dsr_lock ();
+ if (usbs_at91_ep0.state != USBS_STATE_CONFIGURED) {
+ /* If not configured it means there is nothing to do */
+ cyg_drv_dsr_unlock ();
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, -EPIPE);
+ }
+ return;
+ }
+
+ if (pep->halted) {
+ /* Halted means nothing to do */
+ cyg_drv_dsr_unlock ();
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, -EAGAIN);
+ }
+ return;
+ }
+
+ if (BITS_ARE_SET (pIMR, 1 << epn)) {
+ cyg_drv_dsr_unlock ();
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, -EIO);
+ }
+
+ return;
+ }
+
+ CYG_ASSERT (BITS_ARE_SET (pCSR, 1 << 9), "Wrong endpoint type");
+
+ *ppbegin = pep->buffer; /* Set the working pointers */
+ *ppend = (cyg_uint8 *) ((cyg_uint32) pep->buffer + pep->buffer_size);
+
+ if (BITS_ARE_SET (pCSR, 0x400)) { /* IN: tx_endpoint */
+ space = (cyg_uint32) * ppend - (cyg_uint32) * ppbegin;
+ if (space == endpoint_size) {
+ *ppend = *ppbegin; /* Send zero-packet */
+ }
+
+ *ppbegin =
+ write_fifo_uint8 (pFDR, *ppbegin,
+ (cyg_uint8 *) ((cyg_uint32) * ppbegin +
+ MIN (space, endpoint_size)));
+ SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY);
+
+ if (*ppend == *ppbegin) { /* Last packet ? */
+ *ppend = *ppbegin - 1; /* The packet hasn't been sent yet */
+ }
+ }
+
+ usbs_at91_endpoint_interrupt_enable (epn, true);
+
+ cyg_drv_dsr_unlock ();
+}
+
+// Perform transmit handling on an endpoint
+static bool
+usbs_at91_endpoint_isr_tx(cyg_uint8 epn)
+{
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_addrword_t pFDR = pFDRn(epn);
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+ cyg_uint32 space = 0;
+ cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];
+
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_TXCOMP);
+
+ if (BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_TXPKTRDY)) {
+ /* Ready to transmit ? */
+ if (*ppend > *ppbegin) {
+ /* Something to send */
+
+ space = (cyg_uint32) * ppend - (cyg_uint32) * ppbegin;
+ if (space == endpoint_size) {
+ *ppend = *ppbegin; /* Send zero-packet */
+ }
+
+ *ppbegin =
+ write_fifo_uint8 (pFDR, *ppbegin,
+ (cyg_uint8 *) ((cyg_uint32) * ppbegin +
+ MIN (space, endpoint_size)));
+ SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY);
+
+ if (*ppend == *ppbegin) { /* Last packet ? */
+ *ppend = *ppbegin - 1; /* The packet isn't sent yet */
+ }
+ } else {
+ if (*ppend + 1 == *ppbegin) {
+ *ppend = *ppbegin; /* Flag for DSR */
+ return true;
+ } else {
+ *ppend = *ppbegin - 1; /* Flag for zero-packet */
+ SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY); /* Send no data */
+ }
+ }
+ }
+
+ CLEAR_BITS (pCSR,
+ AT91_UDP_CSR_RX_DATA_BK0 | AT91_UDP_CSR_RX_DATA_BK1 |
+ AT91_UDP_CSR_RXSETUP | AT91_UDP_CSR_ISOERROR);
+ return false;
+}
+
+static bool
+usbs_at91_endpoint_isr_rx(cyg_uint8 epn)
+{
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_addrword_t pFDR = pFDRn(epn);
+ cyg_uint16 *pinfifo = &usbs_at91_endpoint_bytes_in_fifo[epn];
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+ cyg_uint16 *preceived = &usbs_at91_endpoint_bytes_received[epn];
+ cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];
+
+ if (*preceived == THERE_IS_A_NEW_PACKET_IN_THE_UDP) {
+ /* There is a new packet */
+ *preceived = ((*(cyg_uint32 *)pCSR) >> 16) & 0x7ff;
+ *pinfifo = *preceived;
+ }
+
+ while ((*ppbegin < *ppend) && *pinfifo) {
+ /* If we have buffer-space AND data in the FIFO */
+ HAL_READ_UINT8(pFDR, **ppbegin);
+ (*ppbegin)++;
+ (*pinfifo)--;
+ }
+
+ if (*ppbegin == *ppend) {
+ /* The buffer is full... call the DSR */
+ return true;
+ }
+
+ if (*pinfifo == 0) {
+ /* If the FIFO is empty, then we can release it */
+ if (usbs_at91_endpoint_pingpong[epn]) {
+ /* Time to clear the interrupt flag */
+
+ if (usbs_at91_endpoint_bank1[epn]) {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_RX_DATA_BK1);
+ } else {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_RX_DATA_BK0);
+ }
+ usbs_at91_endpoint_bank1[epn] = !usbs_at91_endpoint_bank1[epn];
+ } else {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_RX_DATA_BK0);
+ }
+
+ if (*preceived < endpoint_size) {
+ /* If the last packet was smaller then the endpoint-size... */
+ *ppend = *ppbegin;
+ *preceived = THERE_IS_A_NEW_PACKET_IN_THE_UDP; /* Set flag */
+
+ return true; /* We can call the completion-function in the DSR */
+ }
+
+ *preceived = THERE_IS_A_NEW_PACKET_IN_THE_UDP; /* Set flag */
+ }
+ return false;
+}
+
+// ISR for an endpoint. Handle receive and transmit interrupts.
+static bool
+usbs_at91_endpoint_isr (cyg_uint8 epn)
+{
+ cyg_addrword_t pCSR = pCSRn(epn);
+
+ CYG_ASSERT (AT91_USB_ENDPOINTS > epn && epn, "Invalid end point");
+
+ if (BITS_ARE_SET (pCSR, 0x400)) { /* IN: tx_endpoint */
+ if (usbs_at91_endpoint_isr_tx(epn))
+ return true; // Call the DSR
+ } else { /* OUT: rx_endpoint */
+ if (!BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_RX_DATA_BK0) ||
+ !BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_RX_DATA_BK1)) {
+ /* Sometime something received ? */
+ if(usbs_at91_endpoint_isr_rx(epn))
+ return true; // Call the DSR;
+ }
+
+ CLEAR_BITS (pCSR,
+ AT91_UDP_CSR_TXCOMP | AT91_UDP_CSR_RXSETUP |
+ AT91_UDP_CSR_ISOERROR);
+ }
+
+ return false;
+}
+
+// Handle a DSR for an endpoint
+static void
+usbs_at91_endpoint_dsr (cyg_uint8 epn)
+{
+ usbs_rx_endpoint *pep = (usbs_rx_endpoint *) usbs_at91_endpoints[epn];
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+
+ CYG_ASSERT (AT91_USB_ENDPOINTS > epn && epn, "Invalid end point");
+ CYG_ASSERT (pep->complete_fn, "No complete_fn()");
+
+ if (*ppend == *ppbegin) { /* Transmitted/Received ? */
+
+ pep->buffer_size = (cyg_uint32) * ppbegin - (cyg_uint32) pep->buffer;
+ if (pep->buffer_size && pep->complete_fn) {
+ if (!pep->halted) {
+ (*pep->complete_fn) (pep->complete_data, pep->buffer_size);
+ } else {
+ (*pep->complete_fn) (pep->complete_data, -EAGAIN);
+ }
+ }
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ }
+}
+
+// Handle an error condition on the control endpoint
+static ep0_low_level_status_t
+usbs_at91_control_error(ep0_low_level_status_t status)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+
+ usbs_at91_ep0.buffer_size = 0;
+ usbs_at91_ep0.fill_buffer_fn = 0;
+ usbs_at91_ep0.complete_fn = 0;
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin;
+
+ if (status == EP0_LL_IDLE) {
+ if (usbs_at91_ep0.complete_fn) {
+ (*usbs_at91_ep0.complete_fn) (&usbs_at91_ep0,
+ USBS_CONTROL_RETURN_STALL);
+ }
+ }
+
+ status = EP0_LL_IDLE;
+
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_ISOERROR | AT91_UDP_CSR_FORCESTALL);
+
+ return status;
+}
+
+// Handle a get status setup message on the control end point
+static ep0_low_level_status_t
+usbs_at91_control_setup_get_status(void)
+{
+ ep0_low_level_status_t status;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint8 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ cyg_uint16 word = 0;
+
+ status = EP0_LL_SEND_READY;
+
+ switch (recipient) {
+ case USB_DEVREQ_RECIPIENT_DEVICE:
+ case USB_DEVREQ_RECIPIENT_INTERFACE:
+ // Nothing to do
+ break;
+ case USB_DEVREQ_RECIPIENT_ENDPOINT:
+ if ((usbs_at91_ep0.state == USBS_STATE_CONFIGURED) &&
+ (req->index_lo > 0) &&
+ (req->index_lo < AT91_USB_ENDPOINTS)) {
+ cyg_uint32 CSR;
+
+ HAL_READ_UINT32(pCSRn(req->index_lo), CSR);
+ if (CSR & AT91_UDP_CSR_EPEDS) {
+ word = 1;
+ }
+ } else {
+ status = EP0_LL_STALL;
+ }
+ break;
+ default:
+ status = EP0_LL_STALL;
+ }
+
+ *ppbegin = (cyg_uint8 *)&word;
+ *ppend = *ppbegin + sizeof (word);
+ return status;
+}
+
+// Setup the begin and end pointers such that an ACK is sent
+static void
+usbs_at91_control_setup_send_ack(void)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin;
+}
+
+// Handle a get status set feature message on the control endpoint
+static ep0_low_level_status_t
+usbs_at91_control_setup_set_feature(void)
+{
+ ep0_low_level_status_t status;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint8 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ usbs_at91_control_setup_send_ack();
+ status = EP0_LL_SEND_READY;
+
+ switch(recipient) {
+ case USB_DEVREQ_RECIPIENT_DEVICE:
+ status = EP0_LL_STALL;
+ break;
+ case USB_DEVREQ_RECIPIENT_INTERFACE:
+ // Nothing to do
+ break;
+ case USB_DEVREQ_RECIPIENT_ENDPOINT:
+ if ((usbs_at91_ep0.state == USBS_STATE_CONFIGURED) &&
+ (req->index_lo > 0) &&
+ (req->index_lo < AT91_USB_ENDPOINTS)) {
+ cyg_uint32 CSR;
+
+ HAL_READ_UINT32(pCSRn(req->index_lo), CSR);
+ if (CSR & AT91_UDP_CSR_EPEDS) {
+ /* TODO */
+ }
+ } else {
+ status = EP0_LL_STALL;
+ }
+ default:
+ status = EP0_LL_STALL;
+ }
+ return status;
+}
+
+// Handle a get status clear feature message on the control endpoint
+static ep0_low_level_status_t
+usbs_at91_control_setup_clear_feature(void)
+{
+ ep0_low_level_status_t status;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint8 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ usbs_at91_control_setup_send_ack();
+ status = EP0_LL_SEND_READY;
+
+ switch (recipient) {
+ case USB_DEVREQ_RECIPIENT_DEVICE:
+ status = EP0_LL_STALL;
+ break;
+ case USB_DEVREQ_RECIPIENT_INTERFACE:
+ // Nothing to do
+ break;
+ case USB_DEVREQ_RECIPIENT_ENDPOINT:
+ if ((usbs_at91_ep0.state == USBS_STATE_CONFIGURED) &&
+ (req->index_lo > 0) &&
+ (req->index_lo < AT91_USB_ENDPOINTS)) {
+ cyg_uint32 CSR;
+
+ HAL_READ_UINT32(pCSRn(req->index_lo), CSR);
+ if (CSR & AT91_UDP_CSR_EPEDS) {
+ /* TODO */
+ }
+ } else {
+ status = EP0_LL_STALL;
+ }
+ default:
+ status = EP0_LL_STALL;
+ }
+ return status;
+}
+
+// Handle a setup message from the host
+static ep0_low_level_status_t
+usbs_at91_control_setup(ep0_low_level_status_t status)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ usb_devreq *req = (usb_devreq *) usbs_at91_ep0.control_buffer;
+ cyg_uint8 protocol;
+ cyg_uint16 length;
+ bool dev_to_host;
+ usbs_control_return usbcode;
+ bool handled = false;
+
+ usbs_at91_ep0.buffer_size = 0;
+ usbs_at91_ep0.fill_buffer_fn = 0;
+ usbs_at91_ep0.complete_fn = 0;
+
+ read_fifo_uint8 ((cyg_uint8 *)req, pFDR0, sizeof (usb_devreq));
+
+ length = (req->length_hi << 8) | req->length_lo;;
+ dev_to_host = req->type & USB_DEVREQ_DIRECTION_IN;
+
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_DTGLE);
+
+ status = EP0_LL_REQUEST;
+
+ protocol = req->type & (USB_DEVREQ_TYPE_MASK);
+
+ // Set the next transfer direction
+ if (dev_to_host) {
+ SET_BITS (pCSR0, AT91_UDP_CSR_DIR); /* Set IN direction */
+ } else {
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_DIR); /* Set OUT direction */
+ }
+
+ if (protocol == USB_DEVREQ_TYPE_STANDARD) {
+ handled = true;
+ switch (req->request) {
+ case USB_DEVREQ_GET_STATUS:
+ status = usbs_at91_control_setup_get_status();
+ break;
+ case USB_DEVREQ_SET_ADDRESS:
+ // Most of the hard work is done by the hardware. We just need
+ // to send an ACK.
+ usbs_at91_control_setup_send_ack();
+ status = EP0_LL_SEND_READY;
+ break;
+ case USB_DEVREQ_SET_FEATURE:
+ status = usbs_at91_control_setup_set_feature();
+ break;
+ case USB_DEVREQ_CLEAR_FEATURE:
+ status = usbs_at91_control_setup_clear_feature();
+ break;
+ default:
+ handled = false;
+ }
+ }
+ if ((protocol != USB_DEVREQ_TYPE_STANDARD) || !handled) {
+ // Ask the layer above to process the message
+ usbcode = usbs_parse_host_get_command (&usbs_at91_ep0);
+ usbs_at91_ep0.buffer_size = MIN (usbs_at91_ep0.buffer_size, length);
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin + usbs_at91_ep0.buffer_size; /* Ready to send... */
+
+ if (usbcode == USBS_CONTROL_RETURN_HANDLED) { /* OK */
+ if (dev_to_host) {
+ status = EP0_LL_SEND_READY;
+ } else {
+ status = EP0_LL_RECEIVE_READY;
+ }
+ } else {
+ status = EP0_LL_STALL;
+ }
+ }
+ // Clear the setup bit so indicating we have processed the message
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_RXSETUP);
+
+ return status;
+}
+
+static ep0_low_level_status_t
+usbs_at91_control_data_recv(ep0_low_level_status_t status)
+{
+ cyg_uint32 received = 0;
+ cyg_uint32 length;
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ usbs_control_return usbcode;
+
+ if (status == EP0_LL_RECEIVE_READY) {
+ received = ((*(cyg_uint32 *) pCSR0) >> 16) & 0x7ff;
+ length = MIN (received, (cyg_uint32) *ppend - (cyg_uint32) *ppbegin);
+ *ppbegin = read_fifo_uint8 (*ppbegin, pFDR0, length);
+
+ if (received < usbs_at91_endpoint_fifo_size[0]) { /* Last packet ? */
+ *ppend = *ppbegin;
+ }
+
+ if (*ppbegin == *ppend) { /* All received ? */
+ usbs_at91_ep0.buffer_size =
+ (cyg_uint32) *ppend - (cyg_uint32) usbs_at91_ep0.buffer;
+ usbcode = USBS_CONTROL_RETURN_STALL;
+
+ if (usbs_at91_ep0.complete_fn) {
+ usbcode = (*usbs_at91_ep0.complete_fn) (&usbs_at91_ep0, 0);
+ }
+
+ if (usbcode == USBS_CONTROL_RETURN_HANDLED) {
+ status = EP0_LL_SEND_READY;
+ } else {
+ status = EP0_LL_STALL;
+ }
+ }
+ }
+
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_RX_DATA_BK0);
+
+ return status;
+}
+
+static ep0_low_level_status_t
+usbs_at91_control_data_sent(ep0_low_level_status_t status)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ cyg_uint32 bytes_to_write = 0;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint16 value;
+
+ switch (status) {
+ case EP0_LL_SEND_READY:
+ if (*ppbegin == *ppend &&
+ usbs_at91_ep0.fill_buffer_fn == NULL) {
+ // All bytes are sent, send ACK
+ status = EP0_LL_ACK;
+ SET_BITS (pCSR0, AT91_UDP_CSR_TXPKTRDY); // Signal FIFO loaded
+ } else {
+ // We have more bytes to send
+ bytes_to_write =
+ MIN (*ppend - *ppbegin, usbs_at91_endpoint_fifo_size[0]);
+ *ppbegin = write_fifo_uint8 (pFDR0, *ppbegin, (cyg_uint8 *)
+ ((cyg_uint32) *ppbegin + bytes_to_write));
+ // Send next few bytes
+ if (*ppbegin == *ppend) { /* Control-Endoints don't need ACK's */
+ if (usbs_at91_ep0.fill_buffer_fn) { // More Records ?
+ (*usbs_at91_ep0.fill_buffer_fn) (&usbs_at91_ep0);
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin + usbs_at91_ep0.buffer_size;
+
+ /* Ready to send... */
+ bytes_to_write =
+ MIN (*ppend - *ppbegin,
+ usbs_at91_endpoint_fifo_size[0] - bytes_to_write);
+
+ *ppbegin = write_fifo_uint8 (pFDR0, *ppbegin, (cyg_uint8 *)
+ ((cyg_uint32) *ppbegin + bytes_to_write));
+ // Send next few bytes
+ } else {
+ if (bytes_to_write == usbs_at91_endpoint_fifo_size[0]) {
+ // Last packet is full, so we need to send a zero bytes
+ // packet next time
+ status = EP0_LL_SEND_READY;
+ } else {
+ status = EP0_LL_IDLE;
+ }
+
+ }
+ }
+ SET_BITS (pCSR0, AT91_UDP_CSR_TXPKTRDY); // Signal FIFO loaded
+ }
+ break;
+ case EP0_LL_RECEIVE_READY:
+ /* Maybe we have to send an ACK */
+ if (*ppbegin == *ppend) { // All bytes are received, send ACK
+ status = EP0_LL_ACK;
+ SET_BITS (pCSR0, AT91_UDP_CSR_TXPKTRDY); // Signal FIFO loaded
+ }
+ break;
+ case EP0_LL_ACK:
+ if (req->request == USB_DEVREQ_SET_ADDRESS) { // Special-processing
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_FADDR,
+ req->value_lo | AT91_UDP_FADDR_FEN);
+ value = (req->value_hi << 8) | req->value_lo;
+ if (value) {
+ usbs_at91_ep0.state = USBS_STATE_ADDRESSED;
+ }
+ }
+
+ if (usbs_at91_ep0.complete_fn) {
+ (*usbs_at91_ep0.complete_fn) (&usbs_at91_ep0,
+ USBS_CONTROL_RETURN_HANDLED);
+ }
+ status = EP0_LL_IDLE;
+ usbs_state_notify (&usbs_at91_ep0);
+ break;
+ default:
+ break;
+ }
+ return status;
+}
+
+static void
+usbs_at91_control_dsr (void)
+{
+ static ep0_low_level_status_t status = EP0_LL_IDLE;
+
+ while (!BITS_ARE_CLEARED(pCSR0,
+ AT91_UDP_CSR_TXCOMP | AT91_UDP_CSR_RX_DATA_BK0 |
+ AT91_UDP_CSR_RXSETUP | AT91_UDP_CSR_ISOERROR |
+ AT91_UDP_CSR_RX_DATA_BK1)) {
+
+ // Check and handle any error conditions
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_ISOERROR)) {
+ status = usbs_at91_control_error(status);
+ }
+
+ // Check for a setup message and handle it
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_RXSETUP)) {
+ status = usbs_at91_control_setup(status);
+ }
+
+ // Check for received data on the control endpoint
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_RX_DATA_BK0)) {
+ status = usbs_at91_control_data_recv(status);
+ }
+
+ // Check if the last packet has been sent
+ if (BITS_ARE_CLEARED (pCSR0, AT91_UDP_CSR_TXPKTRDY)) {
+ status = usbs_at91_control_data_sent(status);
+ }
+
+ // Received an ACK packet
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_TXCOMP)) {
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_TXCOMP);
+ }
+
+ if (status == EP0_LL_STALL) {
+ CLEAR_BITS (pCSR0, 0x7f);
+ SET_BITS (pCSR0, AT91_UDP_CSR_FORCESTALL);
+ }
+ }
+}
+
+static void
+usbs_at91_dsr (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_uint8 n;
+
+ CYG_ASSERT (CYGNUM_HAL_INTERRUPT_UDP == vector, "Wrong interrupts");
+ CYG_ASSERT (0 == data, "DSR needs no data");
+
+ CLEAR_BITS (AT91_UDP + AT91_UDP_GLB_STATE, 0x10);
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_WAKEUP)) {
+ usbs_at91_ep0.state = USBS_STATE_DEFAULT;
+ usbs_state_notify (&usbs_at91_ep0);
+
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_WAKEUP);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_ENDBUSRES)) { // RESET UDP
+ usbs_at91_ep0.state = USBS_STATE_POWERED;
+ usbs_state_notify (&usbs_at91_ep0);
+ usbs_at91_handle_reset ();
+
+ HAL_WRITE_UINT32 (pCSR0, AT91_UDP_CSR_EPEDS | AT91_UDP_CSR_EPTYPE_CTRL);
+ HAL_WRITE_UINT32 (pIER, AT91_UDP_EPINT0);
+
+ usbs_at91_ep0.state = USBS_STATE_DEFAULT;
+ usbs_state_notify (&usbs_at91_ep0);
+
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_ENDBUSRES);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_SOFINT)) {
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_SOFINT);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_EXTRSM)) {
+ usbs_at91_ep0.state = usbs_at91_ep0.state & ~USBS_STATE_SUSPENDED;
+ usbs_state_notify (&usbs_at91_ep0);
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_EXTRSM);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_RXRSM)) {
+ usbs_at91_ep0.state = usbs_at91_ep0.state & ~USBS_STATE_SUSPENDED;
+ usbs_state_notify (&usbs_at91_ep0);
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_RXRSM);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_RXSUSP)) {
+ usbs_at91_ep0.state = usbs_at91_ep0.state | USBS_STATE_SUSPENDED;
+ usbs_state_notify (&usbs_at91_ep0);
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_RXSUSP);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_EPINT0)) {
+ usbs_at91_control_dsr ();
+ }
+
+ for (n = 1; n < AT91_USB_ENDPOINTS; n++) {
+ if (*(cyg_uint32 *) pIMR & (1 << n)) {
+ usbs_at91_endpoint_dsr (n);
+ }
+ }
+
+ cyg_drv_interrupt_unmask (vector);
+}
+
+static cyg_uint32
+usbs_at91_isr (cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_uint8 n;
+ bool need_dsr = false;
+ cyg_uint32 IMR;
+ cyg_uint32 ISR;
+
+ CYG_ASSERT (CYGNUM_HAL_INTERRUPT_UDP == vector, "Wrong interrupts");
+ CYG_ASSERT (0 == data, "ISR needs no data");
+
+ HAL_READ_UINT32(pIMR, IMR);
+ HAL_READ_UINT32(pISR, ISR);
+
+ for (n = 1; n < AT91_USB_ENDPOINTS; n++) {
+ /* Do any data endpoint need a data transfer ? */
+ if (IMR & ISR & (1 << n)) {
+ need_dsr = usbs_at91_endpoint_isr (n) || need_dsr;
+ }
+ }
+ /* If we don't need any DSR re-enable interrupts and finish */
+ if (BITS_ARE_CLEARED (pISR, AT91_UDP_ALLOWED_IRQs & 0xffffff01)
+ && !need_dsr) {
+ cyg_drv_interrupt_acknowledge (vector);
+ return CYG_ISR_HANDLED;
+ }
+
+ /* Call the DSR */
+ cyg_drv_interrupt_mask (vector);
+ cyg_drv_interrupt_acknowledge (vector);
+
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// Polling support. It is not clear that this is going to work particularly
+// well since according to the documentation the hardware does not generate
+// NAKs automatically - instead the ISR has to set the appropriate bits
+// sufficiently quickly to avoid confusing the host.
+//
+// Calling the isr directly avoids duplicating code, but means that
+// cyg_drv_interrupt_acknowledge() will get called when not inside a
+// real interrupt handler. This should be harmless.
+
+static void
+usbs_at91_poll (usbs_control_endpoint * endpoint)
+{
+ CYG_ASSERT (endpoint == &usbs_at91_ep0, "Wrong endpoint");
+ if (CYG_ISR_CALL_DSR == usbs_at91_isr (CYGNUM_HAL_INTERRUPT_UDP, 0)) {
+ usbs_at91_dsr (CYGNUM_HAL_INTERRUPT_UDP, 0, 0);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Initialization
+//
+// This routine gets called from a prioritized static constructor during
+// eCos startup.
+
+void
+usbs_at91_init (void)
+{
+
+ cyg_uint32 reg;
+
+ HAL_READ_UINT32 (AT91_PMC + AT91_PMC_PLLR, reg);
+
+ /* Set USB divider so we have a 48MHz clock */
+#if ((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 48120000) && \
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 47880000))
+
+ // 48MHz clock, divider set to 1
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_PLLR,
+ (reg & 0x0fffffff) | AT91_PMC_PLLR_USBDIV_1);
+
+#elif ((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 96240000) && \
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 95760000))
+
+ // 96MHz clock, divider set to 2
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_PLLR,
+ (reg & 0x0fffffff) | AT91_PMC_PLLR_USBDIV_2);
+#else
+#error CYGNUM_HAL_ARM_AT91_CLOCK_SPEED is not 48, 96 or 192MHz plusminus 0.25% ...
+#endif
+
+ /* Enable USB clock */
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_SCER, AT91_PMC_SCER_UDP);
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_UDP);
+
+ usbs_at91_set_pullup (false);
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN_NONE
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN,
+ AT91_PIN_OUT);
+#endif
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN_NONE
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN,
+ AT91_PIN_IN);
+#endif
+ usbs_at91_handle_reset ();
+
+ cyg_drv_interrupt_create (CYGNUM_HAL_INTERRUPT_UDP,
+ 6, // priority
+ 0, // data
+ &usbs_at91_isr,
+ &usbs_at91_dsr,
+ &usbs_at91_intr_handle, &usbs_at91_intr_data);
+
+ cyg_drv_interrupt_attach (usbs_at91_intr_handle);
+ cyg_drv_interrupt_unmask (CYGNUM_HAL_INTERRUPT_UDP);
+
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_TXVC, 0);
+
+ usbs_at91_ep0.state = USBS_STATE_POWERED;
+ usbs_state_notify (&usbs_at91_ep0);
+}
+
+// ----------------------------------------------------------------------------
+// Testing support.
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &usbs_at91_ep0,
+#ifdef CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "0c",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1, // zero-byte control transfers are meaningless
+ max_size : 0x0FFFF, // limit imposed by protocol
+ max_in_padding : 0,
+ alignment : 0
+ },
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &usbs_at91_ep1,
+#ifdef CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "1r",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 0,
+ alignment : 0
+ },
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &usbs_at91_ep2,
+#ifdef CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "2w",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 1, // hardware limitation
+ alignment : 0
+ },
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 3,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &usbs_at91_ep3,
+#ifdef CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "3w",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 1, // hardware limitation
+ alignment : 0
+ },
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
--- /dev/null
+//==========================================================================
+//
+// usbs_at91_data.cxx
+//
+// Static data for the ATMEL AT91 USB device driver
+//
+//==========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: bartv
+// Date: 2006-02-22
+//
+// This file contains various objects that should go into extras.o
+// rather than libtarget.a, e.g. devtab entries that would normally
+// be eliminated by the selective linking.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/diag.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/usb/usbs_at91.h>
+#include <pkgconf/devs_usb_at91.h>
+
+// ----------------------------------------------------------------------------
+// Initialization. The goal here is to call usbs_at91_init()
+// early on during system startup, to take care of things like
+// registering interrupt handlers etc. which are best done
+// during system init.
+//
+// If the endpoint 0 devtab entry is available then its init()
+// function can be used to take care of this. However the devtab
+// entries are optional so an alternative mechanism must be
+// provided. Unfortunately although it is possible to give
+// a C function the constructor attribute, it cannot be given
+// an initpri attribute. Instead it is necessary to define a
+// dummy C++ class.
+
+extern "C" void usbs_at91_init(void);
+
+#ifndef CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY
+
+class usbs_at91_initialization {
+public:
+ usbs_at91_initialization() {
+ usbs_at91_init();
+ }
+};
+
+static usbs_at91_initialization CYGBLD_ATTRIB_INIT_BEFORE(CYG_INIT_IO)
+ usbs_at91_init_object;
+#endif
+
+// ----------------------------------------------------------------------------
+// The devtab entries. Each of these is optional, many applications
+// will want to use the lower-level API rather than go via
+// open/read/write/ioctl.
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY
+// For endpoint 0 the only legal operations are get_config() and
+// set_config(), and these are provided by the common package.
+
+static bool usbs_at91_devtab_ep0_init(struct cyg_devtab_entry* tab){
+
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+
+ usbs_at91_init();
+
+ return true;
+}
+
+CHAR_DEVIO_TABLE(usbs_at91_ep0_devtab_functions,
+ &cyg_devio_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep0_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "0",
+ 0,
+ &usbs_at91_ep0_devtab_functions,
+ &usbs_at91_devtab_ep0_init,
+ 0,
+ (void*) &usbs_at91_ep0);
+#endif
+
+// ----------------------------------------------------------------------------
+// Common routines for ep1..3
+
+#if defined(CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY)
+
+static bool usbs_at91_devtab_dummy_init(struct cyg_devtab_entry* tab){
+
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ return true;
+}
+
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep1_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "1",
+ 0,
+ &usbs_at91_ep1_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep1);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep2_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "2",
+ 0,
+ &usbs_at91_ep2_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep2);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep3_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep3_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "3",
+ 0,
+ &usbs_at91_ep3_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep3);
+#endif
--- /dev/null
+2006-06-06 Frank Pagliughi <fpagliughi@mindspring.com>
+
+ * First version of the USB device driver for the philips D12
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# usbs_d12.cdl
+#
+# USB device driver for the Philips PDIUSBD12 Full Speed USB
+# peripheral chip.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 eCosCentric Limited
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+# Contributors:
+# Date: 2004-05-24
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_D12 {
+ display "Philips D12 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_USB
+ implements CYGHWR_IO_USB_SLAVE
+ doc ref/devs-usb-philips-pdiusbd12.html
+
+ description "
+ The Philips PDIUSBD12 is a USB peripheral controller (slave)
+ chip that can connect to a microcontroller or microprocessor
+ through an 8-bit parallel bus. The SoRo Systems USB-D12-104 is
+ a slave board for the PC's ISA or PC/104 bus that contains a
+ D12 chip placed in the PC's I/O space with jumpered selections
+ for IRQ and DMA settings. This package provides an eCos device
+ driver."
+
+ requires CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER
+
+ cdl_option CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER {
+ display "Inline file implementing hardware access"
+ flavor booldata
+ default_value false
+ description "
+ This option should contain the header file which
+ implements basic access to the D12 registers"
+ }
+
+ cdl_component CYGFUN_DEVS_USB_D12_EP0 {
+ display "Support the Control Endpoint 0"
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ requires CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE
+ compile usbs_d12.c
+ compile -library=libextras.a usbs_d12_data.cxx
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable."
+
+ cdl_option CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 0"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 0 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and ioctl calls then a devtab entry is needed.
+ "
+ }
+ cdl_option CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE {
+ display "Size of statically-allocated endpoint 0 transmit buffer"
+ flavor data
+ default_value 256
+ requires { CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE >=
+ CYGNUM_DEVS_USB_D12_EP0_PKTSIZE }
+ description "
+ The implementation of the support for endpoint 0 uses
+ a single static buffer to hold the response to the
+ current control message. Typically this buffer can be
+ fairly small since replies to control messages tend to
+ be small: typically some tens of bytes for the enumeration
+ data, perhaps a bit more for unicode-encoded string
+ descriptors. However if some application-specific protocol
+ depends on larger control messages then this buffer
+ size may need to be increased."
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_BASEADDR {
+ display "Base Address of D12 chip"
+ flavor data
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ description "
+ The base memory or I/O address where the USB chip resides.
+ The value is set by the hardware specific driver's CDL."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_IRQ {
+ display "IRQ for the D12 chip"
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ flavor data
+ description "
+ The IRQ assigned to the D12 chip. The value
+ is set by the hardware specific drivers's CDL."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_INT {
+ display "INT for the D12 chip"
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ flavor data
+ default_value { CYGNUM_DEVS_USB_D12_IRQ + 32 }
+ description "
+ The interrupt vector assigned to the D12 chip."
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_THREAD {
+ display "Use a thread to service D12 chip"
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ default_value 0
+ description "
+ Services the D12 USB chip with a thread, rather than at
+ the DSR level. This allows for increased debug support,
+ like TRACE output from the driver at the expense of some
+ throughput & reaction time. The service thread MUST be at
+ a higher priority than any application thread that uses
+ the USB port. "
+
+ cdl_option CYGNUM_DEVS_USB_D12_THREAD_PRIORITY {
+ display "Thread Priority"
+ flavor data
+ legal_values 1 to 30
+ default_value 4
+ description "
+ The priority of the D12 device driver thread."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_THREAD_STACK_SIZE {
+ display "USB Thread Stack Size"
+ flavor data
+ default_value 4096
+ description "
+ The stack size for the D12 device driver thread."
+ }
+ }
+
+ cdl_component CYGFUN_DEVS_USB_D12_DEBUG {
+ display "Debug output from the D12 Device Driver"
+ requires CYGPKG_DEVS_USB_D12_THREAD
+ default_value 0
+ description "
+ Provide debugging output from the D12 Device Driver"
+
+ cdl_option CYGSEM_DEVS_USB_D12_DEBUG_DUMP_EP0_BUFS {
+ display "Dump the contents of EP0 buffers"
+ flavor bool
+ default_value 0
+ description "
+
+ Dump the contents of the packages going through
+ EP0. This allows you to see things like device
+ requests and responses."
+ }
+
+ cdl_option CYGSEM_DEVS_USB_D12_DEBUG_DUMP_BUFS {
+ display "Dump the contents of data buffers"
+ flavor bool
+ default_value 0
+ description "
+ Dump the contents of the packages going through the generic
+ endpoints. This allow you to see all of the data going through
+ the device."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_TX_EP1 {
+ display "Endpoint 1 Interrupt IN, (tx_ep1)"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ On the D12, Endpoint 1 IN can be used for Interrupt,
+ Bulk, or Control packages. This driver currently only supports
+ Interrupt packages on Endpoint 1 (slave -> host) transfers."
+
+ cdl_option CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 1 IN"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 1 IN will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_RX_EP1 {
+ display "Endpoint 1 Interrupt OUT, (rx_ep1)"
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ In the D12, Endpoint 1 OUT can be used for Interrupt,
+ Bulk, or Control packages. This driver currently only supports
+ Interrupt packages on Endpoint 1 for (host -> slave) transfers"
+
+ cdl_option CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 1 OUT"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 1 OUT will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_TX_EP2 {
+ display "Endpoint 2 Bulk IN, (tx_ep2)"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ In the D12, Endpoint 2 IN can be used for Bulk, Interrupt,
+ or Control packages. This driver currently only supports
+ Bulk packages on Endpoint 2 for (slave -> host) transfers."
+
+ cdl_option CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 2 IN"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 2 IN will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_RX_EP2 {
+ display "Endpoint 2 Bulk OUT, (rx_ep2)"
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ In the D12, Endpoint 2 OUT can be used for Bulk, Interrupt,
+ Control packages. This driver currently only supports
+ Bulk packages on Endpoint 2 for (host -> slave) transfers."
+
+ cdl_option CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 2 OUT"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 2 OUT will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME {
+ display "Base name for devtab entries"
+ flavor data
+ active_if { CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY }
+ default_value { "\"/dev/usbs\"" }
+ description "
+ If the D12 USB device driver package provides devtab entries
+ for any of the endpoints then this option gives
+ control over the names of these entries. By default the
+ endpoints will be called \"/dev/usbs0c\", \"/dev/usbs1r\"
+ \"/dev/usbs1w\", \"/dev/usbs2r\", \"/dev/usbs2w\"
+ (assuming those endpoints are all enabled. The common
+ part \"/dev/usbs\" is determined by this configuration
+ option. It may be necessary to change this if there are
+ multiple USB slave-side devices on the target hardware to
+ prevent a name clash."
+ }
+}
+
--- /dev/null
+#ifndef CYGONCE_USBS_D12_H
+#define CYGONCE_USBS_D12_H
+//==========================================================================
+//
+// include/usbs_d12.h
+//
+// The interface exported by the D12 USB device driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank Pagliughi (fmp)
+// Contributors: fmp
+// Date: 2004-05-24
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/usb/usbs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The Philips D12 is a full speed (12Mbps) USB peripheral controller
+ * chip, with a parallel interface allowing it to be connected to nearly
+ * any microcontroller or microprocessor.
+ */
+extern usbs_control_endpoint usbs_d12_ep0;
+
+extern usbs_rx_endpoint usbs_d12_rx_ep1;
+extern usbs_tx_endpoint usbs_d12_tx_ep1;
+extern usbs_rx_endpoint usbs_d12_rx_ep2;
+extern usbs_tx_endpoint usbs_d12_tx_ep2;
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+#endif /* CYGONCE_USBS_D12_H */
--- /dev/null
+//==========================================================================
+//
+// usbs_d12.c
+//
+// Driver for the D12 USB Slave Board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp)
+// Date: 2004-05-22
+//
+// This code is a device driver for the SoRo Systems USB-D12-104, a PC/104
+// (ISA) Full-Speed USB slave board, which turns a PC/104 stack into a USB
+// slave device. The board contains a Philips PDIUSBD12 Peripheral Controller
+// Chip mapped into the PC's I/O space, with jumper-selectable I/O base
+// address, IRQ, and DMA settings. The eCos config tool is used to adjust
+// settings for this driver to match the physical jumper settings. The chip
+// could run in polled mode without an IRQ, but this wouldn't be a great idea
+// other than maybe a debug environment.
+//
+// The board supports DMA transfers over the Main endpoint, but I temporarily
+// removed that code to make the driver portable to other platforms.
+//
+// *** This driver should also work with the Philips ISA Eval Board
+// for the D12, but I couldn't get one of them from Philips, so
+// I couldn't test it.
+//
+// The D12 uses an indexed register set, which it describes as "commands."
+// You first write a command (index) to the command register then you can
+// read or write data to that register. Each multi-byte command read or write
+// must be dione atomically, so all access to the chip must be serialized.
+//
+// The D12 requests service through a single interrupt. The driver can
+// be configured to service the chip through a DSR or a thread. In either
+// case, the "service" code assumes it has unfettered access to the chip.
+// The interrupt, therefore never touches the chip. It just schedules the
+// DSR or service thread.
+// Currently, the code gets exclusive access to the chip by locking the
+// scheduler. This is suboptimal (locking the whole OS to touch one I/O
+// chip), and better method should be explored.
+//
+// This version of the driver does not support Isocronous transfers.
+//
+// Additional notes on the D12:
+//
+// - The D12 has 4 endpoints (2 IN, and 2 OUT) in addition to the main
+// control endpoint:
+// - Endp 0 (Control In & Out, 16 byte buffer)
+// - Endp 1 (IN & OUT, Bulk or Interrupt, 16 byte ea)
+// - Endp 2 (IN and/or OUT, Bulk, Interrupt, or Isoc, 64 bytes ea)
+//
+// - The "main" endpoint (as Philips calls it) is Endp 2. It's double
+// buffered and has a DMA interface, and thus, is suited for high
+// throughput. For applications that perform either Isoc In or Out,
+// the buffers for Endp 2 can be combined for a 128 byte space.
+// This driver, however, currently does not support this.
+//
+// - There may be a flaw in the double buffering of the rx main endpoint.
+// According to the documentation it should be invisible to the software,
+// but if both buffers fill (on an rx/OUT), they must both be read
+// together, otherwise it appears that the buffers/packets are returned
+// in reverse order. ReadMainEndpointBuf() returns the data properly.
+//
+// - All the interrupt sources on the chip - individual endpoints, bus reset,
+// suspend, and DMA - are OR'ed together and can be checked via the
+// interrupt status register. When using edge-sensitive interrupts, as
+// we do here, the ISR/DSR must be sure all interrupts are cleared before
+// returning otherwise no new interrupts will be latched.
+//
+// - If the DMA controller is not used for the Main Endpoint, you MUST enable
+// the main endpoint interrupts in the DMA register (bits 6 & 7).
+// Personally, I think this should be the default at reset, to make it
+// compatible with the other endpoints, but Philips didn't see it that
+// way.
+//
+// - When a Setup (Device Request) packet arrives in the control endpoint, a
+// bit is set in the endpoint's status register indicating the packet is
+// setup and not data. By the USB standard, a setup packet can not be
+// NAK'ed or STALL'ed, so when the chip receives a setup packet, it
+// flushes the Ctrl (EP0) IN buffer and disables the Validate and Clear
+// Buffer commands. We must send an "acknowledge setup" to both
+// EP0 IN and OUT before a Validate or Clear Buffer command is effective.
+// See ReadSetupPacket().
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+
+#include <pkgconf/devs_usb_d12.h>
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/error/codes.h>
+
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+
+#include <string.h>
+
+// --------------------------------------------------------------------------
+// Common Types
+// --------------------------------------------------------------------------
+
+typedef cyg_uint8 byte;
+typedef cyg_uint8 uint8;
+typedef cyg_int16 int16;
+typedef cyg_uint16 uint16;
+typedef cyg_int32 int32;
+typedef cyg_uint32 uint32;
+
+// --------------------------------------------------------------------------
+// Tracing & Debug
+// --------------------------------------------------------------------------
+// If the driver is configured to use a thread to service the chip, then it
+// can also be configured to dump a lot of debug output.
+// Care must be taken that USB timing requirements are not violated by
+// dumping debug info. If the data is sent to a serial port, it should use
+// a hardware driver and have a large output buffer (115200 baud & 2kB
+// buffer works for me).
+
+#if defined(CYGFUN_DEVS_USB_D12_DEBUG) && CYGFUN_DEVS_USB_D12_DEBUG
+#define TRACE_D12 diag_printf
+#else
+#define TRACE_D12 (1) ? (void)0 : diag_printf
+#endif
+
+#if defined(CYGSEM_DEVS_USB_D12_DEBUG_DUMP_EP0_BUFS) && CYGSEM_DEVS_USB_D12_DEBUG_DUMP_EP0_BUFS
+#define TRACE_EP0 1
+#endif
+
+#if defined(CYGSEM_DEVS_USB_D12_DEBUG_DUMP_BUFS) && CYGSEM_DEVS_USB_D12_DEBUG_DUMP_BUFS
+#define TRACE_EP 1
+#endif
+
+#if defined(TRACE_EP0) || defined(TRACE_EP)
+static void _trace_buf(const char *hdr, const byte* buf, unsigned n)
+{
+ unsigned i;
+
+ if (buf != 0 && n != 0) {
+ if (hdr && hdr[0])
+ TRACE_D12("%s ", hdr);
+
+ TRACE_D12("[");
+ for (i=0; i<n; i++)
+ TRACE_D12(" x%02X", buf[i]);
+ TRACE_D12("]\n");
+ }
+}
+#endif
+
+#if defined(TRACE_EP0)
+#define TRACE_BUF0 _trace_buf
+#else
+#define TRACE_BUF0(hdr, buf, n)
+#endif
+
+#if defined(TRACE_EP)
+#define TRACE_BUF _trace_buf
+#else
+#define TRACE_BUF(hdr, buf, n)
+#endif
+
+// ==========================================================================
+// Chip Wrapper
+// ==========================================================================
+
+// This section contains functions that wrapper the low-level access to the
+// chip. There's a function around each register access on the chip, and then
+// some.
+
+#if defined(CYGSEM_DEVS_USB_D12_IO_MAPPED)
+typedef void* d12_addr_type;
+#else
+typedef byte* d12_addr_type;
+#endif
+
+#define D12_BASE_ADDR ((d12_addr_type) CYGNUM_DEVS_USB_D12_BASEADDR)
+
+#define D12_ENDP0_SIZE 16 // Size of Ctrl Endp
+#define D12_MAIN_ENDP 2 // The D12's "Main" Endp is special, double buffered
+#define D12_MAIN_ENDP_SIZE 64 // Size of each main endp buffer
+#define D12_MAX_PACKET_SIZE 128 // Max packet is actually double main endp
+
+#define D12_CHIP_ID 0x1012 // Value that's returned by a read of
+ //the D12's Chip ID register
+
+// ----- Endpoint Indices -----
+
+enum {
+ D12_ENDP_INVALID = 0xFF,
+ D12_ENDP_MIN = 0,
+
+ D12_RX_CTRL_ENDP = D12_ENDP_MIN, // Rx/Tx Nomenclature
+ D12_TX_CTRL_ENDP,
+
+ D12_RX_ENDP0 = D12_ENDP_MIN,
+ D12_TX_ENDP0,
+ D12_RX_ENDP1,
+ D12_TX_ENDP1,
+ D12_RX_ENDP2,
+ D12_TX_ENDP2,
+ D12_RX_MAIN_ENDP = D12_RX_ENDP2,
+ D12_TX_MAIN_ENDP = D12_TX_ENDP2,
+
+
+ D12_CTRL_ENDP_OUT = D12_ENDP_MIN, // IN/OUT Nomenclature
+ D12_CTRL_ENDP_IN,
+
+ D12_ENDP0_OUT = D12_ENDP_MIN,
+ D12_ENDP0_IN,
+ D12_ENDP1_OUT,
+ D12_ENDP1_IN,
+ D12_ENDP2_OUT,
+ D12_ENDP2_IN,
+ D12_MAIN_ENDP_OUT = D12_ENDP2_OUT,
+ D12_MAIN_ENDP_IN = D12_ENDP2_IN,
+
+ D12_ENDP_INSERT_BEFORE,
+ D12_ENDP_MAX = D12_ENDP_INSERT_BEFORE-1
+};
+
+// ----- Set Mode Reg configuration byte -----
+
+enum {
+ D12_MODE_CFG_NO_LAZYCLOCK = 0x02,
+ D12_MODE_CFG_CLOCK_RUNNING = 0x04,
+ D12_MODE_CFG_INTERRUPT = 0x08,
+ D12_MODE_CFG_SOFT_CONNECT = 0x10,
+
+ D12_MODE_CFG_NON_ISO = 0x00,
+ D12_MODE_CFG_ISO_OUT = 0x40,
+ D12_MODE_CFG_ISO_IN = 0x80,
+ D12_MODE_CFG_ISO_IO = 0xC0,
+
+ D12_MODE_CFG_DFLT = (D12_MODE_CFG_NO_LAZYCLOCK |
+ D12_MODE_CFG_CLOCK_RUNNING |
+ D12_MODE_CFG_NON_ISO)
+};
+
+// ----- Set Mode Reg clock div factor -----
+
+enum {
+ D12_MODE_CLK_24_MHZ = 1,
+ D12_MODE_CLK_16_MHZ = 2,
+ D12_MODE_CLK_12_MHZ = 3,
+ D12_MODE_CLK_8_MHZ = 5,
+ D12_MODE_CLK_6_MHZ = 7,
+ D12_MODE_CLK_4_MHZ = 11,
+
+ D12_MODE_CLK_DIV_MASK = 0x0F,
+
+ D12_MODE_CLK_SET_TO_ONE = 0x40,
+ D12_MODE_CLK_SOF_ONLY_INTR = 0x80,
+
+ D12_MODE_CLK_DFLT = (D12_MODE_CLK_4_MHZ |
+ D12_MODE_CLK_SET_TO_ONE)
+};
+
+// ----- Set DMA Register -----
+
+enum {
+ D12_DMA_SINGLE_CYCLE,
+ D12_DMA_BURST_4_CYCLE,
+ D12_DMA_BURST_8_CYCLE,
+ D12_DMA_BURST_16_CYCLE,
+
+ D12_DMA_ENABLE = 0x04,
+ D12_DMA_DIR_WRITE = 0x08,
+ D12_DMA_DIR_READ = 0x00,
+ D12_DMA_AUTO_RELOAD = 0x10,
+ D12_DMA_INTR_PIN_MODE = 0x20,
+
+ D12_DMA_MAIN_ENDP_OUT_INTR_ENABLE = 0x40,
+ D12_DMA_MAIN_RX_ENDP_INTR_ENABLE = 0x40,
+
+ D12_DMA_MAIN_ENDP_IN_INTR_ENABLE = 0x80,
+ D12_DMA_MAIN_TX_ENDP_INTR_ENABLE = 0x80,
+
+ D12_DMA_MAIN_ENDP_INTR_ENABLE = 0xC0 // Enables IN & OUT Intr
+};
+
+// ----- Interrupt Register Bits -----
+
+enum {
+ D12_INTR_RX_CTRL_ENDP = 0x0001,
+ D12_INTR_TX_CTRL_ENDP = 0x0002,
+
+ D12_INTR_RX_ENDP0 = D12_INTR_RX_CTRL_ENDP,
+ D12_INTR_TX_ENDP0 = D12_INTR_TX_CTRL_ENDP,
+ D12_INTR_RX_ENDP1 = 0x0004,
+ D12_INTR_TX_ENDP1 = 0x0008,
+ D12_INTR_RX_ENDP2 = 0x0010,
+ D12_INTR_TX_ENDP2 = 0x0020,
+
+ D12_INTR_BUS_RESET = 0x0040,
+ D12_INTR_SUSPEND_CHANGE = 0x0080,
+ D12_INTR_DMA_EOT = 0x0100
+};
+
+// ----- Read Endpoint Status -----
+
+enum {
+ D12_ENDP_STAT_SETUP_PACKET = 0x04,
+ D12_ENDP_STAT_BUF0_FULL = 0x20,
+ D12_ENDP_STAT_BUF1_FULL = 0x40,
+ D12_ENDP_STAT_ANY_BUF_FULL = 0x60,
+ D12_ENDP_STAT_BOTH_BUF_FULL = 0x60,
+ D12_ENDP_STAT_STALL = 0x80,
+};
+
+// ----- Last Transaction Status Bits -----
+
+enum {
+ D12_LAST_TRANS_DATA_SUCCESS = 0x01,
+ D12_LAST_TRANS_ERR_CODE_MASK = 0x1E,
+ D12_LAST_TRANS_SETUP_PACKET = 0x20,
+ D12_LAST_TRANS_DATA1_PACKET = 0x40,
+ D12_LAST_TRANS_PREV_STAT_NOT_READ = 0x80
+};
+
+static const byte RX_ENDP_INDEX[] =
+ { D12_RX_ENDP0, D12_RX_ENDP1, D12_RX_ENDP2 };
+static const byte TX_ENDP_INDEX[] =
+ { D12_TX_ENDP0, D12_TX_ENDP1, D12_TX_ENDP2 };
+
+static const int RX_ENDP_SIZE[] = { 16, 16, 64 };
+static const int TX_ENDP_SIZE[] = { 16, 16, 64 };
+
+typedef void (*completion_fn)(void*, int);
+
+#ifndef USB_SETUP_PACKET_LEN
+#define USB_SETUP_PACKET_LEN 8
+#endif
+
+// ----- Command Definitions -----
+
+enum {
+ CMD_SET_ADDR_EN = 0xD0, // Write 1 byte
+ CMD_SET_ENDP_EN = 0xD8, // Write 1 byte
+ CMD_SET_MODE = 0xF3, // Write 2 bytes
+ CMD_SET_DMA = 0xFB, // Write/Read 1 byte
+ CMD_READ_INTR_REG = 0xF4, // Read 2 bytes
+ CMD_SEL_ENDP = 0x00, // (+ Endp Index) Read 1 byte (opt)
+ CMD_READ_LAST_TRANS_STAT = 0x40, // (+ Endp Index) Read 1 byte (opt)
+ CMD_READ_ENDP_STAT = 0x80, // (+ Endp Index) Read 1 byte
+ CMD_READ_BUF = 0xF0, // Read n bytes
+ CMD_WRITE_BUF = 0xF0, // Write n bytes
+ CMD_SET_ENDP_STAT = 0x40, // (+ Endp Index) Write 1 byte
+ CMD_ACK_SETUP = 0xF1, // None
+ CMD_CLEAR_BUF = 0xF2, // None
+ CMD_VALIDATE_BUF = 0xFA, // None
+ CMD_SEND_RESUME = 0xF6, // None
+ CMD_READ_CURR_FRAME_NUM = 0xF5, // Read 1 or 2 bytes
+ CMD_READ_CHIP_ID = 0xFD // Read 2 bytes
+};
+
+// ----- Set Endpoint Enable Register -----
+
+enum {
+ ENDP_DISABLE,
+ ENDP_ENABLE
+};
+
+// ----- Select Endpoint Results -----
+
+enum {
+ SEL_ENDP_FULL = 0x01,
+ SEL_ENDP_STALL = 0x02
+};
+
+// ----- Error Codes from ReadLastTrans (need to be bit shifter) -----
+
+enum {
+ ERROR_NO_ERROR,
+ ERROR_PID_ENCODING,
+ ERROR_PID_UNKNOWN,
+ ERROR_UNEXPECTED_PACKET,
+ ERROR_TOKEN_CRC,
+ ERROR_DATA_CRC,
+ ERROR_TIMEOUT,
+ ERROR_BABBLE,
+ ERROR_UNEXPECTED_EOP,
+ ERROR_NAK,
+ ERROR_PACKET_ON_STALL,
+ ERROR_OVERFLOW,
+ ERROR_BITSTUFF,
+ ERROR_WRONG_DATA_PID
+};
+
+// ------------------------------------------------------------------------
+// Routines to access the D12 registers. The hardware specific driver
+// provides 8bit access functions and block access functions.
+
+#include CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER
+
+
+static inline uint16
+make_word(byte hi, byte lo)
+{
+ return ((uint16) hi << 8) | lo;
+}
+
+// These routines read or write 16 bit values to the data area.
+
+static inline uint16
+d12_read_data_word(d12_addr_type base_addr)
+{
+ uint16 val = d12_read_data_byte(base_addr);
+ val |= ((uint16) d12_read_data_byte(base_addr)) << 8;
+ return val;
+}
+
+static inline void
+d12_write_data_word(d12_addr_type base_addr, uint16 val)
+{
+ d12_write_data_byte(base_addr, (byte) val);
+ d12_write_data_byte(base_addr, (byte) (val >> 8));
+}
+
+// ------------------------------------------------------------------------
+// Command & Data I/O
+// ------------------------------------------------------------------------
+//
+// These routines read & write the registers in the D12. The procedure is
+// to write a register/command value to the command address (A0=1) then
+// read or write any required data a byte at a time to the data address
+// (A0=0). The data can be one byte or two. If two, the low byte is read/
+// written first.
+
+// NOTE: These MUST be atomic operations. It's up to the caller
+// to insure this.
+
+// The hardware specific driver provides the basic access function.
+//
+
+static inline void
+d12_write_byte(d12_addr_type base_addr, byte cmd, byte val)
+{
+ d12_write_cmd(base_addr, cmd);
+ d12_write_data_byte(base_addr, val);
+}
+
+static inline void
+d12_write_word(d12_addr_type base_addr, byte cmd, uint16 val)
+{
+ d12_write_cmd(base_addr, cmd);
+ d12_write_data_word(base_addr, val);
+}
+
+static inline byte
+d12_read_byte(d12_addr_type base_addr, byte cmd)
+{
+ d12_write_cmd(base_addr, cmd);
+ return d12_read_data_byte(base_addr);
+}
+
+static inline uint16
+d12_read_word(d12_addr_type base_addr, byte cmd)
+{
+ d12_write_cmd(base_addr, cmd);
+ return d12_read_data_word(base_addr);
+}
+
+// ------------------------------------------------------------------------
+// Higher Level Commands
+// ------------------------------------------------------------------------
+
+// Stalls or Unstalls the endpoint. Bit0=1 for stall, =0 to unstall.
+
+static inline void
+d12_set_endp_status(d12_addr_type base_addr, byte endp_idx, byte stat)
+{
+ d12_write_byte(base_addr, CMD_SET_ENDP_STAT + endp_idx, stat);
+}
+
+// ------------------------------------------------------------------------
+// Stalls the control endpoint (both in & out).
+
+static void
+d12_stall_ctrl_endp(d12_addr_type base_addr, bool stall)
+{
+ d12_set_endp_status(base_addr, D12_TX_CTRL_ENDP, stall ? 1 : 0);
+ d12_set_endp_status(base_addr, D12_RX_CTRL_ENDP, stall ? 1 : 0);
+}
+
+// ------------------------------------------------------------------------
+// Stalls/unstalls the specified endpoint.
+
+void inline
+d12_stall_endp(d12_addr_type base_addr, byte endp_idx, bool stall)
+{
+ d12_set_endp_status(base_addr, endp_idx, stall ? 1 : 0);
+}
+
+// ------------------------------------------------------------------------ */
+// Tells the chip that the selected endpoint buffer has been completely
+// read. This should be called after the application reads all the data
+// from an endpoint. While there's data in the buffer the chip will
+// automatically NAK any additional OUT packets from the host.
+
+static inline void
+d12_clear_buffer(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_CLEAR_BUF);
+}
+
+// ------------------------------------------------------------------------
+// Tells the chip that the data in the selected endpoint buffer is complete
+// and ready to be sent to the host.
+
+static inline void
+d12_validate_buffer(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_VALIDATE_BUF);
+}
+
+// ------------------------------------------------------------------------
+// Sends an upstream resume signal for 10ms. This command is normally
+// issued when the device is in suspend.
+
+static inline void
+d12_send_resume(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_SEND_RESUME);
+}
+
+// ------------------------------------------------------------------------
+// Gets the frame number of the last successfully received
+// start-of-frame (SOF).
+
+static inline uint16
+d12_read_curr_frame_num(d12_addr_type base_addr)
+{
+ return d12_read_word(base_addr, CMD_READ_CURR_FRAME_NUM);
+}
+
+// ------------------------------------------------------------------------
+// This routine acknowledges a setup packet by writing an Ack Setup command
+// to the currently selected Endpoint. This must be done for both EP0 out
+// and EP0 IN whenever a setup packet is received.
+
+static inline void
+d12_ack_setup(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_ACK_SETUP);
+}
+
+// ------------------------------------------------------------------------
+// Gets the value of the 16-bit interrupt register, which indicates the
+// source of an interrupt (if interrupts are not used, this reg can be
+// polled to find when service is required).
+
+static inline uint16
+d12_read_intr_reg(d12_addr_type base_addr)
+{
+ return d12_read_word(base_addr, CMD_READ_INTR_REG) & 0x01FF;
+}
+
+// ------------------------------------------------------------------------
+// Gets/Sets the contents of the DMA register.
+
+static inline byte
+d12_get_dma(d12_addr_type base_addr)
+{
+ return d12_read_byte(base_addr, CMD_SET_DMA);
+}
+
+static inline void
+d12_set_dma(d12_addr_type base_addr, byte mode)
+{
+ d12_write_byte(base_addr, CMD_SET_DMA, mode);
+}
+
+// ------------------------------------------------------------------------
+// Sends the "Select Endpoint" command (0x00 - 0x0D) to the chip.
+// This command initializes an internal pointer to the start of the
+// selected buffer.
+//
+// Returns: Bitfield containing status of the endpoint
+
+static byte
+d12_select_endp(d12_addr_type base_addr, byte endp_idx)
+{
+ return d12_read_byte(base_addr, CMD_SEL_ENDP + endp_idx);
+}
+
+// ------------------------------------------------------------------------
+// Gets the status of the last transaction of the endpoint. It also resets
+// the corresponding interrupt flag in the interrupt register, and clears
+// the status, indicating that it was read.
+//
+// Returns: Bitfield containing the last transaction status.
+
+static inline byte
+d12_read_last_trans_status(d12_addr_type base_addr, byte endp_idx)
+{
+ return d12_read_byte(base_addr, CMD_READ_LAST_TRANS_STAT + endp_idx);
+}
+
+// ------------------------------------------------------------------------
+// Reads the status of the requested endpoint.
+// Just for the heck of it, we mask off the reserved bits.
+//
+// Returns: Bitfield containing the endpoint status.
+
+static inline byte
+d12_read_endp_status(d12_addr_type base_addr, byte endp_idx)
+{
+ return d12_read_byte(base_addr, CMD_READ_ENDP_STAT + endp_idx) & 0xE4;
+}
+
+// ------------------------------------------------------------------------
+// Returns true if there is data available in the specified endpoint's
+// ram buffer. This is determined by the buf full flags in the endp status
+// register.
+
+static inline bool
+d12_data_available(d12_addr_type base_addr, byte endp_idx)
+{
+ byte by = d12_read_endp_status(base_addr, endp_idx);
+ return (bool) (by & D12_ENDP_STAT_ANY_BUF_FULL);
+}
+
+// ------------------------------------------------------------------------
+// Clears the transaction status for each of the endpoints by calling the
+// d12_read_last_trans_status() function for each.
+
+static void
+d12_clear_all_intr(d12_addr_type base_addr)
+{
+ uint8 endp;
+
+ d12_read_intr_reg(base_addr);
+
+ for (endp=D12_ENDP_MIN; endp<=D12_ENDP_MAX; ++endp)
+ d12_read_last_trans_status(base_addr, endp);
+}
+
+// ------------------------------------------------------------------------
+// Loads a value into the Set Address / Enable register. This sets the
+// device's USB address (lower 7 bits) and enables/disables the function
+// (msb).
+
+static void
+d12_set_addr_enable(d12_addr_type base_addr, byte usb_addr, bool enable)
+{
+ if (enable)
+ usb_addr |= 0x80;
+
+ d12_write_byte(base_addr, CMD_SET_ADDR_EN, usb_addr);
+}
+
+// ------------------------------------------------------------------------
+// Enables/disables the generic endpoints.
+
+static inline void
+d12_set_endp_enable(d12_addr_type base_addr, bool enable)
+{
+ d12_write_byte(base_addr, CMD_SET_ENDP_EN,
+ (enable) ? ENDP_ENABLE : ENDP_DISABLE);
+}
+
+// ------------------------------------------------------------------------
+// Sets the device's configuration and CLKOUT frequency.
+
+static void
+d12_set_mode(d12_addr_type base_addr, byte config, byte clk_div)
+{
+ uint16 w = make_word(clk_div, config);
+ d12_write_word(base_addr, CMD_SET_MODE, w);
+}
+
+// ------------------------------------------------------------------------
+// Reads a setup packet from the control endpoint. This procedure is
+// somewhat different than reading a data packet. By the USB standard, a
+// setup packet can not be NAK'ed or STALL'ed, so when the chip receives a
+// setup packet, it flushes the Ctrl (EP0) IN buffer and disables the
+// Validate and Clear Buffer commands. The processor must send an
+// acknowledge setup to both EP0 IN and OUT before a Validate or Clear
+// Buffer command is effective.
+//
+// Parameters:
+// buf buffer to receive the contents of the setup packet. Must
+// be at least 8 bytes.
+// Returns:
+// true if there are 8 bytes waiting in the EP0 OUT RAM buffer
+// on the D12 (i.e., true if successful)
+// false otherwise
+
+static bool
+d12_read_setup_packet(d12_addr_type base_addr, byte *buf)
+{
+ uint8 n;
+
+ d12_select_endp(base_addr, D12_RX_CTRL_ENDP);
+
+ d12_read_byte(base_addr, CMD_READ_BUF); // Read & discard reserved byte
+ n = d12_read_data_byte(base_addr); // # bytes available
+
+ if (n > USB_SETUP_PACKET_LEN) {
+ //TRACE("* Warning: Setup Packet too large: %u *\n", (unsigned) n);
+ n = USB_SETUP_PACKET_LEN;
+ }
+
+ n = d12_read_data(base_addr, buf, n);
+
+ d12_ack_setup(base_addr);
+ d12_clear_buffer(base_addr);
+
+ // ----- Ack Setup to EP0 IN ------
+
+ d12_select_endp(base_addr, D12_TX_CTRL_ENDP);
+ d12_ack_setup(base_addr);
+
+ return n == USB_SETUP_PACKET_LEN;
+}
+
+// ------------------------------------------------------------------------
+// Reads the contents of the currently selected endpoint's RAM buffer into
+// the buf[] array.
+//
+// The D12's buffer comes in as follows:
+// [0] junk ("reserved" - can be anything). Just disregard
+// [1] # data bytes to follow
+// [2] data byte 0, ...
+// up to
+// [N+2] data byte N-1
+//
+// Parameters:
+// buf byte array to receive data. This MUST be at least the size
+// of the chip's RAM buffer for the currently selected endpoint.
+// If buf is NULL, the data is read & discarded.
+//
+// Returns: the actual number of bytes read (could be <= n)
+
+static uint8
+d12_read_selected_endp_buf(d12_addr_type base_addr, byte *buf)
+{
+ uint8 n;
+
+ d12_read_byte(base_addr, CMD_READ_BUF); // Read & discard reserved byte
+ n = d12_read_data_byte(base_addr); // # bytes in chip's buf
+ d12_read_data(base_addr, buf, n);
+ d12_clear_buffer(base_addr);
+
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Selects the specified endpoint and reads the contents of it's RAM buffer
+// into the buf[] array. For the Main OUT endpoint, it will check whether
+// both buffers are full, and if so, read them both.
+//
+// Side Effects:
+// - Leaves endp_idx as the currently selected endpoint.
+//
+// Parameters:
+// endp_idx the endpoint from which to read
+// buf buffer to receive the data. This MUST be at least the size
+// of the chip's RAM buffer for the specified endpoint.
+// For the Main endp, it must be 2x the buffer size (128 total)
+//
+// Returns: the # of bytes read.
+
+static uint8
+d12_read_endp_buf(d12_addr_type base_addr, byte endp_idx, byte *buf)
+{
+ return (d12_select_endp(base_addr, endp_idx) & SEL_ENDP_FULL)
+ ? d12_read_selected_endp_buf(base_addr, buf) : 0;
+}
+
+// ------------------------------------------------------------------------
+// Does a read of the "main" endpoint (#2). Since it's double buffered,
+// this will check if both buffers are full, and if so it will read them
+// both. Thus the caller's buffer, buf, must be large enough to hold all
+// the data - 128 bytes total.
+//
+// If either buffer contains less than the full amount, the done flag
+// is set indicating that a Bulk OUT transfer is complete.
+//
+// This determines if a bulk transfer is done, since the caller can't
+// necessarily determine this from the size of the return buffer.
+// If either buffer is less than full, '*done' is set to a non-zero value.
+
+static uint8
+d12_read_main_endp_buf(d12_addr_type base_addr, byte *buf, int *done)
+{
+ int nBuf = 1;
+ uint8 n = 0;
+ byte stat = d12_read_endp_status(base_addr, D12_RX_MAIN_ENDP) &
+ D12_ENDP_STAT_ANY_BUF_FULL;
+
+ if (stat == 0)
+ return 0;
+
+ if (stat == D12_ENDP_STAT_BOTH_BUF_FULL)
+ nBuf++;
+
+ *done = false;
+
+ while (nBuf--) {
+ if (d12_select_endp(base_addr, D12_RX_MAIN_ENDP) & SEL_ENDP_FULL) {
+ uint8 n1 = d12_read_selected_endp_buf(base_addr, buf+n);
+ n += n1;
+ if (n1 < D12_MAIN_ENDP_SIZE) {
+ *done = true;
+ break;
+ }
+ }
+ else
+ *done = true;
+ }
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Writes the contents of the buf[] array to the currently selected
+// endpoint's RAM buffer. The host will get the data on the on the next IN
+// packet from the endpoint.
+//
+// Note:
+// - The length of the buffer, n, must be no more than the size of the
+// endpoint's RAM space, though, currently, this is not checked.
+// - It's feasible that the application needs to send an empty (NULL)
+// packet. It's valid for 'n' to be zero, and/or buf NULL.
+
+static uint8
+d12_write_selected_endp_buf(d12_addr_type base_addr, const byte *buf, uint8 n)
+{
+ d12_write_byte(base_addr, CMD_WRITE_BUF, 0);
+ d12_write_data_byte(base_addr, n);
+ d12_write_data(base_addr, buf, n);
+ d12_validate_buffer(base_addr);
+
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Writes the contents of the buf[] array to the specified endoint's RAM
+// buffer. The host will get this data on the next IN packet from the
+// endpoint.
+//
+// Side Effects:
+// - Leaves endp_idx as the currently selected endpoint.
+
+static uint8
+d12_write_endp_buf(d12_addr_type base_addr, byte endp_idx,
+ const byte *buf, uint8 n)
+{
+ d12_select_endp(base_addr, endp_idx);
+ return d12_write_selected_endp_buf(base_addr, buf, n);
+}
+
+// ------------------------------------------------------------------------
+// Reads & returns the contents of the Chip ID register.
+
+static inline uint16
+d12_read_chip_id(d12_addr_type base_addr)
+{
+ return d12_read_word(base_addr, CMD_READ_CHIP_ID);
+}
+
+
+// ==========================================================================
+// eCos-Specific Device Driver Code
+// ==========================================================================
+
+static void usbs_d12_reset(void);
+
+// Make some abbreviations for the configuration options.
+
+#if defined(CYGPKG_DEVS_USB_D12_RX_EP1)
+#define _RX_EP1
+#endif
+
+#if defined(CYGPKG_DEVS_USB_D12_TX_EP1)
+#define _TX_EP1
+#endif
+
+#if defined(CYGPKG_DEVS_USB_D12_RX_EP2)
+#define _RX_EP2
+#endif
+
+#if defined(CYGPKG_DEVS_USB_D12_TX_EP2)
+#define _TX_EP2
+#endif
+
+// --------------------------------------------------------------------------
+// Endpoint 0 Data
+// --------------------------------------------------------------------------
+
+static cyg_interrupt usbs_d12_intr_data;
+static cyg_handle_t usbs_d12_intr_handle;
+
+static byte ep0_tx_buffer[CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE];
+
+static void usbs_d12_start(usbs_control_endpoint*);
+static void usbs_d12_poll(usbs_control_endpoint*);
+
+typedef enum endp_state {
+ ENDP_STATE_IDLE,
+ ENDP_STATE_IN,
+ ENDP_STATE_OUT
+} endp_state;
+
+typedef struct ep0_impl {
+ usbs_control_endpoint common;
+ endp_state ep_state;
+ int length;
+ int transmitted;
+ bool tx_empty;
+} ep0_impl;
+
+static ep0_impl ep0 = {
+ common:
+ {
+ state: USBS_STATE_POWERED,
+ enumeration_data: (usbs_enumeration_data*) 0,
+ start_fn: &usbs_d12_start,
+ poll_fn: &usbs_d12_poll,
+ interrupt_vector: CYGNUM_DEVS_USB_D12_IRQ,
+ control_buffer: { 0, 0, 0, 0, 0, 0, 0, 0 },
+ state_change_fn: 0,
+ state_change_data: 0,
+ standard_control_fn: 0,
+ standard_control_data: 0,
+ class_control_fn: 0,
+ class_control_data: 0,
+ vendor_control_fn: 0,
+ vendor_control_data: 0,
+ reserved_control_fn: 0,
+ reserved_control_data: 0,
+ buffer: 0,
+ buffer_size: 0,
+ fill_buffer_fn: 0,
+ fill_data: 0,
+ fill_index: 0,
+ complete_fn: 0
+ },
+ ep_state: ENDP_STATE_IDLE,
+ length: 0,
+ transmitted: 0,
+ tx_empty: 0
+};
+
+extern usbs_control_endpoint usbs_d12_ep0 __attribute__((alias ("ep0")));
+
+// --------------------------------------------------------------------------
+// Rx Endpoints 1 & 2 Data
+// --------------------------------------------------------------------------
+
+#if defined(_RX_EP1) || defined(_RX_EP2)
+
+typedef struct rx_endpoint {
+ usbs_rx_endpoint common;
+ int endp, received;
+} rx_endpoint;
+
+static void usbs_d12_api_start_rx_ep(usbs_rx_endpoint*);
+static void usbs_d12_api_stall_rx_ep(usbs_rx_endpoint*, cyg_bool);
+
+static void usbs_d12_ep_rx_complete(rx_endpoint *ep, int result);
+static void usbs_d12_stall_rx_ep(rx_endpoint*, cyg_bool);
+
+#endif
+
+
+#if defined(_RX_EP1)
+
+static rx_endpoint rx_ep1 = {
+ common: {
+ start_rx_fn: &usbs_d12_api_start_rx_ep,
+ set_halted_fn: &usbs_d12_api_stall_rx_ep,
+ halted: 0
+ },
+ endp: 1
+};
+
+extern usbs_rx_endpoint usbs_d12_rx_ep1 __attribute__((alias ("rx_ep1")));
+
+#endif
+
+
+#if defined(_RX_EP2)
+
+static rx_endpoint rx_ep2 = {
+ common: {
+ start_rx_fn: &usbs_d12_api_start_rx_ep,
+ set_halted_fn: &usbs_d12_api_stall_rx_ep,
+ halted: 0
+ },
+ endp: 2
+};
+
+extern usbs_rx_endpoint usbs_d12_rx_ep2 __attribute__((alias ("rx_ep2")));
+
+#endif
+
+// --------------------------------------------------------------------------
+// Tx Endpoints 1 & 2 Data
+// --------------------------------------------------------------------------
+
+#if defined(_TX_EP1) || defined(_TX_EP2)
+
+typedef struct tx_endpoint {
+ usbs_tx_endpoint common;
+ int endp, transmitted;
+ bool tx_empty;
+} tx_endpoint;
+
+static void usbs_d12_api_start_tx_ep(usbs_tx_endpoint*);
+static void usbs_d12_api_stall_tx_ep(usbs_tx_endpoint*, cyg_bool);
+
+static void usbs_d12_ep_tx_complete(tx_endpoint *ep, int result);
+static void usbs_d12_stall_tx_ep(tx_endpoint*, cyg_bool);
+#endif
+
+#if defined(_TX_EP1)
+
+static tx_endpoint tx_ep1 = {
+ common: {
+ start_tx_fn: &usbs_d12_api_start_tx_ep,
+ set_halted_fn: &usbs_d12_api_stall_tx_ep,
+ halted: 0
+ },
+ endp: 1
+};
+
+extern usbs_tx_endpoint usbs_d12_tx_ep1 __attribute__((alias ("tx_ep1")));
+#endif
+
+#if defined(_TX_EP2)
+
+static tx_endpoint tx_ep2 = {
+ common: {
+ start_tx_fn: &usbs_d12_api_start_tx_ep,
+ set_halted_fn: &usbs_d12_api_stall_tx_ep,
+ halted: 0
+ },
+ endp: 2
+};
+
+extern usbs_tx_endpoint usbs_d12_tx_ep2 __attribute__((alias ("tx_ep2")));
+
+#endif
+
+// --------------------------------------------------------------------------
+// Synchronization
+
+static inline void usbs_d12_lock(void) { cyg_scheduler_lock(); }
+static inline void usbs_d12_unlock(void) { cyg_scheduler_unlock(); }
+
+// --------------------------------------------------------------------------
+// Control Endpoint
+// --------------------------------------------------------------------------
+
+// Fills the EP0 transmit buffer with a packet. Partial data packets are
+// retrieved by repeatedly calling the fill function.
+
+static int
+ep0_fill_tx_buffer(void)
+{
+ int nFilled = 0;
+
+ while (nFilled < CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE) {
+ if (ep0.common.buffer_size != 0) {
+ if ((nFilled + ep0.common.buffer_size) <
+ CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE) {
+ memcpy(&ep0_tx_buffer[nFilled], ep0.common.buffer,
+ ep0.common.buffer_size);
+ nFilled += ep0.common.buffer_size;
+ ep0.common.buffer_size = 0;
+ }
+ else {
+ break;
+ }
+ }
+ else if (ep0.common.fill_buffer_fn) {
+ (*ep0.common.fill_buffer_fn)(&ep0.common);
+ }
+ else {
+ break;
+ }
+ }
+ CYG_ASSERT((ep0.common.buffer_size == 0) && (!ep0.common.fill_buffer_fn),
+ "EP0 transmit buffer overflow");
+ TRACE_D12("EP0: Filled Tx Buf with %d bytes\n", nFilled);
+
+ ep0.length = nFilled;
+
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.fill_data = 0;
+ ep0.common.fill_index = 0;
+
+ return nFilled;
+}
+
+// --------------------------------------------------------------------------
+// Called when a transfer is complete on the control endpoint EP0.
+// It resets the endpoint's data structure and calls the completion function,
+// if any.
+//
+// PARAMETERS:
+// result 0, on success
+// -EPIPE or -EIO to indicate a cancellation
+
+static usbs_control_return
+usbs_d12_ep0_complete(int result)
+{
+ usbs_control_return ret = USBS_CONTROL_RETURN_UNKNOWN;
+
+ ep0.ep_state = ENDP_STATE_IDLE;
+
+ if (ep0.common.complete_fn)
+ ret = (*ep0.common.complete_fn)(&ep0.common, result);
+
+ ep0.common.buffer = 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.complete_fn = 0;
+ //ep0.common.fill_buffer_fn = 0;
+
+ return ret;
+}
+
+// --------------------------------------------------------------------------
+// This routine is called when we want to send the next packet to the tx ep0
+// on the chip. It is used to start a new transfer, and is also called when
+// the chip interrupts to indicate that the ep0 tx buffer is empty and ready
+// to receive a new packet.
+//
+// NOTE:
+// On the D12, when you send a zero-length packet to a tx endpoint, the
+// chip transmits the empty packet to the host, but doesn't interrupt
+// indicating that it is complete. So immediately after sending the
+// empty packet we complete the transfer.
+
+static void
+usbs_d12_ep0_tx(void)
+{
+ int nRemaining = ep0.length - ep0.transmitted;
+ uint8 n;
+
+ // ----- Intermittent interrupt? Get out -----
+
+ if (!ep0.common.buffer) {
+ TRACE_D12("EP0: Tx no buffer (%d)\n", nRemaining);
+ return;
+ }
+
+ // ----- If prev packet was last, signal that we're done -----
+
+ if (nRemaining == 0 && !ep0.tx_empty) {
+ TRACE_D12("\tEP0: Tx Complete (%d) %p\n", ep0.transmitted,
+ ep0.common.complete_fn);
+ usbs_d12_ep0_complete(0);
+ return;
+ }
+
+ // ----- Load the next tx packet onto the chip -----
+
+ if (nRemaining < D12_ENDP0_SIZE) {
+ n = (uint8) nRemaining;
+ ep0.tx_empty = false;
+ }
+ else
+ n = D12_ENDP0_SIZE;
+
+ d12_write_endp_buf(D12_BASE_ADDR, D12_TX_ENDP0,
+ &ep0_tx_buffer[ep0.transmitted], n);
+
+ TRACE_D12("EP0: Wrote %u bytes\n", (unsigned) n);
+ TRACE_BUF0("\t", &ep0_tx_buffer[ep0.transmitted], n);
+
+ ep0.transmitted += n;
+
+ // ----- If empty packet, D12 won't interrupt, so end now ----- */
+
+ if (n == 0) {
+ TRACE_D12("\tEP0: Tx Complete (%d) %p\n", ep0.transmitted,
+ ep0.common.complete_fn);
+ usbs_d12_ep0_complete(0);
+ }
+}
+
+// --------------------------------------------------------------------------
+// This function is called when a packet has been successfully sent on the
+// primary control endpoint (ep0). It indicates that the chip is ready for
+// another packet. We read the LastTransStatus for the endpoint to clear
+// the interrupt bit, then call ep0_tx() to continue the transfer.
+
+static void
+usbs_d12_ep0_tx_intr(void)
+{
+ d12_read_last_trans_status(D12_BASE_ADDR, D12_TX_ENDP0);
+ usbs_d12_ep0_tx();
+}
+
+// --------------------------------------------------------------------------
+// Try to handle standard requests. This is a three step process:
+// 1. If it's something we should handle internally we take care of it.
+// Currently we can handle SET_ADDRESS requests, and a few others.
+// 2. If the upper level code has installed a standard control handler
+// we let that function have a crack at it.
+// 3. If neither of those handle the packet we let
+// usbs_handle_standard_control() have a last try at it.
+//
+// Locally:
+// SET_ADDRESS: The host is demanding that we change our USB address.
+// This is done by updating the Address/Enable register on the D12.
+// Note, however that the USB protocol requires us to ack at the old
+// address, change address, and then accept the next control message
+// at the new address. The D12 address reg is buffered to do this
+// automatically for us. The updated address on the chip won't take
+// affect until after the empty ack is sent. Nice.
+//
+
+static usbs_control_return
+usbs_d12_handle_std_req(usb_devreq *req)
+{
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+ int recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ if (req->request == USB_DEVREQ_SET_ADDRESS) {
+ TRACE_D12("Setting Addr: %u\n", (unsigned) req->value_lo);
+ d12_set_addr_enable(D12_BASE_ADDR, req->value_lo, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ else if (req->request == USB_DEVREQ_GET_STATUS) {
+ if (recipient == USB_DEVREQ_RECIPIENT_DEVICE) {
+ const usbs_enumeration_data *enum_data = ep0.common.enumeration_data;
+ if (enum_data && enum_data->device.number_configurations == 1 &&
+ enum_data->configurations) {
+ ep0.common.control_buffer[0] =
+ (enum_data->configurations[0].attributes
+ & USB_CONFIGURATION_DESCRIPTOR_ATTR_SELF_POWERED) ? 1 : 0;
+ ep0.common.control_buffer[0] |=
+ (enum_data->configurations[0].attributes
+ & USB_CONFIGURATION_DESCRIPTOR_ATTR_REMOTE_WAKEUP) ? 2 : 0;
+ ep0.common.control_buffer[1] = 0;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+ else if (recipient == USB_DEVREQ_RECIPIENT_ENDPOINT) {
+ bool halted = false;
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ switch (req->index_lo) {
+#if defined(_RX_EP1)
+ case 0x01 : halted = rx_ep1.common.halted; break;
+#endif
+#if defined(_TX_EP1)
+ case 0x81 : halted = tx_ep1.common.halted; break;
+#endif
+#if defined(_RX_EP2)
+ case 0x02 : halted = rx_ep2.common.halted; break;
+#endif
+#if defined(_TX_EP2)
+ case 0x82 : halted = tx_ep2.common.halted; break;
+#endif
+
+ default:
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+
+ TRACE_D12("Get Status: Endp [0x%02X] %s\n", (unsigned) req->index_lo,
+ halted ? "Halt" : "Unhalt");
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+ ep0.common.control_buffer[0] = (halted) ? 1 : 0;
+ ep0.common.control_buffer[1] = 0;
+ }
+ }
+
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+ ep0.common.buffer = ep0.common.control_buffer;
+ ep0.common.buffer_size = 2;
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.complete_fn = 0;
+ }
+ }
+ else if ((req->request == USB_DEVREQ_SET_FEATURE ||
+ req->request == USB_DEVREQ_CLEAR_FEATURE) &&
+ recipient == USB_DEVREQ_RECIPIENT_ENDPOINT) {
+
+ bool halt = (req->request == USB_DEVREQ_SET_FEATURE);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ TRACE_D12("Endpoint [0x%02X] %s\n", (unsigned) req->index_lo,
+ halt ? "Halt" : "Unhalt");
+
+ switch (req->index_lo) {
+#if defined(_RX_EP1)
+ case 0x01 : usbs_d12_stall_rx_ep(&rx_ep1, halt); break;
+#endif
+#if defined(_TX_EP1)
+ case 0x81 : usbs_d12_stall_tx_ep(&tx_ep1, halt); break;
+#endif
+#if defined(_RX_EP2)
+ case 0x02 : usbs_d12_stall_rx_ep(&rx_ep2, halt); break;
+#endif
+#if defined(_TX_EP2)
+ case 0x82 : usbs_d12_stall_tx_ep(&tx_ep2, halt); break;
+#endif
+
+ default:
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ }
+ else if (ep0.common.standard_control_fn != 0) {
+ result = (*ep0.common.standard_control_fn)
+ (&ep0.common,
+ ep0.common.standard_control_data);
+ }
+
+ if (result == USBS_CONTROL_RETURN_UNKNOWN)
+ result = usbs_handle_standard_control(&ep0.common);
+
+ return result;
+}
+
+// --------------------------------------------------------------------------
+// Handler for the receipt of a setup (dev request) packet from the host.
+// We examine the packet to determine what function(s) should get a crack
+// at trying to handle it, then pass control to the proper function. If
+// the function handles the message we either ACK (len==0) or prepare for
+// an IN or OUT data phase. If no one handled the message, we stall the
+// control endpoint.
+
+static void
+usbs_d12_ep0_setup_packet(usb_devreq* req)
+{
+ int len, dir, protocol, recipient;
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+ // ----- See who should take the request -----
+
+ len = make_word(req->length_hi, req->length_lo);
+
+ dir = req->type & USB_DEVREQ_DIRECTION_MASK;
+ protocol = req->type & USB_DEVREQ_TYPE_MASK;
+ recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ TRACE_BUF0("DevReq: ", ep0.common.control_buffer, sizeof(usb_devreq));
+
+ if (protocol == USB_DEVREQ_TYPE_STANDARD)
+ result = usbs_d12_handle_std_req(req);
+ else {
+ // Pass on non-standard requests to registered handlers
+
+ usbs_control_return (*callback_fn)(usbs_control_endpoint*, void*);
+ void *callback_arg;
+
+ if (protocol == USB_DEVREQ_TYPE_CLASS) {
+ callback_fn = ep0.common.class_control_fn;
+ callback_arg = ep0.common.class_control_data;
+ }
+ else if (protocol == USB_DEVREQ_TYPE_VENDOR) {
+ callback_fn = ep0.common.vendor_control_fn;
+ callback_arg = ep0.common.vendor_control_data;
+ }
+ else {
+ callback_fn = ep0.common.reserved_control_fn;
+ callback_arg = ep0.common.reserved_control_data;
+ }
+
+ result = (callback_fn) ? (*callback_fn)(&ep0.common, callback_arg)
+ : USBS_CONTROL_RETURN_STALL;
+ }
+
+ // ----- If handled prep/handle data phase, otherwise stall -----
+
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+ if (len == 0) {
+ TRACE_D12("\tCtrl ACK\n");
+ d12_write_endp_buf(D12_BASE_ADDR, D12_TX_ENDP0, 0, 0);
+ }
+ else {
+ // Set EP0 state to IN or OUT mode for data phase
+ ep0.transmitted = 0;
+ ep0.length = len;
+
+ if (dir == USB_DEVREQ_DIRECTION_OUT) {
+ // Wait for the next packet from the host.
+ ep0.ep_state = ENDP_STATE_OUT;
+ CYG_ASSERT(ep0.common.buffer != 0,
+ "A rx buffer should have been provided for EP0");
+ CYG_ASSERT(ep0.common.complete_fn != 0,
+ "A completion function should be provided for EP0 OUT control messages");
+ }
+ else {
+ ep0.tx_empty = true;
+ ep0.ep_state = ENDP_STATE_IN;
+ ep0_fill_tx_buffer();
+ usbs_d12_ep0_tx();
+ }
+ }
+ }
+ else {
+ TRACE_D12("\t*** Unhandled Device Request ***\n");
+ // The request wasn't handled, so stall control endpoint
+ d12_stall_ctrl_endp(D12_BASE_ADDR, true);
+ }
+}
+
+// --------------------------------------------------------------------------
+// This is called when the chip indicates that a packet has been received
+// on control endpoint 0. If it's a setup packet, we handle it accordingly,
+// otherwise it's a data packet coming in on ep0.
+//
+
+static void
+usbs_d12_ep0_rx_intr(void)
+{
+ byte byStat = d12_read_last_trans_status(D12_BASE_ADDR, D12_RX_ENDP0);
+ TRACE_D12("\tEP0 Status: 0x%02X\n", (unsigned) byStat);
+
+ if (byStat & D12_LAST_TRANS_SETUP_PACKET) {
+ usb_devreq *req = (usb_devreq *) ep0.common.control_buffer;
+
+ if (!d12_read_setup_packet(D12_BASE_ADDR, (byte*) req)) {
+ TRACE_D12("ep0_rx_dsr: Error reading setup packet\n");
+ d12_stall_ctrl_endp(D12_BASE_ADDR, true);
+ }
+ else
+ usbs_d12_ep0_setup_packet(req);
+ }
+ else {
+ if (ep0.common.buffer) {
+ uint8 n = d12_read_endp_buf(D12_BASE_ADDR, D12_RX_ENDP0,
+ ep0.common.buffer + ep0.transmitted);
+ ep0.transmitted += n;
+
+ TRACE_D12("EP0: Received %d bytes\n", (unsigned) n);
+
+ if (n < D12_ENDP0_SIZE ||
+ ep0.common.buffer_size - ep0.transmitted < D12_ENDP0_SIZE) {
+ TRACE_D12("\tEP0: Rx Complete (%d) %p\n",
+ ep0.transmitted, ep0.common.complete_fn);
+
+ if (usbs_d12_ep0_complete(0) == USBS_CONTROL_RETURN_HANDLED)
+ d12_write_endp_buf(D12_BASE_ADDR, D12_TX_ENDP0, 0, 0);
+ else
+ d12_stall_ctrl_endp(D12_BASE_ADDR, true);
+ }
+ }
+ else {
+ TRACE_D12("EP0: No Rx buffer. Discarding packet\n");
+ d12_read_endp_buf(D12_BASE_ADDR, D12_RX_ENDP0, NULL);
+ }
+ }
+}
+
+// --------------------------------------------------------------------------
+// Handler for when the device is put into or taken out of suspend mode.
+// It updates the state variable in the control endpoint and calls the
+// registered state change function, if any.
+
+// TODO: Put the chip into low power mode??? Stop clocks, etc???
+
+static void
+usbs_d12_suspend(bool suspended)
+{
+ int old_state = ep0.common.state;
+ usbs_state_change state_change;
+
+ if (suspended) {
+ ep0.common.state |= USBS_STATE_SUSPENDED;
+ state_change = USBS_STATE_CHANGE_SUSPENDED;
+ }
+ else {
+ ep0.common.state &= USBS_STATE_MASK;
+ state_change = USBS_STATE_CHANGE_RESUMED;
+ }
+
+ if (ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ state_change, old_state);
+ }
+}
+
+// --------------------------------------------------------------------------
+// Common Rx Endpoint 1 & 2
+// --------------------------------------------------------------------------
+
+#if defined(_RX_EP1) || defined(_RX_EP2)
+
+static void usbs_d12_clear_rx_ep(rx_endpoint *ep)
+{
+ ep->common.buffer = 0;
+ ep->common.buffer_size = 0;
+ ep->common.complete_fn = 0;
+ ep->common.complete_data = 0;
+
+ ep->received = 0;
+}
+
+// --------------------------------------------------------------------------
+// This is called when an rx operation is completed. It resets the endpoint
+// vars and calls the registered completion function.
+//
+
+static void
+usbs_d12_ep_rx_complete(rx_endpoint *ep, int result)
+{
+ completion_fn fn = ep->common.complete_fn;
+ void *data = ep->common.complete_data;
+
+ usbs_d12_clear_rx_ep(ep);
+
+ if (fn)
+ (*fn)(data, result);
+}
+
+// --------------------------------------------------------------------------
+// This routine is called when an rx buffer in the chip is full and ready to
+// be read. If there's an endpoint buffer available and room to hold the data
+// we read it in, otherwise we call the completion function, but leave the
+// data in the chip. The hardware will automatically NAK packages from the
+// host until the app calls another start read to continue receiving data.
+//
+// CONTEXT:
+// Called from either the DSR or application thread, via start rx.
+// In either case, it's assumed that the chip is locked.
+//
+
+static void
+usbs_d12_ep_rx(rx_endpoint *ep)
+{
+ int n, ep_size, buf_remaining, endp = ep->endp;
+ bool done;
+
+ // The main endp is double buffered and we need to be prepared
+ // to read both simultaneously.
+ ep_size = (endp == D12_MAIN_ENDP) ? (2 * D12_MAIN_ENDP_SIZE)
+ : RX_ENDP_SIZE[endp];
+
+ buf_remaining = ep->common.buffer_size - ep->received;
+
+ // ----- If no space left in buffer, call completion fn -----
+
+ if (!ep->common.buffer || buf_remaining < ep_size) {
+ int ret = ep->received;
+
+ // See if caller requested a read smaller than the endp. Read &
+ // throw away extra
+ if (ep->common.buffer_size < ep_size) {
+ byte tmp_buf[D12_MAX_PACKET_SIZE];
+
+ if (endp == D12_MAIN_ENDP)
+ n = d12_read_main_endp_buf(D12_BASE_ADDR, tmp_buf, &done);
+ else
+ n = d12_read_endp_buf(D12_BASE_ADDR, RX_ENDP_INDEX[endp], tmp_buf);
+
+ if (n > ep->common.buffer_size) {
+ n = ep->received = ep->common.buffer_size;
+ ret = -ENOMEM;
+ TRACE_D12("\tEP%d: *** Rx Buffer too small. Data Lost ***\n", endp);
+ }
+ else
+ ret = ep->received = n;
+
+ memcpy(ep->common.buffer, tmp_buf, n);
+ buf_remaining = ep->common.buffer_size - n;
+ }
+
+ TRACE_D12("\tEP%d: Rx Complete. Buffer (nearly) full. [%d]\n",
+ endp, buf_remaining);
+ usbs_d12_ep_rx_complete(ep, ret);
+ return;
+ }
+
+ // ----- Read the data from the chip -----
+
+ if (endp == D12_MAIN_ENDP)
+ n = d12_read_main_endp_buf(D12_BASE_ADDR,
+ ep->common.buffer + ep->received, &done);
+ else {
+ n = d12_read_endp_buf(D12_BASE_ADDR, RX_ENDP_INDEX[endp],
+ ep->common.buffer + ep->received);
+ done = (n < RX_ENDP_SIZE[endp]);
+ }
+
+ ep->received += n;
+ buf_remaining = ep->common.buffer_size - ep->received;
+
+ done = done || (buf_remaining < ep_size);
+
+ TRACE_D12("EP%d: Received %d bytes.\n", endp, n);
+ TRACE_BUF("\t", ep->common.buffer + ep->received-n, n);
+
+ // ----- If we're done, complete the receive -----
+
+ if (done) {
+ TRACE_D12("\tEP%d Rx Complete (%d) %p\n", endp,
+ ep->received, ep->common.complete_fn);
+ usbs_d12_ep_rx_complete(ep, ep->received);
+ }
+}
+
+// --------------------------------------------------------------------------
+// Stalls/unstalls the specified endpoint.
+
+static void
+usbs_d12_stall_rx_ep(rx_endpoint *ep, cyg_bool halt)
+{
+ ep->common.halted = halt;
+ d12_stall_endp(D12_BASE_ADDR, RX_ENDP_INDEX[ep->endp], halt);
+}
+
+// --------------------------------------------------------------------------
+// Handler for an Rx endpoint full interrupt. It clears the interrupt on the
+// D12 by reading the endpoint's status register then calls the routine to
+// read the data into the buffer.
+//
+// Called from the DSR context only.
+//
+
+static void
+usbs_d12_ep_rx_intr(rx_endpoint *ep)
+{
+ d12_read_last_trans_status(D12_BASE_ADDR, RX_ENDP_INDEX[ep->endp]);
+ usbs_d12_ep_rx(ep);
+}
+
+#endif
+
+// --------------------------------------------------------------------------
+// Common Tx Endpoint 1 & 2
+// --------------------------------------------------------------------------
+
+#if defined(_TX_EP1) || defined(_TX_EP2)
+
+// Clears out the endpoint data structure before/after a tx is complete.
+
+static void usbs_d12_clear_tx_ep(tx_endpoint *ep)
+{
+ ep->common.buffer = 0;
+ ep->common.buffer_size = 0;
+ ep->common.complete_fn = 0;
+ ep->common.complete_data = 0;
+
+ ep->transmitted = 0;
+ ep->tx_empty = false;
+}
+
+// --------------------------------------------------------------------------
+// This is called when a transmit is completed. It resets the endpoint vars
+// and calls the registered completion function, if any.
+//
+// CONTEXT:
+// Called from either the DSR or the app thread that started tx.
+
+static void usbs_d12_ep_tx_complete(tx_endpoint *ep, int result)
+{
+ completion_fn fn = ep->common.complete_fn;
+ void *data = ep->common.complete_data;
+
+ usbs_d12_clear_tx_ep(ep);
+
+ if (fn)
+ (*fn)(data, result);
+}
+
+// --------------------------------------------------------------------------
+// The routine writes data to the chip and updates the endpoint's counters.
+// It gets called at the start of a transfer operation to prime the device
+// and then gets called each time the chip finishes sending a packet to the
+// host and is ready for more data. If the amount of data remaining is
+// smaller than can fit in the chip's endpoint buffer, then this is the last
+// packet to send, so we call the completion function.
+//
+// CONTEXT:
+// Called from either the DSR or the app thread that started the tx
+// In either case, it's assumed the chip is locked.
+
+static void
+usbs_d12_ep_tx(tx_endpoint *ep)
+{
+ int n, nRemaining;
+
+ // ----- Already done. Intermittent interrupt, so get out -----
+
+ if (!ep->common.buffer)
+ return;
+
+ // ----- See how many bytes remaining in buffer -----
+
+ nRemaining = ep->common.buffer_size - ep->transmitted;
+
+ TRACE_D12("EP%d: Tx %p, %d Done, %d Remaining\n", ep->endp,
+ ep->common.buffer, ep->transmitted, nRemaining);
+
+ // ----- If prev packet was last, signal that we're done -----
+
+ if (nRemaining == 0 && !ep->tx_empty) {
+ TRACE_D12("\tEP%d: Tx complete (%d) %p\n", ep->endp,
+ ep->transmitted, ep->common.complete_fn);
+ usbs_d12_ep_tx_complete(ep, ep->transmitted);
+ return;
+ }
+
+ // ----- Write the next packet to chip -----
+
+ if (nRemaining < TX_ENDP_SIZE[ep->endp]) {
+ n = nRemaining;
+ ep->tx_empty = false;
+ }
+ else
+ n = TX_ENDP_SIZE[ep->endp];
+
+ TRACE_D12("EP%d: Writing %d bytes. %s\n", ep->endp,
+ n, (n == 0) ? "DONE" : "");
+ TRACE_BUF("\t", ep->common.buffer + ep->transmitted, n);
+
+ d12_write_endp_buf(D12_BASE_ADDR, TX_ENDP_INDEX[ep->endp],
+ ep->common.buffer + ep->transmitted, (uint8) n);
+
+ ep->transmitted += n;
+
+ // ----- If empty packet, complete now -----
+
+ if (n == 0) {
+ TRACE_D12("\tEP%d: Tx complete (%d) %p\n", ep->endp,
+ ep->transmitted, ep->common.complete_fn);
+ usbs_d12_ep_tx_complete(ep, ep->transmitted);
+ return;
+ }
+}
+
+// --------------------------------------------------------------------------
+// Stalls/unstalls the specified tx endpoint.
+
+static void
+usbs_d12_stall_tx_ep(tx_endpoint *ep, cyg_bool halt)
+{
+ ep->common.halted = halt;
+ d12_stall_endp(D12_BASE_ADDR, TX_ENDP_INDEX[ep->endp], halt);
+}
+
+// --------------------------------------------------------------------------
+// Handler for when the chip's tx RAM for an endoint has just been emptied
+// (sent to the host) and the chip is ready for more data.
+// We read the endpoint's last trans status register to clear the interrupt
+// on the D12, then call the tx function to send the next packet or
+// complete the transfer.
+
+static void
+usbs_d12_ep_tx_intr(tx_endpoint *ep)
+{
+ d12_read_last_trans_status(D12_BASE_ADDR, TX_ENDP_INDEX[ep->endp]);
+ usbs_d12_ep_tx(ep);
+}
+
+#endif // defined(_TX_EP1) || defined(_TX_EP2)
+
+// --------------------------------------------------------------------------
+// Application Program Interface (API)
+// --------------------------------------------------------------------------
+
+#if defined(_RX_EP1) || defined(_RX_EP2)
+// Starts a receive operation on the specified endpoint. If the buffer size
+// is zero the completion function is called immediately. The routine checks
+// if tehre is data in the chip's endpoint buffer, and if so it will call
+// ep_rx() to start reading the data out of the chip.
+//
+// If the endpoint is currently stalled, a read size of zero can be used to
+// block the calling thread until the stall is cleared. If the read size is
+// non-zero and the endpoint is stalled the completion function is called
+// immediately with an error result.
+
+static void
+usbs_d12_api_start_rx_ep(usbs_rx_endpoint *ep)
+{
+ rx_endpoint *epx = (rx_endpoint *) ep;
+
+ if (ep->halted) {
+ if (ep->buffer_size != 0)
+ usbs_d12_ep_rx_complete(epx, -EAGAIN);
+ }
+ else if (ep->buffer_size == 0) {
+ usbs_d12_ep_rx_complete(epx, 0);
+ }
+ else {
+ TRACE_D12("EP%d: Starting Rx, %p, %d\n", epx->endp, ep->buffer,
+ ep->buffer_size);
+ usbs_d12_lock();
+
+ epx->received = 0;
+ if (d12_data_available(D12_BASE_ADDR, RX_ENDP_INDEX[epx->endp]))
+ usbs_d12_ep_rx(epx);
+
+ usbs_d12_unlock();
+ }
+}
+
+// --------------------------------------------------------------------------
+// Halts/unhalts one of the generic rx (OUT) endpoints.
+//
+
+static void usbs_d12_api_stall_rx_ep(usbs_rx_endpoint *ep, cyg_bool halt)
+{
+ usbs_d12_lock();
+ usbs_d12_stall_rx_ep((rx_endpoint*) ep, halt);
+ usbs_d12_unlock();
+}
+
+#endif // defined(_RX_EP1) || defined(_RX_EP2)
+
+// --------------------------------------------------------------------------
+// Tx API
+// --------------------------------------------------------------------------
+
+#if defined(_TX_EP1) || defined(_TX_EP2)
+
+// This starts a transmit on one of the data endpoints. If the endpoint is
+// stalled a buffer size of zero can be used to block until the stall is
+// cleared. Any other size on a stalled endpoint will result in an error
+// callback immediately. The first packet is sent to the chip immediately,
+// in the application context. If the chip's buffer can contain the whole
+// transfer, the completion function will be called immediately, again,
+// still in the application context.
+//
+// If an empty packet is requested we send one from here and call the
+// completion function. This should not cause an intr on the D12.
+//
+// CONTEXT:
+// Called from an application thread
+
+static void usbs_d12_api_start_tx_ep(usbs_tx_endpoint *ep)
+{
+ tx_endpoint *epx = (tx_endpoint*) ep;
+
+ if (ep->halted) {
+ if (ep->buffer_size != 0)
+ usbs_d12_ep_tx_complete(epx, -EAGAIN);
+ }
+ else if (ep->buffer_size == 0) {
+ usbs_d12_lock();
+
+ d12_write_endp_buf(D12_BASE_ADDR, TX_ENDP_INDEX[epx->endp], 0, 0);
+ usbs_d12_ep_tx_complete(epx, 0);
+
+ usbs_d12_unlock();
+ }
+ else {
+ TRACE_D12("EP%d: Starting Tx, %p, %d\n", epx->endp, ep->buffer,
+ ep->buffer_size);
+ usbs_d12_lock();
+
+ epx->tx_empty = true;
+ epx->transmitted = 0;
+ usbs_d12_ep_tx(epx);
+
+ usbs_d12_unlock();
+ }
+}
+
+// --------------------------------------------------------------------------
+// Halts/unhalts one of the generic endpoints.
+
+static void
+usbs_d12_api_stall_tx_ep(usbs_tx_endpoint *ep, cyg_bool halt)
+{
+ usbs_d12_lock();
+ usbs_d12_stall_tx_ep((tx_endpoint*) ep, halt);
+ usbs_d12_unlock();
+}
+
+#endif // defined(_TX_ENDP1) || defined(_TX_EP2)
+
+// --------------------------------------------------------------------------
+// DSR
+// --------------------------------------------------------------------------
+
+// The DSR for the D12 chip. This is normally called in the DSR context when
+// the D12 has raised its interrupt flag indicating that it needs to be
+// serviced. The interrupt register contains bit flags that are OR'ed togther
+// indicating what items need to be serviced. There are flags for the
+// following:
+// - The endpoints (one bit for each)
+// - Bus Reset
+// - Suspend Change
+// - DMA (terminal count)
+//
+// Care must be taken in that the D12's interrupt output is level-sensitive
+// (in that the interrupt sources are OR'ed together and not all cleared
+// atomically in a single operation). Platforms (such as the PC) may be
+// expecting edge-triggered interrupts, so we must work around that.
+// So, we loop on the interrupt register. Even though, in each loop, we
+// perform all of the required operations to clear the interrupts, a new
+// one may have arrived before we finished clearing the previous ones.
+// So we read the intr reg again. Once the intr reg gives a zero reading
+// we know that the D12 has dropped its IRQ line.
+//
+// Note, if we're configured to use a thread, this routine is called from
+// within a thread context (not a DSR context).
+//
+
+static void
+usbs_d12_dsr(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ uint16 status;
+ bool suspended;
+
+ CYG_ASSERT(vector == CYGNUM_DEVS_USB_D12_INT,
+ "DSR should only be invoked for D12 interrupts");
+
+ while ((status = d12_read_intr_reg(D12_BASE_ADDR)) != 0) {
+ TRACE_D12("Intr Status: 0x%04X\n", (unsigned) status);
+
+ if (status & D12_INTR_BUS_RESET) {
+ TRACE_D12("\n>>> Bus Reset <<<\n");
+ usbs_d12_reset();
+ }
+ else {
+
+ // ----- Suspend Change -----
+
+ suspended = (bool) (ep0.common.state & USBS_STATE_SUSPENDED);
+
+ if (status & D12_INTR_SUSPEND_CHANGE) {
+ if (!suspended && (status & ~D12_INTR_SUSPEND_CHANGE) == 0)
+ usbs_d12_suspend(true);
+ }
+ else if (suspended)
+ usbs_d12_suspend(false);
+
+ // ----- Bulk Endpoints -----
+
+#ifdef _TX_EP2
+ if (status & D12_INTR_TX_ENDP2)
+ usbs_d12_ep_tx_intr(&tx_ep2);
+#endif
+
+#ifdef _RX_EP2
+ if (status & D12_INTR_RX_ENDP2)
+ usbs_d12_ep_rx_intr(&rx_ep2);
+#endif
+
+ // ----- Interrupt Endpoints -----
+
+#ifdef _TX_EP1
+ if (status & D12_INTR_TX_ENDP1)
+ usbs_d12_ep_tx_intr(&tx_ep1);
+#endif
+
+#ifdef _RX_EP1
+ if (status & D12_INTR_RX_ENDP1)
+ usbs_d12_ep_rx_intr(&rx_ep1);
+#endif
+
+ // ----- Control Endpoint -----
+
+ if (status & D12_INTR_TX_CTRL_ENDP)
+ usbs_d12_ep0_tx_intr();
+
+ if (status & D12_INTR_RX_CTRL_ENDP)
+ usbs_d12_ep0_rx_intr();
+ }
+ }
+
+ cyg_drv_interrupt_unmask(vector);
+}
+
+// --------------------------------------------------------------------------
+// Interrupt
+// --------------------------------------------------------------------------
+
+// Here, the ISR does nothing but schedule the DSR to run. The ISR's/DSR's
+// are serialized. The CPU won't process another ISR until after the DSR
+// completes.
+
+static uint32
+usbs_d12_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ CYG_ASSERT(CYGNUM_DEVS_USB_D12_INT == vector,
+ "usbs_isr: Incorrect interrupt");
+
+ // Prevent another interrupt until DSR completes
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+// --------------------------------------------------------------------------
+// Polling
+// --------------------------------------------------------------------------
+
+static void
+usbs_d12_poll(usbs_control_endpoint *endp)
+{
+ CYG_ASSERT(endp == &ep0.common, "usbs_poll: wrong endpoint");
+
+ usbs_d12_lock();
+ usbs_d12_dsr(CYGNUM_DEVS_USB_D12_INT, 0, 0);
+ usbs_d12_unlock();
+}
+
+// --------------------------------------------------------------------------
+// Thread Processing
+// --------------------------------------------------------------------------
+
+// The user can opt to configure the driver to service the D12 using a high
+// priority thread. The thread's priority MUST be greater than the priority
+// of any application thread making calls into the driver.
+// When we use a thread, the DSR simply signals a semaphore tio wake the
+// thread up. The thread, in turn, calls the the routine to service the D12,
+// now in a thread context. This allows for greater debug options, including
+// tracing.
+
+#ifdef CYGPKG_DEVS_USB_D12_THREAD
+
+static byte usbs_d12_thread_stack[CYGNUM_DEVS_USB_D12_THREAD_STACK_SIZE];
+static cyg_thread usbs_d12_thread;
+static cyg_handle_t usbs_d12_thread_handle;
+static cyg_sem_t usbs_d12_sem;
+
+static void
+usbs_d12_thread_dsr(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ cyg_semaphore_post(&usbs_d12_sem);
+
+ CYG_UNUSED_PARAM(cyg_vector_t, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+}
+
+
+static void
+usbs_d12_thread_fn(cyg_addrword_t param)
+{
+ while (1) {
+ cyg_semaphore_wait(&usbs_d12_sem);
+ usbs_d12_poll(&ep0.common);
+ }
+
+ CYG_UNUSED_PARAM(cyg_addrword_t, param);
+}
+
+
+static void
+usbs_d12_thread_init(void)
+{
+ cyg_semaphore_init(&usbs_d12_sem, 0);
+
+ cyg_thread_create(CYGNUM_DEVS_USB_D12_THREAD_PRIORITY,
+ &usbs_d12_thread_fn, 0, "D12 USB Driver Thread",
+ usbs_d12_thread_stack,
+ CYGNUM_DEVS_USB_D12_THREAD_STACK_SIZE,
+ &usbs_d12_thread_handle, &usbs_d12_thread);
+ cyg_thread_resume(usbs_d12_thread_handle);
+}
+
+#endif // CYGPKG_DEVS_USB_D12_THREAD
+
+// --------------------------------------------------------------------------
+// Start/Reset
+// --------------------------------------------------------------------------
+
+// Chip initialization and handler for a USB Bus Reset. This gets called at
+// system startup and after a USB Bus Reset. It puts the chip into the
+// default state, with USB Address 0, connected to the bus (i.e.
+// "SoftConnect" asserted). Interrupts to the main endpoint are turned on
+// via the DMA register.
+
+static void
+usbs_d12_reset(void)
+{
+ int old_state = ep0.common.state;
+ ep0.common.state = USBS_STATE_DEFAULT;
+
+ if (ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_RESET, old_state);
+ }
+
+ d12_set_addr_enable(D12_BASE_ADDR, 0, true);
+ d12_set_endp_enable(D12_BASE_ADDR, true);
+ d12_set_dma(D12_BASE_ADDR, D12_DMA_MAIN_ENDP_INTR_ENABLE);
+ d12_set_mode(D12_BASE_ADDR, D12_MODE_CFG_DFLT | D12_MODE_CFG_SOFT_CONNECT,
+ D12_MODE_CLK_DFLT);
+
+ // If any endpoints were going, signal the end of transfers
+
+#if defined(_TX_EP2)
+ usbs_d12_ep_tx_complete(&tx_ep2, -EPIPE);
+#endif
+
+#if defined(_RX_EP2)
+ usbs_d12_ep_rx_complete(&rx_ep2, -EPIPE);
+#endif
+
+#if defined(_TX_EP1)
+ usbs_d12_ep_tx_complete(&tx_ep1, -EPIPE);
+#endif
+
+#if defined(_RX_EP1)
+ usbs_d12_ep_rx_complete(&rx_ep1, -EPIPE);
+#endif
+}
+
+// --------------------------------------------------------------------------
+// The start function is called indirectly by the application when
+// initialization is complete. By this time, the enumeration data has been
+// assigned to the control endpoint and we're ready to connect to the host.
+// Within the reset function the D12's SoftConnect line is asserted which
+// allows the host (hub) to see us on the USB bus. If connected, the host
+// should start the enumeration process.
+//
+
+static void usbs_d12_start(usbs_control_endpoint *endpoint)
+{
+#if defined(_TRACE) && !defined(_TRACE_STDOUT)
+ TRACE_OPEN(TRACE_SINK);
+#endif
+
+ CYG_ASSERT(endpoint == &ep0.common, "ep0 start: wrong endpoint");
+ TRACE_D12("USBS D12: Starting.\n");
+
+ d12_clear_all_intr(D12_BASE_ADDR);
+ usbs_d12_reset();
+}
+
+// --------------------------------------------------------------------------
+// Initialization
+// --------------------------------------------------------------------------
+
+// This routine is called early in the program's startup, possibly before
+// main (from within a C++ object initialization). We want to put this chip
+// and driver in a neutral, but ready, state until the application gets
+// control, initializes itself and calls the usb start function.
+//
+// The D12 has a "Soft Connect" feature to tristate the USB bus, making it
+// appear that the USB device is not connected to the bus. We initially
+// keep seperated from the bus to allow for initialization.
+
+void
+usbs_d12_init(void)
+{
+ cyg_DSR_t *pdsr;
+
+ d12_set_mode(D12_BASE_ADDR, D12_MODE_CFG_DFLT & ~D12_MODE_CFG_SOFT_CONNECT,
+ D12_MODE_CLK_DFLT);
+
+ d12_set_addr_enable(D12_BASE_ADDR, 0, false);
+ d12_set_endp_enable(D12_BASE_ADDR, false);
+
+ // ----- Clear the endpoints -----
+
+#if defined(_TX_EP2)
+ usbs_d12_clear_tx_ep(&tx_ep2);
+#endif
+
+#if defined(_RX_EP2)
+ usbs_d12_clear_rx_ep(&rx_ep2);
+#endif
+
+#if defined(_TX_EP1)
+ usbs_d12_clear_tx_ep(&tx_ep1);
+#endif
+
+#if defined(_RX_EP1)
+ usbs_d12_clear_rx_ep(&rx_ep1);
+#endif
+
+ // ----- Start the thread (if we're using it) -----
+
+#ifdef CYGPKG_DEVS_USB_D12_THREAD
+ usbs_d12_thread_init();
+ pdsr = &usbs_d12_thread_dsr;
+#else
+ pdsr = &usbs_d12_dsr;
+#endif
+
+ // ----- Attach the ISR -----
+
+ cyg_drv_interrupt_create(CYGNUM_DEVS_USB_D12_INT,
+ 0, 0, &usbs_d12_isr, pdsr,
+ &usbs_d12_intr_handle, &usbs_d12_intr_data);
+
+ cyg_drv_interrupt_attach(usbs_d12_intr_handle);
+ cyg_drv_interrupt_unmask(CYGNUM_DEVS_USB_D12_INT);
+}
+
+// ----------------------------------------------------------------------------
+// Testing support.
+
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep0.common,
+#ifdef CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "0c",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE,
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ /*
+#ifdef _TX_EP1
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &tx_ep1.common,
+# ifdef CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1w",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 0,
+ max_size : 0x0FFFF, // Driver limitation, only a single
+ // buffer descriptor is used
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+#ifdef _RX_EP1
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &rx_ep1.common,
+# ifdef CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1r",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 1,
+ max_size : 0x0FFFF, // Driver limitation
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+ */
+
+#ifdef _TX_EP2
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &tx_ep2.common,
+# ifdef CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2w",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 0,
+ max_size : 0x1000, // 4k for testing
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+#ifdef _RX_EP2
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &rx_ep2.common,
+# ifdef CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2r",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 1,
+ max_size : 0x1000, // 4k for testing
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
+
--- /dev/null
+//==========================================================================
+//
+// usbs_d12_data.cxx
+//
+// Static data for the D12 USB device driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): fmp
+// Contributors: fmp
+// Date: 2004-05-27
+//
+// This file contains various objects that should go into extras.o
+// rather than libtarget.a, e.g. devtab entries that would normally
+// be eliminated by the selective linking.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/devtab.h>
+#include <cyg/io/usb/usbs_d12.h>
+#include <pkgconf/devs_usb_d12.h>
+
+// ----------------------------------------------------------------------------
+// Initialization. The goal here is to call usbs_d12_init()
+// early on during system startup, to take care of things like
+// registering interrupt handlers etc. which are best done
+// during system init.
+//
+// If the endpoint 0 devtab entry is available then its init()
+// function can be used to take care of this. However the devtab
+// entries are optional so an alternative mechanism must be
+// provided. Unfortunately although it is possible to give
+// a C function the constructor attribute, it cannot be given
+// an initpri attribute. Instead it is necessary to define a
+// dummy C++ class.
+
+extern "C" void usbs_d12_init(void);
+
+#ifndef CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY
+class usbs_d12_initialization {
+public:
+ usbs_d12_initialization() {
+ usbs_d12_init();
+ }
+};
+
+static usbs_d12_initialization usbs_d12_init_object
+ CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+#endif
+
+// ----------------------------------------------------------------------------
+// The devtab entries. Each of these is optional, many applications
+// will want to use the lower-level API rather than go via
+// open/read/write/ioctl.
+
+#ifdef CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY
+
+// For endpoint 0 the only legal operations are get_config() and
+// set_config(), and these are provided by the common package.
+
+static bool
+usbs_d12_devtab_ep0_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ usbs_d12_init();
+ return true;
+}
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_ep0_devtab_functions,
+ &cyg_devio_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static CHAR_DEVTAB_ENTRY(usbs_d12_ep0_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "0c",
+ 0,
+ &usbs_d12_ep0_devtab_functions,
+ &usbs_d12_devtab_ep0_init,
+ 0,
+ (void*) &usbs_d12_ep0);
+#endif
+
+// ----------------------------------------------------------------------------
+// Common routines for ep1 and ep2.
+
+#if defined(CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY)
+
+static bool
+usbs_d12_devtab_dummy_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ return true;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// tx (in) ep1 devtab entry. This can only be used for slave->host,
+// so only the cwrite() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_tx_ep1_devtab_functions,
+ &usbs_devtab_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_tx_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1w",
+ 0,
+ &usbs_d12_tx_ep1_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_tx_ep1);
+#endif
+
+// ----------------------------------------------------------------------------
+// rx (out) ep1 devtab entry. This can only be used for host->slave,
+// so only the cread() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_rx_ep1_devtab_functions,
+ &cyg_devio_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_rx_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1r",
+ 0,
+ &usbs_d12_rx_ep1_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_rx_ep1);
+#endif
+
+
+// ----------------------------------------------------------------------------
+// tx (in) ep2 devtab entry. This can only be used for slave->host, so only the
+// cwrite() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_tx_ep2_devtab_functions,
+ &usbs_devtab_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_tx_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2w",
+ 0,
+ &usbs_d12_tx_ep2_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_tx_ep2);
+#endif
+
+// ----------------------------------------------------------------------------
+// rx (out) ep2 devtab entry. This can only be used for host->slave,
+// so only the cread() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_rx_ep2_devtab_functions,
+ &cyg_devio_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_rx_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2r",
+ 0,
+ &usbs_d12_rx_ep2_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_rx_ep2);
+#endif
--- /dev/null
+2006-06-06 Frank Pagliughi <fpagliughi@mindspring.com>
+
+ * First version of the USB device driver using the philips D12
+ for i386 targets.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# usbs_i386_sorod12.cdl
+#
+# Hardware specific parts for the SoRo D12 PC 104 USB card.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004, 2006 eCosCentric Limited
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc., asl
+# Contributors:
+# Date: 2006-04-27
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_I386_SOROD12 {
+ display "Hardware specific part for SoRo D12 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_DEVS_USB_D12
+
+ requires { CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER ==
+ "<cyg/io/usb/usbs_i386_sorod12.inl>" }
+
+ cdl_option CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED {
+ display "I/O mapped."
+ flavor bool
+ default_value 1
+ description "
+ The PDIUSBD12 can be mapped into the processor's I/O space or memory
+ space. If this is set the driver accesses the chip through HAL_READ
+ and HAL_WRITE macros, otherwise it uses direct memory access."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_I386_SOROD12_BASEADDR {
+ display "Base Address of D12 chip"
+ flavor data
+ no_define
+ legal_values 1 to 0xFF8
+ default_value 544
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ requires { CYGNUM_DEVS_USB_D12_BASEADDR ==
+ CYGNUM_DEVS_USB_I386_SOROD12_BASEADDR }
+ description "
+ The base memory or I/O address where the USB chip resides."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_I386_SORODD12_IRQ {
+ display "IRQ for the D12 chip"
+ flavor data
+ no_define
+ legal_values { 3 5 7 }
+ default_value 5
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ requires { CYGNUM_DEVS_USB_D12_IRQ ==
+ CYGNUM_DEVS_USB_I386_SORODD12_IRQ }
+ description "
+ The IRQ assigned to the D12 chip."
+ }
+}
--- /dev/null
+#ifndef USBS_I386_SORO12_INL
+#define USBS_I386_SORO12_INL
+//==========================================================================
+//
+// usbS_i386_sorod12.inl
+//
+// Hardware specific parts for the SoRo D12 PC 104 USB card.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006, eCosCentric
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp), ASL
+// Date: 2004-05-22
+//
+// This code is a hardware specific device driver for the SoRo Systems
+// USB-D12-104, a PC/104 (ISA) Full-Speed USB slave board, which turns
+// a PC/104 stack into a USB slave device. The board contains a
+// Philips PDIUSBD12 Peripheral Controller Chip mapped into the PC's
+// I/O space, with jumper-selectable I/O base address, IRQ, and DMA
+// settings. The eCos config tool is used to adjust settings for this
+// driver to match the physical jumper settings. The chip could run in
+// polled mode without an IRQ, but this wouldn't be a great idea other
+// than maybe a debug environment.
+
+// ------------------------------------------------------------------------
+// Data-Only I/O
+// ------------------------------------------------------------------------
+//
+
+#include <pkgconf/devs_usb_i386_sorod12.h>
+
+// These routines read or write 8 bit values to the data area.
+
+static inline byte d12_read_data_byte(d12_addr_type base_addr)
+{
+ #if defined(CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED)
+ byte val;
+ HAL_READ_UINT8((unsigned) base_addr, val);
+ return val;
+ #else
+ return *base_addr;
+ #endif
+}
+
+static inline void d12_write_data_byte(d12_addr_type base_addr, byte val)
+{
+ #if defined(CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED)
+ HAL_WRITE_UINT8((unsigned) base_addr, val);
+ #else
+ *base_addr = val;
+ #endif
+}
+
+// This routine writes a command to the device.
+
+static inline void d12_write_cmd(d12_addr_type base_addr, byte cmd)
+{
+ #if defined(CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED)
+ HAL_WRITE_UINT8((unsigned) base_addr+1, cmd);
+ #else
+ *(base_addr+1) = cmd;
+ #endif
+}
+
+// ------------------------------------------------------------------------
+// Reads 'n' bytes from the data address of the D12 and places them into
+// the buf[] array. Buf can be NULL, in which case the specified number of
+// bytes are read and discarded.
+
+static uint8 d12_read_data(d12_addr_type base_addr, byte *buf, uint8 n)
+{
+ uint8 i;
+
+ if (buf) {
+ for (i=0; i<n; ++i)
+ buf[i] = d12_read_data_byte(base_addr);
+ }
+ else {
+ for (i=0; i<n; ++i)
+ d12_read_data_byte(base_addr);
+ n = 0;
+ }
+
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Writes 'n' bytes out the data reg of the chip
+
+static void d12_write_data(d12_addr_type base_addr, const byte *buf, uint8 n)
+{
+ uint8 i;
+
+ for (i=0; i<n; ++i)
+ d12_write_data_byte(base_addr, buf[i]);
+}
+
+#endif // USBS_I386_SORO12_INL
--- /dev/null
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip RTC unit
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+
+
--- /dev/null
+# ====================================================================
+#
+# lpc2xxx_wallclock.cdl
+#
+# eCos configuration data for LPC2xxx internal RTC
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Gary Thomas
+## Copyright (C) 2004 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors: jskov
+# Date: 2007-06-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_ARM_LPC2XXX {
+ display "LPC2xxx Real-time clock"
+ description "RTC driver for the LPC2xxx controller"
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_HAL_ARM_LPC2XXX
+
+ requires { CYGHWR_HAL_ARM_LPC2XXX_IDLE_PWRSAVE == 0 }
+ compile lpc2xxx_wallclock.cxx
+
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT {
+ display "RTC prescaler integer portion"
+ flavor data
+ calculated { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED /
+ CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / 32768) - 1 }
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC {
+ display "RTC prescaler fractional portion"
+ flavor data
+ calculated { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED /
+ CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) -
+ ((CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT + 1) * 32768)) }
+ }
+}
--- /dev/null
+//==========================================================================
+//
+// lpc2xxx_wallclock.cxx
+//
+// Wallclock implementation for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+// Copyright (C) 2004 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-06-19
+// Purpose: Wallclock driver for LPC2xxx
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devices_wallclock_arm_lpc2xxx.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/io/wallclock.hxx>
+#include <cyg/io/wallclock/wallclock.inl>
+
+/*
+ * I don't like to write LOTS OF CAPITALIZED TEXT.
+ * This code is intended for LPC2xxx processors _only_, so there is nothing
+ * wrong with accessing this device directly without using the HAL macros.
+ */
+
+struct time {
+ volatile cyg_uint32 sec;
+ volatile cyg_uint32 min;
+ volatile cyg_uint32 hour;
+ volatile cyg_uint32 dom;
+ volatile cyg_uint32 dow;
+ volatile cyg_uint32 doy;
+ volatile cyg_uint32 month;
+ volatile cyg_uint32 year;
+};
+
+struct rtcdev {
+ volatile cyg_uint32 ilr;
+ volatile cyg_uint32 ctc;
+ volatile cyg_uint32 ccr;
+ volatile cyg_uint32 ciir;
+ volatile cyg_uint32 amr;
+ volatile cyg_uint32 ctime[3];
+ struct time time;
+ cyg_uint32 dummy[8];
+ struct time alarm;
+ volatile cyg_uint32 preint;
+ volatile cyg_uint32 prefrac;
+};
+
+static struct rtcdev * const rtc =
+ (struct rtcdev *) CYGARC_HAL_LPC2XXX_REG_RTC_BASE;
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+ /* halt clock, disable interrupts, disable alarm */
+ rtc->ccr = 0x2;
+ rtc->ciir = 0x0;
+ rtc->amr = 0xf;
+
+ /* initialize prescaler */
+ rtc->preint = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT;
+ rtc->prefrac = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC;
+
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+ /* reset time to the Unix Epoch */
+ rtc->time.year = 1970;
+ rtc->time.month = 1;
+ rtc->time.dom = 1;
+ rtc->time.doy = 1;
+ rtc->time.dow = 4;
+ rtc->time.hour = 0;
+ rtc->time.min = 0;
+ rtc->time.sec = 0;
+#endif
+
+ /* reset alarm */
+ rtc->alarm.year = rtc->alarm.month = rtc->alarm.dom = rtc->alarm.doy =
+ rtc->alarm.dow = rtc->alarm.hour = rtc->alarm.min =
+ rtc->alarm.sec = 0;
+
+ /* start clock */
+ rtc->ccr = 0x1;
+}
+
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ return _simple_mktime(rtc->time.year,
+ rtc->time.month,
+ rtc->time.dom,
+ rtc->time.hour,
+ rtc->time.min,
+ rtc->time.sec);
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+ cyg_uint32 year, month, dom, hour, min, sec;
+
+ /* halt clock, reset counter */
+ rtc->ccr = 0x2;
+
+ /* set time */
+ _simple_mkdate(secs, &year, &month, &dom, &hour, &min, &sec);
+ rtc->time.year = year;
+ rtc->time.month = month;
+ rtc->time.dom = dom;
+ rtc->time.hour = hour;
+ rtc->time.min = min;
+ rtc->time.sec = sec;
+
+ /* restart clock */
+ rtc->ccr = 0x1;
+}
+#endif
--- /dev/null
+2006-02-18 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * Added watchdog driver for ARM AT91 devices which have the
+ Watchdog Timer Controller as opposed to the older devices which
+ have the Watchdog Timer Interface.
+
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// 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####
--- /dev/null
+# ====================================================================
+#
+# watchdog_at91wdtc.cdl
+#
+# eCos watchdog for ARM AT91 WDTC driver configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 Andrew Lunn (andrew.lunn@ascom.ch>
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): tkoeller
+# Contributors: tkoeller, nickg, asl
+# Date: 2006-02-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "ARM AT91 WDTC watchdog driver"
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGPKG_KERNEL
+ hardware
+ define_header devs_watchdog_arm_at91wdtc.h
+ compile watchdog_at91wdtc.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WATCHDOG_HARDWARE
+ description "
+ This package uses the watchdog device integrated
+ in the AT91 to execute a predefined action if the
+ application fails to call the reset function for
+ longer than a given timeout interval. This package
+ currently only supports the AT91SAM7S device which
+ use the Watchdog Timer Controller."
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ calculated 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS {
+ display "Desired timeout value"
+ flavor data
+ default_value 1000
+ description "
+ This parameter controls the watchdog timeout interval.
+ Note that you may not get the exact value requested
+ here, the timeout interval may have to be adjusted
+ because of hardware limitations. The actual timeout
+ used will be the smallest possible value that is not
+ less than this parameter. Since the timeout is derived
+ from the LC based slow clock don't expect great accuracy.
+ On my board a 1000ms timeout actually goes off after 550ms!"
+ }
+
+ cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_TIMEOUT_VALUE {
+ display "Calculated timeout value"
+ flavor data
+ calculated { (CYGNUM_HAL_ARM_AT91_SLOW_CLOCK / 128) *
+ (CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS / 1000)
+ }
+ legal_values { 0 to 4096 }
+ description "
+ This is the calculated value that will be placed into
+ watchdog counter timer."
+ }
+
+ cdl_option CYGSEM_DEVS_WATCHDOG_ARM_AT91WDTC_RESET {
+ display "Generate reset on watchdog expiration"
+ flavor bool
+ default_value 1
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ description "
+ Enabling this option changes the watchdog operation mode
+ to generate a system reset upon expiration instead of
+ invoking an application-defined action."
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC_OPTIONS {
+ display "AT91 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF watchdog_at91WDTC.cdl
--- /dev/null
+//==========================================================================
+//
+// devs/watchdog/arm/at91/watchdog_at91wdtc.cxx
+//
+// Watchdog implementation for ARM AT91 CPUs using the WDTC
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tkoeller
+// Contributors: tkoeller, nickg, asl
+// Date: 2006-02-18
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the ATMEL AT91 watchdog timer controller.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/watchdog.h>
+#include <pkgconf/devs_watchdog_arm_at91wdtc.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/io/watchdog.hxx>
+
+#include <cyg/infra/diag.h>
+
+#if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/kernel/intr.hxx>
+#endif
+
+//==========================================================================
+
+#if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+
+#define MRVAL (AT91_WDTC_WDMR_RSTEN | AT91_WDTC_WDMR_DBGHLT)
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+ resolution = CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS * 1000000;
+ CYG_REPORT_RETURN();
+}
+
+#else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+
+#define MRVAL (AT91_WDTC_WDMR_FIEN | AT91_WDTC_WDMR_DBGHLT)
+#define INT_PRIO 7
+
+//==========================================================================
+
+static Cyg_Watchdog *wd;
+
+//==========================================================================
+
+static cyg_uint32
+isr(cyg_vector vector, CYG_ADDRWORD data)
+{
+ cyg_uint32 sr;
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2XV(vector, data);
+
+ // Read the status register to clear the interrupt
+ HAL_READ_UINT32(AT91_WDTC + AT91_WDTC_WDSR, sr);
+
+ wd->trigger();
+ Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WDTC);
+ CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
+ return Cyg_Interrupt::HANDLED;
+}
+
+//==========================================================================
+
+static CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_DRIVERS)
+ Cyg_Interrupt wdint(
+ CYGNUM_HAL_INTERRUPT_WDTC,
+ INT_PRIO,
+ 0,
+ isr,
+ NULL
+ );
+
+//==========================================================================
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ wd = this;
+
+ wdint.attach();
+ wdint.acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WDTC);
+ wdint.unmask_interrupt(CYGNUM_HAL_INTERRUPT_WDTC);
+ resolution = CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS * 1000000;
+ CYG_REPORT_RETURN();
+}
+
+#endif /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+/*
+ * Reset watchdog timer. This needs to be called regularly to prevent
+ * the watchdog from firing.
+ */
+
+void
+Cyg_Watchdog::reset(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ /* Write magic code to reset the watchdog. */
+ HAL_WRITE_UINT32(AT91_WDTC + AT91_WDTC_WDCR,
+ AT91_WDTC_WDCR_RELOAD | AT91_WDTC_WDCR_KEY);
+
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+/*
+ * Start watchdog to generate a hardware reset
+ * or interrupt when expiring.
+ */
+
+void
+Cyg_Watchdog::start(void)
+{
+ cyg_uint32 val, val1;
+
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ val = (MRVAL | CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_TIMEOUT_VALUE |
+ (CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_TIMEOUT_VALUE <<
+ AT91_WDTC_WDMR_WDD_SHIFT));
+
+ HAL_WRITE_UINT32(AT91_WDTC + AT91_WDTC_WDMR, val);
+ HAL_READ_UINT32(AT91_WDTC + AT91_WDTC_WDMR, val1);
+
+ // If this assert goes if it probably means something else has
+ // already programmed the watchdog. The mode register is only
+ // writeable once and once it is set it can only be reset by a
+ // processor reset.
+ CYG_ASSERT(val == val1, "Unable to configure watchdog");
+
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+// End of watchdog_at91.cxx
--- /dev/null
+//==========================================================================
+//
+// ramfs3.c
+//
+// Test fileio system, especially lseek calls.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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, asl, Paluch Sebastian
+// Contributors: nickg
+// Date: 2006-10-05
+// Purpose: Test fileio system
+// Description: This test uses the testfs to check out the initialization
+// and basic operation of the fileio system
+//
+//
+//
+//
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <cyg/fileio/fileio.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h> // HAL polled output
+//==========================================================================
+
+#define SHOW_RESULT( _fn, _res ) \
+diag_printf("FAIL: " #_fn "() returned %ld %s\n", \
+ (unsigned long)_res, _res<0?strerror(errno):"");
+
+//==========================================================================
+
+cyg_uint8 buf[256];
+cyg_uint8 buf1[256];
+
+//==========================================================================
+// main
+
+int main( int argc, char **argv )
+{
+ int err;
+ FILE *stream;
+ long pos;
+ unsigned int i;
+ char header[3];
+
+ CYG_TEST_INIT();
+
+ // --------------------------------------------------------------
+
+ CYG_TEST_INFO("mount /");
+ err = mount( "", "/", "ramfs" );
+
+ if( err < 0 ) SHOW_RESULT( mount, err );
+
+ CYG_TEST_INFO("creating /fseek");
+ stream = fopen("/fseek","w+");
+ if (!stream) {
+ SHOW_RESULT( fopen, NULL);
+ CYG_TEST_FAIL_FINISH("done");\
+ }
+
+ for (i = 0; i < sizeof(buf); i++) {
+ buf[i] = i % 256;
+ }
+
+ CYG_TEST_INFO("writing test pattern");
+ err=fwrite(buf,sizeof(buf), 1, stream);
+ if ( err < 0 ) SHOW_RESULT( fwrite, err );
+
+ pos = ftell(stream);
+ if (pos < 0) SHOW_RESULT( ftell, pos );
+ if (pos != sizeof(buf))
+ diag_printf("<FAIL>: ftell is not telling the truth.");
+
+ CYG_TEST_INFO("fseek()ing to 85");
+ err = fseek(stream, 85, SEEK_SET);
+ if ( err < 0 ) SHOW_RESULT( fseek, err );
+
+ pos = ftell(stream);
+ if (pos < 0) SHOW_RESULT( ftell, pos );
+ if (pos != 85) CYG_TEST_FAIL("ftell is not telling the truth");
+
+ err = fread(header,3,1,stream);
+ if ( err < 0 ) SHOW_RESULT( fwrite, err );
+ if ((header[0] != 85) ||
+ (header[1] != 86) ||
+ (header[2] != 87))
+ CYG_TEST_FAIL("Read returned false data");
+
+ pos = ftell(stream);
+ if (pos < 0) SHOW_RESULT( ftell, pos );
+ if (pos != 88) CYG_TEST_FAIL("ftell is not telling the truth");
+
+ for (i = 88; i < 161; i++) {
+ buf[i] = 0x42;
+ }
+
+ CYG_TEST_INFO("writing");
+ err = fwrite(buf+88, 73, 1, stream);
+ if ( err < 0 ) SHOW_RESULT( fwrite, err );
+
+ pos = ftell(stream);
+ if (pos < 0) SHOW_RESULT( ftell, pos );
+ if (pos != 161) CYG_TEST_FAIL("ftell is not telling the truth");
+
+ CYG_TEST_INFO("closing file");
+ err = fclose(stream);
+ if (err != 0) SHOW_RESULT( fclose, err );
+
+ CYG_TEST_INFO("open file /fseek");
+ stream = fopen("/fseek", "r+");
+ if (!stream) {
+ SHOW_RESULT( fopen, NULL);
+ CYG_TEST_FAIL_FINISH("done");\
+ }
+
+ CYG_TEST_INFO("Seeking to beginning of file");
+ err = fseek(stream, 0, SEEK_SET);
+ if ( err < 0 ) SHOW_RESULT( fseek, err );
+
+ CYG_TEST_INFO("Reading buf1");
+ err = fread(buf1,sizeof(buf1),1, stream);
+ if (err != 1) SHOW_RESULT( fread, err );
+
+ CYG_TEST_INFO("Comparing contents");
+ if (memcmp(buf, buf1, sizeof(buf1)))
+ CYG_TEST_FAIL("File contents inconsistent");
+
+ CYG_TEST_INFO("closing file");
+ err = fclose(stream);
+ if (err != 0) SHOW_RESULT( fclose, err );
+
+ CYG_TEST_INFO("umount /");
+ err = umount( "/" );
+ if( err < 0 ) SHOW_RESULT( umount, err );
+
+ CYG_TEST_PASS_FINISH("ramfs3");
+}
--- /dev/null
+2008-05-11 James G. Smith <jsmith@rallysmith.co.uk
+ Andrew Lunn <andrew@lunn.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl: CDL for crystal vs clock signal.
+ * include/hal_platform_setup.h: Rework flash wait states to remove
+ redundant code when running at > 60MHz. Support clock signal input
+ when starting the main clock.
+
+2008-04-30 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * include/pkgconf/mlt_arm_at91sam7x512_rom.{h|ldi}: Added the
+ memory layout files to support the at91sam7x512
+ * cdl/hal_arm_at91s.cdl: Added the configuration options to
+ support the at91sam7x512
+
+2008-04-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/hal_platform_setup.h: Fix setting the flash wait states
+ when the clock is running faster than 60MHz. r0 was undefined
+ causing a data abort.
+
+2007-03-26 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl: SAM7X and SAM7XC have a CAN bus
+ controller.
+
+2007-01-17 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * include/plf_io.h
+ * src/at91sam7s_misc.c
+ Added code to initialise the platform ethernet hardware if need be
+
+2007-01-02 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/hal_arm_at91sam7s.cdl Moved HAL_PLATFORM_XXX defines and
+ definition of platform header file (CYGBLD_HAL_PLATFORM_H) from
+ package CYGPKG_HAL_ARM_AT91SAM7 into board specific packages.
+
+2006-06-01 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl: Implement the SPI bus 1 interface for
+ the SAM7X and SAM7XC.
+
+2006-06-01 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * include/plf_io.h: Add SPI DMA registers.
+
+2006-05-20 John Eigelaar <jeigelaar@mweb.co.za>
+
+ include/pkgconf/mlt_arm_at91sam7x128_rom.{h|ldi}
+ include/pkgconf/mlt_arm_at91sam7x256_rom.{h|ldi}: Linker files
+ for AT91SAM7X processor.
+
+2006-05-17 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/at91sam7s_misc.c: Use the AT91 generic PIO manipulation
+ macros. Move the LED function out into the board specific HAL
+ package.
+
+2006-04-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl:
+ * include/pkgconf/mlt_arm_at91sam7s32_rom.ldi:
+ * include/pkgconf/mlt_arm_at91sam7s64_rom.ldi:
+ * include/pkgconf/mlt_arm_at91sam7s128_rom.ldi:
+ * include/pkgconf/mlt_arm_at91sam7s267_rom.ldi:
+ Allow CDL to control where in flash the image is placed.
+
+2006-03-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl: Implement the USB interface when chip
+ has the device.
+
+2006-03-10 Oliver Munz <oli@snr.ch>
+
+ * hal_arm_at91sam7s.cdl: Change the PLL-defaults so that 96MHz is
+ generated so that the USB does work.
+
+2006-03-10 Andrew Lunn <andrew.lunn@ascom.ch>
+ Oliver Munz <munz@speag.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl: Set the debug UART as the default
+ channel and fix some dodge spelling.
+ * src/at91sam7s_misc.c (hal_plf_hardware_init): Enable the Debug UART
+ pins for output and control by the device.
+ * include/plf_io.h: Define USART2 to be the debug UART.
+
+2006-03-01 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl: Change the crystal frequency. The
+ numbers printed on top of the crystal are misleading. It has a
+ 18.432MHz crystal, not 20MHz. This error when combined with the
+ previous fix to the PLL made the serial baud rate wrong. Change
+ the multiplier and divisor to achieve about the same CPU clock,
+ which should be USB compatible.
+ * src/at91sam7s_misc.c (hal_at91_us_baud): Need the same PLL fix
+ when calculating the baud rate dynamically.
+ * include/plf_io.h: Add the Programmable Clock Output registers.
+
+2006-02-28 Oliver Munz <munz@speag.ch>
+
+ * include/hal_platform_setup.h: Fix the PLL multiplier settings
+
+2006-02-25 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * misc/redboot_R[AO]M.ecm: Disable FIS and fconfig, enable
+ loading directly into flash with the load command.
+
+2006-01-01 Oliver Munz <munz@speag.ch>
+ Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/hal_arm_at91sam7s.cdl:
+ * include/hal_platform_ints.h:
+ * include/hal_platform_setup.h:
+ * include/plf_io.h:
+ * include/pkgconf/mlt_arm_at91sam7s256_rom.h:
+ * include/pkgconf/mlt_arm_at91sam7s256_rom.ldi:
+ * include/pkgconf/mlt_arm_at91sam7s128_rom.h:
+ * include/pkgconf/mlt_arm_at91sam7s128_rom.ldi:
+ * include/pkgconf/mlt_arm_at91sam7s64_rom.h:
+ * include/pkgconf/mlt_arm_at91sam7s64_rom.ldi:
+ * include/pkgconf/mlt_arm_at91sam7s32_rom.h:
+ * include/pkgconf/mlt_arm_at91sam7s32_rom.ldi:
+ * src/at91sam7s_misc.c:
+ * misc/redboot_ROM.ecm:
+ * misc/redboot_RAM.ecm:
+ * ChangeLog: First import of a hal for the AT91SAM7S family.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_arm_at91_sam7s.cdl
+#
+# ARM AT91 SAM7 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2005 eCosCentric Ltd
+## Copyright (C) 2005 Andrew Lunn
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, tkoeller, nickg, Oliver Munz, asl
+# Date: 2005-06-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_AT91SAM7 {
+ display "Atmel AT91SAM7 HAL"
+ parent CYGPKG_HAL_ARM
+ define_header hal_arm_at91sam7.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The AT91SAM7 HAL package provides the support needed to run
+ eCos on an Atmel AT91SAM7 based board."
+
+ compile at91sam7s_misc.c
+
+ requires { CYGHWR_HAL_ARM_AT91_FIQ }
+ requires { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s32" implies
+ CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0 == 0 }
+
+ implements CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW
+ implements CYGINT_HAL_ARM_AT91_PIT_HW
+ implements CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_arm.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_arm_at91.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
+ }
+
+ cdl_option CYGHWR_HAL_ARM_AT91SAM7 {
+ display "AT91SAM7 variant used"
+ flavor data
+ default_value {"at91sam7s256"}
+ legal_values {"at91sam7s32" "at91sam7s321" "at91sam7s64"
+ "at91sam7s128" "at91sam7s256"
+ "at91sam7x128" "at91sam7x256" "at91sam7x512"
+ "at91sam7xc128" "at91sam7xc256" }
+ description "
+ The AT91SAM7 microcontroller family has several variants,
+ the main differences being the amount of on-chip SRAM,
+ FLASH, peripherals and their layout. This option allows the
+ platform HALs to select the specific microcontroller
+ being used."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_AT91SAM7S {
+ display "SAM7S device"
+ calculated { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s256" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s128" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s64" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s32" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s321" }
+ description "
+ Is the AT91SAM7 device a member of the AT91SAM7S family?"
+ }
+
+ cdl_option CYGHWR_HAL_ARM_AT91SAM7X {
+ display "SAM7X device"
+ calculated { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x512" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x256" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x128" }
+ description "
+ Is the AT91SAM7 device a member of the AT91SAM7X family?"
+ }
+
+ cdl_option CYGHWR_HAL_ARM_AT91SAM7XC {
+ display "SAM7XC device"
+ calculated { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7xc256" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7xc128" }
+ description "
+ Is the AT91SAM7 device a member of the AT91SAM7XC family?"
+ }
+
+ cdl_option CYGBLD_HAL_ARM_AT91SAM7_USB {
+ display "USB device"
+ active_if {!( "at91sam7s32" == CYGHWR_HAL_ARM_AT91SAM7S) ||
+ CYGHWR_HAL_ARM_AT91SAM7X ||
+ CYGHWR_HAL_ARM_AT91SAM7XC }
+ implements CYGINT_DEVS_USB_AT91_HAS_USB
+ default_value 1
+ no_define
+ description "
+ All but the AT91SAM7S32 has the USB device"
+ }
+
+ cdl_option CYGBLD_HAL_ARM_AT91SAM7_SPI1 {
+ display "Second SPI bus controller"
+ active_if { CYGHWR_HAL_ARM_AT91SAM7X ||
+ CYGHWR_HAL_ARM_AT91SAM7XC }
+ implements CYGINT_DEVS_SPI_ARM_AT91_HAS_BUS1
+ default_value 1
+ no_define
+ description "
+ The SAM7X and SAM7XC have the second SPI bus controller"
+ }
+
+ cdl_option CYGBLD_HAL_ARM_AT91SAM7_CAN0 {
+ display "CAN bus controller"
+ active_if { CYGHWR_HAL_ARM_AT91SAM7X ||
+ CYGHWR_HAL_ARM_AT91SAM7XC }
+ implements CYGINT_DEVS_CAN_AT91SAM7_CAN0
+ default_value 1
+ no_define
+ description "
+ The SAM7X and SAM7XC have the CAN controller"
+ }
+
+ cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants"
+ flavor none
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ default_value 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ default_value 100
+ }
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ legal_values 1 to 0xffff
+ calculated ((CYGNUM_HAL_RTC_NUMERATOR * CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/16) / CYGNUM_HAL_RTC_DENOMINATOR / 1000000000)
+ description "
+ CYGNUM_HAL_RTC_PERIOD : (CYGNUM_HAL_RTC_NUMERATOR * CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/16) / CYGNUM_HAL_RTC_DENOMINATOR / 1000000000 "
+ }
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ default_value {"ROM"}
+ legal_values {"RAM" "ROM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+ description "
+ When targeting the AT91SAM7 eval boards it is possible to build
+ the system for either RAM bootstrap or ROM bootstrap(s). Select
+ 'ram' when building programs to load into RAM using on board
+ debug software such as Angel or eCos GDB stubs. Select 'rom'
+ when building a stand-alone application which will be put
+ into ROM"
+ }
+
+ cdl_option CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS {
+ display "Address in flash the image should live"
+ active_if { CYG_HAL_STARTUP == "ROM" }
+ flavor data
+ default_value 0x00100000
+ description "
+ This optionspecifies where in flash the image
+ lives. By default it is at the bottom of the flash,
+ but for example redboot may be at the bottom and an
+ application lives higher up, which is acheived by
+ setting the address here."
+ }
+
+ # Real-time clock/counter specifics
+ cdl_option CYGNUM_HAL_ARM_AT91_CLOCK_SPEED {
+ display "CPU clock speed"
+ flavor data
+ calculated { CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN *
+ CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER /
+ CYGNUM_HAL_ARM_AT91_PLL_DIVIDER / 2}
+ legal_values { 0 to 220000000 }
+ description "
+ The master clock-frequency has to be 48MHz, 96MHz or
+ 192MHz for the USB to work correctly. The clock setup uses
+ PLL clock divided by two"
+ }
+
+ cdl_option CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN {
+ display "Main oscillator frequency"
+ flavor data
+ legal_values { 3000000 to 20000000}
+ default_value { 18432000 }
+ description "
+ The frequency of the clock input, be it a crystal or a clock
+ signal"
+ }
+
+ cdl_option CYGNUM_HAL_ARM_AT91_CLOCK_TYPE {
+ display "Type of main frequency input"
+ flavor data
+ default_value { "CRYSTAL" }
+ legal_values { "CRYSTAL" "EXTCLOCK" }
+ description "
+ Whether a crystal or a XIN input clock is clocking the device."
+ }
+
+ cdl_option CYGNUM_HAL_ARM_AT91_PLL_DIVIDER {
+ display "Divider for PLL clock"
+ flavor data
+ legal_values { 0 to 255 }
+ default_value 24
+ description "
+ The X-tal clock is divided by this value when generating the
+ PLL clock"
+ }
+
+ cdl_option CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER {
+ display "Multiplier for PLL clock"
+ flavor data
+ legal_values { 0 to 2047 }
+ default_value 125
+ description "
+ The X-tal clock is multiplied by this value when generating
+ the PLL clock."
+ }
+
+ cdl_option CYGNUM_HAL_ARM_AT91_SLOW_CLOCK {
+ display "Slow clock frequency"
+ flavor data
+ default_value { 32768 }
+ description "
+ The slow clock is an LC oscillator which runs all the
+ time. The accuracy of this clock is not very high and
+ is temperature dependent."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ default_value 3
+ description "
+ The AT91SAM7S development boards has two Serial port connectors.
+ these correspond to USART0 and the Debug Serial port. The chip
+ has a third serial port which does not have a 9pin D
+ connector, but is accessible via the patch panel pins."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 2
+ description "
+ The AT91SAM7S has three serial ports. This option
+ chooses which port will be used to connect to a host
+ running GDB."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 2
+ description "
+ The AT91SAM7S board has three USART serial ports. This option
+ chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 38400
+ description "
+ This option selects the baud rate used for the diagnostic port."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "GDB serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 38400
+ description "
+ This option controls the baud rate used for the GDB connection."
+ }
+
+ cdl_option CYGBLD_HAL_ARM_AT91_BAUD_DYNAMIC {
+ display "Dynamic calculation of baud rate"
+ default_value 0
+ description "
+ The AT91SAM7S has a flexible clock generation mechanism
+ where the main clock used to drive peripherals can be
+ changed during run time. Such changes affect the serial port
+ baud rate generators. Enabling this option includes code
+ which calculates the baud rate setting dynamically from the
+ current clock settings. Without this option a static
+ calculation is performed which assumes the clock frequency
+ has not been changed."
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM" }
+ description "
+ Enable this option if this program is to be used as a ROM monitor,
+ i.e. applications will be loaded into RAM on the board, and this
+ ROM monitor may process exceptions or interrupts generated from the
+ application. This enables features such as utilizing a separate
+ interrupt stack when exceptions are generated."
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "Generic" "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Support can be enabled for different varieties of ROM monitor.
+ This support changes various eCos semantics such as the encoding
+ of diagnostic output, or the overriding of hardware interrupt
+ vectors.
+ Firstly there is \"Generic\" support which prevents the HAL
+ from overriding the hardware vectors that it does not use, to
+ instead allow an installed ROM monitor to handle them. This is
+ the most basic support which is likely to be common to most
+ implementations of ROM monitor.
+ \"GDB_stubs\" provides support when GDB stubs are included in
+ the ROM monitor or boot ROM."
+ }
+
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid Redboot
+ configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ default_value 1
+ no_define
+ description "This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+ $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+ $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+ $(OBJCOPY) -O binary $< $@
+ }
+ }
+ }
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+ description "
+ Global build options including control over
+ compiler flags, linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "arm-elf" }
+ description "
+ This option specifies the command prefix used when
+ invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+ description "
+ This option controls the global compiler flags which are used to
+ compile all packages by default. Individual packages may define
+ options which override these global flags."
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -Wl,--gc-sections -Wl,-static -g -nostdlib" }
+ description "
+ This option controls the global linker flags. Individual
+ packages may define options which override these global flags."
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { (CYG_HAL_STARTUP == "RAM") ? \
+ "arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_ram" :
+ "arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { (CYG_HAL_STARTUP == "RAM") ? \
+ "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_ram.ldi>" :
+ "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { (CYG_HAL_STARTUP == "RAM") ? \
+ "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_ram.h>" :
+ "<pkgconf/mlt_arm_" . CYGHWR_HAL_ARM_AT91SAM7 . "_rom.h>" }
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+// hal_platform_ints.h
+//
+// HAL Interrupt and clock assignments for AT91SAM7
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, Oliver Munz, Andrew Lunn, John Eigelaar
+// Date: 2001-07-12
+// Purpose: Define Interrupt support
+// Description: The interrupt specifics for the AT91SAM7 platform are
+// defined here.
+//
+// Usage: #include <cyg/hal/hal_platform_ints.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal_arm_at91sam7.h>
+
+#define CYGNUM_HAL_INTERRUPT_FIQ 0
+
+#define CYGNUM_HAL_INTERRUPT_SYS 1
+#define CYGNUM_HAL_INTERRUPT_PIOA 2
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define CYGNUM_HAL_INTERRUPT_PIOB 3
+#define CYGNUM_HAL_INTERRUPT_SPI 4
+#define CYGNUM_HAL_INTERRUPT_SPI1 5
+#endif
+#ifdef CYGHWR_HAL_ARM_AT91SAM7S
+#define CYGNUM_HAL_INTERRUPT_ADC 4
+#define CYGNUM_HAL_INTERRUPT_SPI 5
+#endif
+
+#define CYGNUM_HAL_INTERRUPT_USART0 6
+#define CYGNUM_HAL_INTERRUPT_USART1 7
+#define CYGNUM_HAL_INTERRUPT_SSC 8
+#define CYGNUM_HAL_INTERRUPT_TWI 9
+#define CYGNUM_HAL_INTERRUPT_PWMC 10
+#define CYGNUM_HAL_INTERRUPT_UDP 11
+#define CYGNUM_HAL_INTERRUPT_TC0 12
+#define CYGNUM_HAL_INTERRUPT_TC1 13
+#define CYGNUM_HAL_INTERRUPT_TC2 14
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define CYGNUM_HAL_INTERRUPT_CAN 15
+#define CYGNUM_HAL_INTERRUPT_EMAC 16
+#define CYGNUM_HAL_INTERRUPT_ADC 17
+#endif
+
+#define CYGNUM_HAL_INTERRUPT_IRQ0 30
+#define CYGNUM_HAL_INTERRUPT_IRQ1 31
+
+// Interrupts which are multiplexed on to the System Interrupt
+#define CYGNUM_HAL_INTERRUPT_PITC 32
+#define CYGNUM_HAL_INTERRUPT_RTTC 33
+#define CYGNUM_HAL_INTERRUPT_PMC 34
+#define CYGNUM_HAL_INTERRUPT_MC 35
+#define CYGNUM_HAL_INTERRUPT_WDTC 36
+#define CYGNUM_HAL_INTERRUPT_RSTC 37
+#define CYGNUM_HAL_INTERRUPT_DBG 38
+
+#define CYGNUM_HAL_ISR_MIN 0
+#define CYGNUM_HAL_ISR_MAX 38
+
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX + 1)
+
+// The vector used by the Real time clock
+#ifdef CYGBLD_HAL_ARM_AT91_TIMER_TC
+#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_TC0
+#endif
+#ifdef CYGBLD_HAL_ARM_AT91_TIMER_PIT
+#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_PITC
+#endif
+
+//----------------------------------------------------------------------------
+// Reset.
+__externC void hal_at91_reset_cpu(void);
+#define HAL_PLATFORM_RESET() hal_at91_reset_cpu()
+
+#define HAL_PLATFORM_RESET_ENTRY 0x0000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+/*=============================================================================
+//
+// hal_platform_setup.h
+//
+// Platform specific support for HAL
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copy
+
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:gthomas, asl
+// Date: 2006-02-18
+// Purpose: AT91SAM7S platform specific support routines
+// Description:
+// Usage: #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/plf_io.h>
+
+// Macro to initialise the Memory Controller
+ .macro _flash_init
+__flash_init__:
+ ldr r0,=AT91_MC
+#if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 60000000
+ // When the clock is running faster than 60MHz we need two wait states
+ ldr r1,=(AT91_MC_FMR_2FWS)
+#else
+# if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000
+ // When the clock is running faster than 30MHz we need a wait state
+ ldr r1,=(AT91_MC_FMR_1FWS)
+# else
+ // We have a slow clock, no extra wait states are needed
+ ldr r1,=AT91_MC_FMR_0FWS
+# endif
+#endif
+ str r1,[r0,#AT91_MC_FMR]
+ .endm
+
+// Macro to start the main clock.
+ .macro _main_clock_init
+__main_clock_init__:
+ ldr r0,=AT91_PMC
+ // Swap to the slow clock, just to be sure.
+ ldr r1,=(AT91_PMC_MCKR_PRES_CLK|AT91_PMC_MCKR_SLOW_CLK)
+ str r1,[r0,#AT91_PMC_MCKR]
+ // startup time
+#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK)
+ ldr r1,=(AT91_PMC_MOR_OSCBYPASS)
+#else
+ ldr r1,=(AT91_PMC_MOR_OSCCOUNT(6)|AT91_PMC_MOR_MOSCEN)
+#endif
+ str r1,[r0,#AT91_PMC_MOR]
+
+ // Wait for oscilator start timeout
+wait_pmc_sr_1:
+ ldr r1,[r0,#AT91_PMC_SR]
+ ands r1,r1,#AT91_PMC_SR_MOSCS
+ beq wait_pmc_sr_1
+
+ // Set the PLL multiplier and divider. 16 slow clocks go by
+ // before the LOCK bit is set. */
+ ldr r1,=((AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER))|(AT91_PMC_PLLR_PLLCOUNT(16))|(AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1)))
+ str r1,[r0,#AT91_PMC_PLLR]
+
+ // Wait for PLL locked indication
+wait_pmc_sr_2:
+ ldr r1,[r0,#AT91_PMC_SR]
+ ands r1,r1,#AT91_PMC_SR_LOCK
+ beq wait_pmc_sr_2
+
+ // Enable the PLL clock and set the prescale to 2 */
+ ldr r1,=(AT91_PMC_MCKR_PRES_CLK_2|AT91_PMC_MCKR_PLL_CLK)
+ str r1,[r0,#AT91_PMC_MCKR]
+
+ // Wait for the MCLK ready indication
+wait_pmc_sr_3:
+ ldr r1,[r0,#AT91_PMC_SR]
+ ands r1,r1,#AT91_PMC_SR_MCKRDY
+ beq wait_pmc_sr_3
+ .endm
+
+// Remap the flash from address 0x0 and place RAM there instead.
+ .macro _remap_flash
+__remap_flash:
+ ldr r0,=0x000004 // Use the underfined instruction exception
+ ldr r1,=0x200004
+ ldr r2,[r0] // Save away copies so we can restore them
+ ldr r3,[r1]
+ ldr r4,=0xffffff
+ eor r4,r3,r4 // XOR the contents of 0x20004
+ str r4,[r1] // and write it
+ ldr r5,[r0] // Read from low memory
+ cmp r5,r4
+ beq remap_done
+ ldr r0,=AT91_MC // Need to do a remap
+ ldr r5,=1
+ str r5,[r0,#AT91_MC_RCR]
+remap_done:
+ str r3,[r1] // restore the value we changed
+ .endm
+
+#if defined(CYG_HAL_STARTUP_ROM)
+ .macro _setup
+ _flash_init
+ _main_clock_init
+ _remap_flash
+ .endm
+
+#define PLATFORM_SETUP1 _setup
+#else
+#define PLATFORM_SETUP1
+#endif
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x08000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x20000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00204000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x08000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x20000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x10000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x40000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00210000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x10000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x40000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x02000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x08000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00202000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x02000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x08000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x04000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x10000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00204000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x04000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x10000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x08000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x20000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00204000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x08000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x20000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x10000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x40000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00210000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x10000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x40000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x00200000)
+#define CYGMEM_REGION_ram_SIZE (0x20000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x00100000)
+#define CYGMEM_REGION_rom_SIZE (0x80000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__reserved_bootmon) [];
+#endif
+#define CYGMEM_SECTION_reserved_bootmon (CYG_LABEL_NAME (__reserved_bootmon))
+#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x01000)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x00220000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_at91sam7.h>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00200000, LENGTH = 0x20000
+ rom : ORIGIN = 0x00100000, LENGTH = 0x80000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ CYG_LABEL_DEFN(__reserved_bootmon) = 0x00000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x01000;
+ SECTION_rom_vectors (rom, CYGNUM_HAL_ARM_AT91_IMAGE_ADDRESS, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (ram, 0x00200040, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+// plf_io.h
+//
+// AT91SAM7S board specific registers
+//
+//=============================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tkoeller
+// Contributors: andrew lunn, Oliver Munz
+// Date: 2005-12-31
+// Purpose: Atmel AT91SAM7S board specific registers
+// Description:
+// Usage: #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+#include <pkgconf/hal_arm_at91sam7.h>
+
+#define CYGARC_PHYSICAL_ADDRESS(_x_)
+
+//SPI - Serial Peripheral Interface
+#define AT91_SPI0 0xFFFE0000
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define AT91_SPI1 0xFFFE4000
+#endif
+
+#define AT91_SPI AT91_SPI0
+
+//Extra SPI control bits
+#define AT91_SPI_MR_MODFDIS (1<<4)
+
+// DMA registers
+#define AT91_SPI_RPR 0x100 // Receive Pointer Register
+#define AT91_SPI_RCR 0x104 // Receive Counter Register
+#define AT91_SPI_TPR 0x108 // Transmit Pointer Register
+#define AT91_SPI_TCR 0x10C // Transmit Counter Register
+#define AT91_SPI_NRPR 0x110 // Next Receive Pointer Register
+#define AT91_SPI_NRCR 0x114 // Next Receive Counter Register
+#define AT91_SPI_NTPR 0x118 // Next Transmit Pointer Register
+#define AT91_SPI_NTCR 0x11C // Next Trsnsmit Counter Register
+#define AT91_SPI_PTCR 0x120 // PDC Transfer Control Register
+#define AT91_SPI_PTSR 0x124 // PDC Transfer Status Register
+
+// Peripheral Input/Output Controllers
+#define AT91_PIOA 0xFFFFF400
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+#define AT91_PIOB 0xFFFFF600
+#endif
+
+#define AT91_WSTC 0xFFFFFD40
+
+// USART
+
+#define AT91_USART0 0xFFFC0000
+#define AT91_USART1 0xFFFC4000
+
+// Define USART2 to be the debug UART. It is similar enough to a USART
+// that both the hal_diag and interrupt driven driver will work.
+// However trying to change parity, start/stop bits etc will not work.
+#define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG
+#define AT91_USART2 AT91_DBG
+
+#ifndef __ASSEMBLER__
+#ifdef CYGBLD_HAL_ARM_AT91_BAUD_DYNAMIC
+extern cyg_uint32 hal_at91_us_baud(cyg_uint32 baud);
+#define AT91_US_BAUD(baud) hal_at91_us_baud(baud)
+#endif
+#endif // __ASSEMBLER__
+
+#define AT91_US_RPR 0x100 // Receive Pointer Register
+#define AT91_US_RCR 0x104 // Receive Counter Register
+#define AT91_US_TPR 0x108 // Transmit Pointer Register
+#define AT91_US_TCR 0x10C // Transmit Counter Register
+#define AT91_US_NRPR 0x110 // Next Receive Pointer Register
+#define AT91_US_NRCR 0x114 // Next Receive Counter Register
+#define AT91_US_NTPR 0x118 // Next Transmit Pointer Register
+#define AT91_US_NTCR 0x11C // Next Trsnsmit Counter Register
+#define AT91_US_PTCR 0x120 // PDC Transfer Control Register
+#define AT91_US_PTSR 0x124 // PDC Transfer Status Register
+
+// PIO - Programmable I/O
+
+#define AT91_PIO AT91_PIOA
+
+// AIC - Advanced Interrupt Controller
+
+#define AT91_AIC 0xFFFFF000
+
+// TC - Timer Counter
+
+#define AT91_TC 0xFFFA0000
+
+// Power Management Controller
+
+#define AT91_PMC 0xFFFFFC00
+
+#define AT91_PMC_MOR 0x20 // Main Oscillator Register
+#define AT91_PMC_MOR_MOSCEN (1 << 0) // Main Oscillator Enable
+#define AT91_PMC_MOR_OSCBYPASS (1 << 1) // Main Oscillator Bypass
+#define AT91_PMC_MOR_OSCCOUNT(x) (x << 8) // Slow clocks ticks
+#define AT91_PMC_MCFR 0x24 // Main Clock Frequency Register
+#define AT91_PMC_PLLR 0x2c // PLL Register
+#define AT91_PMC_PLLR_DIV(x) ((x) << 0) // PLL Devide
+#define AT91_PMC_PLLR_PLLCOUNT(x) ((x) << 8) // PLL Count
+#define AT91_PMC_PLLR_MUL(x) ((x) << 16) // PLL Devide
+#define AT91_PMC_PLLR_OUT_0 (0 << 14)
+#define AT91_PMC_PLLR_OUT_1 (1 << 14)
+#define AT91_PMC_PLLR_OUT_2 (2 << 14)
+#define AT91_PMC_PLLR_OUT_3 (3 << 14)
+#define AT91_PMC_PLLR_USBDIV_0 (0 << 28) // USB clock is PLL clock / 1
+#define AT91_PMC_PLLR_USBDIV_1 (1 << 28) // USB clock is PLL clock / 2
+#define AT91_PMC_PLLR_USBDIV_2 (2 << 28) // USB clock is PLL clock / 4
+#define AT91_PMC_MCKR 0x30 // Master Clock Register
+#define AT91_PMC_MCKR_SLOW_CLK (0 << 0) // Slow clock selected
+#define AT91_PMC_MCKR_MAIN_CLK (1 << 0) // Main clock selected
+#define AT91_PMC_MCKR_PLL_CLK (3 << 0) // PLL clock selected
+#define AT91_PMC_MCKR_PRES_CLK (0 << 2) // divide by 1
+#define AT91_PMC_MCKR_PRES_CLK_2 (1 << 2) // divide by 2
+#define AT91_PMC_MCKR_PRES_CLK_4 (2 << 2) // divide by 4
+#define AT91_PMC_MCKR_PRES_CLK_8 (3 << 2) // divide by 8
+#define AT91_PMC_MCKR_PRES_CLK_16 (4 << 2) // divide by 16
+#define AT91_PMC_MCKR_PRES_CLK_32 (5 << 2) // divide by 32
+#define AT91_PMC_MCKR_PRES_CLK_64 (6 << 2) // divide by 64
+#define AT91_PMC_PCKR0 0x40 // Programmable Clock Register 0
+#define AT91_PMC_PCKR1 0x44 // Programmable Clock Register 1
+#define AT91_PMC_PCKR2 0x48 // Programmable Clock Register 2
+#define AT91_PMC_IER 0x60 // Interrupt Enable Register
+#define AT91_PMC_IDR 0x64 // Interrupt Disable Register
+#define AT91_PMC_SR 0x68 // Status Register
+#define AT91_PMC_SR_MOSCS (1 << 0) // Main oscillator stable
+#define AT91_PMC_SR_LOCK (1 << 2) // PLL Locked
+#define AT91_PMC_SR_MCKRDY (1 << 3) // MCK is ready to be enabled
+#define AT91_PMC_SR_PCK0RDY (1 << 8) // Pad clock 0 is ready to be enabled
+#define AT91_PMC_SR_PCK1RDY (1 << 9) // Pad clock 1 is ready to be enabled
+#define AT91_PMC_SR_PCK2RDY (1 << 10) // Pad clock 2 is ready to be enabled
+#define AT91_PMC_SR_PCK3RDY (1 << 11) // Pad clock 3 is ready to be enabled
+#define AT91_PMC_IMR 0x6c // Interrupt Mask Register
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+
+// EMAC - Ethernet Medium Access Controller
+
+#define AT91_EMAC 0xFFFDC000
+
+// CAN - Controller Area Network
+
+#define AT91_CAN 0xFFFD0000
+
+#endif
+
+//----------------------------------------------------------------------
+// The platform needs this initialization during the
+// hal_hardware_init() function in the varient HAL.
+#ifndef __ASSEMBLER__
+extern void hal_plf_hardware_init(void);
+#define HAL_PLF_HARDWARE_INIT() \
+ hal_plf_hardware_init()
+
+#ifdef CYGHWR_HAL_ARM_AT91SAM7X
+extern void hal_plf_eth_init(void);
+#define HAL_PLF_ETH_INIT() \
+ hal_plf_eth_init()
+#endif
+
+#endif //__ASSEMBLER__
+
+
+#endif //CYGONCE_HAL_PLF_IO_H
+
--- /dev/null
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+ description "" ;
+ hardware at91sam7s ;
+ template redboot ;
+ package -hardware CYGPKG_HAL_ARM current ;
+ package -hardware CYGPKG_HAL_ARM_AT91 current ;
+ package -hardware CYGPKG_DEVS_FLASH_AT91 current ;
+ package -template CYGPKG_HAL current ;
+ package -template CYGPKG_INFRA current ;
+ package -template CYGPKG_REDBOOT current ;
+ package CYGPKG_IO_FLASH current ;
+};
+
+cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
+ user_value 6144
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+ user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+ inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+ inferred_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ inferred_value 0 0
+};
+
+cdl_component CYGBLD_BUILD_REDBOOT {
+ user_value 1
+};
+
+cdl_option CYGOPT_REDBOOT_FIS {
+ user_value 0
+};
+
+cdl_component CYGSEM_REDBOOT_FLASH_CONFIG {
+ user_value 0
+};
+
+cdl_option CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG {
+ user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK {
+ user_value -16
+};
+
+
+cdl_option CYGBLD_BUILD_REDBOOT_WITH_EXEC {
+ user_value 0
+};
+
+cdl_option CYGBLD_DEV_FLASH_AT91_LOCKING {
+ user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK {
+ user_value -24
+};
+
+cdl_option CYGBLD_REDBOOT_MIN_IMAGE_SIZE {
+ user_value 0x15000
+};
+
+cdl_option CYGBLD_REDBOOT_LOAD_INTO_FLASH {
+ user_value 1
+};
\ No newline at end of file
--- /dev/null
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+ description "" ;
+ hardware at91sam7s ;
+ template redboot ;
+ package -hardware CYGPKG_HAL_ARM current ;
+ package -hardware CYGPKG_HAL_ARM_AT91 current ;
+ package -hardware CYGPKG_DEVS_FLASH_AT91 current ;
+ package -template CYGPKG_HAL current ;
+ package -template CYGPKG_INFRA current ;
+ package -template CYGPKG_REDBOOT current ;
+ package CYGPKG_IO_FLASH current ;
+};
+
+cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
+ user_value 6144
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+ user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+ inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+ inferred_value 1
+};
+
+cdl_option CYGSEM_HAL_ROM_MONITOR {
+ inferred_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+ user_value ROM
+};
+
+cdl_component CYGBLD_BUILD_REDBOOT {
+ user_value 1
+};
+
+cdl_option CYGOPT_REDBOOT_FIS {
+ user_value 0
+};
+
+cdl_component CYGSEM_REDBOOT_FLASH_CONFIG {
+ user_value 0
+};
+
+cdl_option CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG {
+ user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK {
+ user_value -16
+};
+
+
+cdl_option CYGBLD_BUILD_REDBOOT_WITH_EXEC {
+ user_value 0
+};
+
+cdl_option CYGBLD_DEV_FLASH_AT91_LOCKING {
+ user_value 0
+};
+
+cdl_option CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK {
+ user_value -24
+};
+
+cdl_option CYGBLD_REDBOOT_MIN_IMAGE_SIZE {
+ user_value 0x15000
+};
+
+cdl_option CYGBLD_REDBOOT_LOAD_INTO_FLASH {
+ user_value 1
+};
\ No newline at end of file
--- /dev/null
+/*==========================================================================
+//
+// at91sam7s_misc.c
+//
+// HAL misc board support code for Atmel AT91sam7s
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov, nickg, tkoeller, Oliver Munz, Andrew Lunn
+// Date: 2001-07-12
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_intr.h> // necessary?
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h> // calling interface
+#include <cyg/hal/hal_misc.h> // helper functions
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+#include <cyg/hal/drv_api.h> // HAL ISR support
+#endif
+
+extern void hal_at91_led(int val);
+
+void
+hal_at91_set_leds (int val)
+{
+ hal_at91_led(val);
+}
+
+// -------------------------------------------------------------------------
+// Hardware init
+
+void hal_plf_hardware_init (void)
+{
+ /* Enable the Serial devices to driver the serial port pins */
+ HAL_ARM_AT91_PIO_CFG(AT91_USART_RXD0);
+ HAL_ARM_AT91_PIO_CFG(AT91_USART_TXD0);
+ HAL_ARM_AT91_PIO_CFG(AT91_DBG_DTXD);
+ HAL_ARM_AT91_PIO_CFG(AT91_DBG_DRXD);
+
+#if !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s32)
+ /* Enable the Serial devices to driver the serial port pins */
+ HAL_ARM_AT91_PIO_CFG(AT91_USART_RXD1);
+ HAL_ARM_AT91_PIO_CFG(AT91_USART_TXD1);
+#endif
+
+ /* Setup the Reset controller. Allow user resets */
+ HAL_WRITE_UINT32(AT91_RST+AT91_RST_RMR,
+ AT91_RST_RMR_URSTEN |
+ 10 << 8 |
+ AT91_RST_RMR_KEY);
+
+#ifdef CYGBLD_HAL_ARM_AT91_SERIAL_UART
+ /* Enable peripheral clocks for USART 0 and 1 if they are to be used */
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER,
+ AT91_PMC_PCER_US0 |
+ AT91_PMC_PCER_US1);
+#endif
+
+#ifdef CYGBLD_HAL_ARM_AT91_TIMER_TC
+ /* Enable peripheral clocks for TC 0 and 1 if they are to be used */
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER,
+ AT91_PMC_PCER_TC0 |
+ AT91_PMC_PCER_TC2);
+#endif
+
+#ifndef CYGPKG_IO_WATCHDOG
+ /* Disable the watchdog. The eCos philosophy is that the watchdog is
+ disabled unless the watchdog driver is used to enable it.
+ Whoever if we disable it here we cannot re-enable it in the
+ watchdog driver, hence the conditional compilation. */
+ HAL_WRITE_UINT32(AT91_WDTC + AT91_WDTC_WDMR, AT91_WDTC_WDMR_DIS);
+#endif
+
+/* Perform some platform specific bits to get the Ethernet hardware
+ setup. Specifically if a specific phy is used and does not start in
+ the correct mode a function needs to be supplied as part of the plf
+ to do the necessary initializations.
+*/
+#ifdef CYGPKG_DEVS_ETH_ARM_AT91
+#ifdef HAL_PLF_ETH_INIT
+ HAL_PLF_ETH_INIT();
+#endif
+#endif
+}
+
+// Calculate the baud value to be programmed into the serial port baud
+// rate generators. This function will determine what the clock speed
+// is that is driving the generator so it can be used in situations
+// when the application dynamically changes the clock speed.
+cyg_uint32
+hal_at91_us_baud(cyg_uint32 baud_rate)
+{
+ cyg_uint32 val, pll;
+ cyg_uint32 main_clock = 0;
+ cyg_uint32 baud_value = 0;
+
+ HAL_READ_UINT32((AT91_PMC+AT91_PMC_MCKR), val);
+ switch (val & 0x03) {
+ /* Slow clock */
+ case AT91_PMC_MCKR_SLOW_CLK:
+ main_clock = CYGNUM_HAL_ARM_AT91_SLOW_CLOCK;
+ break;
+
+ /* Main clock */
+ case AT91_PMC_MCKR_MAIN_CLK:
+ main_clock = CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN;
+ break;
+ /* PLL */
+ case AT91_PMC_MCKR_PLL_CLK:
+ HAL_READ_UINT32((AT91_PMC+AT91_PMC_PLLR), pll);
+ main_clock = CYGNUM_HAL_ARM_AT91_CLOCK_OSC_MAIN *
+ (((pll & 0x7FF0000) >> 16) + 1) / (pll & 0xFF);
+ break;
+ }
+
+ // Process prescale
+ val = (val & 0x1C) >> 2;
+ main_clock = main_clock >> val;
+
+ /* Define the baud rate divisor register, (round) */
+ baud_value = (main_clock/(8*baud_rate)+1)/2;
+
+ return baud_value;
+}
+
+//--------------------------------------------------------------------------
+// EOF at91sam7s_misc.c
--- /dev/null
+2007-10-16 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/at91sam7sek_misc.c (hal_at91_led): Fix off by one error on
+ GPIO lines for LEDs. Reported by Rasmus Stougaard
+ <rasmus.stougaard@gmail.com>
+
+2007-01-02 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/hal_arm_at91sam7s.cdl Moved HAL_PLATFORM_XXX defines and
+ definition of platform header file (CYGBLD_HAL_PLATFORM_H) from
+ package CYGPKG_HAL_ARM_AT91SAM7 into board specific packages.
+
+2006-05-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * AT91SAM7X-EK development board package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_arm_at91_sam7sek.cdl
+#
+# ARM AT91 SAM7S EK development board package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 2006 Andrew Lunn
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): andrew lunn
+# Contributors:
+# Date: 2006-05-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_AT91SAM7SEK {
+ display "Atmel AT91SAM7S EK development board"
+ parent CYGPKG_HAL_ARM_AT91SAM7
+ define_header hal_arm_at91sam7sek.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The AT91SAM7SEK HAL package provides the support needed to run
+ eCos on an Atmel AT91SAM7S-EK development board."
+
+ compile at91sam7sek_misc.c
+
+ requires { CYGHWR_HAL_ARM_AT91 == "AT91SAM7S" }
+ requires { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s256" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s128" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s64" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s32" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7s321" }
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_at91sam7sek.h>"
+ puts $::cdl_header "/***** proc output start *****/"
+ puts $::cdl_header "#include <pkgconf/hal_arm_at91sam7.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Atmel (AT91SAM7S-EK)\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ puts $::cdl_header "/****** proc output end ******/"
+ }
+}
--- /dev/null
+/*==========================================================================
+//
+// at91sam7sek_misc.c
+//
+// HAL misc board support code for Atmel AT91sam7s EK board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew lunn
+// Contributors: Oliver Munz, Andrew Lunn
+// Date: 2006-06-20
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+
+// The development board has four LEDs
+void
+hal_at91_led (int val)
+{
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA0, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA1, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA2, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PA3, AT91_PIN_OUT);
+
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA0, AT91_PIN_PULLUP_DISABLE);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA1, AT91_PIN_PULLUP_DISABLE);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA2, AT91_PIN_PULLUP_DISABLE);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PA3, AT91_PIN_PULLUP_DISABLE);
+
+ // Set the bits. The logic is inverted
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA0, !(val & 1));
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA1, !(val & 2));
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA2, !(val & 4));
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PA3, !(val & 8));
+}
+
+//--------------------------------------------------------------------------
+// EOF at91sam7sek_misc.c
--- /dev/null
+2008-04-30 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * cdl/hal_arm_at91sam7xek.cdl: Added configuration options in
+ order to support the at91sam7x512
+ * src/at91sam7xek_misc.c: Fix a typo in the phy initialisation code.
+ Pin 18 was being setup to drive the powerdown pin of the phy but
+ pin 19 was driven low instead.
+
+2007-01-17 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * Added hal_plf_eth_init() in order to initialise the Davicom
+ 9161A PHY properly on the Evaluation board
+
+2007-01-02 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/hal_arm_at91sam7s.cdl Moved HAL_PLATFORM_XXX defines and
+ definition of platform header file (CYGBLD_HAL_PLATFORM_H) from
+ package CYGPKG_HAL_ARM_AT91SAM7 into board specific packages.
+
+2006-05-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * AT91SAM7X-EK development board package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_arm_at91_sam7xek.cdl
+#
+# ARM AT91 SAM7X EK development board package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 2006 Andrew Lunn
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): andrew lunn
+# Contributors:
+# Date: 2006-05-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_AT91SAM7XEK {
+ display "Atmel AT91SAM7X EK development board"
+ parent CYGPKG_HAL_ARM_AT91SAM7
+ define_header hal_arm_at91sam7xek.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The AT91SAM7XEK HAL package provides the support needed to run
+ eCos on an Atmel AT91SAM7X-EK development board."
+
+ compile at91sam7xek_misc.c
+
+ requires { CYGHWR_HAL_ARM_AT91 == "AT91SAM7S" }
+ requires { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x256" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x128" ||
+ CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x512" }
+
+ requires { is_active(CYGPKG_DEVS_ETH_PHY) implies
+ (1 == CYGHWR_DEVS_ETH_PHY_DM9161A) }
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_at91sam7xek.h>"
+ puts $::cdl_header "/***** proc output start *****/"
+ puts $::cdl_header "#include <pkgconf/hal_arm_at91sam7.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Atmel (AT91SAM7X-EK)\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ puts $::cdl_header "/****** proc output end ******/"
+ }
+}
--- /dev/null
+/*==========================================================================
+//
+// at91sam7xek_misc.c
+//
+// HAL misc board support code for Atmel AT91SAM7X EK board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew lunn
+// Contributors: Andrew Lunn, John Eigelaar
+// Date: 2006-06-20
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+
+// The development board has four LEDs
+void
+hal_at91_led (int val)
+{
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB19, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB20, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB21, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB22, AT91_PIN_OUT);
+
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB19, AT91_PIN_PULLUP_DISABLE);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB20, AT91_PIN_PULLUP_DISABLE);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB21, AT91_PIN_PULLUP_DISABLE);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB22, AT91_PIN_PULLUP_DISABLE);
+
+ // Set the bits. The logic is inverted
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB19, !(val & 1));
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB20, !(val & 2));
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB21, !(val & 4));
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB22, !(val & 8));
+}
+
+void hal_plf_eth_init(void)
+{
+ cyg_uint32 stat;
+
+ /* Enable the PIOB Clock */
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOB);
+
+ /* RXDV / Testmode select */
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB15, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB15, AT91_PIN_PULLUP_DISABLE);
+
+ //TODO: The errata reports that the RMII mode for the SAM7X does not work.
+ // It would probably still be a good idea to use the RMII/MII CDL
+ // configuration to select the appropriate mode here
+ /* COL / !MII select */
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB16, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB16, AT91_PIN_PULLUP_DISABLE);
+
+ /* TXCLK / ISOLATE */
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB0, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB0, AT91_PIN_PULLUP_DISABLE);
+
+ /* Power Down Mode */
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB18, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB18,0);
+
+ /* All the lines setup correctly. Now do a external reset and let the phy
+ start up in the correct mode */
+ HAL_WRITE_UINT32(AT91_RST+AT91_RST_RMR,AT91_RST_RMR_KEY|(1<<0x8));
+ HAL_WRITE_UINT32(AT91_RST+AT91_RST_RCR,AT91_RST_RCR_KEY|AT91_RST_RCR_EXTRST);
+
+ do {
+ HAL_READ_UINT32(AT91_RST+AT91_RST_RSR,stat);
+ } while (!(stat&AT91_RST_RSR_NRST_SET));
+}
+
+//--------------------------------------------------------------------------
+// EOF at91sam7sek_misc.c
--- /dev/null
+2007-04-10 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/hal_arm_sam7ex256.cdl Removed "implements
+ CYGINT_DEVS_CAN_AT91SAM7_CAN0" because this interface is already
+ implemented by package CYGPKG_HAL_ARM_AT91SAM7
+
+2007-04-06 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/sam7ex256_misc.c Added hal_plf_eth_init() in order to initialise
+ the Micrel KS8721 PHY properly on the Olimex board
+
+2007-08-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/sam7ex256_misc.c Use the backlight of the lcd as a simple 1-bit LED
+
+2006-12-30 Uwe Kindler <uwe_kindler@web.de>
+
+ * SAM7-EX256 development board package
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_arm_sam7ex256.cdl
+#
+# Olimex SAM7-EX256 development board package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 2006 Andrew Lunn
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2006-12-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_SAM7EX256 {
+ display "Olimex SAM7-EX256 development board"
+ parent CYGPKG_HAL_ARM_AT91SAM7
+ define_header hal_arm_sam7ex256.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The SAM7EX256 HAL package provides the support needed to run
+ eCos on an Olimex SAM7-EX256 development board."
+
+ compile sam7ex256_misc.c
+
+ requires { CYGHWR_HAL_ARM_AT91 == "AT91SAM7S" }
+ requires { CYGHWR_HAL_ARM_AT91SAM7 == "at91sam7x256" }
+
+ requires { is_active(CYGPKG_DEVS_ETH_PHY) implies
+ (1 == CYGHWR_DEVS_ETH_PHY_KS8721) }
+
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_sam7ex256.h>"
+ puts $::cdl_header "/***** proc output start *****/"
+ puts $::cdl_header "#include <pkgconf/hal_arm_at91sam7.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Olimex SAM7-EX256\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ puts $::cdl_header "/****** proc output end ******/"
+ }
+}
--- /dev/null
+/*==========================================================================
+//
+// sam7ex256_misc.c
+//
+// HAL misc board support code for Olimex SAM7-EX256 board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Andrew Lunn, John Eigelaar
+// Date: 2006-12-30
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+
+//
+// The development board does not contain any leds but a nokia 320 x 320
+// pixel lcd. We use the backlight of the lcd as a simple 1-bit LED
+//
+void hal_at91_led (int val)
+{
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB20, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB20, (val & 1));
+}
+
+//
+// Initialisation of Micrel KS8721 ethernet phy
+//
+void hal_plf_eth_init(void)
+{
+ cyg_uint32 stat;
+
+ // Enable the PIOB Clock
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOB);
+
+ // PU = Enables PCS_LPBK mode at power-up / reset.
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB15, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB15, AT91_PIN_PULLUP_DISABLE);
+
+ // PU = Enables ISOLATE mode at power-up /reset.
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB7, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB7, AT91_PIN_PULLUP_DISABLE);
+
+ // PU = Enables RMII mode at power-up / reset
+ // TODO: The errata reports that the RMII mode for the SAM7X does not work.
+ // It would probably still be a good idea to use the RMII/MII CDL
+ // configuration to select the appropriate mode here
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB16, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB16, AT91_PIN_PULLUP_DISABLE);
+
+ // PU = Enable RMII_BTB mode at power-up / reset.
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB4, AT91_PIN_IN);
+ HAL_ARM_AT91_GPIO_CFG_PULLUP(AT91_GPIO_PB4, AT91_PIN_PULLUP_DISABLE);
+
+ // Power Down Mode = 1 = normal operation
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(AT91_GPIO_PB18, AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_PUT(AT91_GPIO_PB18, 1);
+
+ // All the lines setup correctly. Now do a external reset and let the phy
+ // start up in the correct mode
+ HAL_WRITE_UINT32(AT91_RST+AT91_RST_RMR,AT91_RST_RMR_KEY|(1<<0x8));
+ HAL_WRITE_UINT32(AT91_RST+AT91_RST_RCR,AT91_RST_RCR_KEY|AT91_RST_RCR_EXTRST);
+
+ do
+ {
+ HAL_READ_UINT32(AT91_RST+AT91_RST_RSR,stat);
+ } while (!(stat & AT91_RST_RSR_NRST_SET));
+}
+
+
+//--------------------------------------------------------------------------
+// EOF sam7ex256_misc.c
--- /dev/null
+/*=============================================================================
+//
+// hal_diag_dbg.c
+//
+// HAL diagnostic output code using the debug serial port
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, gthomas
+// Date: 2001-07-12
+// Purpose: HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_at91.h>
+
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h> // base types
+
+#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_if.h> // interface API
+#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h> // Helper functions
+#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h> // Device registers
+
+#include "hal_diag_dcc.h" // DCC initialization file
+//-----------------------------------------------------------------------------
+typedef struct {
+ cyg_uint8* base;
+ cyg_int32 msec_timeout;
+ int isr_vector;
+ cyg_uint32 baud_rate;
+} channel_data_t;
+
+//-----------------------------------------------------------------------------
+
+static void
+cyg_hal_plf_serial_dbg_init_channel(void* __ch_data)
+{
+ cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
+
+ cyg_uint32 baud_value = 0;
+ cyg_uint32 baud_rate = ((channel_data_t*)__ch_data)->baud_rate;
+
+ /* Enable pins to be driven by peripheral, using peripheral A. */
+ HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_ASR),
+ (AT91_PIO_PSR_DRXD |
+ AT91_PIO_PSR_DTXD));
+
+ /* Disables the PIO from controlling the corresponding pin
+ (enables peripheral control of the pin). */
+ HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_PDR),
+ (AT91_PIO_PSR_DRXD |
+ AT91_PIO_PSR_DTXD));
+
+ /* Disable interrupt */
+ HAL_WRITE_UINT32((base+AT91_DBG_IDR), 0xFFFFFFFF);
+
+ /* Reset receiver and transmitter */
+ HAL_WRITE_UINT32((base+AT91_DBG_CR),
+ (AT91_DBG_CR_RSTRX | AT91_DBG_CR_RSTTX |
+ AT91_DBG_CR_RXDIS | AT91_DBG_CR_TXDIS));
+
+ baud_value = AT91_US_BAUD(baud_rate);
+
+ HAL_WRITE_UINT32((base+AT91_DBG_BRGR), baud_value);
+
+ /* Define the USART mode */
+ /* (USART) Normal, 1 stop bit, No Parity, Character Length: 8 bits, Clock */
+ HAL_WRITE_UINT32(base+AT91_DBG_MR,
+ (AT91_DBG_MR_CHMODE_NORMAL |
+ AT91_DBG_MR_PAR_NONE));
+
+ /* Enable Transmitter */
+ HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_TXEN);
+
+ /* Enable Receiver */
+ HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_RXEN);
+}
+
+void
+cyg_hal_plf_serial_dbg_putc(void* __ch_data, char c)
+{
+ cyg_uint8 * base = ((channel_data_t*)__ch_data)->base;
+ cyg_uint32 status;
+ CYGARC_HAL_SAVE_GP();
+
+ // Wait for Tx FIFO not full
+ do
+ {
+ HAL_READ_UINT32((base+AT91_DBG_CSR), status);
+ }
+ while (!(status & AT91_DBG_CSR_TXRDY)) ;
+
+ //UART TX data register
+ HAL_WRITE_UINT8((base+AT91_DBG_THR), c);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_serial_dbg_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+ cyg_uint8 * base = ((channel_data_t*)__ch_data)->base;
+ cyg_uint32 status;
+
+ HAL_READ_UINT32((base+AT91_DBG_CSR), status);
+ if (status & AT91_DBG_CSR_RXRDY)
+ {
+ HAL_READ_UINT8((base+AT91_DBG_RHR), *ch);
+ return true;
+ }
+ return false;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_dbg_getc(void* __ch_data)
+{
+ cyg_uint8 ch;
+ CYGARC_HAL_SAVE_GP();
+
+ while (!cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, &ch));
+
+ CYGARC_HAL_RESTORE_GP();
+ return ch;
+}
+
+static void
+cyg_hal_plf_serial_dbg_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while (__len-- > 0)
+ cyg_hal_plf_serial_dbg_putc(__ch_data, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_dbg_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while (__len-- > 0)
+ *__buf++ = cyg_hal_plf_serial_dbg_getc(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_dbg_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+ int delay_count;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_bool res;
+ CYGARC_HAL_SAVE_GP();
+
+ delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+ for (;;) {
+ res = cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, ch);
+ if (res || 0 == delay_count--)
+ break;
+
+ CYGACC_CALL_IF_DELAY_US(100);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+static int
+cyg_hal_plf_serial_dbg_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+ static int irq_state = 0;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ int ret = 0;
+ va_list ap;
+
+ CYGARC_HAL_SAVE_GP();
+ va_start(ap, __func);
+
+ switch (__func) {
+ case __COMMCTL_GETBAUD:
+ ret = chan->baud_rate;
+ break;
+ case __COMMCTL_SETBAUD:
+ chan->baud_rate = va_arg(ap, cyg_int32);
+ // Should we verify this value here?
+ cyg_hal_plf_serial_dbg_init_channel(chan);
+ ret = 0;
+ break;
+ case __COMMCTL_IRQ_ENABLE:
+ irq_state = 1;
+ HAL_INTERRUPT_UNMASK(chan->isr_vector);
+ HAL_WRITE_UINT32((chan->base+AT91_DBG_IER), AT91_DBG_CSR_RXRDY);
+ break;
+ case __COMMCTL_IRQ_DISABLE:
+ ret = irq_state;
+ irq_state = 0;
+ HAL_WRITE_UINT32((chan->base+AT91_DBG_IDR), AT91_DBG_CSR_RXRDY);
+ HAL_INTERRUPT_MASK(chan->isr_vector);
+ break;
+ case __COMMCTL_DBG_ISR_VECTOR:
+ ret = chan->isr_vector;
+ break;
+ case __COMMCTL_SET_TIMEOUT:
+ ret = chan->msec_timeout;
+ chan->msec_timeout = va_arg(ap, cyg_uint32);
+ default:
+ break;
+ }
+ CYGARC_HAL_RESTORE_GP();
+ return ret;
+}
+
+static int
+cyg_hal_plf_serial_dbg_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+ int res = 0;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint32 status;
+ cyg_uint32 c;
+ cyg_uint8 ch;
+ CYGARC_HAL_SAVE_GP();
+
+ *__ctrlc = 0;
+ HAL_READ_UINT32(chan->base+AT91_DBG_CSR, status);
+ if ( (status & AT91_DBG_CSR_RXRDY) != 0 ) {
+
+ HAL_READ_UINT32(chan->base+AT91_DBG_RHR, c);
+ ch = (cyg_uint8)(c & 0xff);
+ if( cyg_hal_is_break( &ch , 1 ) )
+ *__ctrlc = 1;
+
+ res = CYG_ISR_HANDLED;
+ }
+
+ HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+static channel_data_t at91_ser_channels[1] = {
+ { (cyg_uint8*)AT91_DBG, 1000, CYGNUM_HAL_INTERRUPT_DBG,
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD}
+};
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur;
+
+ cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+ // Init channels
+ cyg_hal_plf_serial_dbg_init_channel(&at91_ser_channels[0]);
+
+ // Setup procs in the vector table
+
+ // Set channel 0
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &at91_ser_channels[0]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_dbg_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_dbg_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_dbg_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_dbg_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_dbg_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_dbg_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_dbg_getc_timeout);
+
+ // Restore original console
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+
+ initialized = 1;
+
+ cyg_hal_plf_serial_init();
+
+#ifdef CYGBLD_HAL_ARM_AT91_DCC
+ cyg_hal_plf_dcc_init(CYGBLD_HAL_ARM_AT91_DCC_CHANNEL);
+#endif
+}
+
+void
+hal_diag_led(int mask)
+{
+ hal_at91_set_leds(mask);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag_dbg.c
--- /dev/null
+/*=============================================================================
+//
+// hal_diag_dcc.c
+//
+// HAL diagnostic output via the DCC interface.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 FSF
+//
+// 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): Andrew Lunn
+// Contributors:jskov, gthomas
+// Date: 2008-06-15
+// Purpose: HAL diagnostic output via DCC.
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h> // base types
+
+#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_if.h> // interface API
+#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h> // Helper functions
+#include <cyg/hal/hal_diag.h>
+
+#define DCC_TX_BUSY 2
+#define DCC_RX_READY 1
+
+//-----------------------------------------------------------------------------
+
+static void
+cyg_hal_plf_dcc_putc(void * __ch_data, char ch)
+{
+ unsigned int status;
+ CYG_UNUSED_PARAM(void *, __ch_data);
+
+ CYGARC_HAL_SAVE_GP();
+
+ do {
+ __asm__ volatile ( "mrc p14,0, %0, c0, c0\n" : "=r" (status));
+ } while ( status & DCC_TX_BUSY );
+ __asm__( "mcr p14,0, %0, c1, c0\n" : : "r" (ch));
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_dcc_getc_nonblock(cyg_uint8* ch)
+{
+ cyg_uint32 status;
+ cyg_uint32 c;
+
+ __asm__( "mrc p14,0, %0, c0, c0\n" : "=r" (status));
+
+ if (status & DCC_RX_READY) {
+ __asm__( "mrc p14,0, %0, c1, c0\n" : "=r" (c));
+ *ch = (char )c;
+ return true;
+ } else
+ return false;
+}
+
+static cyg_uint8
+cyg_hal_plf_dcc_getc(void* __ch_data)
+{
+ cyg_uint8 ch;
+ CYG_UNUSED_PARAM(void *, __ch_data);
+ CYGARC_HAL_SAVE_GP();
+
+ while(!cyg_hal_plf_dcc_getc_nonblock(&ch));
+
+ CYGARC_HAL_RESTORE_GP();
+ return ch;
+}
+
+static void
+cyg_hal_plf_dcc_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ CYG_UNUSED_PARAM(void *, __ch_data);
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ cyg_hal_plf_dcc_putc(NULL, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_dcc_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYG_UNUSED_PARAM(void *, __ch_data);
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_plf_dcc_getc(NULL);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_dcc_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+ int delay_count;
+ cyg_bool res;
+ CYG_UNUSED_PARAM(void *, __ch_data);
+
+ CYGARC_HAL_SAVE_GP();
+
+ delay_count = 100010; // delay in .1 ms steps
+
+ for(;;) {
+ res = cyg_hal_plf_dcc_getc_nonblock(ch);
+ if (res || 0 == delay_count--)
+ break;
+
+ CYGACC_CALL_IF_DELAY_US(100);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+static int
+cyg_hal_plf_dcc_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+ CYG_UNUSED_PARAM(void *, __ch_data);
+ CYG_UNUSED_PARAM(__comm_control_cmd_t, __func);
+
+ return 0;
+}
+
+static void
+cyg_hal_plf_dcc_register(const int channel)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur;
+
+ cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ // Setup procs in the vector table
+
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(channel);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, NULL);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_dcc_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_dcc_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_dcc_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_dcc_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_dcc_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, NULL);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_dcc_getc_timeout);
+
+ // Restore to original console.
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_dcc_init(const int channel)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+
+ initialized = 1;
+
+ cyg_hal_plf_dcc_register(channel);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag_dcc.c
--- /dev/null
+#ifndef CYGONCE_HAL_DIAG_DCC_H
+#define CYGONCE_HAL_DIAG_DCC_H
+
+//=============================================================================
+//
+// hal_diag_dcc.h
+//
+// HAL Support for Kernel Diagnostic Routines via DCC
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 FSF.
+//
+// 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): asl
+// Contributors:
+// Date: 2008-06-15
+// Purpose: HAL Support for Kernel Diagnostic Routines via DCC.
+// Description: Diagnostic routines for use during kernel development.
+// Usage: #include "hal_diag_dcc.h"
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+externC void cyg_hal_plf_dcc_init(const int channel);
+
+#endif
+
--- /dev/null
+/*==========================================================================
+//
+// timer_pit.c
+//
+// HAL timer code using the Periodic Interval Timer
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): asl, Oliver Munz
+// Contributors: asl, Oliver Munz
+// Date: 2006-02-12
+// Purpose: Clock support using the PIT
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_platform_ints.h>
+// -------------------------------------------------------------------------
+// Use system clock
+void
+hal_clock_initialize(cyg_uint32 period)
+{
+ cyg_uint32 sr;
+
+ CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC,
+ "Invalid timer interrupt");
+
+ /* Set Period Interval timer and enable interrupt */
+ HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+ (period - 1) |
+ AT91_PITC_PIMR_PITEN |
+ AT91_PITC_PIMR_PITIEN);
+
+ // Read the status register to clear any pending interrupt
+ HAL_READ_UINT32(AT91_PITC + AT91_PITC_PISR, sr);
+}
+
+// This routine is called during a clock interrupt.
+void
+hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+ cyg_uint32 reg;
+ cyg_uint32 pimr;
+
+ CYG_ASSERT(period < AT91_PITC_VALUE_MASK, "Invalid HAL clock configuration");
+
+ // Check that the PIT has the right period.
+ HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR), pimr);
+ if ((pimr & AT91_PITC_VALUE_MASK) != (period - 1)) {
+ HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+ (period - 1) |
+ AT91_PITC_PIMR_PITEN |
+ AT91_PITC_PIMR_PITIEN);
+ }
+
+ /* Read the value register so that we clear the interrupt */
+ HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIVR, reg);
+}
+
+// Read the current value of the clock, returning the number of hardware
+// "ticks" that have occurred (i.e. how far away the current value is from
+// the start)
+void
+hal_clock_read(cyg_uint32 *pvalue)
+{
+ cyg_uint32 ir;
+ cyg_uint32 pimr;
+
+ // Check that the PIT is running. If not start it.
+ HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR),pimr);
+ if (!(pimr & AT91_PITC_PIMR_PITEN)) {
+ HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+ AT91_PITC_VALUE_MASK | AT91_PITC_PIMR_PITEN);
+ }
+
+ HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir);
+ *pvalue = ir & AT91_PITC_VALUE_MASK;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+// PIT is clocked at MCLK / 16
+//
+void hal_delay_us(cyg_int32 usecs)
+{
+ cyg_int64 ticks;
+ cyg_uint32 val1, val2;
+ cyg_uint32 piv;
+
+ // Calculate how many PIT ticks the required number of microseconds
+ // equate to. We do this calculation in 64 bit arithmetic to avoid
+ // overflow.
+ ticks = (((cyg_uint64)usecs) *
+ ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL;
+
+ // Calculate the wrap around period.
+ HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv);
+ piv = (piv & AT91_PITC_VALUE_MASK) - 1;
+
+ hal_clock_read(&val1);
+ while (ticks > 0) {
+ hal_clock_read(&val2);
+ if (val2 < val1)
+ ticks -= ((piv + val2) - val1); //overflow occurred
+ else
+ ticks -= (val2 - val1);
+ val1 = val2;
+ }
+}
+
+// timer_pit.c
--- /dev/null
+/*==========================================================================
+//
+// timer_tc.c
+//
+// HAL timer code using the Timer Counter
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov, nickg, tkoeller
+// Date: 2001-07-12
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_intr.h> // necessary?
+
+// -------------------------------------------------------------------------
+// Clock support
+
+static cyg_uint32 _period;
+
+void hal_clock_initialize(cyg_uint32 period)
+{
+ CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+
+ CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+ // Disable counter
+ HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+ // Set registers
+ HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | // Reset counter on CPC
+ AT91_TC_CMR_CLKS_MCK32); // 1 MHz
+ HAL_WRITE_UINT32(timer+AT91_TC_RC, period);
+
+ // Start timer
+ HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+ // Enable timer 0 interrupt
+ HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC);
+}
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+ CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+ cyg_uint32 sr;
+
+ CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+ HAL_READ_UINT32(timer+AT91_TC_SR, sr); // Clear interrupt
+
+ if (period != _period) {
+ hal_clock_initialize(period);
+ }
+ _period = period;
+
+}
+
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+ CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+ cyg_uint32 val;
+
+ HAL_READ_UINT32(timer+AT91_TC_CV, val);
+ *pvalue = val;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+// Use timer #2 in MCLOCK/32 mode.
+//
+void hal_delay_us(cyg_int32 usecs)
+{
+ cyg_uint32 stat;
+ cyg_uint64 ticks;
+#if defined(CYGHWR_HAL_ARM_AT91_JTST)
+ // TC2 is reserved for AD/DA. Use TC1 instead.
+ CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1;
+#else
+ CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2;
+#endif
+ // Calculate how many timer ticks the required number of
+ // microseconds equate to. We do this calculation in 64 bit
+ // arithmetic to avoid overflow.
+ ticks = (((cyg_uint64)usecs) *
+ ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL;
+
+ // CYG_ASSERT(ticks < (1 << 16), "Timer overflow");
+
+ if (ticks > (1 << 16))
+ ticks = (1 << 16) - 1;
+
+ if (ticks == 0)
+ return;
+
+ // Disable counter
+ HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+ // Set registers
+ HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32); // 1MHz
+ HAL_WRITE_UINT32(timer+AT91_TC_RA, 0);
+ HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks);
+
+ // Clear status flags
+ HAL_READ_UINT32(timer+AT91_TC_SR, stat);
+
+ // Start timer
+ HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+ // Wait for the compare
+ do {
+ HAL_READ_UINT32(timer+AT91_TC_SR, stat);
+ } while ((stat & AT91_TC_SR_CPC) == 0);
+}
+
+// timer_tc.c
--- /dev/null
+2008-07-21 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/ea2468_misc.c: Added hal_lpc_can_init() to initialize CAN
+ channels
+ * include/plf_io.h: Added HAL_LPC2XXX_INIT_CAN() macro for CAN channel
+ initialisation
+
+2008-07-06 Uwe Kindler <uwe_kindler@web.de>
+
+ * Initial release of Embedded Artists LPC2468 OEM board package
+ * cdl/hal_arm_lpc2xxx_ea2468.cdl
+ * include/plf_io.h
+ * include/hal_platform_setup.h
+ * src/ea2468_misc
+
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 eCosCentric Ltd.
+##
+## 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.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
--- /dev/null
+# ====================================================================
+#
+# hal_arm_lpc24xx_ea2468.cdl
+#
+# Embedded Artists LPC2468 OEM Board HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors: Uwe Kindler
+# Date: 2008-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_LPC24XX_EA2468 {
+ display "Embedded Artists LPC2468 OEM Board board HAL"
+ parent CYGPKG_HAL_ARM_LPC24XX
+ define_header hal_arm_lpc24xx_ea2468.h
+ include_dir cyg/hal
+ hardware
+ implements CYGINT_DEVS_CAN_LPC2XXX_CAN0
+ implements CYGINT_DEVS_CAN_LPC2XXX_CAN1
+ implements CYGINT_IO_SERIAL_LPC24XX_UART0
+ implements CYGINT_IO_SERIAL_LPC24XX_UART1
+ description "
+ The LPC2468 OEM HAL package provides the support needed to run
+ eCos on Embedded Artists LPC2468 OEM 16/32 boards."
+
+ compile ea2468_misc.c
+
+ requires { CYGHWR_HAL_ARM_LPC24XX == "LPC2468" }
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_arm.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_arm_lpc24xx.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_lpc24xx_ea2468.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI-S\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Embedded Artists LPC2468 OEM Board\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ {
+ display "CPU xtal frequency"
+ parent CYGNUM_HAL_ARM_LPC24XX_CLOCKING
+ flavor data
+ default_value {12000000}
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_MAX_CLOCK_SPEED {
+ display "Max. CPU clock speed"
+ parent CYGNUM_HAL_ARM_LPC24XX_CLOCKING
+ flavor data
+ calculated {57600000}
+ requires CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED <= 57600000
+ description "
+ Due to a silicon errata, the highest internal core
+ clock frequency (at the time of writing this document)
+ is 57.6 MHz. This corresponds to an internal PLL
+ frequency of 288 MHz that is divided by 6 to get a 48
+ MHz clock for the core and the USB interface."
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ default_value {"ROM"}
+ legal_values {"RAM" "ROM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+ description "
+ Choose RAM or ROM startup type. Typically ROM startup is used for
+ building RedBoot. RedBoot runs from internal on chip flash of
+ LPC24xx. Use RAM startup for building eCos applications.
+ RedBoot manages the external on board flash devices. It copies
+ the eCos application image from FLASH to on board SDRAM
+ and then starts the eCos application."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ calculated 2
+ description "
+ Channel 0: UART0, Channel 1: UART1"
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+ display "Default console channel."
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ calculated 0
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The LPC2468 OEM board has two serial channels. The first
+ channel, UART0, ist routed to an USB-to-serial bridge and
+ the second channel, UART1, is available on the Sub-D9
+ RS232 connector. This option chooses which channel will be
+ used to connect to a host running GDB."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "GDB serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 38400
+ description "
+ This option controls the baud rate used for the GDB
+ connection."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The LPC2468 OEM board has two serial ports. This option
+ chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 38400
+ description "
+ This option selects the baud rate used for the diagnostic port."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH {
+ display "Data bus width"
+ flavor data
+ default_value { 16 }
+ legal_values { 16 32 }
+ description "
+ The LPC2468 OEM board is sold in two different data bus
+ versions - a 16-bit version and a 32-bit version."
+ }
+
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+ description "
+ Global build options including control over compiler flags,
+ linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "arm-elf" }
+ description "
+ This option specifies the command prefix used when
+ invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+ description "
+ This option controls the global compiler flags which
+ are used to compile all packages by default. Individual
+ packages may define options which override these global
+ flags."
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wl,--gc-sections -Wl,-static -g -nostdlib" }
+ description "
+ This option controls the global linker flags. Individual
+ packages may define options which override these global
+ flags."
+ }
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM"}
+ description "
+ Enable this option if this program is to be used as a
+ ROM monitor, i.e. applications will be loaded into RAM on
+ the board, and this ROM monitor may process exceptions or
+ interrupts generated from the application. This enables
+ features such as utilizing a separate interrupt stack when
+ exceptions are generated."
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "Generic" "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Support can be enabled for different varieties of ROM
+ monitor. This support changes various eCos semantics such
+ as the encoding of diagnostic output, or the overriding of
+ hardware interrupt vectors.
+ Firstly there is \"Generic\" support which prevents the
+ HAL from overriding the hardware vectors that it does not
+ use, to instead allow an installed ROM monitor to handle
+ them. This is the most basic support which is likely to be
+ common to most implementations of ROM monitor.
+ \"GDB_stubs\" provides support when GDB stubs are included
+ in the ROM monitor or boot ROM."
+ }
+
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid
+ Redboot configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ requires { !CYGBLD_BUILD_REDBOOT_WITH_EXEC }
+ default_value 1
+ no_define
+ description "
+ This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+ $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+ $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+ $(OBJCOPY) -O ihex $< $(@:.bin=.hex)
+ $(OBJCOPY) -O binary $< $@
+ }
+
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "arm_lpc24xx_ea2468_ram" :
+ "arm_lpc24xx_ea2468_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { (CYG_HAL_STARTUP == "RAM") ?
+ "<pkgconf/mlt_arm_lpc24xx_ea2468_ram.ldi>" :
+ "<pkgconf/mlt_arm_lpc24xx_ea2468_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { (CYG_HAL_STARTUP == "RAM") ?
+ "<pkgconf/mlt_arm_lpc24xx_ea2468_ram.h>" :
+ "<pkgconf/mlt_arm_lpc24xx_ea2468_rom.h>" }
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+/*=============================================================================
+//
+// hal_platform_setup.h
+//
+// Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2008-06-05
+// Purpose: EA LPC2468 OEM platform specific support routines
+// Description:
+// Usage: #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+#include <pkgconf/system.h>
+#include <cyg/hal/var_io.h>
+
+
+//
+// The minimum initialisation code - we simply setup a valid C stack in
+// internal SRAM and do any further initialisation in C code
+//
+#if defined(CYG_HAL_STARTUP_ROM)
+.macro _setup
+ //
+ // While setting the stack pointer please note that the
+ // Flash programming routines use a
+ // section of the on-chip SRAM. In-System Programming (ISP) uses
+ // the top 256 bytes and In-Application Programming (IAP) uses the
+ // top 128 bytes of the on-chip SRAM. The application stack should
+ // not overlap this area.
+ //
+ ldr r2,=0x4000ffff // ram end
+ sub sp,r2,#0xff
+
+ //
+ // now map the vector table to internal flash - normally this should be
+ // the default value after boot - but we go the save way here and force
+ // the mapping to internal flash (the value for
+ // CYGARC_HAL_LPC24XX_REG_MEMMAP is 1)
+ //
+ ldr r0,=CYGARC_HAL_LPC24XX_REG_SCB_BASE
+ mov r1,#1
+ str r1, [r0,#CYGARC_HAL_LPC24XX_REG_MEMMAP]
+
+ //
+ // Now its is save to copy the first 64 bytes of flash to RAM
+ //
+ mov r0,#0
+ mov r1,#0x40000000
+ mov r2,#0x40
+1:
+ ldr r3,[r0,#4]!
+ str r3,[r1,#4]!
+ cmps r0,r2
+ bne 1b
+
+ //
+ // Now we can map the vector table to internal SRAM because the SRAM no
+ // contains a copy of the vector table from flash (the value for
+ // CYGARC_HAL_LPC24XX_REG_MEMMAP is 2 = SRAM)
+ //
+ ldr r0,=CYGARC_HAL_LPC24XX_REG_SCB_BASE
+ mov r1,#2 // User RAM Mode. Interrupt
+ // vectors are re-mapped to Static RAM.
+ str r1, [r0,#CYGARC_HAL_LPC24XX_REG_MEMMAP]
+
+ //
+ // now we have a valid stack and we can jump into the beautiful
+ // world of C and do any further initialisation in C code
+ //
+ bl hal_plf_startup
+.endm
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+#else
+.macro _setup
+.endm
+#endif
+
+#define PLATFORM_SETUP1 _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
--- /dev/null
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00010000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0xA0000000)
+#define CYGMEM_REGION_ram_SIZE (0x02000000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0xA2000000 - (size_t) CYG_LABEL_NAME (__heap1))
+
--- /dev/null
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc24xx_ea2468.h>
+
+MEMORY
+{
+ sram : ORIGIN = 0x40000000, LENGTH = 0x10000
+ ram : ORIGIN = 0xA0000000, LENGTH = 0x2000000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+ SECTION_rom_vectors (ram, 0xA0010000, LMA_EQ_VMA)
+ SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
+
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00010000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0xA0000000)
+#define CYGMEM_REGION_ram_SIZE (0x02000000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_rom (0x00000000)
+#define CYGMEM_REGION_rom_SIZE (0x00080000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0xA2000000 - (size_t) CYG_LABEL_NAME (__heap1))
+
--- /dev/null
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc24xx_ea2468.h>
+
+MEMORY
+{
+ rom : ORIGIN = 0x00000000, LENGTH = 0x80000
+ sram : ORIGIN = 0x40000000, LENGTH = 0x10000
+ ram : ORIGIN = 0xA0000000, LENGTH = 0x2000000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_rom_vectors (rom, 0x00000000, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+ SECTION_data (ram, 0xA0000000, FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
+
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+// plf_io.h
+//
+// Embedded Artists LPC2468 OEM board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2008-07-06
+// Purpose: EA LPC2468 oem board specific registers
+// Description:
+// Usage: #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+
+//----------------------------------------------------------------------
+// The platform needs this initialization during the
+// hal_hardware_init() function in the varient HAL.
+#ifndef __ASSEMBLER__
+extern void hal_plf_hardware_init(void);
+#define HAL_PLF_HARDWARE_INIT() \
+ hal_plf_hardware_init()
+
+//-----------------------------------------------------------------------------
+// LPX24xx variant specific initialisation of CAN channels
+// This function configures the pin functions for CAN use
+//-----------------------------------------------------------------------------
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX
+externC void hal_lpc_can_init(cyg_uint8 can_chan_no);
+#define HAL_LPC2XXX_INIT_CAN(_can_chan_no_) hal_lpc_can_init(_can_chan_no_)
+#endif // CYGPKG_DEVS_CAN_LPC2XXX
+
+#endif //__ASSEMBLER__
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_HAL_PLF_IO_H
+
--- /dev/null
+/*==========================================================================
+//
+// ea2468_misc.c
+//
+// HAL misc board support code for EA LPC2468 OEM board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2008-06-15
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_lpc24xx_ea2468.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_io.h> // IO macros
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/plf_io.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+#include <redboot.h>
+#endif
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+#define SCB_BASE CYGARC_HAL_LPC24XX_REG_SCB_BASE
+#define EMC_BASE CYGARC_HAL_LPC24XX_REG_EMC_BASE
+#define PIN_BASE CYGARC_HAL_LPC24XX_REG_PIN_BASE
+#define IO_BASE CYGARC_HAL_LPC24XX_REG_IO_BASE
+#define FIO_BASE CYGARC_HAL_LPC24XX_REG_FIO_BASE
+#define SDRAM_BASE 0xA0000000
+
+extern void cyg_hal_plf_serial_init(void);
+
+
+//===========================================================================
+// Initialize communication channels
+//===========================================================================
+void cyg_hal_plf_comms_init(void)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ cyg_hal_plf_serial_init();
+}
+
+
+//===========================================================================
+// Finalize hardware initialisation of platform
+//===========================================================================
+void hal_plf_hardware_init(void)
+{
+
+}
+
+
+//===========================================================================
+// hal_gpio_init
+//===========================================================================
+void hal_gpio_init(void)
+{
+ //
+ // Enable UART0 pins
+ //
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL0, 0x00000050);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL1, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL2, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL3, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL4, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL5, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL6, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL7, 0x30003fff);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL8, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL9, 0);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL10,0);
+
+ HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO0DIR, 0);
+ HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO1DIR, 0);
+ HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO0SET, 0xffffffff);
+ HAL_WRITE_UINT32(IO_BASE + CYGARC_HAL_LPC24XX_REG_IO1SET, 0xffffffff);
+
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO0DIR, 0);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO1DIR, 0);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO2DIR, 0);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO3DIR, 0);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO4DIR, 0);
+
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO0SET, 0xffffffff);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO1SET, 0xffffffff);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO2SET, 0xffffffff);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO3SET, 0xffffffff);
+ HAL_WRITE_UINT32(FIO_BASE + CYGARC_HAL_LPC24XX_REG_FIO4SET, 0xffffffff);
+}
+
+
+//===========================================================================
+// hal_pll_init - initialize pll and all clocks
+//===========================================================================
+void hal_pll_init(void)
+{
+ cyg_uint32 regval;
+
+ HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLSTAT, regval);
+ if (regval & CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLC)
+ {
+ //
+ // Enable PLL, disconnected
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON,
+ CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55);
+ }
+
+ //
+ // Disable PLL, disconnected
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON, 0x00);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55);
+
+ //
+ // Enables main oscillator and wait until it is usable
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_SCS,
+ CYGARC_HAL_LPC24XX_REG_SCS_OSCEN);
+ do
+ {
+ HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_SCS, regval);
+ } while (!(regval & CYGARC_HAL_LPC24XX_REG_SCS_OSCSTAT));
+
+ //
+ // select main OSC, 12MHz, as the PLL clock source
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_CLKSRCSEL,
+ CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_MAIN);
+
+ //
+ // Configure PLL multiplier and pre divider according to
+ // configuration values
+ //
+ regval = ((CYGNUM_HAL_ARM_LPC24XX_PLL_MUL - 1) |
+ (CYGNUM_HAL_ARM_LPC24XX_PLL_DIV - 1) << 16);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCFG, regval);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55);
+
+ //
+ // Enable PLL, disconnected
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON,
+ CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55);
+
+ //
+ // Set CPU clock divider
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_CCLKCFG,
+ CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV - 1);
+
+ //
+ // Set USB clock divider
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_CCLKCFG,
+ CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV - 1);
+
+ //
+ // Check lock bit status
+ //
+ do
+ {
+ HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLSTAT, regval);
+ } while(!(regval & CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLOCK));
+
+ //
+ // Enable PLL and connect
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLCON,
+ CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE |
+ CYGARC_HAL_LPC24XX_REG_PLLCON_PLLC);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0xaa);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLFEED, 0x55);
+
+ //
+ // Check connect bit status
+ //
+ do
+ {
+ HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PLLSTAT, regval);
+ } while(!(regval & CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLC));
+
+ //
+ // entry for JTAG debugger- enable this while loop as a stop for
+ // the JTAG debugger - the JTAG debugger only works after the PLL is
+ // initialized properly
+ //
+ /*while (1)
+ {
+ }*/
+}
+
+
+//===========================================================================
+// hal_mem_init - initialize external memory interface
+//===========================================================================
+void hal_mem_init(void)
+{
+ volatile unsigned int i;
+ volatile unsigned int dummy;
+ volatile cyg_uint32 regval;
+
+ //
+ // Enable external memory interface
+ //
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMC_CTRL,
+ CYGARC_HAL_LPC24XX_REG_EMC_CTRL_EN);
+ HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP, regval);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP,
+ regval | CYGARC_HAL_LPC24XX_REG_PCONP_EMC);
+
+ //
+ // Setup pin functions
+ //
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL4, 0x50000000);
+#if defined(CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH_32)
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL5, 0x55010115);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL7, 0x55555555);
+#else
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL5, 0x05050555);
+#endif
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL6, 0x55555555);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL8, 0x55555555);
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL9, 0x50555555);
+
+#if defined(CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH_32)
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RP, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RAS, 3);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_SREX, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_APR, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_DAL, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_WR, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RC, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RFC, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_XSR, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RRD, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_MRD, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RDCFG, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS0,
+ 0x00000202);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0,
+ 0x00005480);
+#else
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RP, 2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RAS, 3);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_SREX, 7);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_APR, 2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_DAL, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_WR, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RC, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RFC, 5);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_XSR, 7);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RRD, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_MRD, 2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RDCFG, 1);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS0,
+ 0x00000303);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0,
+ 0x00000680);
+#endif
+
+ //
+ // Wait 100 ms and then send command: NOP
+ //
+ HAL_DELAY_US(100000);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL,
+ 0x00000183);
+
+ //
+ // wait 200 ms and then send command: PRECHARGE-ALL, shortest
+ // possible refresh period
+ //
+ HAL_DELAY_US(200000);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL,
+ 0x00000103);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_REFRESH,
+ 0x00000002);
+
+ //
+ // wait 128 ABH clock cycles
+ //
+ for(i = 0; i < 64; i++)
+ {
+ asm volatile(" nop");
+ }
+
+ //
+ // Set correct refresh period and the send command MODE
+ //
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_REFRESH, 28);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL,
+ 0x00000083);
+
+ //
+ // Set mode register in SDRAM
+ //
+#if defined(CYGHWR_HAL_ARM_LPC24XX_EA2468_DATA_BUS_WIDTH_32)
+ dummy = *((volatile unsigned int*)(SDRAM_BASE | (0x22 << 11)));
+#else
+ dummy = *((volatile unsigned int*)(SDRAM_BASE | (0x33 << 12)));
+#endif
+
+ //
+ //Send command: NORMAL, enable buffer and wait for 1 second
+ //
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL,
+ 0x00000000);
+ HAL_READ_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0, regval);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0,
+ regval | 0x00080000);
+ HAL_DELAY_US(1000);
+
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN0, 0x2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN0, 0x2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD0, 0x1f);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE0, 0x1f);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR0, 0x1f);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN0, 0xf);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG0,
+ 0x00000081);
+
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN1, 0x2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN1, 0x2);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD1, 0x8);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE1, 0x1f);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR1, 0x8);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN1, 0xf);
+ HAL_WRITE_UINT32(EMC_BASE + CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG1,
+ 0x00000080);
+}
+
+
+//===========================================================================
+// hal_plf_startup
+//===========================================================================
+void hal_plf_startup(void)
+{
+ hal_pll_init();
+
+ //
+ // Set clock speed of all peripherals to reset value (CPU speed / 4)
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCLKSEL0, 0x00000000);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCLKSEL1, 0x00000000);
+
+ //
+ // Setup memory acceleration module
+ //
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_MAMCR, 0);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_MAMTIM, 4);
+
+ hal_gpio_init();
+ HAL_DELAY_US(20000);
+ hal_mem_init();
+}
+
+
+//===========================================================================
+// hal_lpc2xxx_set_leds
+//===========================================================================
+void hal_lpc24xx_set_leds (int mask)
+{
+ //
+ // implement function for setting diagnostic leds
+ //
+}
+
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX
+//===========================================================================
+// Configure CAN pins
+//===========================================================================
+void hal_lpc_can_init(cyg_uint8 can_chan_no)
+{
+ CYG_ASSERT(can_chan_no < 2, "CAN channel number out of bounds");
+
+ cyg_uint32 pinsel0_val;
+ cyg_uint32 pconp_val;
+ HAL_READ_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL0, pinsel0_val);
+ HAL_READ_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP, pconp_val);
+ switch (can_chan_no)
+ {
+ case 0:
+ CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 0, 1);
+ CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 1, 1);
+ pconp_val |= CYGARC_HAL_LPC24XX_REG_PCONP_CAN1;
+ break;
+
+ case 1:
+ CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 4, 2);
+ CYGARC_HAL_LPC24XX_SET_PIN_FUN(pinsel0_val, 5, 2);
+ pconp_val |= CYGARC_HAL_LPC24XX_REG_PCONP_CAN2;
+ break;
+ }
+ HAL_WRITE_UINT32(PIN_BASE + CYGARC_HAL_LPC24XX_REG_PINSEL0, pinsel0_val);
+ HAL_WRITE_UINT32(SCB_BASE + CYGARC_HAL_LPC24XX_REG_PCONP, pconp_val);
+}
+#endif // #ifdef CYGPKG_DEVS_CAN_LPC2XXX
+
+//--------------------------------------------------------------------------
+// EOF ea2468_misc.c
--- /dev/null
+2008-07-21 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/lpc2xxx_misc.c: Added hal_lpc_can_init() to initialize CAN
+ channels
+ * cdl/hal_arm_lpc24xx.cdl: Added a number of CYGHWR_HAL_ARM_LPC2XXX_xxx
+ options for device driver compatibility reasons. Some LPC2xxx device
+ drivers rely on these definitions. Moved some configuration options
+ to make configuration more intuitive in configuration tool. Added
+ CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK option for configuration of CAN
+ peripheral clock.
+ * include/var_io.h: Added macro CYGARC_HAL_LPC24XX_SET_PIN_FUN()
+ * src/lpc2xxx_misc.c: Added function hal_lpc_set_pclk() to set
+ peripheral clocks easily. Initialize peripheral clocks in
+ hal_hardware_init() according to configuration.
+
+2008-07-06 Uwe Kindler <uwe_kindler@web.de>
+
+ * Initial release of LPC24xx variant support (based on LPX2xxx variant)
+ * src/hal_diag.c:
+ * src/lpc2xxx_misc.c:
+ * include/plf_stub.h:
+ * include/var_io.h:
+ * include/var_arch.h:
+ * include/hal_var_ints.h:
+ * include/hal_diag.h:
+ * include/hal_cache.h:
+ * cdl/hal_arm_lpc24xx.cdl: New port - based on LPX2xxx variant.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_arm_lpc24xx.cdl
+#
+# NXP LPC24XX HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2004 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors: gthomas, tkoeller, tdrury, nickg
+# Date: 2008-07-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_LPC24XX {
+ display "NXP LPC24XX variant HAL"
+ parent CYGPKG_HAL_ARM
+ define_header hal_arm_lpc24xx.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The LPC24XX HAL package provides the support needed to run
+ eCos on NXP LPC24XX based targets."
+
+ compile hal_diag.c lpc24xx_misc.c
+
+ implements CYGINT_HAL_DEBUG_GDB_STUBS
+ implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+ implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+ implements CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
+ implements CYGINT_HAL_ARM_ARCH_ARM7
+ implements CYGINT_HAL_ARM_THUMB_ARCH
+
+ # Let the architectural HAL see this variant's files
+ define_proc {
+ puts $::cdl_header "#define CYGBLD_HAL_VAR_INTS_H <cyg/hal/hal_var_ints.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
+ puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_ARCH_H"
+ }
+
+ cdl_component CYGHWR_HAL_ARM_LPC24XX {
+ display "LPC24XX variant used"
+ flavor data
+ default_value { "LPC246x" }
+ legal_values { "LPC246x" "LPC2458" "LPC2460" "LPC2468" "LPC2470"
+ "LPC2478"}
+ description "
+ The LPC24XX microcontroller family has several variants,
+ the main differences being the amount of on-chip RAM,
+ flash and peripherals. This option allows the platform
+ HALs to select the specific microcontroller being used."
+
+ cdl_option CYGHWR_HAL_ARM_LPC24XX_FAMILY {
+ display "LPC24XX variant family"
+ flavor data
+ calculated {
+ is_substr(CYGHWR_HAL_ARM_LPC24XX, "LPC246") ?
+ "LPC246X" : "LPC24XX"
+ }
+ description "
+ This specifies the family that the processor
+ belongs to. This is useful as it defines certain common
+ characteristics which affect which features should be
+ available in the HAL."
+ }
+ }
+
+ # This is going to get really messy before long as the number of parts
+ # explodes. Its useful to know the actual part in use, but its just as
+ # useful to know which family it belongs to. LPC210x shouldn't really
+ # be in the list of devices, but will probably break something if removed.
+ cdl_component CYGHWR_HAL_ARM_LPC2XXX {
+ display "LPC2XXX variant used"
+ flavor data
+ calculated CYGHWR_HAL_ARM_LPC24XX
+ description "
+ This option is only here for compatibility reasons because some of
+ the LPC2XXX device drivers rely on these definitions. If this
+ is defined here, the LPC24XX variant can use the LPC2XXX device
+ drivers for on-chip peripherals."
+
+ cdl_option CYGHWR_HAL_ARM_LPC2XXX_FAMILY {
+ display "LPC2XXX variant family"
+ flavor data
+ calculated CYGHWR_HAL_ARM_LPC24XX_FAMILY
+ description "
+ This option is only here for compatibility reasons
+ because some of the LPC2XXX device drivers rely on
+ these definitions. If this is defined here, the
+ LPC24XX variant can use the LPC2XXX device drivers
+ for on-chip peripherals."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION {
+ display "LPC2XXX variant version"
+ flavor data
+ calculated {
+ is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC21") ? 1 :
+ is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC22") ? 2 :
+ is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC24") ? 4 : 0
+ }
+ description "
+ This specifies the variant version that the processor
+ belongs to. Some common characteristics may be
+ different in newer LPC2xxx versions. I.e. the LPC24xx variants
+ are significant different from former LPC2xxx variants."
+ }
+ }
+
+ # Important! Be very careful changing this value. That will always
+ # enter the LPC24XX bootloader after reset and consequently will
+ # never run your code. You must know what you are doing. Look at
+ # arch. vectors.S for details.
+ cdl_option CYGNUM_HAL_ARM_VECTOR_0x14 {
+ display "ARM vector at 0x14"
+ flavor data
+ default_value 0xB4405F62
+ legal_values 0 to 0xFFFFFFFF
+ description "
+ In order to detect if a valid program is present, every
+ user program must have a program signature. This signature
+ is a word-wide number that is stored in the unused
+ location in the ARM7 vector table at 0x00000014. The
+ program signature is the two's compliment of the checksum
+ of the ARM vector table."
+ }
+
+ cdl_component CYGNUM_HAL_ARM_LPC24XX_CLOCKING {
+ display "Clocking"
+ flavor none
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_PLL_MUL {
+ display "PLL multiplier"
+ flavor data
+ legal_values 6 to 32767
+ default_value { 12 }
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_PLL_DIV {
+ display "PLL divider"
+ flavor data
+ legal_values 1 to 32
+ default_value { 1 }
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_PLL_OUTPUT {
+ display "PLL output (MHz)"
+ flavor data
+ legal_values 275000000 to 290000000
+ calculated { 2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL *
+ CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ /
+ CYGNUM_HAL_ARM_LPC24XX_PLL_DIV}
+ description "
+ Normally the PLL output must be in the range of 275 MHz to
+ 550 MHz Because of a chip errata the maximum output of the CCO
+ within the PLL block is limited to 290 MHz."
+ }
+
+ cdl_component CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED {
+ display "CPU clock speed"
+ flavor data
+ calculated { 2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL *
+ CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ /
+ CYGNUM_HAL_ARM_LPC24XX_PLL_DIV /
+ CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV}
+ description "
+ The core CPU clock speed is the PLL output divided by the
+ CPU clock divider"
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV {
+ display "CPU clock divider"
+ flavor data
+ legal_values 6 to 256
+ default_value { 6 }
+ description "
+ The CPU clock divider controls the division of the PLL
+ output before it is used by the CPU. When the PLL is
+ bypassed, the division may be by 1. When the PLL is
+ running, the output must be divided in order to bring the
+ CPU clock frequency (CCLK) within operating limits. An 8
+ bit divider allows a range of options, including slowing
+ CPU operation to a low rate for temporary power savings
+ without turning off the PLL. Only even values
+ (2, 4, 6, ..., 256) are supported and can be used.
+ Warning: Using an odd value (1, 3, 5, ..., 255) when
+ setting this option may result in incorrect operation of
+ the device."
+ }
+ }
+
+
+ cdl_component CYGNUM_HAL_ARM_LPC24XX_USB_CLOCK_SPEED {
+ display "USB clock speed"
+ flavor data
+ calculated { 2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL *
+ CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ /
+ CYGNUM_HAL_ARM_LPC24XX_PLL_DIV /
+ CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV}
+ description "
+ The USB clock speed is the PLL output divided by the
+ USB clock divider"
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV {
+ display "USB clock divider"
+ flavor data
+ legal_values 1 to 8
+ default_value { 6 }
+ description "
+ This divider controls the division of the PLL output before
+ it is used by the USB block. If the PLL is bypassed, the
+ division may be by 1. In that case, the PLL input frequency
+ must be 48 MHz, with a 500 ppm tolerance. When the PLL is
+ running, the output must be divided in order to bring the
+ USB clock frequency to 48 MHz with a 50% duty cycle. A
+ 4-bit divider allows obtaining the correct USB clock from
+ any even multiple of 48 MHz (i.e. any mutliple of 96 MHz)
+ within the PLL operating range."
+ }
+ }
+
+ cdl_component CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK {
+ display "CAN clock speed"
+ flavor data
+ calculated { CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED /
+ CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV}
+ description "
+ The CAN clock speed is the CPU clock output divided by the
+ CAN clock divider"
+
+ cdl_option CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV {
+ display "CAN clock divider"
+ flavor data
+ legal_values { 1 2 4 6 }
+ default_value { 1 }
+ description "
+ This divider selects the peripheral clock for both CAN
+ channels. The divider divides the CPU clock to get the
+ clock for the CAN peripherals."
+ }
+ }
+ }
+
+ cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants"
+ flavor none
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ default_value 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ default_value 100
+ }
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ default_value { ((CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED) /
+ CYGNUM_HAL_RTC_DENOMINATOR) }
+ }
+ }
+
+ cdl_option CYGHWR_HAL_ARM_LPC24XX_IDLE_PWRSAVE {
+ display "Stop clock in idle loop to save power"
+ flavor bool
+ default_value { is_active(CYGPKG_REDBOOT) ? 0 : 1 }
+ description "
+ Select this option when it is desired to save power by
+ stopping the processor clock in the idle loop. This is
+ controlled by the PCON register. Generally this is a good
+ thing, but it may be necessary to disable this when
+ debugging via JTAG, as stopping the clock can prevent the
+ debugger getting control of the system."
+ }
+
+ cdl_option CYGNUM_HAL_KERNEL_COUNTERS_CLOCK_ISR_DEFAULT_PRIORITY {
+ display "Default priority for system clock interrupts"
+ flavor data
+ legal_values { 0 to 15 }
+ default_value 15
+ description "
+ There are 16 priority levels, corresponding to the values 0 through
+ 15 decimal, of which 15 is the lowest priority. The reset value of
+ these interrupt priority registers defaults all interrupts to the
+ lowest priority, allowing a single write to elevate the priority
+ of an individual interrupt."
+ }
+
+}
--- /dev/null
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+// hal_cache.h
+//
+// HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jani
+// Contributors:
+// Date: 2004-09-08
+// Purpose: Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+// cache control operations.
+// Usage:
+// #include <cyg/hal/hal_cache.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Purge contents of data cache
+#define HAL_DCACHE_PURGE_ALL()
+
+// Query the state of the data cache (does not affect the caching)
+#define HAL_DCACHE_IS_ENABLED(_state_) \
+ CYG_MACRO_START \
+ (_state_) = 0; \
+ CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+// Query the state of the instruction cache (does not affect the caching)
+#define HAL_ICACHE_IS_ENABLED(_state_) \
+ CYG_MACRO_START \
+ (_state_) = 0; \
+ CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
--- /dev/null
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+//=============================================================================
+//
+// hal_diag.h
+//
+// HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, gthomas, tkoeller
+// Date: 2001-07-12
+// Purpose: HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage: #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+//-----------------------------------------------------------------------------
+// LED
+externC void hal_diag_led(int mask);
+externC void hal_lpc24xx_set_leds(int mask);
+
+//-----------------------------------------------------------------------------
+// delay
+
+externC void hal_delay_us(cyg_int32 usecs);
+#define HAL_DELAY_US(n) hal_delay_us(n);
+
+//-----------------------------------------------------------------------------
+// end of hal_diag.h
+#endif // CYGONCE_HAL_DIAG_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_INTS_H
+#define CYGONCE_HAL_VAR_INTS_H
+//==========================================================================
+//
+// hal_var_ints.h
+//
+// HAL Interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2008-07-05
+// Purpose: Define Interrupt support
+// Description: The interrupt details for the LPC24XX are defined here.
+// Usage:
+// #include <pkgconf/system.h>
+// #include CYGBLD_HAL_VARIANT_H
+// #include CYGBLD_HAL_VAR_INTS_H
+//
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#define CYGNUM_HAL_INTERRUPT_WD 0
+#define CYGNUM_HAL_INTERRUPT_SOFT 1
+#define CYGNUM_HAL_INTERRUPT_DCC_RX 2
+#define CYGNUM_HAL_INTERRUPT_DCC_TX 3
+#define CYGNUM_HAL_INTERRUPT_TIMER0 4
+#define CYGNUM_HAL_INTERRUPT_TIMER1 5
+#define CYGNUM_HAL_INTERRUPT_UART0 6
+#define CYGNUM_HAL_INTERRUPT_UART1 7
+#define CYGNUM_HAL_INTERRUPT_PWM0 8
+#define CYGNUM_HAL_INTERRUPT_I2C 9
+#define CYGNUM_HAL_INTERRUPT_SPI0 10
+#define CYGNUM_HAL_INTERRUPT_SPI1 11
+#define CYGNUM_HAL_INTERRUPT_PLL 12
+#define CYGNUM_HAL_INTERRUPT_RTCDEV 13 // actual RTC device not the
+ // eCos 'real time clock'
+ // interrupt. The latter is on
+ // TIMER0.
+#define CYGNUM_HAL_INTERRUPT_EINT0 14
+#define CYGNUM_HAL_INTERRUPT_EINT1 15
+#define CYGNUM_HAL_INTERRUPT_EINT2 16
+#define CYGNUM_HAL_INTERRUPT_EINT3 17
+#define CYGNUM_HAL_INTERRUPT_AD 18
+#define CYGNUM_HAL_INTERRUPT_I2C1 19
+#define CYGNUM_HAL_INTERRUPT_BOD 20
+#define CYGNUM_HAL_INTERRUPT_ETH 21
+#define CYGNUM_HAL_INTERRUPT_USB 22
+#define CYGNUM_HAL_INTERRUPT_CAN 23
+#define CYGNUM_HAL_INTERRUPT_SD_MMC 24
+#define CYGNUM_HAL_INTERRUPT_DMA 25
+#define CYGNUM_HAL_INTERRUPT_TIMER2 26
+#define CYGNUM_HAL_INTERRUPT_TIMER3 27
+#define CYGNUM_HAL_INTERRUPT_UART2 28
+#define CYGNUM_HAL_INTERRUPT_UART3 29
+#define CYGNUM_HAL_INTERRUPT_I2C2 30
+#define CYGNUM_HAL_INTERRUPT_I2S 31
+
+
+#define CYGNUM_HAL_ISR_MIN 0
+#define CYGNUM_HAL_ISR_MAX (31)
+
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX+1)
+
+/* use non-vectored interrupts in kernel tests intr0/kintr0 */
+#define HAL_INTR_TEST_PRIO_A 16
+#define HAL_INTR_TEST_PRIO_B 16
+#define HAL_INTR_TEST_PRIO_C 16
+
+//The vector used by the Real time clock
+#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_TIMER0
+
+// Other entries here moved to variant specific include file
+// This is included here to avoid breaking anything
+#include <cyg/hal/lpc24xx_misc.h>
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_HAL_VAR_INTS_H
--- /dev/null
+#ifndef CYGONCE_HAL_ARM_LPC24XX_VAR_LPC24XX_MISC_H
+#define CYGONCE_HAL_ARM_LPC24XX_VAR_LPC24XX_MISC_H
+//=============================================================================
+//
+// lpc24xx_misc.h
+//
+// HAL misc variant support code for NCP LPC24xx header file
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andyj
+// Contributors: jani
+// Date: 2006-02-04
+// Purpose: LPC2XXX specific miscellaneous support header file
+// Description:
+// Usage: #include <cyg/hal/lpc24xx_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Functions to obtain the current processor clock settings
+//-----------------------------------------------------------------------------
+externC cyg_uint32 hal_lpc_get_pclk(cyg_uint32 peripheral_id);
+
+//
+// Identifiers for peripheral clock. Use these identifiers with the function
+// hal_get_pclk()
+//
+#define CYNUM_HAL_LPC24XX_PCLK_WDT 0
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER0 1
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER1 2
+#define CYNUM_HAL_LPC24XX_PCLK_UART0 3
+#define CYNUM_HAL_LPC24XX_PCLK_UART1 4
+#define CYNUM_HAL_LPC24XX_PCLK_PWM0 5
+#define CYNUM_HAL_LPC24XX_PCLK_PWM1 6
+#define CYNUM_HAL_LPC24XX_PCLK_I2C0 7
+#define CYNUM_HAL_LPC24XX_PCLK_SPI 8
+#define CYNUM_HAL_LPC24XX_PCLK_RTC 9
+#define CYNUM_HAL_LPC24XX_PCLK_SSP1 10
+#define CYNUM_HAL_LPC24XX_PCLK_DAC 11
+#define CYNUM_HAL_LPC24XX_PCLK_ADC 12
+#define CYNUM_HAL_LPC24XX_PCLK_CAN1 13
+#define CYNUM_HAL_LPC24XX_PCLK_CAN2 14
+#define CYNUM_HAL_LPC24XX_PCLK_ACF 15
+#define CYNUM_HAL_LPC24XX_PCLK_BATRAM 16
+#define CYNUM_HAL_LPC24XX_PCLK_GPIO 17
+#define CYNUM_HAL_LPC24XX_PCLK_PCB 18
+#define CYNUM_HAL_LPC24XX_PCLK_I2C1 19
+#define CYNUM_HAL_LPC24XX_PCLK_SSP0 21
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER2 22
+#define CYNUM_HAL_LPC24XX_PCLK_TIMER3 23
+#define CYNUM_HAL_LPC24XX_PCLK_UART2 24
+#define CYNUM_HAL_LPC24XX_PCLK_UART3 25
+#define CYNUM_HAL_LPC24XX_PCLK_I2C2 26
+#define CYNUM_HAL_LPC24XX_PCLK_I2S 27
+#define CYNUM_HAL_LPC24XX_PCLK_MCI 28
+#define CYNUM_HAL_LPC24XX_PCLK_SYSCON 30
+
+
+//-----------------------------------------------------------------------------
+// Macros to derive the baudrate divider values for the internal UARTs
+// The LPC24xx family supports differents baudrate clocks for each single
+// UART. So we need a way to calculate the baudrate for each single UART
+// Now we rely on the fact that we use the same baurate clock for all
+// UARTs and we query only UART0
+//-----------------------------------------------------------------------------
+#define CYG_HAL_ARM_LPC24XX_PCLK(_pclkid_) hal_lpc_get_pclk(_pclkid_)
+#define CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud) \
+ (CYG_HAL_ARM_LPC24XX_PCLK(CYNUM_HAL_LPC24XX_PCLK_UART0)/((baud)*16))
+#define CYG_HAL_ARM_LPC24XX_BAUD_GENERATOR(_pclkid_, baud) \
+ (CYG_HAL_ARM_LPC24XX_PCLK(_pclkid_)/((baud)*16))
+
+
+//-----------------------------------------------------------------------------
+// LPX24xx platform reset (watchdog resets the board)
+//-----------------------------------------------------------------------------
+externC void hal_lpc_watchdog_reset(void);
+
+#define HAL_PLATFORM_RESET() hal_lpc_watchdog_reset()
+#define HAL_PLATFORM_RESET_ENTRY 0
+
+//-----------------------------------------------------------------------------
+// end of lpc24xx_misc.h
+#endif // CYGONCE_HAL_ARM_LPC24XX_VAR_LPC24XX_MISC_H
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+// plf_stub.h
+//
+// Platform header for GDB stub support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jani
+// Contributors:jskov, gthomas
+// Date: 2004-10-5
+// Purpose: Platform HAL stub support for LPC2XXX based boards.
+// Usage: #include <cyg/hal/plf_stub.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM
+
+#include <cyg/hal/arm_stub.h> // architecture stub support
+
+//----------------------------------------------------------------------------
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() CYG_EMPTY_STATEMENT
+
+//----------------------------------------------------------------------------
+// Stub initializer.
+#define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+//=============================================================================
+//
+// var_arch.h
+//
+// LPC24XX variant architecture overrides
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Jonathan Larmour <jifl@eCosCentric.com>
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: jlarmour,Daniel Neri
+// Date: 2008-07-06
+// Purpose: LPC24XX variant architecture overrides
+// Description:
+// Usage: #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor. These implementations halt the system core clock.
+
+#ifdef CYGHWR_HAL_ARM_LPC24XX_IDLE_PWRSAVE
+#ifndef HAL_IDLE_THREAD_ACTION
+
+#define HAL_IDLE_THREAD_ACTION(_count_) \
+CYG_MACRO_START \
+HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + \
+ CYGARC_HAL_LPC24XX_REG_PCON, \
+ CYGARC_HAL_LPC24XX_REG_PCON_IDL); \
+CYG_MACRO_END
+
+#endif // HAL_IDLE_THREAD_ACTION
+#endif // CYGHWR_HAL_ARM_LPC24XX_IDLE_MODE
+
+//-----------------------------------------------------------------------------
+// end of var_arch.h
+#endif // CYGONCE_HAL_VAR_ARCH_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_IO_H
+#define CYGONCE_HAL_VAR_IO_H
+//=============================================================================
+//
+// var_io.h
+//
+// Variant specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2008-07-05
+// Purpose: NXP LPC24xx variant specific registers
+// Description:
+// Usage: #include <cyg/hal/var_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal_arm_lpc24xx.h> // variant chip model selection.
+#include <cyg/hal/plf_io.h>
+
+//=============================================================================
+// Watchdog (WD)
+#define CYGARC_HAL_LPC24XX_REG_WD_BASE 0xE0000000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_WDMOD 0x0000
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDEN (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDRESET (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDTOF (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_WDMOD_WDINT (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_WDTC 0x0004
+#define CYGARC_HAL_LPC24XX_REG_WDFEED 0x0008
+#define CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC1 0xAA
+#define CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC2 0x55
+#define CYGARC_HAL_LPC24XX_REG_WDTV 0x000C
+
+
+//=============================================================================
+// Timers (Tx)
+
+#define CYGARC_HAL_LPC24XX_REG_TIMER0_BASE 0xE0004000
+#define CYGARC_HAL_LPC24XX_REG_TIMER1_BASE 0xE0008000
+#define CYGARC_HAL_LPC24XX_REG_TIMER2_BASE 0xE0070000
+#define CYGARC_HAL_LPC24XX_REG_TIMER3_BASE 0xE0074000
+
+// Registers are offsets from base for each timer
+#define CYGARC_HAL_LPC24XX_REG_TxIR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR0 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR1 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR2 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_MR3 (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR0 (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR1 (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR2 (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_TxIR_CR3 (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_TxTCR 0x0004
+#define CYGARC_HAL_LPC24XX_REG_TxTCR_CTR_ENABLE (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxTCR_CTR_RESET (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxTC 0x0008
+#define CYGARC_HAL_LPC24XX_REG_TxPR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_TxPC 0x0010
+#define CYGARC_HAL_LPC24XX_REG_TxMCR 0x0014
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_INT (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_STOP (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR1_INT (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR1_RESET (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR1_STOP (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR2_INT (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR2_RESET (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR2_STOP (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR3_INT (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR3_RESET (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_TxMCR_MR3_STOP (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_TxMR0 0x0018
+#define CYGARC_HAL_LPC24XX_REG_TxMR1 0x001C
+#define CYGARC_HAL_LPC24XX_REG_TxMR2 0x0020
+#define CYGARC_HAL_LPC24XX_REG_TxMR3 0x0024
+#define CYGARC_HAL_LPC24XX_REG_TxCCR 0x0028
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR0_RISE (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR0_FALL (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR0 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR1_RISE (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR1_FALL (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR1 (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR2_RISE (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR2_FALL (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR2 (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR3_RISE (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR3_FALL (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_TxCCR_INT_CR3 (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_TxCR0 0x002C
+#define CYGARC_HAL_LPC24XX_REG_TxCR1 0x0030
+#define CYGARC_HAL_LPC24XX_REG_TxCR2 0x0034
+#define CYGARC_HAL_LPC24XX_REG_TxCR3 0x0038
+#define CYGARC_HAL_LPC24XX_REG_TxEMR 0x003C
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM0 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM1 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM2 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_TxEMR_EM3 (1<<3)
+
+//=============================================================================
+// UARTs (Ux)
+
+#define CYGARC_HAL_LPC24XX_REG_UART0_BASE 0xE000C000
+#define CYGARC_HAL_LPC24XX_REG_UART1_BASE 0xE0010000
+#define CYGARC_HAL_LPC24XX_REG_UART2_BASE 0xE0078000
+#define CYGARC_HAL_LPC24XX_REG_UART3_BASE 0xE007C000
+
+// Registers are offsets from base for each UART
+#define CYGARC_HAL_LPC24XX_REG_UxRBR 0x0000 // DLAB=0 read
+#define CYGARC_HAL_LPC24XX_REG_UxTHR 0x0000 // DLAB=0 write
+#define CYGARC_HAL_LPC24XX_REG_UxDLL 0x0000 // DLAB=1 r/w
+#define CYGARC_HAL_LPC24XX_REG_UxIER 0x0004 // DLAB=0
+#define CYGARC_HAL_LPC24XX_REG_UxIER_RXDATA_INT (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxIER_THRE_INT (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxIER_RXLS_INT (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_U1IER_RXMS_INT (1<<3) // U1 only
+#define CYGARC_HAL_LPC24XX_REG_UxDLM 0x0004 // DLAB=1
+
+#define CYGARC_HAL_LPC24XX_REG_UxIIR 0x0008 // read
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR0 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR1 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_IIR3 (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_UxIIR_FIFOS (0xB0)
+
+#define CYGARC_HAL_LPC24XX_REG_UxFCR 0x0008 // write
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_FIFO_ENA (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_FIFO_RESET (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_TX_FIFO_RESET (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_0 (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_1 (0x40)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_2 (0x80)
+#define CYGARC_HAL_LPC24XX_REG_UxFCR_RX_TRIGGER_3 (0xB0)
+
+#define CYGARC_HAL_LPC24XX_REG_UxLCR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_5 (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_6 (0x01)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_7 (0x02)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_8 (0x03)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_STOP_1 (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_STOP_2 (0x04)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ENA (0x08)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ODD (0x00)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_EVEN (0x10)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ONE (0x20)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_PARITY_ZERO (0x30)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_BREAK_ENA (0x40)
+#define CYGARC_HAL_LPC24XX_REG_UxLCR_DLAB (0x80)
+
+
+// Modem Control Register is UART1 only
+#define CYGARC_HAL_LPC24XX_REG_U1MCR 0x0010
+#define CYGARC_HAL_LPC24XX_REG_U1MCR_DTR (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_U1MCR_RTS (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_U1MCR_LOOPBACK (1<<4)
+
+#define CYGARC_HAL_LPC24XX_REG_UxLSR 0x0014
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_RDR (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_OE (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_PE (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_FE (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_BI (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_THRE (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_TEMT (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_UxLSR_RX_FIFO_ERR (1<<7)
+
+// Modem Status Register is UART1 only
+#define CYGARC_HAL_LPC24XX_REG_U1MSR 0x0018
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DCTS (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DDSR (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_RI_FALL (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DDCD (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_CTS (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DSR (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_RI (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_U1MSR_DCD (1<<7)
+
+#define CYGARC_HAL_LPC24XX_REG_UxSCR 0x001C
+#define CYGARC_HAL_LPC24XX_REG_UxACR 0x0020
+#define CYGARC_HAL_LPC24XX_REG_U3ICR 0x0024
+#define CYGARC_HAL_LPC24XX_REG_UxFDR 0x0028
+#define CYCARC_HAL_LPC24XX_REG_UxTER 0x0030
+
+
+//=============================================================================
+// Pulse Width Modulator (PWM)
+
+#define CYGARC_HAL_LPC24XX_REG_PWM0_BASE 0xE0014000
+#define CYGARC_HAL_LPC24XX_REG_PWM1_BASE 0xE0018000
+
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_PWMIR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR0_INT (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR1_INT (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR2_INT (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR3_INT (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR4_INT (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR5_INT (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PWMIR_MR6_INT (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR 0x0004
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR_CTR_ENA (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR_CTR_RESET (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMTCR_PWM_ENA (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMTC 0x0008
+#define CYGARC_HAL_LPC24XX_REG_PWMPR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_PWMPC 0x0010
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR 0x0014
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR0_INT (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR0_RESET (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR0_STOP (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR1_INT (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR1_RESET (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR1_STOP (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR2_INT (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR2_RESET (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR2_STOP (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR3_INT (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR3_RESET (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR3_STOP (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR4_INT (1<<12)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR4_RESET (1<<13)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR4_STOP (1<<14)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR5_INT (1<<15)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR5_RESET (1<<16)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR5_STOP (1<<17)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR6_INT (1<<18)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR6_RESET (1<<19)
+#define CYGARC_HAL_LPC24XX_REG_PWMMCR_MR6_STOP (1<<20)
+#define CYGARC_HAL_LPC24XX_REG_PWMMR0 0x0018
+#define CYGARC_HAL_LPC24XX_REG_PWMMR1 0x001C
+#define CYGARC_HAL_LPC24XX_REG_PWMMR2 0x0020
+#define CYGARC_HAL_LPC24XX_REG_PWMMR3 0x0024
+#define CYGARC_HAL_LPC24XX_REG_PWMMR4 0x0040
+#define CYGARC_HAL_LPC24XX_REG_PWMMR5 0x0044
+#define CYGARC_HAL_LPC24XX_REG_PWMMR6 0x0048
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR 0x004C
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL1 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL2 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL3 (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL4 (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL5 (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_SEL6 (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA1 (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA2 (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA3 (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA4 (1<<12)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA5 (1<<13)
+#define CYGARC_HAL_LPC24XX_REG_PWMMPCR_ENA6 (1<<14)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER 0x0050
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M0_ENA (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M1_ENA (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M2_ENA (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M3_ENA (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M4_ENA (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M5_ENA (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PWMLER_M6_ENA (1<<6)
+
+#define CYGARC_HAL_LPC24XX_REG_PWMCTCR 0x0070
+
+//=============================================================================
+// I2C (I2)
+
+#define CYGARC_HAL_LPC24XX_REG_I2C0_BASE 0xE001C000
+#define CYGARC_HAL_LPC24XX_REG_I2C1_BASE 0xE005C000
+#define CYGARC_HAL_LPC24XX_REG_I2C2_BASE 0xE0080000
+
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET 0x0000
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_AA (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_SI (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_STO (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_STA (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_I2CONSET_I2EN (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_I2STAT 0x0004
+#define CYGARC_HAL_LPC24XX_REG_I2STAT_SHIFT 3
+#define CYGARC_HAL_LPC24XX_REG_I2DAT 0x0008
+#define CYGARC_HAL_LPC24XX_REG_I2ADR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_I2ADR_GC (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_I2SCLH 0x0010
+#define CYGARC_HAL_LPC24XX_REG_I2SCLL 0x0014
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR 0x0018
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_AAC (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_SIC (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_STAC (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_I2CONCLR_I2ENC (1<<6)
+
+//=============================================================================
+// SPI (S)
+
+#define CYGARC_HAL_LPC24XX_REG_SPI0_BASE 0xE0020000
+#define CYGARC_HAL_LPC24XX_REG_SPI1_BASE 0xE0030000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_CPHA (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_CPOL (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_MSTR (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_LSBF (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCR_SPIE (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR 0x0004
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_ABRT (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_MODF (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_ROVR (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_WCOL (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPSR_SPIF (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPDR 0x0008
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPCCR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_SPI_SPINT 0x001C
+
+
+//=============================================================================
+// RTC
+
+#define CYGARC_HAL_LPC24XX_REG_RTC_BASE 0xE0024000
+
+// Registers are offsets from base of this subsystem
+
+#define CYGARC_HAL_LPC24XX_REG_RTC_ILR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_RTC_ILR_CIF (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_RTC_ILR_ALF (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTC 0x0004
+#define CYGARC_HAL_LPC24XX_REG_RTC_CCR 0x0008
+#define CYGARC_HAL_LPC24XX_REG_RTC_CCR_CLKEN (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_RTC_CCR_CTCRST (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_RTC_CIIR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_RTC_AMR 0x0010
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTIME0 0x0014
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTIME1 0x0018
+#define CYGARC_HAL_LPC24XX_REG_RTC_CTIME2 0x001C
+#define CYGARC_HAL_LPC24XX_REG_RTC_SEC 0x0020
+#define CYGARC_HAL_LPC24XX_REG_RTC_MIN 0x0024
+#define CYGARC_HAL_LPC24XX_REG_RTC_HOUR 0x0028
+#define CYGARC_HAL_LPC24XX_REG_RTC_DOM 0x002C
+#define CYGARC_HAL_LPC24XX_REG_RTC_DOW 0x0030
+#define CYGARC_HAL_LPC24XX_REG_RTC_DOY 0x0034
+#define CYGARC_HAL_LPC24XX_REG_RTC_MONTH 0x0038
+#define CYGARC_HAL_LPC24XX_REG_RTC_YEAR 0x003C
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALSEC 0x0060
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALMIN 0x0064
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALHOUR 0x0068
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALDOM 0x006C
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALDOW 0x0070
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALDOY 0x0074
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALMON 0x0078
+#define CYGARC_HAL_LPC24XX_REG_RTC_ALYEAR 0x007C
+#define CYGARC_HAL_LPC24XX_REG_RTC_PREINT 0x0080
+#define CYGARC_HAL_LPC24XX_REG_RTC_PREFRAC 0x0084
+
+//=============================================================================
+// GPIO (IO)
+
+#define CYGARC_HAL_LPC24XX_REG_IO_BASE 0xE0028000
+#define CYGARC_HAL_LPC24XX_REG_FIO_BASE 0x3FFFC000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_IO0PIN 0x000
+#define CYGARC_HAL_LPC24XX_REG_IO0SET 0x004
+#define CYGARC_HAL_LPC24XX_REG_IO0DIR 0x008
+#define CYGARC_HAL_LPC24XX_REG_IO0CLR 0x00C
+
+#define CYGARC_HAL_LPC24XX_REG_IO1PIN 0x010
+#define CYGARC_HAL_LPC24XX_REG_IO1SET 0x014
+#define CYGARC_HAL_LPC24XX_REG_IO1DIR 0x018
+#define CYGARC_HAL_LPC24XX_REG_IO1CLR 0x01C
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0DIR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_FIO1DIR 0x0020
+#define CYGARC_HAL_LPC24XX_REG_FIO2DIR 0x0040
+#define CYGARC_HAL_LPC24XX_REG_FIO3DIR 0x0050
+#define CYGARC_HAL_LPC24XX_REG_FIO4DIR 0x0080
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0SET 0x0018
+#define CYGARC_HAL_LPC24XX_REG_FIO1SET 0x0038
+#define CYGARC_HAL_LPC24XX_REG_FIO2SET 0x0058
+#define CYGARC_HAL_LPC24XX_REG_FIO3SET 0x0078
+#define CYGARC_HAL_LPC24XX_REG_FIO4SET 0x0098
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0CLR 0x001C
+#define CYGARC_HAL_LPC24XX_REG_FIO1CLR 0x003C
+#define CYGARC_HAL_LPC24XX_REG_FIO2CLR 0x005C
+#define CYGARC_HAL_LPC24XX_REG_FIO3CLR 0x007C
+#define CYGARC_HAL_LPC24XX_REG_FIO4CLR 0x009C
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0PIN 0x0014
+#define CYGARC_HAL_LPC24XX_REG_FIO1PIN 0x0034
+#define CYGARC_HAL_LPC24XX_REG_FIO2PIN 0x0054
+#define CYGARC_HAL_LPC24XX_REG_FIO3PIN 0x0074
+#define CYGARC_HAL_LPC24XX_REG_FIO4PIN 0x0094
+
+#define CYGARC_HAL_LPC24XX_REG_FIO0MASK 0x0010
+#define CYGARC_HAL_LPC24XX_REG_FIO1MASK 0x0030
+#define CYGARC_HAL_LPC24XX_REG_FIO2MASK 0x0050
+#define CYGARC_HAL_LPC24XX_REG_FIO3MASK 0x0070
+#define CYGARC_HAL_LPC24XX_REG_FIO4MASK 0x0090
+
+
+
+//=============================================================================
+// Pin Connect Block (PIN)
+
+#define CYGARC_HAL_LPC24XX_REG_PIN_BASE 0xE002C000
+
+#define CYGARC_HAL_LPC24XX_REG_PINSEL0 0x000
+#define CYGARC_HAL_LPC24XX_REG_PINSEL1 0x004
+#define CYGARC_HAL_LPC24XX_REG_PINSEL2 0x008
+#define CYGARC_HAL_LPC24XX_REG_PINSEL3 0x00C
+#define CYGARC_HAL_LPC24XX_REG_PINSEL4 0x010
+#define CYGARC_HAL_LPC24XX_REG_PINSEL5 0x014
+#define CYGARC_HAL_LPC24XX_REG_PINSEL6 0x018
+#define CYGARC_HAL_LPC24XX_REG_PINSEL7 0x01C
+#define CYGARC_HAL_LPC24XX_REG_PINSEL8 0x020
+#define CYGARC_HAL_LPC24XX_REG_PINSEL9 0x024
+#define CYGARC_HAL_LPC24XX_REG_PINSEL10 0x028
+#define CYGARC_HAL_LPC24XX_REG_PINSEL11 0x02C
+
+#define CYGARC_HAL_LPC24XX_REG_PINMODE0 0x040
+#define CYGARC_HAL_LPC24XX_REG_PINMODE1 0x044
+#define CYGARC_HAL_LPC24XX_REG_PINMODE2 0x048
+#define CYGARC_HAL_LPC24XX_REG_PINMODE3 0x04C
+#define CYGARC_HAL_LPC24XX_REG_PINMODE4 0x050
+#define CYGARC_HAL_LPC24XX_REG_PINMODE5 0x054
+#define CYGARC_HAL_LPC24XX_REG_PINMODE6 0x058
+#define CYGARC_HAL_LPC24XX_REG_PINMODE7 0x05C
+#define CYGARC_HAL_LPC24XX_REG_PINMODE8 0x060
+#define CYGARC_HAL_LPC24XX_REG_PINMODE9 0x064
+
+#define CYGARC_HAL_LPC24XX_SET_PIN_FUN(_regval_, _pin_, _func_) \
+ (_regval_) = ((_regval_) & ~(0x3 << ((_pin_) << 1))) | ((_func_) << ((_pin_) << 1))
+
+
+//=============================================================================
+// SSP - Synchronous Serial Port
+#define CYGARC_HAL_LPC24XX_REG_SSP0_BASE 0xE0068000
+#define CYGARC_HAL_LPC24XX_REG_SSP1_BASE 0xE0030000
+
+#define CYGARC_HAL_LPC24XX_REG_SSP_CR0 0x0000
+#define CYGARC_HAL_LPC24XX_REG_SSP_CR1 0x0004
+#define CYGARC_HAL_LPC24XX_REG_SSP_DR 0x0008
+#define CYGARC_HAL_LPC24XX_REG_SSP_SR 0x000C
+#define CYGARC_HAL_LPC24XX_REG_SSP_CPSR 0x0010
+#define CYGARC_HAL_LPC24XX_REG_SSP_IMSC 0x0014
+#define CYGARC_HAL_LPC24XX_REG_SSP_RIS 0x0018
+#define CYGARC_HAL_LPC24XX_REG_SSP_MIS 0x001C
+#define CYGARC_HAL_LPC24XX_REG_SSP_ICR 0x0020
+#define CYGARC_HAL_LPC24XX_REG_SSP_DMACR 0x0024
+
+
+//=============================================================================
+// ADC (AD)
+
+#define CYGARC_HAL_LPC24XX_REG_AD_BASE 0xE0034000
+
+// Registers are offsets from base of this subsystem
+#define CYGARC_HAL_LPC24XX_REG_ADCR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_ADCR_BURST (1<<16)
+#define CYGARC_HAL_LPC24XX_REG_ADCR_PDN (1<<21)
+#define CYGARC_HAL_LPC24XX_REG_ADCR_EDGE (1<<27)
+#define CYGARC_HAL_LPC24XX_REG_ADGDR 0x0004
+#define CYGARC_HAL_LPC24XX_REG_ADSTAT 0x0030
+#define CYGARC_HAL_LPC24XX_REG_ADINTEN 0x000C
+#define CYGARC_HAL_LPC24XX_REG_ADDR0 0x0010
+#define CYGARC_HAL_LPC24XX_REG_ADDR1 0x0018
+#define CYGARC_HAL_LPC24XX_REG_ADDR2 0x0018
+#define CYGARC_HAL_LPC24XX_REG_ADDR3 0x001C
+#define CYGARC_HAL_LPC24XX_REG_ADDR4 0x0020
+#define CYGARC_HAL_LPC24XX_REG_ADDR5 0x0024
+#define CYGARC_HAL_LPC24XX_REG_ADDR6 0x0028
+#define CYGARC_HAL_LPC24XX_REG_ADDR7 0x002C
+
+
+//=============================================================================
+// CAN
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_RAM 0xE0038000
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_BASE 0xE003C000
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_AFMR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_SFF_sa 0x0004
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_SFF_GRP_sa 0x0008
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_EFF_sa 0x000C
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_EFF_GRP_sa 0x0010
+#define CYGARC_HAL_LPC24XX_REG_CAN_ACCFILT_END 0x0014
+
+#define CYGARC_HAL_LPC24XX_REG_CAN_COMMON_BASE 0xE0040000
+#define CYGARC_HAL_LPC24XX_REG_CAN_TxSR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_CAN_RxSR 0x0004
+#define CYGARC_HAL_LPC24XX_REG_CAN_MSR 0x0008
+
+#define CYGARC_HAL_LPC24XX_REG_CAN0_BASE 0xE0044000
+#define CYGARC_HAL_LPC24XX_REG_CAN1_BASE 0xE0048000
+#define CYCARC_HAL_LPC24XX_REG_CANx_MOD 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_CMR 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_GSR 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_ICR 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_IER 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_BTR 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_EWL 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_SR 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFS 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RID 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RDA 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RDB 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFI1 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TID1 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDA1 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDB1 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFI2 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TID2 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDA2 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDB2 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_RFI3 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TID3 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDA3 0x0000
+#define CYCARC_HAL_LPC24XX_REG_CANx_TDB3 0x0000
+
+
+//=============================================================================
+// DAC
+#define CYGARC_HAL_LPC24XX_REG_DAC_BASE 0xE006C000
+
+
+//=============================================================================
+// Battery RAM
+#define CYGARC_HAL_LPC24XX_REG_BATTERY_RAM 0xE0084000
+
+
+//=============================================================================
+// I2S
+#define CYGARC_HAL_LPC24XX_REG_I2S_BASE 0xE0088000
+
+#define CYGARC_HAL_LPC24XX_REG_I2S_DAO 0x0000
+#define CYGARC_HAL_LPC24XX_REG_I2S_DAI 0x0004
+#define CYGARC_HAL_LPC24XX_REG_I2S_TXFIFO 0x0008
+#define CYGARC_HAL_LPC24XX_REG_I2S_RXFIFO 0x000C
+#define CYGARC_HAL_LPC24XX_REG_I2S_STATE 0x0010
+#define CYGARC_HAL_LPC24XX_REG_I2S_DMA1 0x0014
+#define CYGARC_HAL_LPC24XX_REG_I2S_DMA2 0x0018
+#define CYGARC_HAL_LPC24XX_REG_I2S_IRQ 0x001C
+#define CYGARC_HAL_LPC24XX_REG_I2S_TXRATE 0x0020
+#define CYGARC_HAL_LPC24XX_REG_I2S_RXRATE 0x0024
+
+
+
+//=============================================================================
+// SD/MMC Card Interface
+#define CYGARC_HAL_LPC24XX_REG_SD_MMC_BASE 0xE008C000
+
+
+//=============================================================================
+// System Control Block
+
+#define CYGARC_HAL_LPC24XX_REG_SCB_BASE 0xE01FC000
+
+// Registers are offsets from base of this subsystem
+
+// Memory accelerator module
+#define CYGARC_HAL_LPC24XX_REG_MAMCR 0x0000
+#define CYGARC_HAL_LPC24XX_REG_MAMCR_DISABLED 0x00
+#define CYGARC_HAL_LPC24XX_REG_MAMCR_PARTIAL 0x01
+#define CYGARC_HAL_LPC24XX_REG_MAMCR_FULL 0x02
+#define CYGARC_HAL_LPC24XX_REG_MAMTIM 0x0004
+
+// Memory mapping control
+#define CYGARC_HAL_LPC24XX_REG_MEMMAP 0x0040
+
+// PLL
+#define CYGARC_HAL_LPC24XX_REG_PLLCON 0x0080
+#define CYGARC_HAL_LPC24XX_REG_PLLCON_PLLE (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PLLCON_PLLC (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PLLCFG 0x0084
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT 0x0088
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLE (1<<24)
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLLC (1<<25)
+#define CYGARC_HAL_LPC24XX_REG_PLLSTAT_PLOCK (1<<26)
+#define CYGARC_HAL_LPC24XX_REG_PLLFEED 0x008C
+
+// Power Control
+#define CYGARC_HAL_LPC24XX_REG_PCON 0x00C0
+#define CYGARC_HAL_LPC24XX_REG_PCON_IDL (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_PCON_PD (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PCONP 0x00C4
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM0 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM1 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT0 (1<<3)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT1 (1<<4)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_PWM0 (1<<5)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_PWM1 (1<<6)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2C0 (1<<7)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SPI (1<<8)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_RTC (1<<9)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SSP1 (1<<10)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_EMC (1<<11)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_AD (1<<12)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_CAN1 (1<<13)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_CAN2 (1<<14)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2C1 (1<<19)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_LCD (1<<20)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SSP0 (1<<21)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM2 (1<<22)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_TIM3 (1<<23)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT2 (1<<24)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_URT3 (1<<25)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2C2 (1<<26)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_I2S (1<<27)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_SD (1<<28)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_DMA (1<<29)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_ENET (1<<30)
+#define CYGARC_HAL_LPC24XX_REG_PCONP_USB (1<<31)
+
+// External interrupt inputs
+#define CYGARC_HAL_LPC24XX_REG_EXTINT 0x0140
+#define CYGARC_HAL_LPC24XX_REG_EXTMODE 0x0148
+#define CYGARC_HAL_LPC24XX_REG_EXTPOLAR 0x014C
+
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT0 (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT1 (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT2 (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_EXTxxx_INT3 (1<<3)
+
+// Reset source identification register
+#define CYGARC_HAL_LPC24XX_REG_RSID 0x0180
+#define CYGARC_HAL_LPC24XX_REG_RSID_POR (1<<0)
+#define CYGARC_HAL_LPC24XX_REG_RSID_EXTR (1<<1)
+#define CYGARC_HAL_LPC24XX_REG_RSID_WDTR (1<<2)
+#define CYGARC_HAL_LPC24XX_REG_RSID_BODR (1<<3)
+
+// System control and status register
+#define CYGARC_HAL_LPC24XX_REG_SCS 0x01A0
+#define CYGARC_HAL_LPC24XX_REG_SCS_OSCEN 0x20
+#define CYGARC_HAL_LPC24XX_REG_SCS_OSCSTAT 0x40
+
+// Clock source selection register
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL 0x010C
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_IRC 0x00
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_MAIN 0x01
+#define CYGARC_HAL_LPC24XX_REG_CLKSRCSEL_RTC 0x10
+
+#define CYGARC_HAL_LPC24XX_REG_CCLKCFG 0x0104
+#define CYGARC_HAL_LPC24XX_REG_USBCLKCFG 0x0108
+#define CYGARC_HAL_LPC24XX_REG_IRCTRIM 0x01A4
+#define CYGARC_HAL_LPC24XX_REG_PCLKSEL0 0x01A8
+#define CYGARC_HAL_LPC24XX_REG_PCLKSEL1 0x01AC
+#define CYGARC_HAL_LPC24XX_REG_INTWAKE 0x0144
+
+
+//=============================================================================
+// External Memory Controller
+#define CYGARC_HAL_LPC24XX_REG_EMC_BASE 0xFFE08000
+
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL 0x0000
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL_EN (1 << 0)
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL_ADDRMIRR (1 << 1)
+#define CYGARC_HAL_LPC24XX_REG_EMC_CTRL_LOWPOW (1 << 2)
+#define CYGARC_HAL_LPC24XX_REG_EMC_STATUS 0x0004
+#define CYGARC_HAL_LPC24XX_REG_EMC_CONFIG 0x0008
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONTROL 0x0020
+#define CYGARC_HAL_LPC24XX_REG_EMCD_REFRESH 0x0024
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RDCFG 0x0028
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RP 0x0030
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RAS 0x0034
+#define CYGARC_HAL_LPC24XX_REG_EMCD_SREX 0x0038
+#define CYGARC_HAL_LPC24XX_REG_EMCD_APR 0x003C
+#define CYGARC_HAL_LPC24XX_REG_EMCD_DAL 0x0040
+#define CYGARC_HAL_LPC24XX_REG_EMCD_WR 0x0044
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RC 0x0048
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RFC 0x004C
+#define CYGARC_HAL_LPC24XX_REG_EMCD_XSR 0x0050
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RRD 0x0054
+#define CYGARC_HAL_LPC24XX_REG_EMCD_MRD 0x0058
+#define CYGARC_HAL_LPC24XX_REG_EMCS_EXT_WAIT 0x0080
+
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG0 0x0100
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS0 0x0104
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG1 0x0120
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS1 0x0124
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG2 0x0140
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS2 0x0144
+#define CYGARC_HAL_LPC24XX_REG_EMCD_CONFIG3 0x0160
+#define CYGARC_HAL_LPC24XX_REG_EMCD_RASCAS3 0x0164
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG0 0x0200
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN0 0x0204
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN0 0x0208
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD0 0x020C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE0 0x0210
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR0 0x0214
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN0 0x0218
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG1 0x0220
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN1 0x0224
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN1 0x0228
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD1 0x022C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE1 0x0230
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR1 0x0234
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN1 0x0238
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG2 0x0240
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN2 0x0244
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN2 0x0248
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD2 0x024C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE2 0x0250
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR2 0x0254
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN2 0x0258
+
+#define CYGARC_HAL_LPC24XX_REG_EMCS_CONFIG3 0x0260
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITW_EN3 0x0264
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITO_EN3 0x0268
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITRD3 0x026C
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITPAGE3 0x0270
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITWR3 0x0274
+#define CYGARC_HAL_LPC24XX_REG_EMCS_WAITTURN3 0x0278
+
+
+//=============================================================================
+// Vectored Interrupt Controller (VIC)
+
+#define CYGARC_HAL_LPC24XX_REG_VIC_BASE 0xFFFFF000
+
+// Registers are offsets from base of this subsystem
+
+#define CYGARC_HAL_LPC24XX_REG_VICIRQSTAT 0x000
+#define CYGARC_HAL_LPC24XX_REG_VICFIQSTAT 0x004
+#define CYGARC_HAL_LPC24XX_REG_VICRAWINTR 0x008
+#define CYGARC_HAL_LPC24XX_REG_VICINTSELECT 0x00C
+#define CYGARC_HAL_LPC24XX_REG_VICINTENABLE 0x010
+#define CYGARC_HAL_LPC24XX_REG_VICINTENCLEAR 0x014
+#define CYGARC_HAL_LPC24XX_REG_VICSOFTINT 0x018
+#define CYGARC_HAL_LPC24XX_REG_VICSOFTINTCLEAR 0x01C
+#define CYGARC_HAL_LPC24XX_REG_VICPROTECTION 0x020
+#define CYGARC_HAL_LPC24XX_REG_VICSWPRIOMASK 0x020
+
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR0 0x100
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR1 0x104
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR2 0x108
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR3 0x10C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR4 0x110
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR5 0x114
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR6 0x118
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR7 0x11C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR8 0x120
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR9 0x124
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR10 0x128
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR11 0x12C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR12 0x130
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR13 0x134
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR14 0x138
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR15 0x13C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR16 0x140
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR17 0x144
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR18 0x148
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR19 0x14C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR20 0x150
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR21 0x154
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR22 0x158
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR23 0x15C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR24 0x160
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR25 0x164
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR26 0x168
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR27 0x16C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR28 0x170
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR29 0x174
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR30 0x178
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR31 0x17C
+
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO0 0x200
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO1 0x204
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO2 0x208
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO3 0x20C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO4 0x210
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO5 0x214
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO6 0x218
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO7 0x21C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO8 0x220
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO9 0x224
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO10 0x228
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO11 0x22C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO12 0x230
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO13 0x234
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO14 0x238
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO15 0x23C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO16 0x240
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO17 0x244
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO18 0x248
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO19 0x24C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO20 0x250
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO21 0x254
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO22 0x258
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO23 0x25C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO24 0x260
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO25 0x264
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO26 0x268
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO27 0x26C
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO28 0x270
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO29 0x274
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO30 0x278
+#define CYGARC_HAL_LPC24XX_REG_VICVECTPRIO31 0x27C
+
+
+#define CYGARC_HAL_LPC24XX_REG_VICVECTADDR 0xF00
+
+//-----------------------------------------------------------------------------
+// end of var_io.h
+#endif // CYGONCE_HAL_VAR_IO_H
--- /dev/null
+/*=============================================================================
+//
+// hal_diag.c
+//
+// HAL diagnostic output code
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jani
+// Contributors:jskov, gthomas
+// Date: 2001-07-12
+// Purpose: HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h> // base types
+
+#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_if.h> // interface API
+#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h> // Helper functions
+#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h> // USART registers
+#include <cyg/hal/lpc24xx_misc.h> // peripheral identifiers
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================-
+typedef struct
+{
+ cyg_uint8* base;
+ cyg_int32 msec_timeout;
+ int isr_vector;
+ int baud_rate;
+ cyg_uint8 periph_id;
+} channel_data_t;
+
+
+//
+// Diagnostic serial channel data
+//
+static channel_data_t lpc2xxx_ser_channels[2] =
+{
+ { (cyg_uint8*)CYGARC_HAL_LPC24XX_REG_UART0_BASE,
+ 1000,
+ CYGNUM_HAL_INTERRUPT_UART0,
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD,
+ CYNUM_HAL_LPC24XX_PCLK_UART0},
+
+ { (cyg_uint8*)CYGARC_HAL_LPC24XX_REG_UART1_BASE,
+ 1000,
+ CYGNUM_HAL_INTERRUPT_UART1,
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD,
+ CYNUM_HAL_LPC24XX_PCLK_UART1}
+};
+
+
+//===========================================================================
+// Initialize diagnostic serial channel
+//===========================================================================
+static void cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint8* base = chan->base;
+ cyg_uint16 divider = CYG_HAL_ARM_LPC24XX_BAUD_GENERATOR(chan->periph_id,
+ chan->baud_rate);
+ // Set baudrate
+ HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLCR,
+ CYGARC_HAL_LPC24XX_REG_UxLCR_DLAB);
+ HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxDLM, divider >> 8);
+ HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxDLL, divider & 0xFF);
+
+ // 8-1-no parity.
+ HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLCR,
+ CYGARC_HAL_LPC24XX_REG_UxLCR_WORD_LENGTH_8 |
+ CYGARC_HAL_LPC24XX_REG_UxLCR_STOP_1);
+
+ // Reset and enable FIFO
+ HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxFCR,
+ CYGARC_HAL_LPC24XX_REG_UxFCR_FIFO_ENA |
+ CYGARC_HAL_LPC24XX_REG_UxFCR_RX_FIFO_RESET |
+ CYGARC_HAL_LPC24XX_REG_UxFCR_TX_FIFO_RESET);
+}
+
+
+//===========================================================================
+// Write single character
+//===========================================================================
+void cyg_hal_plf_serial_putc(void *__ch_data, char c)
+{
+ cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+ cyg_uint8 stat;
+ CYGARC_HAL_SAVE_GP();
+
+ do {
+ HAL_READ_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLSR, stat);
+ } while ((stat & CYGARC_HAL_LPC24XX_REG_UxLSR_THRE) == 0);
+
+ HAL_WRITE_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxTHR, c);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+
+//===========================================================================
+// Read single character non blocking
+//===========================================================================
+static cyg_bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint8* base = chan->base;
+ cyg_uint8 stat;
+
+ HAL_READ_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxLSR, stat);
+ if ((stat & CYGARC_HAL_LPC24XX_REG_UxLSR_RDR) == 0)
+ return false;
+
+ HAL_READ_UINT32(base + CYGARC_HAL_LPC24XX_REG_UxRBR, *ch);
+
+ return true;
+}
+
+
+//===========================================================================
+// Read single character blocking
+//===========================================================================
+cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data)
+{
+ cyg_uint8 ch;
+ CYGARC_HAL_SAVE_GP();
+
+ while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+ CYGARC_HAL_RESTORE_GP();
+ return ch;
+}
+
+
+//===========================================================================
+// Write data buffer via serial line
+//===========================================================================
+static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+
+//===========================================================================
+// Read data buffer
+//===========================================================================
+static void cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+
+//===========================================================================
+// Read single character with timeout
+//===========================================================================
+cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+ int delay_count;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_bool res;
+ CYGARC_HAL_SAVE_GP();
+
+ delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+ for(;;) {
+ res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+ if (res || 0 == delay_count--)
+ break;
+
+ CYGACC_CALL_IF_DELAY_US(100);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+
+//===========================================================================
+// Control serial channel configuration
+//===========================================================================
+static int cyg_hal_plf_serial_control(void *__ch_data,
+ __comm_control_cmd_t __func, ...)
+{
+ static int irq_state = 0;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+ int ret = 0;
+ va_list ap;
+
+ CYGARC_HAL_SAVE_GP();
+ va_start(ap, __func);
+
+ switch (__func) {
+ case __COMMCTL_GETBAUD:
+ ret = chan->baud_rate;
+ break;
+ case __COMMCTL_SETBAUD:
+ chan->baud_rate = va_arg(ap, cyg_int32);
+ // Should we verify this value here?
+ cyg_hal_plf_serial_init_channel(chan);
+ ret = 0;
+ break;
+ case __COMMCTL_IRQ_ENABLE:
+ irq_state = 1;
+ HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+ HAL_INTERRUPT_UNMASK(chan->isr_vector);
+ HAL_WRITE_UINT32(base+CYGARC_HAL_LPC24XX_REG_UxIER,
+ CYGARC_HAL_LPC24XX_REG_UxIER_RXDATA_INT);
+ break;
+ case __COMMCTL_IRQ_DISABLE:
+ ret = irq_state;
+ irq_state = 0;
+ HAL_INTERRUPT_MASK(chan->isr_vector);
+ HAL_WRITE_UINT32(base+CYGARC_HAL_LPC24XX_REG_UxIER, 0);
+ break;
+ case __COMMCTL_DBG_ISR_VECTOR:
+ ret = chan->isr_vector;
+ break;
+ case __COMMCTL_SET_TIMEOUT:
+ ret = chan->msec_timeout;
+ chan->msec_timeout = va_arg(ap, cyg_uint32);
+ default:
+ break;
+ }
+
+ va_end(ap);
+ CYGARC_HAL_RESTORE_GP();
+ return ret;
+}
+
+
+//===========================================================================
+// Serial channel ISR
+//===========================================================================
+static int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+ int res = 0;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint8 c;
+ cyg_uint8 iir;
+
+ CYGARC_HAL_SAVE_GP();
+
+ *__ctrlc = 0;
+
+ HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC24XX_REG_UxIIR, iir);
+
+ if((iir & (CYGARC_HAL_LPC24XX_REG_UxIIR_IIR0 |
+ CYGARC_HAL_LPC24XX_REG_UxIIR_IIR1 |
+ CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2))
+ == CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2)
+ {
+ // Rx data available or character timeout
+ // Read data in order to clear interrupt
+ HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC24XX_REG_UxRBR, c);
+ if( cyg_hal_is_break( &c , 1 ) ) *__ctrlc = 1;
+
+ res = CYG_ISR_HANDLED;
+ }
+
+ HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+
+//===========================================================================
+// Initialize serial channel
+//===========================================================================
+void cyg_hal_plf_serial_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur;
+
+ cur =
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+ // Init channels
+ cyg_hal_plf_serial_init_channel(&lpc2xxx_ser_channels[0]);
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+ cyg_hal_plf_serial_init_channel(&lpc2xxx_ser_channels[1]);
+#endif
+
+ // Setup procs in the vector table
+
+ // Set channel 0
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &lpc2xxx_ser_channels[0]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+ // Set channel 1
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &lpc2xxx_ser_channels[1]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+ // Restore original console
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+
+//===========================================================================
+// Set diagnostic led
+//===========================================================================
+void hal_diag_led(int mask)
+{
+ hal_lpc24xx_set_leds(mask);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag.c
--- /dev/null
+/*==========================================================================
+//
+// lpc24xx_misc.c
+//
+// HAL misc variant support code for NXP LPC24xx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2004 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: gthomas, jskov, nickg, tkoeller
+// Date: 2008-07-06
+// Purpose: Prozessor support
+// Description: Implementations of LPC24xx processor support
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_lpc24xx.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_intr.h> // necessary?
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h> // calling interface
+#include <cyg/hal/hal_misc.h> // helper functions
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+#include <cyg/hal/drv_api.h> // HAL ISR support
+#endif
+#include <cyg/hal/var_io.h> // platform registers
+
+#include <cyg/infra/diag.h> // For diagnostic printing
+
+
+//===========================================================================
+// Get peripheral clock for a certain peripheral
+//===========================================================================
+cyg_uint32 hal_lpc_get_pclk(cyg_uint32 peripheral_id)
+{
+ static const cyg_uint8 divider_tbl[4] =
+ {
+ 4, 1, 2, 8
+ };
+ cyg_uint32 pclkselreg;
+ cyg_uint32 regval;
+ cyg_uint8 divider;
+
+ //
+ // decide if we need PCLKSEL0 or PCLKSEL1
+ //
+ pclkselreg = ((peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ?
+ CYGARC_HAL_LPC24XX_REG_PCLKSEL0 :
+ CYGARC_HAL_LPC24XX_REG_PCLKSEL1);
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval);
+ regval = (regval >> ((peripheral_id & 0xF) << 1)) & 0x03;
+ divider = divider_tbl[regval];
+ if ((8 == divider) && (peripheral_id >= CYNUM_HAL_LPC24XX_PCLK_CAN1)
+ && (peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF))
+ {
+ divider = 6;
+ }
+ return CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED / divider;
+}
+
+
+//===========================================================================
+// Set peripheral clock
+//===========================================================================
+void hal_lpc_set_pclk(cyg_uint32 peripheral_id, cyg_uint8 divider)
+{
+ static const cyg_uint8 clock_tbl[4] =
+ {
+ 0x01, 0x02, 0x00, 0x03
+ };
+ cyg_uint32 clock;
+ cyg_uint32 pclkselreg;
+ cyg_uint32 regval;
+
+ CYG_ASSERT(divider <= 8, "Wrong peripheral clock divider value");
+ //
+ // decide if we need PCLKSEL0 or PCLKSEL1
+ //
+ pclkselreg = (peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ?
+ CYGARC_HAL_LPC24XX_REG_PCLKSEL0 :
+ CYGARC_HAL_LPC24XX_REG_PCLKSEL1;
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval);
+ divider = (6 == divider) ? 8 : divider;
+ clock = clock_tbl[divider >> 1];
+ regval |= (clock << ((peripheral_id & 0xF) << 1));
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval);
+}
+
+
+//===========================================================================
+// initialize timer 0 as eCos realtime clock source
+//===========================================================================
+void hal_clock_initialize(cyg_uint32 period)
+{
+ CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER0_BASE;
+
+ period = period / (CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED /
+ hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER0));
+
+ //
+ // Disable and reset counter, set prescale register to 0 and
+ // Set up match register
+ //
+ HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxTCR, 2);
+ HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxPR, 0);
+ HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxMR0, period);
+
+ //
+ // Reset and generate interrupt on match and Enable counter
+ //
+ HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxMCR,
+ CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_INT |
+ CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET);
+ HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 1);
+}
+
+
+//===========================================================================
+// Reset clock
+//===========================================================================
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+ static cyg_uint32 _period = 0;
+ CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER0_BASE;
+
+ HAL_WRITE_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxIR,
+ CYGARC_HAL_LPC24XX_REG_TxIR_MR0); // Clear interrupt
+
+ if (period != _period)
+ {
+ hal_clock_initialize(period);
+ }
+ _period = period;
+}
+
+
+//===========================================================================
+// Reset clock value
+//===========================================================================
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+ CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER0_BASE;
+ cyg_uint32 val;
+
+ HAL_READ_UINT32(timer + CYGARC_HAL_LPC24XX_REG_TxTC, val);
+ *pvalue = val;
+}
+
+
+//===========================================================================
+// Delay for some number of micro-seconds - use TIMER1
+//===========================================================================
+void hal_delay_us(cyg_int32 usecs)
+{
+ CYG_ADDRESS timer = CYGARC_HAL_LPC24XX_REG_TIMER1_BASE;
+ cyg_uint32 stat;
+ cyg_uint64 ticks;
+
+ // Calculate how many timer ticks the required number of
+ // microseconds equate to. We do this calculation in 64 bit
+ // arithmetic to avoid overflow.
+ ticks = (((cyg_uint64)usecs) *
+ ((cyg_uint64)hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER1))) /
+ 1000000LL;
+
+ // Disable and reset counter
+ HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 2);
+
+ // Stop on match
+ HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxMR0, ticks);
+ HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxMCR,
+ CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_STOP |
+ CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET);
+
+ //set prescale register to 0
+ HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxPR, 0);
+
+ // Enable counter
+ HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 1);
+
+ // Wait for the match
+ do {
+ HAL_READ_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTC, stat);
+ } while (stat < ticks);
+}
+
+
+//===========================================================================
+// Perform variant setup. This optionally calls into the platform
+// HAL if it has defined HAL_PLF_HARDWARE_INIT.
+//===========================================================================
+void hal_hardware_init(void)
+{
+ cyg_uint32 i;
+
+ //
+ // Setup peripheral clocks here according to configuration
+ //
+ hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_CAN1, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV);
+ hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_CAN2, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV);
+ hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_ACF, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV);
+
+ //
+ // Fill vector address registers with interrupt number. If an interrupt
+ // occurs we can simply read the interrupt number from the vector
+ // address register later
+ //
+ cyg_uint32 addr = CYGARC_HAL_LPC24XX_REG_VIC_BASE +
+ CYGARC_HAL_LPC24XX_REG_VICVECTADDR0;
+ for (i = 0; i < 32; ++i)
+ {
+ HAL_WRITE_UINT32(addr, i);
+ addr += 4;
+ }
+#ifdef HAL_PLF_HARDWARE_INIT
+ // Perform any platform specific initializations
+ HAL_PLF_HARDWARE_INIT();
+#endif
+
+ // Set up eCos/ROM interfaces
+ hal_if_init();
+}
+
+
+//===========================================================================
+// This routine is called to respond to a hardware interrupt (IRQ). It
+// should interrogate the hardware and return the IRQ vector number.
+//===========================================================================
+int hal_IRQ_handler(void)
+{
+ cyg_uint32 irq_num;
+
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE +
+ CYGARC_HAL_LPC24XX_REG_VICVECTADDR, irq_num);
+
+ return (irq_num);
+}
+
+
+//===========================================================================
+// Block the interrupt associated with the vector
+//===========================================================================
+void hal_interrupt_mask(int vector)
+{
+ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE +
+ CYGARC_HAL_LPC24XX_REG_VICINTENCLEAR, 1 << vector);
+}
+
+
+//===========================================================================
+// Unblock the interrupt associated with the vector
+//===========================================================================
+void hal_interrupt_unmask(int vector)
+{
+ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE +
+ CYGARC_HAL_LPC24XX_REG_VICINTENABLE, 1 << vector);
+}
+
+
+//===========================================================================
+// Acknowledge the interrupt associated with the vector. This
+// clears the interrupt but may result in another interrupt being
+// delivered
+//===========================================================================
+void hal_interrupt_acknowledge(int vector)
+{
+
+ // External interrupts have to be cleared from the EXTINT register
+ if (vector >= CYGNUM_HAL_INTERRUPT_EINT0 &&
+ vector <= CYGNUM_HAL_INTERRUPT_EINT3)
+ {
+ // Map int vector to corresponding bit (0..3)
+ vector = 1 << (vector - CYGNUM_HAL_INTERRUPT_EINT0);
+
+ // Clear the external interrupt
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_EXTINT, vector);
+ }
+
+ //
+ // Write any value to vector address register to
+ // acknowledge the interrupt
+ //
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_VIC_BASE +
+ CYGARC_HAL_LPC24XX_REG_VICVECTADDR, 0xFFFFFFFF);
+}
+
+
+//===========================================================================
+// This provides control over how an interrupt signal is detected.
+// Options are between level or edge sensitive (level) and high/low
+// level or rising/falling edge triggered (up).
+//===========================================================================
+void hal_interrupt_configure(int vector, int level, int up)
+{
+ cyg_uint32 regval;
+
+ // Only external interrupts are configurable
+ CYG_ASSERT(vector <= CYGNUM_HAL_INTERRUPT_EINT3 &&
+ vector >= CYGNUM_HAL_INTERRUPT_EINT0 , "Invalid vector");
+
+ // Map int vector to corresponding bit (0..3)
+ vector = 1 << (vector - CYGNUM_HAL_INTERRUPT_EINT0);
+
+ // Read current mode and update for level (0) or edge detection (1)
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_EXTMODE, regval);
+ if (level)
+ {
+ regval &= ~vector;
+ }
+ else
+ {
+ regval |= vector;
+ }
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_EXTMODE, regval);
+
+ // Read current polarity and update for trigger level or edge
+ // level: high (1), low (0) edge: rising (1), falling (0)
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_EXTPOLAR, regval);
+ if (up)
+ {
+ regval |= vector;
+ }
+ else
+ {
+ regval &= ~vector;
+ }
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_EXTPOLAR, regval);
+
+ // Clear any spurious interrupt that might have been generated
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_EXTINT, vector);
+}
+
+
+//===========================================================================
+// These selects select a priority level for the 32 vectored IRQs.
+// There are 16 priority levels, corresponding to the values 0
+// through 15 decimal, of which 15 is the lowest priority.
+// The reset value of these registers defaults all interrupt to the
+// lowest priority, allowing a single write to elevate the priority
+// of an individual interrupt.
+//===========================================================================
+void hal_interrupt_set_level(int vector, int level)
+{
+ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+ CYG_ASSERT(level >= 0 && level <= 15, "Invalid level");
+
+ cyg_uint32 prioreg_addr = CYGARC_HAL_LPC24XX_REG_VIC_BASE +
+ CYGARC_HAL_LPC24XX_REG_VICVECTPRIO0 +
+ (vector << 2);
+ HAL_WRITE_UINT32(prioreg_addr, level & 0xF);
+}
+
+
+//===========================================================================
+// Use the watchdog to generate a reset
+//===========================================================================
+void hal_lpc_watchdog_reset(void)
+{
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE +
+ CYGARC_HAL_LPC24XX_REG_WDTC, 0xFF);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE +
+ CYGARC_HAL_LPC24XX_REG_WDMOD,
+ CYGARC_HAL_LPC24XX_REG_WDMOD_WDEN |
+ CYGARC_HAL_LPC24XX_REG_WDMOD_WDRESET);
+
+ // feed WD with the two magic values
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE +
+ CYGARC_HAL_LPC24XX_REG_WDFEED,
+ CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC1);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE +
+ CYGARC_HAL_LPC24XX_REG_WDFEED,
+ CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC2);
+
+ while(1)
+ continue;
+}
+
+
+//--------------------------------------------------------------------------
+// EOF lpc24xx_misc.c
--- /dev/null
+2008-01-04 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/hal_arm_lpc2xxx_phycore229x.cdl
+ * include/plf_io.h
+ * include/hal_platform_setup.h
+ * src/phycore229x_misc:
+ Initial release of phyCORE-LPC229x development board package
+
+
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 eCosCentric Ltd.
+##
+## 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.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
--- /dev/null
+# ====================================================================
+#
+# hal_arm_lpc2xxx_phycore229x.cdl
+#
+# Phytec phyCORE-LPC2292/94 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2008 eCosCentric Limited
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors: Uwe Kindler
+# Date: 2007-11-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_LPC2XXX_PHYCORE229X {
+ display "Phytec phyCORE-LPC2292/94 development board HAL"
+ parent CYGPKG_HAL_ARM_LPC2XXX
+ define_header hal_arm_lpc2xxx_phycore229x.h
+ include_dir cyg/hal
+ hardware
+ implements CYGINT_DEVS_CAN_LPC2XXX_CAN0
+ implements CYGINT_DEVS_CAN_LPC2XXX_CAN1
+ description "
+ The phyCORE-229x HAL package provides the support needed to run
+ eCos on Phytec phyCORE-LPC2292/94 development board."
+
+ compile phycore229x_misc.c
+
+ requires { CYGHWR_HAL_ARM_LPC2XXX == "LPC2292" || CYGHWR_HAL_ARM_LPC2XXX == "LPC2294" }
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_arm.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_arm_lpc2xxx.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_lpc2xxx_phycore229x.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI-S\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Phytec phyCORE-LPC2292/94\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ default_value {"ROM"}
+ legal_values {"RAM" "ROM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+ description "
+ Choose RAM or ROM startup type. Typically ROM startup is used for
+ building RedBoot. RedBoot runs from internal on chip flash of
+ LPC229x. Use RAM startup for building eCos applications.
+ RedBoot manages the external on board flash devices. It copies
+ the eCos application image from FLASH to phyCORE on board SRAM
+ and then starts the eCos application."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ calculated 2
+ description "
+ Channel 0: UART0, Channel 1: UART1"
+ }
+
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+ display "Default console channel."
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ calculated 0
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ Phytec phyCORE-LPC2292/94 board has two serial channels. This option
+ chooses which channel will be used to connect to a host
+ running GDB."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The phyCORE-LPC2292/94 board has two serial ports. This option
+ chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 38400
+ description "
+ This option selects the baud rate used for the diagnostic port."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "GDB serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 38400
+ description "
+ This option controls the baud rate used for the GDB
+ connection."
+ }
+
+ cdl_component CYGHWR_HAL_ARM_PHYCORE229X_MEMCFG {
+ display "Memory configuration"
+ flavor none
+ description "
+ Configuration options for FLASH and SRAM memory of phyCORE
+ board."
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH {
+ display "Flash configuration"
+ flavor data
+ legal_values { "AM29DL800" "AM29LV800" "AM29LV160" "AM29LV320" }
+ default_value { "AM29LV800" }
+ description "
+ Select the type of FLASH device that is fitted on the phyCORE
+ board."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH_DEVICE_SIZE {
+ display "FLASH device size"
+ flavor data
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29DL800" ?
+ 0x100000 :
+ CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV800" ?
+ 0x100000 :
+ CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV160" ?
+ 0x200000 :
+ CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV320" ?
+ 0x400000 : 0x000 }
+ description "
+ Size of one single flash device."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH_CNT {
+ display "Number of flash devices"
+ flavor data
+ legal_values { 0 2 4 }
+ default_value { 2 }
+ description "
+ This option defines the number of flash devices
+ fitted. The board supports two 16-bit data bus width
+ Flash devices in parallel connected to a 32-bit data
+ bus on the LPC2292/94. Flash devices are always fitted
+ in pairs and there is space for up to 4 devices."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_FLASH_SIZE {
+ display "FLASH size"
+ flavor data
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH_DEVICE_SIZE *
+ CYGHWR_HAL_ARM_PHYCORE229X_FLASH_CNT }
+ description "
+ This option defines the size of the onboard FLASH.
+ The board can be fitted with 0, 2 or 4 FLASH devices of
+ 1MB, 2MB or 4MB."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE {
+ display "SRAM size"
+ flavor data
+ legal_values { 0x100000 0x200000 0x400000 0x800000 }
+ default_value 0x100000
+ description "
+ This option defines the size of the onboard SRAM.
+ The board can be fittet with 2 or 4 SRAM devices of
+ 512KB, 1MB or 2MB."
+ }
+ }
+
+ cdl_component CYGHWR_HAL_ARM_PHYCORE229X_ETH {
+ display "Ethernet options"
+ flavor none
+ description "
+ Configuration options for on board SMSC LAN91C111 ethernet
+ chip."
+
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT {
+ display "Ethernet controller interrupt"
+ flavor data
+ legal_values { 0 1 }
+ default_value { 0 }
+ description "
+ Jumper J501 selects, which of the microcontroller external
+ interrupts (EINT) connects with the interrupt output(LAN_IRQ)
+ of the Ethernet controller. This configuration option should
+ match the actual jumper settings. The LAN chip may use EINT0
+ or EINT1."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_ETH_INT_PRIO {
+ display "Ethernet interrupt priority"
+ flavor data
+ legal_values { 0 to 16 }
+ default_value { 15 }
+ description "
+ Interrupt priority of ethernet interrupt. The LPC2xxx
+ eCos HAL supports up to 17 interrupt levels.
+ Interrupt levels 0 - 15 are vectored IRQs. Vectored
+ IRQs have a higher priority then non vectored IRQs and
+ they are processed faster. Non vectored IRQs are all
+ chained together into one single slot and the ISR need
+ to find out which interrupt occured. The default value
+ for the ethernt interrupt is 15. This is the lowest
+ vectored IRQ priority. That ensures that the ethernet
+ interrupt is processed fast while it has still a lower
+ priority than any other verctored interrupt."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_PHYCORE229X_ETH_MEM_AREA {
+ display "Ethernet controller memory area"
+ flavor data
+ legal_values { 0x82000000 0x83000000 }
+ default_value { 0x82000000 }
+ description "
+ Access to the optional Ethernet controller can be established
+ via /CS2 (addr. 0x82000000) or /CS3 (addr. 0x83000000)
+ configurable with Jumper J502. The default configuration
+ allows access via /CS2."
+ }
+ }
+
+ # Real-time clock/counter specifics
+ cdl_option CYGNUM_HAL_ARM_LPC2XXX_XTAL_FREQ {
+ display "CPU xtal frequency"
+ flavor data
+ default_value {10000000}
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC2XXX_PLL_MUL {
+ display "CPU PLL multiplier"
+ flavor data
+ default_value {6}
+ }
+
+ cdl_option CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED {
+ display "CPU clock speed"
+ flavor data
+ calculated { CYGNUM_HAL_ARM_LPC2XXX_PLL_MUL *
+ CYGNUM_HAL_ARM_LPC2XXX_XTAL_FREQ }
+ }
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+ description "
+ Global build options including control over compiler flags,
+ linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "arm-elf" }
+ description "
+ This option specifies the command prefix used when
+ invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+ description "
+ This option controls the global compiler flags which
+ are used to compile all packages by default. Individual
+ packages may define options which override these global
+ flags."
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mno-short-load-words -Wl,--gc-sections -Wl,-static -g -nostdlib" }
+ description "
+ This option controls the global linker flags. Individual
+ packages may define options which override these global
+ flags."
+ }
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM"}
+ description "
+ Enable this option if this program is to be used as a
+ ROM monitor, i.e. applications will be loaded into RAM on
+ the board, and this ROM monitor may process exceptions or
+ interrupts generated from the application. This enables
+ features such as utilizing a separate interrupt stack when
+ exceptions are generated."
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "Generic" "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Support can be enabled for different varieties of ROM
+ monitor. This support changes various eCos semantics such
+ as the encoding of diagnostic output, or the overriding of
+ hardware interrupt vectors.
+ Firstly there is \"Generic\" support which prevents the
+ HAL from overriding the hardware vectors that it does not
+ use, to instead allow an installed ROM monitor to handle
+ them. This is the most basic support which is likely to be
+ common to most implementations of ROM monitor.
+ \"GDB_stubs\" provides support when GDB stubs are included
+ in the ROM monitor or boot ROM."
+ }
+
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid
+ Redboot configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ requires { !CYGBLD_BUILD_REDBOOT_WITH_EXEC }
+ default_value 1
+ no_define
+ description "
+ This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+ $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+ $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+ $(OBJCOPY) -O ihex $< $(@:.bin=.hex)
+ $(OBJCOPY) -O binary $< $@
+ }
+
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "arm_lpc2xxx_phycore229x_ram" :
+ "arm_lpc2xxx_phycore229x_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.ldi>" :
+ "<pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_lpc2xxx_phycore229x_ram.h>" :
+ "<pkgconf/mlt_arm_lpc2xxx_phycore229x_rom.h>" }
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+/*=============================================================================
+//
+// hal_platform_setup.h
+//
+// Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-12-02
+// Purpose: phyCORE-LPC229x platform specific support routines
+// Description:
+// Usage: #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+#include <pkgconf/system.h>
+#include <cyg/hal/var_io.h>
+
+//===========================================================================*/
+
+#define LINES (0xFE<<16)
+#define LINE (1<<16)
+.macro _line_init
+ // set to GPIO
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL2]
+ bic r1, r1, #8
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL2]
+ // set to output
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+ ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1DIR]
+ orr r1,r1,#LINE
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1DIR]
+ // turn ON
+ ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1PIN]
+ bic r1,r1,#LINES
+ orr r1,r1,#LINE
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO1PIN]
+.endm
+
+//----------------------------------------------------------------------------
+// The phyCORE Carrier Board HD200 offers a programmable LED at
+// D3 for user implementations. This LED can be connected to port pin
+// P0.8 (TxD1) of the phyCORE-LPC2292/94 which is available via
+// signal GPIO0 (JP17 = closed). A low-level at port pin P0.8 causes the
+// LED to illuminate, LED D3 remains off when writing a high-level to
+// P0.8.
+//
+.macro _led_init
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+ ldr r1,=(1<<8) // GPIO0 pins 8 is LED output
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0DIR]
+.endm
+
+.macro _led x
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+ ldr r1,=(1<<8)
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0CLR]
+ ldr r1,=((\x & 1)<<8)
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0SET]
+.endm
+#define CYGHWR_LED_MACRO _led \x
+
+
+//----------------------------------------------------------------------------
+// PLL initialisation
+//
+.macro _pll_init
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_SCB_BASE
+
+ mov r2,#0xAA
+ mov r3,#0x55
+
+ mov r1,#(0x20 | (CYGNUM_HAL_ARM_LPC2XXX_PLL_MUL - 1))
+ // load the PLL configuration register
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLCFG]
+
+ mov r1,#1
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLCON] // enable PLL
+
+ // perform validation sequence 0XAA followed by 0x55
+ str r2,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED]
+ str r3,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED]
+
+1:
+ ldr r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLSTAT] // wait for it to lock
+ ands r1,r1,#(1<<10)
+ beq 1b
+
+ mov r1,#3 // connect PLL
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLCON]
+
+ // perform validation sequence 0XAA followed by 0x55
+ str r2,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED]
+ str r3,[r0,#CYGARC_HAL_LPC2XXX_REG_PLLFEED]
+.endm
+
+
+//----------------------------------------------------------------------------
+// External memory and bus initialisation
+//
+.macro _mem_init
+ //
+ // first map the vector table to internal flash - normally this should be
+ // the default value after boot - but we go the safe way here and force
+ // the mapping to internal flash (the value for
+ // CYGARC_HAL_LPC2XXX_REG_MEMMAP is 1)
+ //
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_SCB_BASE
+ mov r1,#1
+ str r1, [r0,#CYGARC_HAL_LPC2XXX_REG_MEMMAP]
+
+ //
+ // Now its is save to copy the first 64 bytes of flash to RAM
+ //
+ mov r0,#0
+ mov r1,#0x40000000
+ mov r2,#0x40
+1:
+ ldr r3,[r0,#4]!
+ str r3,[r1,#4]!
+ cmps r0,r2
+ bne 1b
+
+ //
+ // Now we can map the vector table to internal SRAM because the SRAM no
+ // contains a copy of the vector tablefrom flash (the value for
+ // CYGARC_HAL_LPC2XXX_REG_MEMMAP is 2 = SRAM)
+ //
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_SCB_BASE
+ // User RAM Mode. Interrupt vectors are re-mapped to Static RAM.
+ mov r1,#2
+ str r1, [r0,#CYGARC_HAL_LPC2XXX_REG_MEMMAP]
+ // 4 processor clocks fetch cycle
+ mov r1,#4
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_MAMTIM] // flash timings
+ mov r1,#2
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_MAMCR] // enable full MAM
+
+ //
+ // Set-up external memory - the main task here is to setup the
+ // wait states for the external memory properly
+ //
+ // Bank Configuration Registers 0-3 (BCFG0-3)
+ // [0..3] IDCY: Min. number of idle Cycles <0-15>
+ // [4] Reserved
+ // [5..9] WST1: Wait States 1 <0-31>
+ // [10] RBLE: Read Byte Lane Enable
+ // [11..15] WST2: Wait States 2 <0-31>
+ // [16..23] Reserved
+ // [26] WP: Write Protect
+ // [27] BM: Burst ROM
+ // [28..29] MW: Memory Width <0=8-bit,1=16-bit,2=32-bit,3=Reserved>
+ // [30..31] Reserved
+ //
+
+ // enable external parallel bus signals
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ // A0..1 enabled, CS0..3, OE, WE, BLS0..3, D0..31, A2..23, JTAG Pins
+ ldr r1,=0x0FE149E4
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL2]
+
+ // setup external FLASH wait states
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG0
+ ldr r1,=0x20003CE3
+ str r1, [r0]
+
+ // setup external SRAM wait states
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG1
+ ldr r1,=0x020002483
+ str r1, [r0]
+
+ // setup Ethernet chip wait states for /CS2 and /CS3
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG2
+ ldr r1,=0x020000C23
+ str r1, [r0]
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_BCFG3
+ ldr r1,=0x020000C23
+ str r1, [r0]
+.endm
+
+.macro _gpio_init
+ // enable RX and TX on UART0 and UART1
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ ldr r1,=0x00050005
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL0]
+
+ // set pin function to EINT0
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ ldr r1,=0x00000001
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_PINSEL1]
+.endm
+
+.macro _block
+ ldr r0,=CYGARC_HAL_LPC2XXX_REG_IO_BASE
+ ldr r1,=(1<<8)
+ str r1,[r0,#CYGARC_HAL_LPC2XXX_REG_IO0CLR]
+2:
+ nop
+ b 2
+.endm
+#define PLATFORM_BLOCK _block
+//===========================================================================*/
+
+#if defined(CYG_HAL_STARTUP_ROM)
+.macro _setup
+ _line_init
+ _led_init
+ _led 1
+ _pll_init
+ _mem_init
+ _gpio_init
+.endm
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+#else
+ .macro _setup
+
+ .endm
+#endif
+
+#define PLATFORM_SETUP1 _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
--- /dev/null
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00004000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0x81000000)
+#define CYGMEM_REGION_ram_SIZE (0x00100000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x81100000 - (size_t) CYG_LABEL_NAME (__heap1))
+
--- /dev/null
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+
+MEMORY
+{
+ sram : ORIGIN = 0x40000000, LENGTH = 0x4000
+ ram : ORIGIN = 0x81000000, LENGTH = CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+ SECTION_rom_vectors (ram, 0x81010000, LMA_EQ_VMA)
+ SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
+
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_sram (0x40000000)
+#define CYGMEM_REGION_sram_SIZE (0x00004000)
+#define CYGMEM_REGION_sram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_ram (0x81000000)
+#define CYGMEM_REGION_ram_SIZE (CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+
+#define CYGMEM_REGION_rom (0x00000000)
+#define CYGMEM_REGION_rom_SIZE (0x00040000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+
+#define CYGMEM_REGION_flash (0x80000000)
+#define CYGMEM_REGION_flash_SIZE (CYGHWR_HAL_ARM_PHYCORE229X_FLASH_SIZE)
+#define CYGMEM_REGION_flash_ATTR (CYGMEM_REGION_ATTR_R)
+
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x81000000 + CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE - (size_t) CYG_LABEL_NAME (__heap1))
+
--- /dev/null
+#include <cyg/infra/cyg_type.inc>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+
+MEMORY
+{
+ rom : ORIGIN = 0x00000000, LENGTH = 0x40000
+ sram : ORIGIN = 0x40000000, LENGTH = 0x4000
+ ram : ORIGIN = 0x81000000, LENGTH = CYGHWR_HAL_ARM_PHYCORE229X_SRAM_SIZE
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_rom_vectors (rom, 0x00000000, LMA_EQ_VMA)
+ SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (sram, 0x40000400, LMA_EQ_VMA)
+ SECTION_data (ram, 0x81000000, FOLLOWING (.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
+
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+// plf_io.h
+//
+// Phytec phyCORE-LPC2292/94 board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Sergei Gavrikov
+// Date: 2007-11-20
+// Purpose: Phytec phyCORE-LPC2292/94 board specific registers
+// Description:
+// Usage: #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+
+//----------------------------------------------------------------------
+// The platform needs this initialization during the
+// hal_hardware_init() function in the varient HAL.
+#ifndef __ASSEMBLER__
+extern void hal_plf_hardware_init(void);
+#define HAL_PLF_HARDWARE_INIT() \
+ hal_plf_hardware_init()
+#endif //__ASSEMBLER__
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_HAL_PLF_IO_H
+
--- /dev/null
+/*==========================================================================
+//
+// phycore_misc.c
+//
+// HAL misc board support code for Phytec phyCORE-LPC2292/94
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2008 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-11-20
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+#include <cyg/hal/hal_io.h> // IO macros
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/plf_io.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+#include <redboot.h>
+#endif
+
+extern void cyg_hal_plf_serial_init(void);
+
+void cyg_hal_plf_comms_init(void)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ cyg_hal_plf_serial_init();
+}
+
+//--------------------------------------------------------------------------
+// hal_plf_hardware_init
+//
+void hal_plf_hardware_init(void)
+{
+#if defined(CYG_HAL_STARTUP_ROM) && defined(CYGPKG_DEVS_ETH_ARM_PHYCORE229X)
+ cyg_uint32 regval;
+
+ //
+ // Configures the LAN IRQ
+ // The interrupt is being used as active high edge triggered.
+ // IMPORTANT: We execute this step only for ROM startup. If this is done
+ // for RAM startup then wrong values are stored in EXTMODE and EXTPOLAR
+ // register because of a bug in LPC229x hardware.
+ //
+ HAL_INTERRUPT_CONFIGURE(CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT + // the configured external interrupt
+ CYGNUM_HAL_INTERRUPT_EINT0, // the first external interrupt
+ 0, // level = 0 - edge triggered
+ 1); // up = 1 - rising edge
+
+ //
+ // Set pin function of P0.16 to EINT0 or P0.14 to EINT1 for ethernet interrupt
+ //
+#if CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT == 0
+ HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE +
+ CYGARC_HAL_LPC2XXX_REG_PINSEL1, regval);
+ regval |= 0x01;
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE +
+ CYGARC_HAL_LPC2XXX_REG_PINSEL1, regval);
+#elif CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT == 1
+ HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE +
+ CYGARC_HAL_LPC2XXX_REG_PINSEL0, regval);
+ regval |= (0x10 << 28);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_PIN_BASE +
+ CYGARC_HAL_LPC2XXX_REG_PINSEL0, regval);
+#else
+#error "Invalid CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT value"
+#endif
+#endif // #if defined(CYG_HAL_STARTUP_ROM) && defined(CYGPKG_DEVS_ETH_ARM_PHYCORE229X)
+}
+
+//--------------------------------------------------------------------------
+// hal_lpc2xxx_set_leds
+//
+void hal_lpc2xxx_set_leds (int mask)
+{
+ //
+ // implement function for setting diagnostic leds
+ //
+}
+
+//--------------------------------------------------------------------------
+// EOF phycore_misc.c
+
+
+
+
+
+
+
--- /dev/null
+#ifndef CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
+#define CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
+//=============================================================================
+//
+// lpc2xxx_misc.h
+//
+// HAL misc variant support code for Philips LPC2xxx header file
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andyj
+// Contributors: jani
+// Date: 2006-02-04
+// Purpose: LPC2XXX specific miscellaneous support header file
+// Description:
+// Usage: #include <cyg/hal/lpc2xxx_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Macros to derive the baudrate divider values for the internal UARTs
+//-----------------------------------------------------------------------------
+#define CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud) \
+ (CYGNUM_HAL_ARM_LPC2XXX_PCLK/((baud)*16))
+
+//-----------------------------------------------------------------------------
+// LPX2xxx varaint specific initialisatio of CAN channels
+// This function configures the pin functions for CAN use
+//-----------------------------------------------------------------------------
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX
+externC void hal_lpc_can_init(cyg_uint8 can_chan_no);
+#define HAL_LPC2XXX_INIT_CAN(_can_chan_no_) hal_lpc_can_init(_can_chan_no_)
+#define CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK CYGNUM_HAL_ARM_LPC2XXX_PCLK
+#endif // CYGPKG_DEVS_CAN_LPC2XXX
+
+//-----------------------------------------------------------------------------
+// LPX2xxx watchdog support
+//-----------------------------------------------------------------------------
+externC void hal_lpc_watchdog_reset(void);
+
+#define HAL_PLATFORM_RESET() hal_lpc_watchdog_reset()
+#define HAL_PLATFORM_RESET_ENTRY 0
+
+//-----------------------------------------------------------------------------
+// end of lpc2xxx_misc.h
+#endif // CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
--- /dev/null
+2006-06-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/hal_arm_mac7100_mac7100evb.cdl:
+ * include/plf_io.h:
+ * include/hal_platform_ints.h:
+ * include/hal_platform_setup.h:
+ * include/mac7100evb_misc.h:
+ * include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi:
+ * include/pkgconf/mlt_arm_mac7100_mac7100evb_rom.h:
+ * src/mac7100evb_misc.c:
+ New HAL added to support the Freescale MAC7100 board.
+ Adapted from MACE1
+
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+
+# ====================================================================
+#
+# hal_arm_mac7100_mac7100evb.cdl
+#
+# ARM MAC7100 MAC7100EVB HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Contributors:
+# Date: 2006-06-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_MAC7100_MAC7100EVB {
+ display "MAC7100EVB evaluation board HAL"
+ parent CYGPKG_HAL_ARM_MAC7100
+ define_header hal_arm_mac7100_mac7100evb.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The MAC7100EVB HAL package provides the support needed to run
+ eCos on the Freescale MAC7100EVB eval board."
+
+ compile mac7100evb_misc.c
+
+ requires { CYGHWR_HAL_ARM_MAC7100 == "MAC7111" }
+ requires { CYGNUM_PIT_CHAN_CLOCK_PRIORITY ==
+ CYGNUM_KERNEL_COUNTERS_CLOCK_ISR_PRIORITY }
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_arm.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_arm_mac7100.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_mac7100_mac7100evb.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Freescale MAC7100/MAC7100EVB\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ }
+
+ cdl_component CYG_PIT_CLOCKS {
+ display "Real time clock configuration."
+ flavor none
+ description "
+ Periodic Interrupt Timer Module - PIT comprise of 11 timer
+ channels. RTI channel (PIT0) as well as PIT1 .. PIT4 can
+ generate interrupts and are eligible for the real time
+ clock."
+
+ cdl_option CYGNUM_PIT_CHAN_CLOCK {
+ display "System CLOCK device"
+ flavor data
+ legal_values 0 to 4
+ default_value 3
+ requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+ description "
+ RTI (PIT0) and PIT1 .. PIT4 can be used for real time
+ clock. RTI is clocked by oscillator clock while
+ channels 1 to 4 by 1/2 system clock frequency.
+ Selection of RTI vs PIT1 .. PIT4 affects Real-time
+ clock period (see Real-time clock constants). NOTE:
+ Real time clock channel must not be the same as US
+ delay channel.
+ "
+ }
+
+ cdl_option CYGNUM_PIT_CHAN_CLOCK_PRIORITY {
+ display "System clock's INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 12
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+
+ cdl_option CYGNUM_PIT_CHAN_US {
+ display "PIT channel for us delay"
+ flavor data
+ legal_values 0 to 4
+ default_value 0
+ requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+ description "
+ RTI is clocked by oscillator while channels PIT1
+ .. PIT4 by half system clock frequency, hence RTI
+ should allow for larger maximal period. NOTE: US
+ delay channel must not be the same as real time clock
+ channel.
+ "
+ }
+ }
+
+ cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants"
+ flavor none
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ default_value 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ default_value 100
+ }
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ default_value (CYGNUM_PIT_CHAN_CLOCK !=0 ? \
+ (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED / 2 / CYGNUM_HAL_RTC_DENOMINATOR - 1) : \
+ (CYGNUM_HAL_ARM_MAC7100_Q_FREQ / CYGNUM_HAL_RTC_DENOMINATOR - 1))
+ }
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ calculated {"ROM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+ description "
+ Current MAC7100EVB port supports only ROM startup type."
+ }
+
+ # Real-time clock/counter specifics
+
+ cdl_component CYG_HAL_MAC7100_OSC {
+ display "System Clocks Module"
+ flavor none
+
+ cdl_option CYGNUM_HAL_ARM_MAC7100_F_OSC {
+ display "FOSC - Oscillator clock"
+ flavor data
+ default_value 8000000
+ }
+
+ cdl_option CYGNUM_HAL_ARM_MAC7100_FDIV {
+ display "FDIV - Frequency divider for PLL"
+ flavor booldata
+ legal_values 0 to 16
+ default_value 2
+ description "
+ If enabled (FDIV != 0),
+ you set divider for PLL.
+ Then REFDV is calculated as REFDV=FDIV-1;
+ If disabled (FDIV == 0),
+ REFDV is calculated from FOSC so that referent frequency
+ for PLL is 500kHz.
+ SYNR is then derived from desired CPU clock, FOSC and REFDV.
+ "
+ }
+ }
+
+ cdl_option CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED {
+ display "CPU clock - PLL frequency"
+ flavor data
+ default_value 48000000
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ legal_values 0 1 2
+ default_value 2
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The MAC7100 MAC7100EVB board has two serial ports. This option
+ chooses which port will be used to connect to a host
+ running GDB."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The MAC7100 MAC7100EVB board has two serial ports. This option
+ chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400
+ default_value 38400
+ description "
+ This option selects the baud rate used for the diagnostic port."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "GDB serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400
+ default_value 38400
+ description "
+ This option controls the baud rate used for the GDB connection."
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM" ||
+ CYG_HAL_STARTUP == "ROMRAM" }
+ description "
+ Enable this option if this program is to be used as a ROM monitor,
+ i.e. applications will be loaded into RAM on the board, and this
+ ROM monitor may process exceptions or interrupts generated from the
+ application. This enables features such as utilizing a separate
+ interrupt stack when exceptions are generated."
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "Generic" "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Support can be enabled for different varieties of ROM monitor.
+ This support changes various eCos semantics such as the encoding
+ of diagnostic output, or the overriding of hardware interrupt
+ vectors.
+ Firstly there is \"Generic\" support which prevents the HAL
+ from overriding the hardware vectors that it does not use, to
+ instead allow an installed ROM monitor to handle them. This is
+ the most basic support which is likely to be common to most
+ implementations of ROM monitor.
+ \"GDB_stubs\" provides support when GDB stubs are included in
+ the ROM monitor or boot ROM."
+ }
+
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid Redboot
+ configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ default_value 1
+ no_define
+ description "This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+ $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+ $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+ $(OBJCOPY) -O binary $< $@
+ }
+
+ }
+ }
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+ description "
+ Global build options including control over
+ compiler flags, linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "arm-elf" }
+ description "
+ This option specifies the command prefix used when
+ invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -gdwarf-2 -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+ description "
+ This option controls the global compiler flags which
+ are used to compile all packages by
+ default. Individual packages may define options which
+ override these global flags."
+
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wl,--gc-sections -Wl,-static -gdwarf-2 -nostdlib" }
+ description "
+ This option controls the global linker flags. Individual
+ packages may define options which override these global flags."
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "arm_mac7100_mac7100evb_ram" :
+ (CYG_HAL_STARTUP == "ROMRAM") ? "arm_mac7100_mac7100evb_romram" :
+ "arm_mac7100_mac7100evb_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_ram.ldi>" :
+ (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_romram.ldi>" :
+ "<pkgconf/mlt_arm_mac7100_mac7100evb_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_ram.h>" :
+ (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mac7100evb_romram.h>" :
+ "<pkgconf/mlt_arm_mac7100_mac7100evb_rom.h>" }
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+// hal_platform_ints.h
+//
+// HAL Interrupt and clock assignments for MAC7100EVB
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2996 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-06-07
+// Purpose: Define Interrupt support
+// Description: The interrupt specifics for the MAC7100EVB board/platform
+// are defined here.
+//
+// Usage: #include <cyg/hal/hal_platform_ints.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define CYGNUM_HAL_ISR_MIN 0
+#define CYGNUM_HAL_ISR_MAX 63
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX + 1)
+
+// INTC levels
+
+#define MAC7100_EDMA0_LEVEL (0)
+#define MAC7100_EDMA1_LEVEL (0)
+#define MAC7100_EDMA2_LEVEL (0)
+#define MAC7100_EDMA3_LEVEL (0)
+#define MAC7100_EDMA4_LEVEL (0)
+#define MAC7100_EDMA5_LEVEL (0)
+#define MAC7100_EDMA6_LEVEL (0)
+#define MAC7100_EDMA7_LEVEL (0)
+#define MAC7100_EDMA8_LEVEL (0)
+#define MAC7100_EDMA9_LEVEL (0)
+#define MAC7100_EDMA10_LEVEL (0)
+#define MAC7100_EDMA11_LEVEL (0)
+#define MAC7100_EDMA12_LEVEL (0)
+#define MAC7100_EDMA13_LEVEL (0)
+#define MAC7100_EDMA14_LEVEL (0)
+#define MAC7100_EDMA15_LEVEL (0)
+#define MAC7100_EDMA_Error_LEVEL (0)
+#define MAC7100_MCM_SWT_LEVEL (0)
+#define MAC7100_CRG_LEVEL (0)
+#define MAC7100_PIT1_LEVEL (9)
+#define MAC7100_PIT2_LEVEL (9)
+#define MAC7100_PIT3_LEVEL (10)
+#define MAC7100_PIT4_RTI_LEVEL (9)
+#define MAC7100_VREG_LEVEL (4)
+#define MAC7100_CAN_A_MB_LEVEL (4)
+#define MAC7100_CAN_A_MB14_LEVEL (4)
+#define MAC7100_CAN_A_Error_LEVEL (4)
+#define MAC7100_CAN_B_MB_LEVEL (4)
+#define MAC7100_CAN_B_MB14_LEVEL (4)
+#define MAC7100_CAN_B_Error_LEVEL (4)
+#define MAC7100_CAN_C_MB_LEVEL (4)
+#define MAC7100_CAN_C_MB14_LEVEL (4)
+#define MAC7100_CAN_C_Error_LEVEL (4)
+#define MAC7100_CAN_D_MB_LEVEL (4)
+#define MAC7100_CAN_D_MB14_LEVEL (4)
+#define MAC7100_CAN_D_Error_LEVEL (4)
+#define MAC7100_I2C_LEVEL (4)
+#define MAC7100_DSPI_A_LEVEL (5)
+#define MAC7100_DSPI_B_LEVEL (5)
+#define MAC7100_ESCI_A_LEVEL (8)
+#define MAC7100_ESCI_B_LEVEL (8)
+#define MAC7100_ESCI_C_LEVEL (8)
+#define MAC7100_ESCI_D_LEVEL (8)
+#define MAC7100_EMIOS0_LEVEL (7)
+#define MAC7100_EMIOS1_LEVEL (7)
+#define MAC7100_EMIOS2_LEVEL (7)
+#define MAC7100_EMIOS3_LEVEL (7)
+#define MAC7100_EMIOS4_LEVEL (7)
+#define MAC7100_EMIOS5_LEVEL (7)
+#define MAC7100_EMIOS6_LEVEL (7)
+#define MAC7100_EMIOS7_LEVEL (7)
+#define MAC7100_EMIOS8_LEVEL (7)
+#define MAC7100_EMIOS9_LEVEL (7)
+#define MAC7100_EMIOS10_LEVEL (7)
+#define MAC7100_EMIOS11_LEVEL (7)
+#define MAC7100_EMIOS12_LEVEL (7)
+#define MAC7100_EMIOS13_LEVEL (7)
+#define MAC7100_EMIOS14_LEVEL (7)
+#define MAC7100_EMIOS15_LEVEL (7)
+#define MAC7100_ATD_LEVEL (11)
+#define MAC7100_CFM_LEVEL (7)
+#define MAC7100_PIM_LEVEL (11)
+#define MAC7100_IRQ_LEVEL (12)
+#define MAC7100_XIRQ_LEVEL (12)
+
+// The vector used by the Real time clock
+#if CYGNUM_PIT_CHAN_CLOCK==0
+#define CYGNUM_HAL_INTERRUPT_RTC MAC7100_PIT4_RTI_IV
+#else
+#define CYGNUM_HAL_INTERRUPT_RTC (MAC7100_PIT1_IV+CYGNUM_PIT_CHAN_CLOCK-1)
+#endif
+
+//----------------------------------------------------------------------------
+// Reset.
+__externC void hal_mac7100_reset_cpu(void);
+#define HAL_PLATFORM_RESET() hal_mac7100_reset_cpu()
+
+#define HAL_PLATFORM_RESET_ENTRY 0x01000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+//=============================================================================
+//
+// hal_platform_setup.h
+//
+// Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-06-07
+// Purpose: MAC7100EVB platform specific support routines
+// Description:
+// Usage: #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/hal_var_setup.h>
+//===========================================================================
+
+ .macro _led y
+ ldr r0,=MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET)
+ ldrh r1,[r0]
+ and r1,r1,#0x00ff
+ orr r1,r1,#(((~\y)&0xff)<<8)
+ strh r1,[r0]
+ .endm
+
+
+// Initialize LED PORT
+// Set appropriate peripheral pins
+ .macro _led_init
+ _led 0 // Set initial LED state.
+ mov r1, #MAC7100_PIM_DDR // Pin setting: Output+Low
+ ldr r0,=MAC7100_PIM_CONFIG(MAC7100_PORT_F_OFFSET, 8) // LED pin cfg
+ strh r1,[r0],#2 // LED: LSB ...
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2 // LED: ... MSB
+ .endm
+
+
+// Clock initilalization
+ .macro _pclock_init
+ _mac7100_setpll
+ .endm
+
+// Memory re-mapping
+ .macro _memory_remap
+ _mac7100_remap_single_chip
+ .endm
+
+
+// Initialize paralel port
+ .macro _pio_init
+ .endm
+
+
+#define CYGHWR_LED_MACRO _led \x
+
+//===========================================================================
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+ .macro _setup
+ ldr r0,=VAE_MAC7100_FlashSecurity
+ _led_init
+ _memory_remap
+ _pclock_init
+ _pio_init
+ .endm
+
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+
+#else
+
+ .macro _setup
+ _led_init
+ _led 16
+ _pclock_init
+ _pio_init
+ .endm
+
+#endif
+
+#define PLATFORM_SETUP1 _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
--- /dev/null
+#ifndef CYGONCE_HAL_MAC7100EVB_MISC_H
+#define CYGONCE_HAL_MAC7100EVB_MISC_H
+//=============================================================================
+//
+// mac7100evb_misc.h
+//
+// MAC7100EVB board specific functions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-05-07
+// Purpose: MAC7100EVB board specific registers
+// Description:
+// Usage: #include <cyg/hal/mac7100evb_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+void hal_mac7100evb_set_leds(int);
+void hal_mac7100evb_led_on(int);
+void hal_mac7100evb_led_off(int);
+int hal_mac7100evb_get_leds(void);
+
+#define HAL_MAC7100_SET_LEDS(x) hal_mac7100evb_set_leds(x)
+#define HAL_MAC7100_LED_ON(x) hal_mac7100evb_led_on(x)
+#define HAL_MAC7100_LED_OFF(x) hal_mac7100evb_led_off(x)
+#define HAL_MAC7100_GET_LEDS(x) hal_mac7100evb_get_leds(x)
+
+//-----------------------------------------------------------------------------
+// end of mac7100evb_misc.h
+#endif // CYGONCE_HAL_MAC7100EVB_MISC_H
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+// Initially RAM is at 0x40000000 but we ramap to 0x0
+#define CYGMEM_REGION_ram (0x00000000)
+#define CYGMEM_REGION_ram_SIZE (0x00008000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x20000000)
+#define CYGMEM_REGION_rom_SIZE (0x80000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE \
+ ((CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE) - \
+ (size_t) CYG_LABEL_NAME (__heap1))
+
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00000000, LENGTH = 0x8000
+ rom : ORIGIN = 0x20000000, LENGTH = 0x80000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_rom_vectors (rom, 0x20000000, LMA_EQ_VMA)
+
+// MAC7100 Flash Security
+// Following section is manually added to address MAC7100 flash security area
+// It should actually be something like this
+// SECTION_sgfm_config (rom, 0x20000400, LMA_EQ_VMA)
+
+ .mac7100_flash_security 0x20000400 : { KEEP (*(.mac7100_flash_security))} > rom
+
+// END MAC7100 Flash Security
+
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+
+ SECTION_fixed_vectors (ram, 0x00000020, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN(0x4), FOLLOWING(.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+// plf_io.h
+//
+// MAC7100EVB board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-06-07
+// Purpose: MAC7100EVB board specific registers
+// Description:
+// Usage: #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+#define CYGARC_PHYSICAL_ADDRESS(_x_)
+
+#endif // CYGONCE_HAL_PLF_IO_H
+//-----------------------------------------------------------------------------
+// end of plf_io.h
--- /dev/null
+//==========================================================================
+//
+// mac7100evb_misc.c
+//
+// HAL misc board support code for MAC7100EVB board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-06-07
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/hal/hal_io.h> // low level i/o
+#include <cyg/hal/var_io.h> // common registers
+#include <cyg/hal/plf_io.h> // platform registers
+#include <cyg/hal/mac7100evb_misc.h> // mac7100evb misc functions
+
+void
+hal_mac7100evb_set_leds(int val)
+{
+ HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET),
+ ~((val<<8)&0xff00)); // turn all LEDs off
+}
+
+void
+hal_mac7100evb_led_on(int val)
+{
+ cyg_uint16 leds;
+
+ // read old LED state
+ HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds);
+ leds&=~(1<<(8+val));
+ // Write new state
+ HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds);
+}
+
+void
+hal_mac7100evb_led_off(int val)
+{
+ cyg_uint16 leds;
+
+ // read old LED state
+ HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds);
+ leds|=1<<(8+val);
+ // Write new state
+ HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds);
+}
+
+int
+hal_mac7100evb_get_leds(void)
+{
+ cyg_uint16 leds = 0;
+
+ // read old LED state
+ HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_F_OFFSET), leds);
+ return ~(leds>>8&0xFF);
+}
+
+//--------------------------------------------------------------------------
+// EOF mac7100evb_misc.c
--- /dev/null
+2006-06-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * include/hal_platform_setup.h: PLL clock and memory remap
+ moved to hal_var_setup.h
+ * include/mace1_misc.h: LED macros added
+
+2006-05-24 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/hal_arm_mac7100_mace1.cdl:
+ * include/plf_io.h:
+ * include/hal_platform_ints.h:
+ * include/hal_platform_setup.h:
+ * include/mace1_misc.h:
+ * include/pkgconf/mlt_arm_mac7100_mace1_rom.ldi:
+ * include/pkgconf/mlt_arm_mac7100_mace1_rom.h:
+ * src/mace1_misc.c:
+ New HAL added to support the SIvA MACE1 board. Adapted from the
+ EB55 by Nick Garnett
+
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+
+# ====================================================================
+#
+# hal_arm_mac7100_mace1.cdl
+#
+# ARM MAC7100 MACE1 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Contributors:
+# Date: 2006-04-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_MAC7100_MACE1 {
+ display "MACE1 - MAC7100 eval board HAL"
+ parent CYGPKG_HAL_ARM_MAC7100
+ define_header hal_arm_mac7100_mace1.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The MACE1 HAL package provides the support needed to run
+ eCos on an MACE1 - MAC7100 eval board."
+
+ compile mace1_misc.c
+
+ requires { CYGHWR_HAL_ARM_MAC7100 == "MAC7121" }
+ requires { CYGNUM_PIT_CHAN_CLOCK_PRIORITY ==
+ CYGNUM_KERNEL_COUNTERS_CLOCK_ISR_PRIORITY }
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_arm.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_arm_mac7100.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_mac7100_mace1.h>"
+ puts $::cdl_header "#define HAL_PLATFORM_CPU \"ARM7TDMI\""
+ puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Freescale MAC7100/MACE1\""
+ puts $::cdl_header "#define HAL_PLATFORM_EXTRA \"\""
+ }
+
+ cdl_component CYG_PIT_CLOCKS {
+ display "Real time clock configuration."
+ flavor none
+ description "
+ Periodic Interrupt Timer Module - PIT comprizes 11 timer
+ channels. RTI channel (PIT0) as well as PIT1 .. PIT4 can
+ generate interrupts and are eligible for the real time
+ clock. "
+
+ cdl_option CYGNUM_PIT_CHAN_CLOCK {
+ display "System CLOCK device"
+ flavor data
+ legal_values 0 to 4
+ default_value 3
+ requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+ description "
+ RTI (PIT0) and PIT1 .. PIT4 can be used for ral time
+ clock. RTI is clocked by oscillator clock while
+ channels 1 to 4 by 1/2 system clock frequency.
+ Selection of RTI vs PIT1 .. PIT4 affects Real-time
+ clock period (see Real-time clock constants). NOTE:
+ Real time clock channel must not be the same as US
+ delay channel.
+ "
+ }
+
+ cdl_option CYGNUM_PIT_CHAN_CLOCK_PRIORITY {
+ display "System clock's INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 12
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+
+ cdl_option CYGNUM_PIT_CHAN_US {
+ display "PIT channel for us delay"
+ flavor data
+ legal_values 0 to 4
+ default_value 0
+ requires {CYGNUM_PIT_CHAN_CLOCK != CYGNUM_PIT_CHAN_US}
+ description "
+ RTI is clocked by oscillator while channels PIT1
+ .. PIT4 by half system clock frequency, hence RTI
+ should allow for larger maximal period. NOTE: US
+ delay channel must not be the same as real time clock
+ channel.
+ "
+ }
+ }
+
+ cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants"
+ flavor none
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ default_value 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ default_value 100
+ }
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ default_value (CYGNUM_PIT_CHAN_CLOCK !=0 ? \
+ (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED / 2 / CYGNUM_HAL_RTC_DENOMINATOR - 1) : \
+ (CYGNUM_HAL_ARM_MAC7100_Q_FREQ / CYGNUM_HAL_RTC_DENOMINATOR - 1))
+ }
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ calculated {"ROM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+ description "
+ Current MACE1 port supports only ROM startup type."
+ }
+
+ # Real-time clock/counter specifics
+
+ cdl_component CYG_HAL_MAC7100_OSC {
+ display "System Clocks Module"
+ flavor none
+
+ cdl_option CYGNUM_HAL_ARM_MAC7100_F_OSC {
+ display "FOSC - Oscillator clock"
+ flavor data
+ default_value 8000000
+ }
+
+ cdl_option CYGNUM_HAL_ARM_MAC7100_FDIV {
+ display "FDIV - Frequency divider for PLL"
+ flavor booldata
+ legal_values 0 to 16
+ default_value 2
+ description "
+ If enabled (FDIV != 0),
+ you set divider for PLL.
+ Then REFDV is calculated as REFDV=FDIV-1;
+ If disabled (FDIV == 0),
+ REFDV is calculated from FOSC so that referent frequency
+ for PLL is 500kHz.
+ SYNR is then derived from desired CPU clock, FOSC and REFDV.
+ "
+ }
+ }
+
+ cdl_option CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED {
+ display "CPU clock - PLL frequency"
+ flavor data
+ default_value 48000000
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ legal_values 0 1 2
+ default_value 2
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The MAC7100 MACE1 board has two serial ports. This option
+ chooses which port will be used to connect to a host
+ running GDB."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The MAC7100 MACE1 board has two serial ports. This option
+ chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400
+ default_value 38400
+ description "
+ This option selects the baud rate used for the diagnostic port."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "GDB serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400
+ default_value 38400
+ description "
+ This option controls the baud rate used for the GDB connection."
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM" ||
+ CYG_HAL_STARTUP == "ROMRAM" }
+ description "
+ Enable this option if this program is to be used as a ROM monitor,
+ i.e. applications will be loaded into RAM on the board, and this
+ ROM monitor may process exceptions or interrupts generated from the
+ application. This enables features such as utilizing a separate
+ interrupt stack when exceptions are generated."
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "Generic" "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Support can be enabled for different varieties of ROM monitor.
+ This support changes various eCos semantics such as the encoding
+ of diagnostic output, or the overriding of hardware interrupt
+ vectors.
+ Firstly there is \"Generic\" support which prevents the HAL
+ from overriding the hardware vectors that it does not use, to
+ instead allow an installed ROM monitor to handle them. This is
+ the most basic support which is likely to be common to most
+ implementations of ROM monitor.
+ \"GDB_stubs\" provides support when GDB stubs are included in
+ the ROM monitor or boot ROM."
+ }
+
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid Redboot
+ configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ default_value 1
+ no_define
+ description "This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+ $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+ $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+ $(OBJCOPY) -O binary $< $@
+ }
+
+ }
+ }
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+ description "
+ Global build options including control over
+ compiler flags, linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "arm-elf" }
+ description "
+ This option specifies the command prefix used when
+ invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -gdwarf-2 -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+ description "
+ This option controls the global compiler flags which
+ are used to compile all packages by
+ default. Individual packages may define options which
+ override these global flags."
+
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { (CYGHWR_THUMB ? "-mthumb " : "") . (CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork " : "") . "-mcpu=arm7tdmi -mbig-endian -mno-short-load-words -Wl,--gc-sections -Wl,-static -gdwarf-2 -nostdlib" }
+ description "
+ This option controls the global linker flags. Individual
+ packages may define options which override these global flags."
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "arm_mac7100_mace1_ram" :
+ (CYG_HAL_STARTUP == "ROMRAM") ? "arm_mac7100_mace1_romram" :
+ "arm_mac7100_mace1_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mace1_ram.ldi>" :
+ (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mace1_romram.ldi>" :
+ "<pkgconf/mlt_arm_mac7100_mace1_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_arm_mac7100_mace1_ram.h>" :
+ (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_arm_mac7100_mace1_romram.h>" :
+ "<pkgconf/mlt_arm_mac7100_mace1_rom.h>" }
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+// hal_platform_ints.h
+//
+// HAL Interrupt and clock assignments for MAC7100/MACE1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2996 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-13
+// Purpose: Define Interrupt support
+// Description: The interrupt specifics for the MAC7100/MACE1 board/platform
+// are defined here.
+//
+// Usage: #include <cyg/hal/hal_platform_ints.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define CYGNUM_HAL_ISR_MIN 0
+#define CYGNUM_HAL_ISR_MAX 63
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX + 1)
+
+// INTC levels
+
+#define MAC7100_EDMA0_LEVEL (0)
+#define MAC7100_EDMA1_LEVEL (0)
+#define MAC7100_EDMA2_LEVEL (0)
+#define MAC7100_EDMA3_LEVEL (0)
+#define MAC7100_EDMA4_LEVEL (0)
+#define MAC7100_EDMA5_LEVEL (0)
+#define MAC7100_EDMA6_LEVEL (0)
+#define MAC7100_EDMA7_LEVEL (0)
+#define MAC7100_EDMA8_LEVEL (0)
+#define MAC7100_EDMA9_LEVEL (0)
+#define MAC7100_EDMA10_LEVEL (0)
+#define MAC7100_EDMA11_LEVEL (0)
+#define MAC7100_EDMA12_LEVEL (0)
+#define MAC7100_EDMA13_LEVEL (0)
+#define MAC7100_EDMA14_LEVEL (0)
+#define MAC7100_EDMA15_LEVEL (0)
+#define MAC7100_EDMA_Error_LEVEL (0)
+#define MAC7100_MCM_SWT_LEVEL (0)
+#define MAC7100_CRG_LEVEL (0)
+#define MAC7100_PIT1_LEVEL (9)
+#define MAC7100_PIT2_LEVEL (9)
+#define MAC7100_PIT3_LEVEL (10)
+#define MAC7100_PIT4_RTI_LEVEL (9)
+#define MAC7100_VREG_LEVEL (4)
+#define MAC7100_CAN_A_MB_LEVEL (4)
+#define MAC7100_CAN_A_MB14_LEVEL (4)
+#define MAC7100_CAN_A_Error_LEVEL (4)
+#define MAC7100_CAN_B_MB_LEVEL (4)
+#define MAC7100_CAN_B_MB14_LEVEL (4)
+#define MAC7100_CAN_B_Error_LEVEL (4)
+#define MAC7100_CAN_C_MB_LEVEL (4)
+#define MAC7100_CAN_C_MB14_LEVEL (4)
+#define MAC7100_CAN_C_Error_LEVEL (4)
+#define MAC7100_CAN_D_MB_LEVEL (4)
+#define MAC7100_CAN_D_MB14_LEVEL (4)
+#define MAC7100_CAN_D_Error_LEVEL (4)
+#define MAC7100_I2C_LEVEL (4)
+#define MAC7100_DSPI_A_LEVEL (5)
+#define MAC7100_DSPI_B_LEVEL (5)
+#define MAC7100_ESCI_A_LEVEL (8)
+#define MAC7100_ESCI_B_LEVEL (8)
+#define MAC7100_ESCI_C_LEVEL (8)
+#define MAC7100_ESCI_D_LEVEL (8)
+#define MAC7100_EMIOS0_LEVEL (7)
+#define MAC7100_EMIOS1_LEVEL (7)
+#define MAC7100_EMIOS2_LEVEL (7)
+#define MAC7100_EMIOS3_LEVEL (7)
+#define MAC7100_EMIOS4_LEVEL (7)
+#define MAC7100_EMIOS5_LEVEL (7)
+#define MAC7100_EMIOS6_LEVEL (7)
+#define MAC7100_EMIOS7_LEVEL (7)
+#define MAC7100_EMIOS8_LEVEL (7)
+#define MAC7100_EMIOS9_LEVEL (7)
+#define MAC7100_EMIOS10_LEVEL (7)
+#define MAC7100_EMIOS11_LEVEL (7)
+#define MAC7100_EMIOS12_LEVEL (7)
+#define MAC7100_EMIOS13_LEVEL (7)
+#define MAC7100_EMIOS14_LEVEL (7)
+#define MAC7100_EMIOS15_LEVEL (7)
+#define MAC7100_ATD_LEVEL (11)
+#define MAC7100_CFM_LEVEL (7)
+#define MAC7100_PIM_LEVEL (11)
+#define MAC7100_IRQ_LEVEL (12)
+#define MAC7100_XIRQ_LEVEL (12)
+
+// The vector used by the Real time clock
+#if CYGNUM_PIT_CHAN_CLOCK==0
+#define CYGNUM_HAL_INTERRUPT_RTC MAC7100_PIT4_RTI_IV
+#else
+#define CYGNUM_HAL_INTERRUPT_RTC (MAC7100_PIT1_IV+CYGNUM_PIT_CHAN_CLOCK-1)
+#endif
+
+//----------------------------------------------------------------------------
+// Reset.
+__externC void hal_mac7100_reset_cpu(void);
+#define HAL_PLATFORM_RESET() hal_mac7100_reset_cpu()
+
+#define HAL_PLATFORM_RESET_ENTRY 0x01000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+//=============================================================================
+//
+// hal_platform_setup.h
+//
+// Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-03-12
+// Purpose: MAC7100/MACE1 platform specific support routines
+// Description:
+// Usage: #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <cyg/hal/var_io.h>
+#include <cyg/hal/hal_var_setup.h>
+//===========================================================================
+
+ .macro _led y
+ ldr r0,=MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET)
+ ldrh r1,[r0]
+ and r1,r1,#0x00ff
+ add r1,r1,#(\y<<8)
+ strh r1,[r0]
+ .endm
+
+
+// Initialize LED PORT
+// Set appropriate peripheral pins
+ .macro _led_init
+ mov r1, #MAC7100_PIM_DDR // Pin setting: Output+Low
+ ldr r0,=MAC7100_PIM_CONFIG(MAC7100_PORT_A_OFFSET, 8) // LED pin cfg
+ strh r1,[r0],#2 // LED: LSB ...
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2
+ strh r1,[r0],#2 // LED: MSB ...
+ _led 0 // Set initial LED state.
+ .endm
+
+
+// Clock initilalization
+ .macro _pclock_init
+ _mac7100_setpll
+ .endm
+
+// Memory re-mapping
+ .macro _memory_remap
+ _mac7100_remap_single_chip
+ .endm
+
+
+// Initialize paralel port
+ .macro _pio_init
+ .endm
+
+
+#define CYGHWR_LED_MACRO _led \x
+
+//===========================================================================
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+ .macro _setup
+ ldr r0,=VAE_MAC7100_FlashSecurity
+ _led_init
+ _memory_remap
+ _pclock_init
+ _pio_init
+ .endm
+
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+
+#else
+
+ .macro _setup
+ _led_init
+ _led 16
+ _pclock_init
+ _pio_init
+ .endm
+
+#endif
+
+#define PLATFORM_SETUP1 _setup
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H
--- /dev/null
+#ifndef CYGONCE_HAL_MACE1_MISC_H
+#define CYGONCE_HAL_MACE1_MISC_H
+//=============================================================================
+//
+// mace1_misc.h
+//
+// MACE1 board specific functions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-02-03
+// Purpose: MACE1 board specific registers
+// Description:
+// Usage: #include <cyg/hal/mece1_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+void hal_mace1_set_leds(int);
+void hal_mace1_led_on(int);
+void hal_mace1_led_off(int);
+int hal_mace1_get_leds(void);
+
+#define HAL_MAC7100_SET_LEDS(x) hal_mace1_set_leds(x)
+#define HAL_MAC7100_LED_ON(x) hal_mace1_led_on(x)
+#define HAL_MAC7100_LED_OFF(x) hal_mace1_led_off(x)
+#define HAL_MAC7100_GET_LEDS(x) hal_mace1_get_leds(x)
+
+
+//-----------------------------------------------------------------------------
+// end of mace1_misc.h
+#endif // CYGONCE_HAL_MACE1_MISC_H
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+// Initially RAM is at 0x40000000 but we ramap to 0x0
+#define CYGMEM_REGION_ram (0x00000000)
+#define CYGMEM_REGION_ram_SIZE (0x00008000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x20000000)
+#define CYGMEM_REGION_rom_SIZE (0x80000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE \
+ ((CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE) - \
+ (size_t) CYG_LABEL_NAME (__heap1))
+
--- /dev/null
+// eCos memory layout - Wed Apr 11 13:49:55 2001
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+ ram : ORIGIN = 0x00000000, LENGTH = 0x8000
+ rom : ORIGIN = 0x20000000, LENGTH = 0x80000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_rom_vectors (rom, 0x20000000, LMA_EQ_VMA)
+
+// MAC7100 Flash Security
+// Following section is manually added to address MAC7100 flash security area
+// It should actually be something like this
+// SECTION_sgfm_config (rom, 0x20000400, LMA_EQ_VMA)
+
+ .mac7100_flash_security 0x20000400 : { KEEP (*(.mac7100_flash_security))} > rom
+
+// END MAC7100 Flash Security
+
+ SECTION_text (rom, ALIGN (0x1), LMA_EQ_VMA)
+ SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+
+ SECTION_fixed_vectors (ram, 0x00000020, LMA_EQ_VMA)
+ SECTION_data (ram, ALIGN(0x4), FOLLOWING(.gcc_except_table))
+ SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_IO_H
+#define CYGONCE_HAL_PLF_IO_H
+//=============================================================================
+//
+// plf_io.h
+//
+// MACE1 board specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-02-03
+// Purpose: MACE1 board specific registers
+// Description:
+// Usage: #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+// On-chip device base addresses
+
+#define CYGARC_PHYSICAL_ADDRESS(_x_)
+
+#endif // CYGONCE_HAL_PLF_IO_H
+//-----------------------------------------------------------------------------
+// end of plf_io.h
--- /dev/null
+//==========================================================================
+//
+// mace1_misc.c
+//
+// HAL misc board support code for MACE1 board
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-12
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/hal/hal_io.h> // low level i/o
+#include <cyg/hal/var_io.h> // common registers
+#include <cyg/hal/plf_io.h> // platform registers
+#include <cyg/hal/mace1_misc.h> // mace1 misc functions
+
+void
+hal_mace1_set_leds(int val)
+{
+ HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET),
+ ((val<<8)&0xff00)); // turn all LEDs off
+}
+
+void
+hal_mace1_led_on(int val)
+{
+ cyg_uint16 leds;
+
+ // read old LED state
+ HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds);
+ leds|=1<<(8+val);
+ // Write new state
+ HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds);
+}
+
+void
+hal_mace1_led_off(int val)
+{
+ cyg_uint16 leds;
+
+ // read old LED state
+ HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds);
+ leds&=~(1<<(8+val));
+ // Write new state
+ HAL_WRITE_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds);
+}
+
+int
+hal_mace1_get_leds(void)
+{
+ cyg_uint16 leds = 0;
+
+ // read old LED state
+ HAL_READ_UINT16(MAC7100_PIM_PORTDATA(MAC7100_PORT_A_OFFSET), leds);
+ return (leds>>8)&0xFF;
+}
+
+//--------------------------------------------------------------------------
+// EOF mace1_misc.c
--- /dev/null
+2007-01-10 Ilija Koco <ilijak@siva.com.mk>
+
+ * hal_arm_mac7100.cdl: added property
+ "requires CYGPKG_IO_SERIAL_FREESCALE_ESCI_H"
+
+2006-08-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * var_io.h: Freescale eSCI platform dependent clock related macros
+ moved here from ser_esci.h
+
+2006-06-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * hal_var_setup.h: (new) Assembly macros shared between targets.
+ * cdl/hal_arm_mac7100.cdl: some defaults changed in favour of
+ MAC7100EVB
+
+2006-05-24 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/hal_arm_mac7100.cdl:
+ * include/hal_cache.h:
+ * include/hal_diag.h:
+ * include/mac7100_misc.h:
+ * include/plf_stub.h: unchanged from AT91
+ * include/var_arch.h:
+ * include/var_io.h:
+ * src/flash_security.S:
+ * src/hal_diag.c:
+ * src/mac7100_misc.c
+ New variant port - based on at91 variant by Gary Thomas
+
+//===========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_arm_mac7100.cdl
+#
+# Freescale MAC7100 HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+## Copyright (C) 2006 eCosCentric Ltd
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Contributors:
+# Date: 2006-02-03
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_MAC7100 {
+ display "Freescale MAC7100 variant HAL"
+ parent CYGPKG_HAL_ARM
+ define_header hal_arm_mac7100.h
+ include_dir cyg/hal
+ hardware
+ description "
+ The MAC7100 HAL package provides the support needed to run
+ eCos on Freescale MAC7100 based targets."
+
+ compile flash_security.S hal_diag.c mac7100_misc.c
+
+ implements CYGINT_HAL_DEBUG_GDB_STUBS
+ implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+ implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+ implements CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
+ implements CYGINT_HAL_ARM_ARCH_ARM7
+ implements CYGINT_HAL_ARM_THUMB_ARCH
+ implements CYGINT_HAL_ARM_BIGENDIAN
+
+ requires CYGHWR_HAL_ARM_BIGENDIAN == 1
+
+ requires CYGPKG_IO_SERIAL_FREESCALE_ESCI_H
+
+ # Let the architectural HAL see this variant's files
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
+ puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_ARCH_H"
+ }
+
+ cdl_option CYGHWR_HAL_ARM_MAC7100 {
+ display "MAC7100 variant used"
+ flavor data
+ default_value {"MAC7111"}
+ legal_values {"MAC7111" "MAC7121" "MAC7116" }
+ description "
+ The MAC7100 microcontroller family has several variants,
+ the main differences being the amount of on-chip SRAM,
+ peripherals and their layout. This option allows the
+ platform HALs to select the specific microcontroller being
+ used."
+ }
+
+ cdl_option CYGHWR_HAL_ARM_MAC7100_FIQ {
+ display "handle FIQ as an IRQ"
+ flavor bool
+ default_value 0
+ description "
+ Enable this option if you need to handle FIQ interrupts in the
+ normal way, i.e. a FIQ interrupt will be treated as a normal IRQ
+ using the highest priority
+ "
+ }
+
+ cdl_option CYGHWR_HAL_ARM_MAC7100_INTC_FIQDEF {
+ display "Set FIQDEF"
+ flavor data
+ default_value CYGHWR_HAL_ARM_MAC7100_FIQ ? 14 : 16
+ legal_values 0 to 32
+ description "
+ Set maximum level that shall be routed to IRQ.
+ "
+ }
+
+ cdl_option CYGHWR_HAL_ARM_MAC7100_INTC_EMASK {
+ display "enable INTC to automatically handle CLMASK"
+ flavor data
+ default_value 0x20
+ legal_values 0x00 0x20
+ description "
+ Enable this option if you need INTC to automatically mask
+ lower level IRQ.
+
+ - 0x00 - disable
+ - 0x20 - enable
+
+ "
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+// hal_cache.h
+//
+// HAL cache control API
+//
+//=============================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg, gthomas
+// Contributors: nickg, gthomas
+// Date: 1998-09-28
+// Purpose: Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+// cache control operations.
+// Usage:
+// #include <cyg/hal/hal_cache.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Cache dimensions
+
+// Data cache
+//#define HAL_DCACHE_SIZE 0 // Size of data cache in bytes
+//#define HAL_DCACHE_LINE_SIZE 0 // Size of a data cache line
+//#define HAL_DCACHE_WAYS 0 // Associativity of the cache
+
+// Instruction cache
+//#define HAL_ICACHE_SIZE 0 // Size of cache in bytes
+//#define HAL_ICACHE_LINE_SIZE 0 // Size of a cache line
+//#define HAL_ICACHE_WAYS 0 // Associativity of the cache
+
+//#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+//#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Purge contents of data cache
+#define HAL_DCACHE_PURGE_ALL()
+
+// Query the state of the data cache (does not affect the caching)
+#define HAL_DCACHE_IS_ENABLED(_state_) \
+ CYG_MACRO_START \
+ (_state_) = 0; \
+ CYG_MACRO_END
+
+// Set the data cache refill burst size
+//#define HAL_DCACHE_BURST_SIZE(_size_)
+
+// Set the data cache write mode
+//#define HAL_DCACHE_WRITE_MODE( _mode_ )
+
+//#define HAL_DCACHE_WRITETHRU_MODE 0
+//#define HAL_DCACHE_WRITEBACK_MODE 1
+
+// Load the contents of the given address range into the data cache
+// and then lock the cache so that it stays there.
+//#define HAL_DCACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+//#define HAL_DCACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+//#define HAL_DCACHE_UNLOCK_ALL()
+
+//-----------------------------------------------------------------------------
+// Data cache line control
+
+// Allocate cache lines for the given address range without reading its
+// contents from memory.
+//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory and invalidate the cache entries
+// for the given address range.
+//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory for the given address range.
+//#define HAL_DCACHE_STORE( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of reading
+// from it later.
+//#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of writing
+// to it later.
+//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
+
+// Allocate and zero the cache lines associated with the given range.
+//#define HAL_DCACHE_ZERO( _base_ , _size_ )
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+// Query the state of the instruction cache (does not affect the caching)
+#define HAL_ICACHE_IS_ENABLED(_state_) \
+ CYG_MACRO_START \
+ (_state_) = 0; \
+ CYG_MACRO_END
+
+// Set the instruction cache refill burst size
+//#define HAL_ICACHE_BURST_SIZE(_size_)
+
+// Load the contents of the given address range into the instruction cache
+// and then lock the cache so that it stays there.
+//#define HAL_ICACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+//#define HAL_ICACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+//#define HAL_ICACHE_UNLOCK_ALL()
+
+//-----------------------------------------------------------------------------
+// Instruction cache line control
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
--- /dev/null
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+
+//=============================================================================
+//
+// hal_diag.h
+//
+// HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, gthomas, tkoeller, ilijak
+// Date: 2001-07-12
+// Purpose: HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage: #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+//-----------------------------------------------------------------------------
+// LED
+externC void hal_diag_led(int mask);
+
+//-----------------------------------------------------------------------------
+// delay
+
+externC void hal_delay_us(cyg_int32 usecs);
+#define HAL_DELAY_US(n) hal_delay_us(n);
+
+//-----------------------------------------------------------------------------
+// reset
+
+extern void hal_mac7100_reset_cpu(void);
+
+//-----------------------------------------------------------------------------
+// end of hal_diag.h
+#endif // CYGONCE_HAL_DIAG_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_SETUP_H
+#define CYGONCE_HAL_VAR_SETUP_H
+
+//=============================================================================
+//
+// hal_var_setup.h
+//
+// Variant specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-06-05
+// Purpose: MAC7100 variant specific support routines
+// Description:
+// Usage: in <cyg/hal/hal_platform_serup.h> include following:
+// #include <cyg/hal/hal_var_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+// Clock initilalization
+// Initialize PLL
+#if defined(CYGNUM_HAL_ARM_MAC7100_FDIV) // Divider set by user.
+# define MAC7100_CRG_REFDV_VAL (CYGNUM_HAL_ARM_MAC7100_FDIV-1)
+#else // Divider calculated.
+ //NOTE: works for f_osc <= 8MHz
+# define MAC7100_CRG_REFDV_VAL (((CYGNUM_HAL_ARM_MAC7100_F_OSC/500000) - 1) & 0x0F) // 15 (1)
+#endif
+#define MAC7100_CRG_SYNR_VAL (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED / 2 / \
+ (CYGNUM_HAL_ARM_MAC7100_F_OSC / (MAC7100_CRG_REFDV_VAL+1))-1) // 47 (5)
+
+#define MAC7100_CRG_PLLCTL_VAL \
+ (MAC7100_CRG_CME|MAC7100_CRG_PLLON|MAC7100_CRG_AUTO| \
+ MAC7100_CRG_ACQ|MAC7100_CRG_SCME)
+#define MAC7100_CRG_CLKSEL_VAL (MAC7100_CRG_PLLSEL)
+
+ .macro _mac7100_setpll
+ ldr r2,=MAC7100_CRG_BASE
+ mov r3,#0
+ // Disable clock interrupts
+ strb r3,[r2,#(MAC7100_CRG_CRGINT-MAC7100_CRG_BASE)]
+ // DeSelect PLL clock
+ mov r3,#MAC7100_CRG_REFDV_VAL
+ // Reference Divider reg.
+ strb r3,[r2,#(MAC7100_CRG_REFDV-MAC7100_CRG_BASE)]
+ mov r3,#MAC7100_CRG_SYNR_VAL
+ // Synthesizer register
+ strb r3,[r2,#(MAC7100_CRG_SYNR-MAC7100_CRG_BASE)]
+ mov r3,#MAC7100_CRG_PLLCTL_VAL
+ // PLL control register
+ strb r3,[r2,#(MAC7100_CRG_PLLCTL-MAC7100_CRG_BASE)]
+ // Wait PLL lock <-----------------------------------<
+1: ldrb r3,[r2,#(MAC7100_CRG_CRGFLG-MAC7100_CRG_BASE)]
+ tst r3,#MAC7100_CRG_LOCK
+ bne 2f // PLL locked, GO ON ---------->>
+ b 1b // Still waiting for PLL lock ------------>
+2: mov r3,#MAC7100_CRG_CLKSEL_VAL // <<-------<<
+ // Select PLL clock
+ strb r3,[r2,#(MAC7100_CRG_CLKSEL-MAC7100_CRG_BASE)]
+ mov r3,#0
+ strb r3,[r2,#(MAC7100_CRG_BDMCTL-MAC7100_CRG_BASE)] // Set CRG BDMCTL
+ mov r3,r3
+ .endm
+
+// Memory re-mapping for single chip configuration
+// Re-map internal memory so that vectors can reside in RAM.
+// RAM base 0x00000000 (as well as 0x40000000)
+// Flash base 0x20000000
+ .macro _mac7100_remap_single_chip
+ _led 1
+ ldr r1, _mac7100_teleport
+ ldr r0, [r1] //AAMR Register
+
+ mvn r4, #0xf0000000 // 1.Copy telepoter to RAM
+ ldr r2, _mac7100_teleport+4 // TelePorter
+ ldr r3, _mac7100_teleport+8 // TelePort (TelePorter end)
+ and r2,r2,r4
+ and r3,r3,r4
+ mov r4, #0x40000000 // RAM address
+1: // Copy teleporter: // copying teleporter <---<
+ ldr r5,[r2],#4
+ str r5,[r4],#4
+ cmp r2,r3
+ bne 1b // Copy teleporter -------->
+ ldr r3,_mac7100_teleport+12
+ mov pc,#0x40000000 // 2.Jump to _mac7100_teleporter in RAM
+_mac7100_teleporter:
+ bic r0,r0,#0x000000ff // 3.Re-map memory
+ orr r0,r0,#0x8b // Flash -> 0x20000000
+ str r0,[r1] // RAM -> 0x00000000 and 0x40000000
+ mov pc,r3 // 4.Teleport back to Flash
+_mac7100_teleport:
+ .long MAC7100_MCM_AAMR
+ .long _mac7100_teleporter
+ .long _mac7100_teleport
+ .long _mac7100_teleport_return
+_mac7100_teleport_return:
+ .endm
+
+// End memory re-mapping for single chip configuration
+
+//-----------------------------------------------------------------------------
+// end of hal_var_setup.h
+#endif // CYGONCE_HAL_VAR_SETUP_H
--- /dev/null
+#ifndef CYGONCE_HAL_MAC7100_MISC_H
+#define CYGONCE_HAL_MAC7100_MISC_H
+//=============================================================================
+//
+// mac7100_misc.h
+//
+// Variant specific functions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) eCosCentric Ltd
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-02-03
+// Purpose: MAC7100 specific hal functions
+// Description:
+// Usage: #include <cyg/hal/mac7100_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// *********************************************************************
+//
+// ESCI Module
+//
+// *********************************************************************
+
+externC void hal_mac7100_esci_pins(cyg_uint32 i_esci);
+
+#endif // CYGONCE_HAL_MAC7100_MISC_H
+// end of mac7100_misc.h
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+// plf_stub.h
+//
+// Platform header for GDB stub support.
+//
+//=============================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, gthomas
+// Date: 2001-07-12
+// Purpose: Platform HAL stub support for MAC7100 based boards.
+// Usage: #include <cyg/hal/plf_stub.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM
+
+#include <cyg/hal/arm_stub.h> // architecture stub support
+
+//----------------------------------------------------------------------------
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() CYG_EMPTY_STATEMENT
+
+//----------------------------------------------------------------------------
+// Stub initializer.
+#define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+//=============================================================================
+//
+// var_arch.h
+//
+// MAC7100 variant architecture overrides
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Jonathan Larmour <jifl@eCosCentric.com>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-02-03
+// Purpose: MAC7100 variant architecture overrides
+// Description:
+// Usage: #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_io.h>
+
+//--------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor. These implementations halt the system core clock.
+
+#ifndef HAL_IDLE_THREAD_ACTION
+
+// No idle action
+
+#endif
+
+#endif // CYGONCE_HAL_VAR_ARCH_H
+//-----------------------------------------------------------------------------
+// end of var_arch.h
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_IO_H
+#define CYGONCE_HAL_VAR_IO_H
+//=============================================================================
+//
+// var_io.h
+//
+// Variant specific registers
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-02-03
+// Purpose: MAC7100 variant specific registers
+// Description: based on freescale's mac7100.h
+// Usage: #include <cyg/hal/var_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/plf_io.h>
+
+#if !defined HAL_IO_MACROS_NO_ADDRESS_MUNGING
+#define HAL_IO_MACROS_NO_ADDRESS_MUNGING 1
+#endif // HAL_IO_MACROS_NO_ADDRESS_MUNGING
+
+// *********************************************************************
+//
+// INTC Module
+//
+// *********************************************************************
+
+// Interrupt Controller Definitions
+#define MAC7100_INTC_BASE (0xFC048000)
+
+#define MAC7100_IPRH_OFFSET (0x0000)
+#define MAC7100_IPRL_OFFSET (0x0004)
+#define MAC7100_IMRH_OFFSET (0x0008)
+#define MAC7100_IMRL_OFFSET (0x000C)
+#define MAC7100_INTFRCH_OFFSET (0x0010)
+#define MAC7100_INTFRCL_OFFSET (0x0014)
+#define MAC7100_ICONFIG_OFFSET (0x001B)
+#define MAC7100_SIMR_OFFSET (0x001C)
+#define MAC7100_CIMR_OFFSET (0x001D)
+#define MAC7100_CLMASK_OFFSET (0x001E) // CLMASK - Current Level Mask Register
+#define MAC7100_SLMASK_OFFSET (0x001F) // SLMASK - Saved Level Mask Register
+#define MAC7100_ICR_OFFSET (0x0040)
+#define MAC7100_IRQIACK_OFFSET (0x00EC)
+#define MAC7100_FIQIACK_OFFSET (0x00F0)
+
+#define MAC7100_INTC_IPRH(intc_base) (intc_base + MAC7100_IPRH_OFFSET)
+#define MAC7100_INTC_IPRL(intc_base) (intc_base + MAC7100_IPRL_OFFSET)
+#define MAC7100_INTC_IMRH(intc_base) (intc_base + MAC7100_IMRH_OFFSET)
+#define MAC7100_INTC_IMRL(intc_base) (intc_base + MAC7100_IMRL_OFFSET)
+#define MAC7100_INTC_INTFRC(intc_base) (intc_base + MAC7100_INTFRCH_OFFSET)
+#define MAC7100_INTC_INTFRCH(intc_base) (intc_base + MAC7100_INTFRCH_OFFSET)
+#define MAC7100_INTC_INTFRCL(intc_base) (intc_base + MAC7100_INTFRCL_OFFSET)
+#define MAC7100_INTC_ICONFIG(intc_base) (intc_base + MAC7100_ICONFIG_OFFSET)
+#define MAC7100_INTC_IRQIACK(intc_base) (intc_base + MAC7100_IRQIACK_OFFSET)
+#define MAC7100_INTC_FIQIACK(intc_base) (intc_base + MAC7100_FIQIACK_OFFSET)
+#define MAC7100_INTC_ICR(intc_base,src) (intc_base + MAC7100_ICR_OFFSET + src)
+#define MAC7100_INTC_SIMR(intc_base) (intc_base + MAC7100_SIMR_OFFSET)
+#define MAC7100_INTC_CIMR(intc_base) (intc_base + MAC7100_CIMR_OFFSET)
+#define MAC7100_INTC_CLMASK(intc_base) (intc_base + MAC7100_CLMASK_OFFSET)
+#define MAC7100_INTC_SLMASK(intc_base) (intc_base + MAC7100_SLMASK_OFFSET)
+
+#define MAC7100_INTC_INT_LEVEL(lev) (lev)
+
+// hardware interrupt source vector numbers
+#define MAC7100_EDMA0_IV (0)
+#define MAC7100_EDMA1_IV (1)
+#define MAC7100_EDMA2_IV (2)
+#define MAC7100_EDMA3_IV (3)
+#define MAC7100_EDMA4_IV (4)
+#define MAC7100_EDMA5_IV (5)
+#define MAC7100_EDMA6_IV (6)
+#define MAC7100_EDMA7_IV (7)
+#define MAC7100_EDMA8_IV (8)
+#define MAC7100_EDMA9_IV (9)
+#define MAC7100_EDMA10_IV (10)
+#define MAC7100_EDMA11_IV (11)
+#define MAC7100_EDMA12_IV (12)
+#define MAC7100_EDMA13_IV (13)
+#define MAC7100_EDMA14_IV (14)
+#define MAC7100_EDMA15_IV (15)
+#define MAC7100_EDMA_Error_IV (16)
+#define MAC7100_MCM_SWT_IV (17)
+#define MAC7100_CRG_IV (18)
+#define MAC7100_PIT1_IV (19)
+#define MAC7100_PIT2_IV (20)
+#define MAC7100_PIT3_IV (21)
+#define MAC7100_PIT4_RTI_IV (22)
+#define MAC7100_VREG_IV (23)
+#define MAC7100_CAN_A_MB_IV (24)
+#define MAC7100_CAN_A_MB14_IV (25)
+#define MAC7100_CAN_A_Error_IV (26)
+#define MAC7100_CAN_B_MB_IV (27)
+#define MAC7100_CAN_B_MB14_IV (28)
+#define MAC7100_CAN_B_Error_IV (29)
+#define MAC7100_CAN_C_MB_IV (30)
+#define MAC7100_CAN_C_MB14_IV (31)
+#define MAC7100_CAN_C_Error_IV (32)
+#define MAC7100_CAN_D_MB_IV (33)
+#define MAC7100_CAN_D_MB14_IV (34)
+#define MAC7100_CAN_D_Error_IV (35)
+#define MAC7100_I2C_IV (36)
+#define MAC7100_DSPI_A_IV (37)
+#define MAC7100_DSPI_B_IV (38)
+#define MAC7100_ESCI_A_IV (39)
+#define MAC7100_ESCI_B_IV (40)
+#define MAC7100_ESCI_C_IV (41)
+#define MAC7100_ESCI_D_IV (42)
+#define MAC7100_EMIOS0_IV (43)
+#define MAC7100_EMIOS1_IV (44)
+#define MAC7100_EMIOS2_IV (45)
+#define MAC7100_EMIOS3_IV (46)
+#define MAC7100_EMIOS4_IV (47)
+#define MAC7100_EMIOS5_IV (48)
+#define MAC7100_EMIOS6_IV (49)
+#define MAC7100_EMIOS7_IV (50)
+#define MAC7100_EMIOS8_IV (51)
+#define MAC7100_EMIOS9_IV (52)
+#define MAC7100_EMIOS10_IV (53)
+#define MAC7100_EMIOS11_IV (54)
+#define MAC7100_EMIOS12_IV (55)
+#define MAC7100_EMIOS13_IV (56)
+#define MAC7100_EMIOS14_IV (57)
+#define MAC7100_EMIOS15_IV (58)
+#define MAC7100_ATD_IV (59)
+#define MAC7100_CFM_IV (60)
+#define MAC7100_PIM_IV (61)
+#define MAC7100_IRQ_IV (62)
+#define MAC7100_XIRQ_IV (63)
+
+#define MAC7100_IRQ_SPURIOUS (-1)
+
+// *******************************************************************
+//
+// eSCI Module
+// Note: eSCI definitions are in cyg/devs/ser_esci.h
+// *******************************************************************
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE 0xFC0C4000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_VECTOR MAC7100_ESCI_A_IV
+
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE 0xFC0C8000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_VECTOR MAC7100_ESCI_B_IV
+
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE 0xFC0CC000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_VECTOR MAC7100_ESCI_C_IV
+
+#define CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE 0xFC0D0000
+#define CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_VECTOR MAC7100_ESCI_D_IV
+
+#define CYGNUM_DEV_SER_FREESCALE_ESCI_SYSTEM_CLOCK \
+ (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED/2)
+#define FREESCALE_ESCI_BAUD(baud_rate) \
+ ((CYGNUM_DEV_SER_FREESCALE_ESCI_SYSTEM_CLOCK)/(baud_rate*16))
+
+
+// *********************************************************************
+//
+// PIT Module
+//
+// *********************************************************************
+
+// Periodic Interrupt Timer Module Definitions
+
+#define MAC7100_PIT_BASE (0xFC08C000)
+#define MAC7100_TLVAL0_OFFSET (0x0000)
+#define MAC7100_TVAL0_OFFSET (0x0080)
+
+#define MAC7100_PIT_TLVAL(pit_base,chan) \
+ (pit_base + MAC7100_TLVAL0_OFFSET + (4 * chan))
+#define MAC7100_PIT_TVAL(pit_base,chan) \
+ (pit_base + MAC7100_TVAL0_OFFSET + (4 * chan))
+
+#define MAC7100_PITFLG_OFFSET (0x0100)
+#define MAC7100_PITINTEN_OFFSET (0x0104)
+#define MAC7100_PITINTSEL_OFFSET (0x0108)
+#define MAC7100_PITEN_OFFSET (0x010C)
+#define MAC7100_PITCTRL_OFFSET (0x0110)
+
+#define MAC7100_PIT_FLAG_RTIF (0x00000001)
+#define MAC7100_PIT_FLAG_TIF(chan) (0x00000001 << chan)
+#define MAC7100_PIT_INTSEL_ISEL(chan) (0x00000001 << chan)
+#define MAC7100_PIT_INTEN_RTIE (0x00000001)
+#define MAC7100_PIT_INTEN_TIE(chan) (0x00000001 << chan)
+
+#define MAC7100_PIT_EN_RTIEN (0x00000001)
+#define MAC7100_PIT_EN_PEN(chan) (0x00000001 << chan)
+
+#define MAC7100_PIT_FLG(pit_base) (pit_base + MAC7100_PITFLG_OFFSET)
+#define MAC7100_PIT_INTEN(pit_base) (pit_base + MAC7100_PITINTEN_OFFSET)
+#define MAC7100_PIT_INTSEL(pit_base) (pit_base + MAC7100_PITINTSEL_OFFSET)
+#define MAC7100_PIT_EN(pit_base) (pit_base + MAC7100_PITEN_OFFSET)
+
+#define MAC7100_PIT_CTRL(pit_base) (pit_base + MAC7100_PITCTRL_OFFSET)
+#define MAC7100_PIT_MDIS (0x01000000)
+
+
+// *********************************************************************
+//
+// PIM Module
+//
+// *********************************************************************/
+
+#define MAC7100_PIM_BASE (0xFC0E8000)
+
+#define MAC7100_PORT_A_OFFSET (0x000)
+#define MAC7100_PORT_B_OFFSET (0x040)
+#define MAC7100_PORT_C_OFFSET (0x080)
+#define MAC7100_PORT_D_OFFSET (0x0C0)
+#define MAC7100_PORT_E_OFFSET (0x100)
+#define MAC7100_PORT_F_OFFSET (0x140)
+#define MAC7100_PORT_G_OFFSET (0x180)
+#define MAC7100_PORT_H_OFFSET (0x1C0)
+#define MAC7100_PORT_I_OFFSET (0x200)
+
+// PORT Pin Configuration Registers
+#define MAC7100_PIM_CONFIG(port,pin) (MAC7100_PIM_BASE+port+((pin)*2))
+// Port Wide Interrupt Flag Register
+#define MAC7100_PIM_PORTIFR(port) (MAC7100_PIM_BASE+port+0x20)
+// Port Wide Data Read/Write Register
+#define MAC7100_PIM_PORTDATA(port) (MAC7100_PIM_BASE+port+0x24)
+// Port Wide Input Register
+#define MAC7100_PIM_PORTIR(port) (MAC7100_PIM_BASE+port+0x26)
+// Port Pin Data Registers
+#define MAC7100_PIM_DATA(port,pin) (MAC7100_PIM_BASE+port+0x28+pin)
+
+// Global Interrupt Status Register
+#define MAC7100_PIM_GLBLINT (MAC7100_PIM_BASE+0x03C0)
+// PIM Configuration Register
+#define MAC7100_PIM_PIMCONFIG (MAC7100_PIM_BASE+0x03C2)
+// TDI Pin Configuration Register
+#define MAC7100_PIM_CONFIG_TDI (MAC7100_PIM_BASE+0x03C4)
+// TDO Pin Configuration Register
+#define MAC7100_PIM_CONFIG_TDO (MAC7100_PIM_BASE+0x03C6)
+// TMS Pin Configuration Register
+#define MAC7100_PIM_CONFIG_TMS (MAC7100_PIM_BASE+0x03C8)
+// TCK Pin Configuration Register
+#define MAC7100_PIM_CONFIG_TCK (MAC7100_PIM_BASE+0x03CA)
+// TA Pin Configuration Register
+#define MAC7100_PIM_CONFIG_TA (MAC7100_PIM_BASE+0x03CC)
+
+// Bit definitions and macros for PIM_PA_CONFIGn
+// Pin Interrupt Flag Register
+#define MAC7100_PIM_PIFR (0x0001)
+// Pin Interrupt Enable Register
+#define MAC7100_PIM_PIER (0x0002)
+// Pull-up/down Enable Register
+#define MAC7100_PIM_PULL(x) (((x)&0x0003)<<2)
+// Reduced Drive Strength Register
+#define MAC7100_PIM_RDR (0x0010)
+// Open Drain Enable Register
+#define MAC7100_PIM_ODER (0x0020)
+// Data Direction Register
+#define MAC7100_PIM_DDR (0x0040)
+#define MAC7100_PIM_MODE (0x0080)
+#define MAC7100_PIM_MODE_PERIPHERAL MAC7100_PIM_MODE
+
+// Bit definitions and macros for PIM_GLBLINT
+// Interrupt Pending
+#define MAC7100_PIM_INT_PENDING(x) (((x)&0x01FF)<<0)
+
+// Bit definitions and macros for PIM_PIMCONFIG
+// Clock Enable for the EIM module
+#define MAC7100_PIM_PORTHSEL (0x0001)
+// Port H Select
+#define MAC7100_PIM_EIMCLKEN (0x0002)
+
+#define MAC7100_PIM_PORT32IR(port32ir) (MAC7100_PIM_BASE+0x03E0+port32ir)
+
+#define MAC7100_PIM_PORT32IR_AB (0x00)
+#define MAC7100_PIM_PORT32IR_CD (0x04)
+#define MAC7100_PIM_PORT32IR_EF (0x08)
+#define MAC7100_PIM_PORT32IR_GH (0x0C)
+#define MAC7100_PIM_PORT32IR_BC (0x10)
+#define MAC7100_PIM_PORT32IR_DE (0x14)
+#define MAC7100_PIM_PORT32IR_FG (0x18)
+#define MAC7100_PIM_PORT32IR_HI (0x1C)
+
+
+// ********************************************************************
+//
+// CRG Module
+//
+// ********************************************************************
+
+// Register read/write macros
+#define MAC7100_CRG_BASE 0xFC088000 // SYNR - Synthesizer Register
+#define MAC7100_CRG_SYNR 0xFC088000 // SYNR - Synthesizer Register
+#define MAC7100_CRG_REFDV 0xFC088001 // REFDV - Reference Divider Register
+#define MAC7100_CRG_CTFLG 0xFC088002 // CTFLG - Test Flags Register (reserved)
+#define MAC7100_CRG_CRGFLG 0xFC088003 // CRGFLG - Flags Register
+#define MAC7100_CRG_CRGINT 0xFC088004 // CRGINT - Interrupt Enable Register
+#define MAC7100_CRG_CLKSEL 0xFC088005 // CLKSEL - Clock Select Register
+#define MAC7100_CRG_PLLCTL 0xFC088006 // PLLCTL - PLL Control Register
+#define MAC7100_CRG_SDMCTL 0xFC088007 // SDMCTL - STOP/DOZE Control Register
+#define MAC7100_CRG_BDMCTL 0xFC088008 // BDMCTL - BDM Control Register
+#define MAC7100_CRG_FORBYP 0xFC088009 // FORBYP - Force and Bypass Test
+#define MAC7100_CRG_CTCTL 0xFC08800A // CTCTL - Test Control Register (resvd)
+
+// Bit definitions and macros for CRG_SYNR
+#define MAC7100_CRG_SYN(x) (((x)&0x3F)<<0) // Synthesizer Count value
+
+// Bit definitions and macros for CRG_REFDV
+#define MAC7100_CRG_REFD(x) (((x)&0x0F)<<0) //Reference divider
+
+// Bit definitions and macros for CRG_CRGFLG
+#define MAC7100_CRG_SCM (0x01) //Self Clock Mode Status
+#define MAC7100_CRG_SCMIF (0x02) //Self Clock Mode Interrupt Flag
+#define MAC7100_CRG_TRACK (0x04) //Track Status
+#define MAC7100_CRG_LOCK (0x08) //Lock Status
+#define MAC7100_CRG_LOCKIF (0x10) //PLL Lock Interrupt Flag
+#define MAC7100_CRG_LVRF (0x20) //Low Voltage Reset Flag
+#define MAC7100_CRG_PORF (0x40) //Power on Reset Flag
+#define MAC7100_CRG_STPEF (0x80) //Stop Entry Flag
+
+// Bit definitions and macros for CRG_CRGINT
+#define MAC7100_CRG_SCMIE (0x02) //Self Clock Mode Interrupt Enable
+#define MAC7100_CRG_LOCKIE (0x10) //Lock Interrupt Enable
+
+// Bit definitions and macros for CRG_CLKSEL
+#define MAC7100_CRG_SWTDOZE (0x01) //SWT stops in Doze Mode
+#define MAC7100_CRG_RTIDOZE (0x02) /* RTI stops in Doze Mode */
+#define MAC7100_CRG_PLLDOZE (0x08) /* PLL stops in Doze Mode */
+#define MAC7100_CRG_DOZE_ROA (0x10) /* Reduced Osc Amp in Doze Mode */
+#define MAC7100_CRG_PSTP (0x40) /* Pseudo Stop */
+#define MAC7100_CRG_PLLSEL (0x80) /* PLL Select */
+
+// Bit definitions and macros for CRG_PLLCTL
+#define MAC7100_CRG_SCME (0x01) //Self Clock Mode Enable
+#define MAC7100_CRG_PWE (0x02) //SWT Enable during Pseudo Stop
+#define MAC7100_CRG_PRE (0x04) //RTI Enable during Pseudo Stop
+#define MAC7100_CRG_FSTWKP (0x08) //Fast Wake-up from Full Stop Bit
+#define MAC7100_CRG_ACQ (0x10) //Acquisition
+#define MAC7100_CRG_AUTO (0x20) //Automatic Bandwidth Control
+#define MAC7100_CRG_PLLON (0x40) //Phase Lock Loop On
+#define MAC7100_CRG_CME (0x80) //Clock Monitor Enable
+
+// Bit definitions and macros for CRG_SDMCTL
+#define MAC7100_CRG_STOP (0x01) //STOP mode
+#define MAC7100_CRG_DOZE (0x02) //DOZE mode
+
+// Bit definitions and macros for CRG_BDMCTL
+#define MAC7100_CRG_RSBCK (0x40) //SWT & RTI stop in Active BDM mode
+
+
+// *********************************************************************
+//
+// MCM Module
+//
+// *********************************************************************
+
+// Register read/write macros
+#define MAC7100_MCM_PCT 0xFC040000 //
+#define MAC7100_MCM_REV 0xFC040002 //
+#define MAC7100_MCM_AMC 0xFC040004 //
+#define MAC7100_MCM_ASC 0xFC040006 //
+#define MAC7100_MCM_IMC 0xFC040008 //
+// MRSR - Miscellaneous Reset Status Register
+#define MAC7100_MCM_MRSR 0xFC04000F
+// MWCR - Miscellaneous Wakeup Control Register
+#define MAC7100_MCM_MWCR 0xFC040013
+// MSWTCR - Miscellaneous Software Watchdog Timer Control Register
+#define MAC7100_MCM_MSWTCR 0xFC040016
+// MSWTSR - Miscellaneous Software Watchdog Timer Service Register
+#define MAC7100_MCM_MSWTSR 0xFC04001B
+// MSWTIR - Miscellaneous Software Watchdog Timer Interrupt Register
+#define MAC7100_MCM_MSWTIR 0xFC04001F
+// AAMR - AXBS Address Map Register
+#define MAC7100_MCM_AAMR 0xFC040020
+// CFADR - Core Fault Address Register
+#define MAC7100_MCM_CFADR 0xFC040070
+// CFLOC - Core Fault Location Register
+#define MAC7100_MCM_CFLOC 0xFC040076
+// CFATR - Core Fault Attributes Register
+#define MAC7100_MCM_CFATR 0xFC040077
+// CFDTR - Core Fault Data Register
+#define MAC7100_MCM_CFDTR 0xFC04007C
+
+// Bit definitions and macros for MCM_AMC
+
+// AXBS Master Configuration
+#define MAC7100_MCM_AXMC(x) (((x)&0x00FF)<<0)
+
+// Bit definitions and macros for MCM_ASC
+// AXBS Slave Configuration
+#define MAC7100_MCM_AXSC(x) (((x)&0x00FF)<<0)
+#define MAC7100_MCM_DP64 (0x8000) // 64-bit Datapath
+
+// Bit definitions and macros for MCM_MRSR
+#define MAC7100_MCM_SWTR (0x20) // Watchdog Timer Reset
+#define MAC7100_MCM_DIR (0x40) // Device Input Reset
+#define MAC7100_MCM_POR (0x80) // Power-On Reset
+
+// Bit definitions and macros for MCM_MWCR
+#define MAC7100_MCM_PRILVL(x) (((x)&0x0F)<<0) // Interrupt Priority Level
+#define MAC7100_MCM_ENBWCR (0x80) // Enable WCR
+
+// Bit definitions and macros for MCM_MSWTCR
+#define MAC7100_MCM_SWT(x) (((x)&0x001F)<<0) // Watchdog Time-Out Period
+#define MAC7100_MCM_SWRI(x) (((x)&0x0003)<<5) // Watchdog Reset/Interrupt
+#define MAC7100_MCM_SWE (0x0080) // Watchdog Enable
+#define MAC7100_MCM_SWRWH (0x0100) // Watchdog Run While Halted
+#define MAC7100_MCM_SWCIN16 (0x0200) // Force SWT CarryIn16
+#define MAC7100_MCM_RO (0x8000) // Read-Only
+
+// Bit definitions and macros for MCM_MSWTIR
+#define MAC7100_MCM_SWTIC (0x01) // Watchdog Interrupt Flag
+
+// Bit definitions and macros for MCM_AAMR
+
+
+// Address 0 Slave Number
+#define MAC7100_MCM_ASLAVE(adr_reg,sl_n) (((sl_n)&0x00000007)<<(adr_reg*4)
+// Enable Address Region 0
+#define MAC7100_MCM_EA(adr_reg) (0x00000008<<(adr_reg*4))
+
+// Bit definitions and macros for MCM_CFLOC
+#define MAC7100_MCM_LOCALERR (0x80) // Bus Error Indicator
+
+// Bit definitions and macros for MCM_CFATR
+// Protection fault type
+#define MAC7100_MCM_PROTECTION(x) (((x)&0x0F)<<0)
+// 8-16-32-64-bit core access
+#define MAC7100_MCM_SIZE(x) (((x)&0x07)<<4)
+// Core read/write access
+#define MAC7100_MCM_WRITE (0x80)
+
+//=============================================================================
+// FIQ interrupt vector which is shared by all HAL variants.
+
+#define CYGNUM_HAL_INTERRUPT_FIQ 0
+#endif // CYGONCE_HAL_VAR_IO_H
+//-----------------------------------------------------------------------------
+// end of var_io.h
--- /dev/null
+/*==========================================================================
+//
+// flash_security.S
+//
+// MAC7100 Flash security area
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-11
+// Purpose: HAL board support
+// Description: MAC7100 Flash security area.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+/////////////////////////////////////////////////////////////////////////////
+// This section contains Common Flash Module (CFM) configuration field
+// For detail description see Common Flash Module (CFM) chapter
+// @ MAC7100 Microcontroller Familly Reference Manual
+//
+// Deafault factorry setting:
+// 0xffffffff for All words except Flash Security Word
+// 0xfffffffe for Flash Security Word
+/////////////////////////////////////////////////////////////////////////////
+
+ .section ".mac7100_flash_security", "a"
+ .code 32
+ .global VAE_MAC7100_FlashSecurity
+VAE_MAC7100_FlashSecurity:
+ .long 0xffffffff // Backdoor Comparison Key bit 63-32
+ .long 0xffffffff // Backdoor Comparison key bit 31-0
+ .long 0xffffffff // Program FLASH protection Bytes
+ .long 0xffffffff // Program FLASH SUPV Access Bytes
+ .long 0xffffffff // Program FLASH DATA Access Bytes
+ .long 0xfffffffe // Flash Security Word
+ .long 0xffffffff // Data FLASH protection, SUPV access, DATA access
+
+ .long 0xe0f00420 // Just a placeholder (round to 0x420)
+ .end
+
+//--------------------------------------------------------------------------
+// EOF flash_security.S
--- /dev/null
+/*=============================================================================
+//
+// hal_diag.c
+//
+// HAL diagnostic output code
+//
+//=============================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-15
+// Purpose: HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+ */
+
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h> // base types
+
+#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_if.h> // interface API
+#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h> // Helper functions
+#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h> //
+#include <cyg/devs/ser_esci.h> // ESCI registers
+
+//-----------------------------------------------------------------------------
+typedef struct {
+ void *base;
+ cyg_int32 msec_timeout;
+ int isr_vector;
+ int isr_level;
+ int baud_rate;
+} channel_data_t;
+
+
+
+//-----------------------------------------------------------------------------
+
+void
+cyg_hal_plf_serial_putc(void *__ch_data, char c);
+
+
+static void
+cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint8 *esci_base = chan->base;
+
+
+ // Reset device
+ // 8-1-no parity.
+
+ HAL_WRITE_UINT8(FREESCALE_ESCI_CR3(esci_base), 0);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_LINCTRL(esci_base), 0);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_BD(esci_base),
+ FREESCALE_ESCI_BAUD(chan->baud_rate));
+
+ // Enable RX and TX
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), (FREESCALE_ESCI_CR12_TE |
+ FREESCALE_ESCI_CR12_RE));
+}
+
+void
+cyg_hal_plf_serial_putc(void* __ch_data, char ch_out)
+{
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
+ cyg_uint16 esci_sr;
+
+ CYGARC_HAL_SAVE_GP();
+
+ do {
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ } while (!(esci_sr & FREESCALE_ESCI_SR_TDRE));
+
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_TDRE);
+ HAL_WRITE_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_out);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* p_ch_in)
+{
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
+ cyg_uint16 esci_sr;
+ cyg_uint8 ch_in;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ if (!(esci_sr & FREESCALE_ESCI_SR_RDRF))
+ return false;
+
+ HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+ *p_ch_in = ch_in;
+
+ return true;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+ cyg_uint8 ch;
+ CYGARC_HAL_SAVE_GP();
+
+ while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+ CYGARC_HAL_RESTORE_GP();
+ return ch;
+}
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* p_ch_in)
+{
+ int delay_count;
+ cyg_bool res;
+ CYGARC_HAL_SAVE_GP();
+
+ // delay in .1 ms steps
+ delay_count = ((channel_data_t*)__ch_data)->msec_timeout * 10;
+
+ for(;;) {
+ res = cyg_hal_plf_serial_getc_nonblock(__ch_data, p_ch_in);
+ if (res || 0 == delay_count--)
+ break;
+
+ CYGACC_CALL_IF_DELAY_US(100);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+ static int irq_state = 0;
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+ cyg_uint16 ser_port_reg;
+ int ret = 0;
+ va_list ap;
+
+ CYGARC_HAL_SAVE_GP();
+ va_start(ap, __func);
+
+ switch (__func) {
+ case __COMMCTL_GETBAUD:
+ ret = chan->baud_rate;
+ break;
+ case __COMMCTL_SETBAUD:
+ chan->baud_rate = va_arg(ap, cyg_int32);
+ // Should we verify this value here?
+ cyg_hal_plf_serial_init_channel(chan);
+ ret = 0;
+ break;
+ case __COMMCTL_IRQ_ENABLE:
+ irq_state = 1;
+ HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+ HAL_INTERRUPT_UNMASK(chan->isr_vector);
+
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+ ser_port_reg |= FREESCALE_ESCI_CR12_RIE;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+
+ break;
+ case __COMMCTL_IRQ_DISABLE:
+ ret = irq_state;
+ irq_state = 0;
+ HAL_INTERRUPT_MASK(chan->isr_vector);
+
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+ ser_port_reg &= ~(cyg_uint16)FREESCALE_ESCI_CR12_RIE;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
+ break;
+ case __COMMCTL_DBG_ISR_VECTOR:
+ ret = chan->isr_vector;
+ break;
+ case __COMMCTL_SET_TIMEOUT:
+ ret = chan->msec_timeout;
+ chan->msec_timeout = va_arg(ap, cyg_uint32);
+ default:
+ break;
+ }
+
+ va_end(ap);
+ CYGARC_HAL_RESTORE_GP();
+ return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+
+ channel_data_t* chan = (channel_data_t*)__ch_data;
+ CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
+ cyg_uint16 esci_sr;
+ int res = 0;
+ cyg_uint8 ch_in;
+ CYGARC_HAL_SAVE_GP();
+
+ *__ctrlc = 0;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ if (esci_sr & FREESCALE_ESCI_SR_RDRF){
+ HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
+ if( cyg_hal_is_break( &ch_in , 1 ) )
+ *__ctrlc = 1;
+
+ res = CYG_ISR_HANDLED;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+ }
+
+ HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+static channel_data_t mac7100_ser_channels[4] = {
+ { (cyg_uint16*)FREESCALE_ESCI_A_BASE, 1000, MAC7100_ESCI_A_IV,
+ MAC7100_ESCI_A_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+ { (cyg_uint16*)FREESCALE_ESCI_B_BASE, 1000, MAC7100_ESCI_B_IV,
+ MAC7100_ESCI_B_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+ { (cyg_uint16*)FREESCALE_ESCI_C_BASE, 1000, MAC7100_ESCI_C_IV,
+ MAC7100_ESCI_C_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+ { (cyg_uint16*)FREESCALE_ESCI_D_BASE, 1000, MAC7100_ESCI_D_IV,
+ MAC7100_ESCI_D_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
+};
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur;
+
+ cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+ // Init channels
+ cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[0]);
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+ cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[1]);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 2
+ cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[2]);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 3
+ cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[3]);
+#endif
+ // Setup procs in the vector table
+
+ // Set channel 0
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[0]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
+ // Set channel 1
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[1]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 2
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(2);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[2]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+#if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 3
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(3);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[3]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+ // Restore original console
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+ initialized = 1;
+ cyg_hal_plf_serial_init();
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag.c
--- /dev/null
+/*==========================================================================
+//
+// mac7100_misc.c
+//
+// HAL misc board support code for Freescale MAC7100
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+// Copyright (c) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-12
+// Purpose: HAL board support
+// Description: Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_intr.h> // necessary?
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h> // calling interface
+#include <cyg/hal/hal_misc.h> // helper functions
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+#include <cyg/hal/drv_api.h> // HAL ISR support
+#endif
+#include <cyg/hal/var_io.h> // platform registers
+#include <cyg/devs/ser_esci.h> // ESCI registers
+#include <pkgconf/io_serial_freescale_esci.h>
+
+// -------------------------------------------------------------------------
+// Clock support
+
+static cyg_uint32 _period;
+
+void hal_clock_initialize(cyg_uint32 period)
+{
+ CYG_ADDRESS pit_base = MAC7100_PIT_BASE;
+ cyg_uint32 pit_en;
+
+ CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+ // Disable counter
+ HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+ pit_en &= ~MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+ HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+
+ // Set registers
+ _period=period;
+ HAL_WRITE_UINT32(MAC7100_PIT_TLVAL(pit_base, CYGNUM_PIT_CHAN_CLOCK),
+ period);
+
+ // Start timer
+ pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+ HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+
+ // Enable timer interrupt
+ HAL_READ_UINT32(MAC7100_PIT_INTEN(pit_base), pit_en);
+ pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+ HAL_WRITE_UINT32(MAC7100_PIT_INTEN(pit_base), pit_en);
+
+ HAL_READ_UINT32(MAC7100_PIT_INTSEL(pit_base), pit_en);
+ pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
+ HAL_WRITE_UINT32(MAC7100_PIT_INTSEL(pit_base), pit_en);
+}
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+ HAL_WRITE_UINT32(MAC7100_PIT_FLG(MAC7100_PIT_BASE),
+ MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_CLOCK));
+}
+
+
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+ cyg_uint32 val;
+
+ HAL_READ_UINT32(MAC7100_PIT_TLVAL(MAC7100_PIT_BASE,CYGNUM_PIT_CHAN_CLOCK),
+ val);
+ *pvalue = _period-val;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+//
+
+#if CYGNUM_PIT_CHAN_US!=0
+#define CYGNUM_1_US (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED/2000000)
+#else
+#define CYGNUM_1_US (CYGNUM_HAL_ARM_MAC7100_F_OSC/1000000)
+#endif
+
+void hal_delay_us(cyg_int32 usecs)
+{
+ CYG_ADDRESS pit_base = MAC7100_PIT_BASE;
+ cyg_uint32 pit_en;
+
+
+ // Clear flag
+ HAL_WRITE_UINT32(MAC7100_PIT_FLG(pit_base),
+ MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_US));
+
+ // Set timer
+ HAL_WRITE_UINT32(MAC7100_PIT_TLVAL(pit_base, CYGNUM_PIT_CHAN_US),
+ usecs*CYGNUM_1_US-1);
+ HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+ pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_US);
+ HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+
+ do {
+ HAL_READ_UINT32(MAC7100_PIT_FLG(pit_base), pit_en);
+ }while (!(pit_en & MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_US)));
+
+ // Disable counter
+ HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+ pit_en &= ~MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_US);
+ HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
+}
+
+
+// -------------------------------------------------------------------------
+// Hardware init
+
+void hal_intc_init(void);
+void hal_pit_init(void);
+static void hal_mac7100_esci_pins(cyg_uint32);
+void hal_hardware_init(void)
+{
+ // Reset all interrupts
+ //
+
+ // Flush internal priority level stack
+ //
+
+ // Set up eCos/ROM interfaces
+#if (defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_A) || \
+ (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 0)
+ hal_mac7100_esci_pins(FREESCALE_ESCI_A_I);
+#endif
+#if (defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_B) || \
+ (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
+ hal_mac7100_esci_pins(FREESCALE_ESCI_B_I);
+#endif
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
+ hal_mac7100_esci_pins(FREESCALE_ESCI_C_I);
+#endif
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
+ hal_mac7100_esci_pins(FREESCALE_ESCI_D_I);
+#endif
+
+ hal_intc_init(); // Initialize interrupt controller
+ hal_pit_init(); // Initilaize CLOCK for channels 1..10
+ hal_if_init();
+}
+
+void hal_pit_init(void)
+{
+ cyg_uint32 pit_ctrl;
+
+ CYG_ADDRESS pit_base=MAC7100_PIT_BASE;
+
+ HAL_READ_UINT32(MAC7100_PIT_CTRL(pit_base), pit_ctrl);
+ pit_ctrl &= ~MAC7100_PIT_MDIS;
+ HAL_WRITE_UINT32(MAC7100_PIT_CTRL(pit_base), pit_ctrl);
+}
+
+
+// -------------------------------------------------------------------------
+// This routine is called to respond to a hardware interrupt (IRQ). It
+// should interrogate the hardware and return the IRQ vector number.
+
+typedef struct ClSlMask_T {
+ cyg_uint8 ClMask;
+ cyg_uint8 SlMask;
+} ClSlMask_T;
+
+static ClSlMask_T ClSlMasks[CYGNUM_HAL_ISR_COUNT];
+
+void hal_intc_init(void)
+{
+ cyg_uint8 iconfig;
+ CYG_ADDRESS intc_base=MAC7100_INTC_BASE;
+
+ iconfig = (CYGHWR_HAL_ARM_MAC7100_INTC_FIQDEF |
+ CYGHWR_HAL_ARM_MAC7100_INTC_EMASK);
+ HAL_WRITE_UINT8(MAC7100_INTC_ICONFIG(intc_base), iconfig);
+}
+
+int hal_IRQ_handler(void)
+{
+ CYG_ADDRESS intc_base=MAC7100_INTC_BASE;
+ cyg_int8 irq_num;
+ ClSlMask_T clslmask;
+
+ HAL_READ_UINT8(MAC7100_INTC_CLMASK(intc_base), clslmask.ClMask);
+ HAL_READ_UINT8(MAC7100_INTC_SLMASK(intc_base), clslmask.SlMask);
+#ifdef CYGHWR_HAL_ARM_MAC7100_FIQ
+ HAL_READ_UINT8(MAC7100_FIQIACK(intc_base), irq_num);
+ if((irq_num-=CYGNUM_HAL_ISR_COUNT)<0){
+#endif //CYGHWR_HAL_ARM_MAC7100_FIQ
+ HAL_READ_UINT8(MAC7100_INTC_IRQIACK(intc_base), irq_num);
+ if((irq_num-=CYGNUM_HAL_ISR_COUNT)<0){
+ irq_num=CYGNUM_HAL_INTERRUPT_NONE;
+ }else{
+ ClSlMasks[irq_num]=clslmask;
+ }
+ return irq_num;
+#ifdef CYGHWR_HAL_ARM_MAC7100_FIQ
+ }
+#endif // CYGHWR_HAL_ARM_MAC7100_FIQ
+}
+
+// -------------------------------------------------------------------------
+// Interrupt control
+//
+
+void hal_interrupt_mask(int vector)
+{
+ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+
+ HAL_WRITE_UINT8(MAC7100_INTC_SIMR(MAC7100_INTC_BASE), vector);
+}
+
+void hal_interrupt_unmask(int vector)
+{
+ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+
+ HAL_WRITE_UINT8(MAC7100_INTC_CIMR(MAC7100_INTC_BASE), vector);
+}
+
+void hal_interrupt_acknowledge(int vector)
+{
+ // ?? No check for valid vector here! Spurious interrupts
+ // ?? must be acknowledged, too.
+
+ if(vector>=0)
+ HAL_WRITE_UINT8(MAC7100_INTC_CLMASK(MAC7100_INTC_BASE),
+ ClSlMasks[vector].ClMask);
+}
+
+void hal_interrupt_configure(int vector, int level, int up)
+{
+ // TO DO
+}
+
+void hal_interrupt_set_level(int vector, int level)
+{
+ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
+ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
+ CYG_ASSERT(level >=0 level <= 15, "Invalid level");
+
+ HAL_WRITE_UINT8(MAC7100_INTC_ICR(MAC7100_INTC_BASE,vector),
+ MAC7100_INTC_INT_LEVEL(level));
+}
+
+void hal_show_IRQ(int vector, int data, int handler)
+{
+// UNDEFINED(__FUNCTION__); // FIXME
+}
+
+
+void hal_mac7100_reset_cpu(void)
+{
+ // TO DO use watchdog to reset cpu
+}
+
+// Set ESCI channel pins in perpheral mode
+
+void
+hal_mac7100_esci_pins(cyg_uint32 i_esci){
+ cyg_uint16 *p_pim_config=0;
+
+ switch(i_esci){
+ case FREESCALE_ESCI_A_I:
+ p_pim_config=
+ (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,2);
+ break;
+ case FREESCALE_ESCI_B_I:
+ p_pim_config=(cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,0);
+ break;
+ case FREESCALE_ESCI_C_I:
+ p_pim_config=
+ (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,14);
+ break;
+ case FREESCALE_ESCI_D_I:
+ p_pim_config=
+ (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,15);
+ break;
+ }
+ HAL_WRITE_UINT16(p_pim_config++, MAC7100_PIM_MODE_PERIPHERAL);
+ HAL_WRITE_UINT16(p_pim_config, MAC7100_PIM_MODE_PERIPHERAL);
+}
+
+
+//--------------------------------------------------------------------------
+// EOF mac7100_misc.c
--- /dev/null
+2005-06-24 Enrico Piria <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+ * src/coldfire.ld:
+ * src/coldfire_stub.c:
+ * src/context.S:
+ * src/hal_misc.c:
+ * src/hal_mk_defs.c:
+ * src/hal_startup.c:
+ * src/vectors.S:
+ * include/arch.inc:
+ * include/basetype.h:
+ * include/coldfire_regs.h:
+ * include/coldfire_stub.h:
+ * include/hal_arch.h:
+ * include/hal_cache.h:
+ * include/hal_intr.h:
+ * include/hal_io.h:
+ * include/hal_startup.h:
+ * cdl/hal_coldfire.cdl:
+ * doc/readme.txt:
+ Rework of the original ColdFire architecture HAL contributed by
+ Wade Jensen.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_coldfire.cdl
+#
+# ColdFire architecture HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Enrico Piria
+## Contributors: Wade Jensen
+## Date: 2005-25-06
+##
+######DESCRIPTIONEND####
+##========================================================================
+
+cdl_package CYGPKG_HAL_COLDFIRE {
+ display "ColdFire architecture"
+ parent CYGPKG_HAL
+ hardware
+ include_dir cyg/hal
+ define_header hal_coldfire.h
+ description "
+ The ColdFire architecture HAL package provides generic
+ support for this processor architecture. It is also
+ necessary to select a specific target platform HAL
+ package."
+
+ cdl_interface CYGINT_HAL_COLDFIRE_VARIANT {
+ display "Number of variant implementations in this configuration"
+ no_define
+ requires 1 == CYGINT_HAL_COLDFIRE_VARIANT
+ }
+
+ compile hal_startup.c hal_misc.c coldfire_stub.c vectors.S context.S
+
+ # The "-o file" is a workaround for CR100958 - without it the
+ # output file would end up in the source directory under CygWin.
+ # n.b. grep does not behave itself under win32
+ make -priority 1 {
+ <PREFIX>/include/cyg/hal/cf_offsets.inc : <PACKAGE>/src/hal_mk_defs.c
+ $(CC) $(ACTUAL_CFLAGS) $(INCLUDE_PATH) -Wp,-MD,cf_offsets.tmp -o hal_mk_defs.tmp -S $<
+ fgrep .equ hal_mk_defs.tmp | sed s/#// > $@
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 cf_offsets.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm cf_offsets.tmp hal_mk_defs.tmp
+ }
+
+ make {
+ <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
+ $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -c -o $@ $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 vectors.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm vectors.tmp
+ }
+
+ make {
+ <PREFIX>/lib/target.ld: <PACKAGE>/src/coldfire.ld
+ $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -o $@ $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 target.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm target.tmp
+ }
+
+ cdl_option CYGBLD_LINKER_SCRIPT {
+ display "Linker script"
+ flavor data
+ no_define
+ calculated { "src/coldfire.ld" }
+ }
+
+}
--- /dev/null
+SOME NOTES ON THE USAGE OF THE HAL FOR COLDFIRE
+
+This HAL was obtained by rewriting the original port of eCos to ColdFire done
+by Wade Jensen. The following guidelines give you hints about using this
+software.
+
+* Use at least GCC version 3.4.1. This version has an improved support for
+ ColdFire processors. However, this compiler might not be able to build the
+ "cxxsupp.cxx" test in the "infra" package.
+
+* The version of the binutils I used is 2.15.90.0.1.1.
+
+* The version of newlib I used is 1.13.0.
+
+* The version of the BDM tools I used is 1.3.0.
+
+* If you want to debug code by means of the serial connection to eCos, don't
+use a version of GDB with BDM support compiled into. There is some kind of
+interaction between BDM and serial targets that prevents the latter from
+functioning correctly. Do not even use a clean GDB 6.3 distribution to debug
+through the serial cable. The downloading of code to the target is broken in
+that version. Instead, use a version of GDB grabbed from CVS repository. I
+used a version downloaded after June 13, 2005, and the bug had been corrected.
+
+* Currently (version 6.3), GDB doesn't support the ColdFire MAC unit. Thus, it
+is not possible to show the MAC registers, via the "info registers" command,
+when debugging an eCos application through a serial connection. The BDM addon
+to GDB doesn't suffer from a similar limitation. However, there is a little
+hack in order to show and modify the MAC registers even with a serial
+connection. When a breakpoint is hit, the GDB module of eCos stores the
+current register values in a structure of type HAL_SavedRegisters, pointed to
+by the _hal_registers variable. If you included the GDB stub in your
+application, it is then possible to display the MAC registers (and all of the
+others) by issuing at the GDB prompt the following command:
+
+print *(struct HAL_SavedRegisters *)_hal_registers
+
+In case you are using a GDB stub burned in ROM to debug an application in RAM,
+you first have to determine where the GDB stub stores the _hal_registers
+variable in its own private region of RAM: use the tool m68k-elf-objdump to
+find that. For example, if the address of the _hal_registers variable used by
+the GDB stub is 0x1e88, then you should use the following command to display
+the registers of the application being debugged:
+
+print *(struct HAL_SavedRegisters *)*0x1e88
+
+It is also possible to modify the value of the MAC registers, by updating the
+relative field of the HAL_SavedRegisters structure. Don't try to modify the
+other registers because the modifications will be discarded when the
+application is restarted: use the usual GDB commands instead. Finally, the
+correct value of the PC register is the one shown by the "info registers"
+command.
+
+* I added at the architecture level only the features that I could directly
+test. When I developed the architecture HAL, I had a ColdFire MCF5272 at
+hands, which has a MAC unit. That's why in the architecture HAL there is
+currently only support for the MAC unit, and no support for the EMAC and
+floating point units. However, I tried to write the HAL in the most generic
+fashion I could imagine, in order to make it easy to add new architectural
+features and new processor variants.
+
+* If you want to burn an eCos image into the flash ROM, you cannot rely on the
+ROM monitor provided with the board, but you have to use the BDM interface.
+If you work under Windows, you can use the free CFFlasher utility, available
+on the Freescale Semiconductor web site. The BDM tools also contain a
+text-mode utility to do that, but I have not tested it.
+
+
+Enrico Piria (epiria AT fastwebnet DOT it)
+November 16, 2005
--- /dev/null
+#ifndef CYGONCE_HAL_ARCH_INC
+#define CYGONCE_HAL_ARCH_INC
+|=============================================================================
+|
+| arch.inc
+|
+| ColdFire architecture assembler header file
+|
+|=============================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| 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.
+| -------------------------------------------
+|###ECOSGPLCOPYRIGHTEND####
+|=============================================================================
+|#####DESCRIPTIONBEGIN####
+|
+| Author(s): Enrico Piria
+| Contributors:
+| Date: 2005-25-06
+| Purpose: MCF5272 variant definitions.
+| Description: This file contains macro definitions used in the
+| architecture HAL assembler file.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+
+#define FUNC_START(name) \
+ .text; \
+ .balign 4; \
+ .type name,@function; \
+ .globl name; \
+name:
+
+
+| ----------------------------------------------------------------------------
+| Macros to deal with the interrupt priority level in the status register.
+
+ .macro hal_cpu_int_disable
+ move.w #0x2700,%sr
+ .endm
+
+
+ .macro hal_cpu_int_enable work
+ move.w %sr,\work
+ and.l #0xf8ff,\work
+ move.w \work,%sr
+ .endm
+
+
+ .macro hal_cpu_int_merge from work
+ move.w %sr,\work
+ and.l #0xf8ff,\work
+ and.l #0x0700,\from
+ or.l \from,\work
+ move.w \work,%sr
+ .endm
+
+| ----------------------------------------------------------------------------
+| Macro to find the value the SP register had before an exception.
+
+ .macro find_original_sp out
+ move.b CYGARC_CF_FMTVECWORD(%sp),\out
+ lsr.l #4,\out
+ and.l #0x00000003,\out
+ add.l #CYGARC_CF_EXCEPTION_SIZE,\out
+ add.l %sp,\out
+ .endm
+
+
+| ----------------------------------------------------------------------------
+| Macros used to save and restore MAC registers during interrupts/exceptions.
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ .macro save_mac_registers work
+ | Store MACSR register
+ move.l %macsr,\work
+ move.l \work,CYGARC_CFREG_MACSR(%sp)
+
+ | Switch to integer mode. This allows to save the contents of ACC
+ | without rounding
+ and.l #0x000000df,\work
+ move.l \work,%macsr
+
+ | Store ACC register
+ move.l %acc,\work
+ move.l \work,CYGARC_CFREG_MACC(%sp)
+
+ | Store MASK register
+ move.l %mask,\work
+ move.l \work,CYGARC_CFREG_MASK(%sp)
+ .endm
+
+
+ .macro restore_mac_registers work
+ | Load MACSR register
+ move.l CYGARC_CFREG_MACSR(%sp),\work
+ move.l \work,%macsr
+
+ | Load ACC register
+ move.l CYGARC_CFREG_MACC(%sp),\work
+ move.l \work,%acc
+
+ | Load MASK register
+ move.l CYGARC_CFREG_MASK(%sp),\work
+ move.l \work,%mask
+ .endm
+#endif
+
+
+| ----------------------------------------------------------------------------
+| Macros used to save registers in interrupt handlers. During an interrupt,
+| we save registers %d0-%d1 and %a0-%a1 because of the GNU C calling
+| conventions. During the handler we also need register %d2.
+
+#ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ .macro int_pres_regs
+ lea.l -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+ movem.l %d0-%d2,CYGARC_CFREG_DREGS(%sp)
+ movem.l %a0-%a1,CYGARC_CFREG_AREGS(%sp)
+ .endm
+
+
+ .macro int_rest_regs
+ movem.l CYGARC_CFREG_AREGS(%sp),%a0-%a1
+ movem.l CYGARC_CFREG_DREGS(%sp),%d0-%d2
+ lea.l CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+ .endm
+
+#else /* CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT */
+
+ .macro int_pres_regs
+ lea.l -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+ movem.l %d0-%d7,CYGARC_CFREG_DREGS(%sp)
+ movem.l %a0-%a6,CYGARC_CFREG_AREGS(%sp)
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ save_mac_registers %d0
+#endif
+
+ | Save old SP (before interrupt)
+ find_original_sp %d0
+ move.l %d0,CYGARC_CFREG_SP(%sp)
+ .endm
+
+
+ .macro int_rest_regs
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ restore_mac_registers %d0
+#endif
+
+ movem.l CYGARC_CFREG_AREGS(%sp),%a0-%a6
+ movem.l CYGARC_CFREG_DREGS(%sp),%d0-%d7
+ lea.l CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+ .endm
+
+#endif /* CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT */
+
+
+| ----------------------------------------------------------------------------
+| Macros used to save/restore registers during context switches.
+| We don't save registers %d0-%d1 and %a0-%a1 because of the GNU C calling
+| conventions: these macros are used in a routine called by C code.
+
+#ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+
+ .macro ctx_save_registers
+ lea -CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+ movem.l %d2-%d7,CYGARC_CFREG_D2(%sp)
+ movem.l %a2-%a6,CYGARC_CFREG_A2(%sp)
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ save_mac_registers %d0
+#endif
+ | Save SR and interrupt level
+ move.w %sr,%d0
+ move.w %d0,CYGARC_CF_SR(%sp)
+ .endm
+
+
+ .macro ctx_restore_registers
+ | Restore SR and interrupt level
+ move.w CYGARC_CF_SR(%sp),%d0
+ move.w %d0,%sr
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ restore_mac_registers %d0
+#endif
+ movem.l CYGARC_CFREG_D2(%sp),%d2-%d7
+ movem.l CYGARC_CFREG_A2(%sp), %a2-%a6
+ lea CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+ .endm
+
+#else /* CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM */
+
+ .macro ctx_save_registers
+ | Save all of the registers
+ lea -CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+ movem.l %d0-%d7,CYGARC_CFREG_DREGS(%sp)
+ movem.l %a0-%a7,CYGARC_CFREG_AREGS(%sp)
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ save_mac_registers %d0
+#endif
+
+ | Save pc (useful during debugging with GDB)
+ lea (%pc),%a0
+ move.l %a0,CYGARC_CFREG_PC(%sp)
+
+ | Save SR and interrupt level
+ move.w %sr,%d0
+ move.w %d0,CYGARC_CF_SR(%sp)
+ .endm
+
+
+ .macro ctx_restore_registers
+ | Restore SR and interrupt level
+ move.w CYGARC_CF_SR(%sp),%d0
+ move.w %d0,%sr
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ restore_mac_registers %d0
+#endif
+ movem.l CYGARC_CFREG_DREGS(%sp),%d0-%d7
+ movem.l CYGARC_CFREG_AREGS(%sp),%a0-%a6
+ lea CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+ .endm
+#endif /* CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM */
+
+| ----------------------------------------------------------------------------
+| End of arch.inc
+#endif /* ifndef CYGONCE_HAL_ARCH_INC */
--- /dev/null
+#ifndef CYGONCE_HAL_BASETYPE_H
+#define CYGONCE_HAL_BASETYPE_H
+
+//=============================================================================
+//
+// basetype.h
+//
+// Standard types for this architecture
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Provide ColdFire-specific type definitions.
+// Usage: Included by "cyg_type.h", do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// Include variant specific types
+#include <cyg/hal/var_basetype.h>
+
+
+// ---------------------------------------------------------------------------
+// Characterize the architecture
+
+#define CYG_BYTEORDER CYG_MSBFIRST // Big endian
+
+// The ColdFire architecture uses the default definitions of the base types,
+// so we do not need to define any here.
+
+// ---------------------------------------------------------------------------
+// Override the alignment definitions from cyg_type.h
+
+#ifndef CYGARC_ALIGNMENT
+#define CYGARC_ALIGNMENT 4
+#endif
+
+// The corresponding power of two alignment
+#ifndef CYGARC_P2ALIGNMENT
+#define CYGARC_P2ALIGNMENT 2
+#endif
+
+// ---------------------------------------------------------------------------
+// End of basetype.h
+#endif // CYGONCE_HAL_BASETYPE_H
--- /dev/null
+#ifndef CYGONCE_HAL_CF_REGS_H
+#define CYGONCE_HAL_CF_REGS_H
+
+//==========================================================================
+//
+// coldfire_regs.h
+//
+// ColdFire CPU definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Provide ColdFire register definitions.
+// Usage: #include <cyg/hal/coldfire_regs.h>
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/var_regs.h>
+
+
+// Macro to embed movec instructions in C code
+#define CYGARC_MOVEC(_value_, _reg_) \
+ asm volatile("movec %0,%1" : : "d" (_value_), "i" (_reg_))
+
+
+// ---------------------------------------------------------------------------
+// End of coldfire_regs.h
+#endif // ifdef CYGONCE_HAL_CF_REGS_H
--- /dev/null
+#ifndef CYGONCE_HAL_COLDFIRE_STUB_H
+#define CYGONCE_HAL_COLDFIRE_STUB_H
+
+//========================================================================
+//
+// coldfire_stub.h
+//
+// ColdFire-specific definitions for generic stub
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose:
+// Description: ColdFire-specific definitions for generic stub.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NUMREGS 18
+
+// ColdFire stub has special needs for register handling because flating point
+// registers are bigger than the rest. Special put_register and get_register
+// are provided.
+#define CYGARC_STUB_REGISTER_ACCESS_DEFINED 1
+
+#define REGSIZE( _x_ ) (4)
+
+typedef unsigned long target_register_t;
+
+enum regnames {
+ D0, D1, D2, D3, D4, D5, D6, D7,
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ SR, PC,
+};
+
+#define SP A7
+
+typedef enum regnames regnames_t;
+
+// Given a trap value TRAP, return the corresponding signal
+extern int __computeSignal(unsigned int trap_number);
+
+// Return the ColdFire trap number corresponding to the last-taken trap
+extern int __get_trap_number(void);
+
+// Return the currently-saved value corresponding to register REG
+extern target_register_t get_register(regnames_t reg);
+
+// Store VALUE in the register corresponding to WHICH
+extern void put_register(regnames_t which, target_register_t value);
+
+// Read the contents of register WHICH into VALUE as raw bytes
+extern int get_register_as_bytes(regnames_t which, char *value);
+
+// Write the contents of register WHICH into VALUE as raw bytes
+extern int put_register_as_bytes(regnames_t which, char *value);
+
+// Set the currently-saved pc register value to PC. This also updates NPC
+// as needed.
+extern void set_pc(target_register_t pc);
+
+// Set things up so that the next user resume will execute one instruction.
+// This may be done by setting breakpoints or setting a single step flag
+// in the saved user registers, for example.
+extern void __single_step(void);
+
+// Clear the single-step state
+extern void __clear_single_step(void);
+
+// If the breakpoint we hit is in the breakpoint() instruction, return a
+// non-zero value
+extern int __is_breakpoint_function(void);
+
+// Skip the current instruction
+extern void __skipinst(void);
+
+extern void __install_breakpoints(void);
+
+extern void __clear_breakpoints(void);
+
+// We have to rewind the PC in case of a breakpoint.
+#define HAL_STUB_PLATFORM_STUBS_FIXUP() \
+CYG_MACRO_START \
+ if (CYGNUM_HAL_VECTOR_DEBUGTRAP == __get_trap_number()) \
+ { \
+ CYG_ADDRESS pc = get_register(PC) - HAL_BREAKINST_SIZE; \
+ put_register(PC, pc); \
+ } \
+CYG_MACRO_END
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------------------------------------------------------------------
+// End of coldfire_stub.h
+#endif // ifndef CYGONCE_HAL_COLDFIRE_STUB_H
--- /dev/null
+#ifndef CYGONCE_HAL_ARCH_H
+#define CYGONCE_HAL_ARCH_H
+
+//=============================================================================
+//
+// hal_arch.h
+//
+// Architecture specific abstractions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose:
+// Description: Definitions for the ColdFire architecture HAL.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// Include some variant specific architectural defines
+#include <cyg/hal/var_arch.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#include <cyg/hal/coldfire_stub.h>
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+// ----------------------------------------------------------------------------
+// Macros to deal with exception stack frame fields
+
+// The ColdFire family of processors has a simplified exception stack
+// frame that looks like the following:
+//
+// 8 +----------------+----------------+
+// | Program Counter |
+// 4 +----------------+----------------+
+// |Fmt/FS/Vector/FS| SR |
+// SP --> 0 +----------------+----------------+
+// The stack self-aligns to a 4-byte boundary at an exception, with
+// the Fmt/FS/Vector/FS field indicating the size of the adjustment
+// (SP += 0,1,2,3 bytes).
+
+// Define the Fmt/FS/Vector/FS word.
+// Bits 31-28 are the format word which tells the
+// RTI instruction how to align the stack.
+#define HAL_CF_EXCEPTION_FORMAT_MSK ((CYG_WORD16)0xF000)
+// Bits 25-18 are the vector number of the exception.
+#define HAL_CF_EXCEPTION_VECTOR_MSK ((CYG_WORD16)0x03FC)
+// Bits 27-26, and 17-16 are the fault status used
+// for bus and address errors.
+#define HAL_CF_EXCEPTION_FS32_MSK ((CYG_WORD16)0x0C00)
+#define HAL_CF_EXCEPTION_FS10_MSK ((CYG_WORD16)0x0003)
+
+// Macros to access fields in the format vector word.
+
+#define HAL_CF_EXCEPTION_FORMAT(_fmt_vec_word_) \
+ ((((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_FORMAT_MSK) >> 12)
+
+#define HAL_CF_EXCEPTION_VECTOR(_fmt_vec_word_) \
+ ((((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_VECTOR_MSK) >> 2)
+
+#define HAL_CF_EXCEPTION_FS(_fmt_vec_word_) \
+ (((((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_FS32_MSK) >> 8) \
+ | (((CYG_WORD16)(_fmt_vec_word_)) & HAL_CF_EXCEPTION_FS10_MSK))
+
+// ----------------------------------------------------------------------------
+// HAL_SavedRegisters -- Saved by a context switch or by an exception/interrupt
+
+typedef struct
+{
+ // These are common to all saved states and are in the order
+ // stored and loaded by the movem instruction.
+
+ // Data regs D0-D7
+ CYG_WORD32 d[8];
+
+ // Address regs A0-A7
+ CYG_ADDRESS a[8];
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ // MAC registers
+ CYG_WORD32 macc;
+ CYG_WORD32 macsr;
+ CYG_WORD32 mask;
+#endif
+
+ // On exception/interrupt PC, SR and exception are pushed on the
+ // stack automatically, so there is no need to allocate the entire
+ // structure.
+
+ // 16-bit format/vector word
+ CYG_WORD16 fmt_vec_word;
+
+ // Status register
+ CYG_WORD16 sr;
+
+ // Program counter
+ CYG_ADDRESS pc;
+
+} __attribute__ ((aligned, packed)) HAL_SavedRegisters;
+
+#ifndef HAL_THREAD_SWITCH_CONTEXT
+
+// ***************************************************************************
+// HAL_THREAD_SWITCH_CONTEXT
+//
+// This macro saves the state of the currently running thread and writes
+// its stack pointer to *(_fspptr_).
+// It then switches to the thread context that *(_tspptr_) points to.
+//
+// INPUT:
+// _fspptr_: A pointer to the location to save the current thread's stack
+// pointer to.
+//
+// _tspptr_: A pointer to the location containing the stack pointer of
+// the thread context to switch to.
+//
+// OUTPUT:
+// *(_fspptr_): Contains the stack pointer of the previous thread's context.
+//
+// ***************************************************************************
+
+externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
+externC void hal_thread_load_context( CYG_ADDRESS to )
+ CYGBLD_ATTRIB_NORET;
+
+#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \
+ hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_);
+#endif // HAL_THREAD_SWITCH_CONTEXT
+
+#ifndef HAL_THREAD_LOAD_CONTEXT
+
+// ***************************************************************************
+// hal_thread_load_context
+//
+// This routine loads the thread context that *(_tspptr_) points to.
+// This routine does not return.
+//
+// INPUT:
+// _tspptr_: A pointer to the location containing the stack pointer of
+// the thread context to switch to.
+//
+// ***************************************************************************
+
+#define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \
+ hal_thread_load_context( (CYG_ADDRESS)_tspptr_ );
+#endif // HAL_THREAD_LOAD_CONTEXT
+
+
+#ifndef HAL_THREAD_INIT_CONTEXT
+
+// ***************************************************************************
+// HAL_THREAD_INIT_CONTEXT -- Context Initialization
+//
+// Initialize the context of a thread.
+//
+// INPUT:
+// _sparg_: The name of the variable containing the current sp. This
+// will be written with the new sp.
+//
+// _thread_: The thread object address, passed as argument to entry
+// point.
+//
+// _entry_: The thread's entry point address.
+//
+// _id_: A bit pattern used in initializing registers, for debugging.
+//
+// OUTPUT:
+// _sparg_: Updated with the value of the new sp.
+//
+// ***************************************************************************
+
+#define HAL_THREAD_INIT_CONTEXT(_sparg_, _thread_, _entry_, _id_) \
+ CYG_MACRO_START \
+ CYG_WORD32 * _sp_ = ((CYG_WORD32*)((CYG_WORD32)(_sparg_) & ~15)); \
+ HAL_SavedRegisters * _regs_; \
+ int _i_; \
+ \
+ /* Thread's parameter. */ \
+ *(--_sp_) = (CYG_WORD32)(_thread_); \
+ /* Fake thread's return addr. Needed because thread is a function */ \
+ /* and parameters to functions are always follwed by the return */ \
+ /* address on the stack. */ \
+ *(--_sp_) = (CYG_WORD32)(0xDEADC0DE); \
+ /* Thread's return addr. (used by hal_thread_load_context) */ \
+ *(--_sp_) = (CYG_WORD32)(_entry_); \
+ \
+ _regs_ = (HAL_SavedRegisters *) \
+ ((CYG_WORD32)_sp_ - sizeof(HAL_SavedRegisters)); \
+ \
+ for (_i_=0; _i_ < 8; _i_++) \
+ _regs_->a[_i_] = _regs_->d[_i_] = (_id_); \
+ /* A6, initial frame pointer should be null */ \
+ _regs_->a[6] = (CYG_ADDRESS)0; \
+ \
+ /* Thread's starting SR. All interrupts enabled. */ \
+ _regs_->sr = 0x3000; \
+ \
+ /* Thread's starting PC */ \
+ _regs_->pc = (CYG_ADDRESS)(_entry_); \
+ \
+ (_sparg_) = (CYG_ADDRESS)_regs_; \
+ CYG_MACRO_END
+#endif // HAL_THREAD_INIT_CONTEXT
+
+// ----------------------------------------------------------------------------
+// Bit manipulation routines.
+
+externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
+externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
+
+#define HAL_LSBIT_INDEX(index, mask) (index) = hal_lsbit_index(mask);
+
+#define HAL_MSBIT_INDEX(index, mask) (index) = hal_msbit_index(mask);
+
+// ----------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor.
+
+externC void hal_idle_thread_action(cyg_uint32 loop_count);
+
+#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
+
+// ----------------------------------------------------------------------------
+// Execution reorder barrier.
+// When optimizing the compiler can reorder code. In multithreaded systems
+// where the order of actions is vital, this can sometimes cause problems.
+// This macro may be inserted into places where reordering should not happen.
+
+#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
+
+// ----------------------------------------------------------------------------
+// Breakpoint support
+// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen
+// if executed.
+// HAL_BREAKINST is the value of the breakpoint instruction and
+// HAL_BREAKINST_SIZE is its size in bytes.
+
+// The host side of GDB debugger uses trap #15 to install breakpoints.
+
+#define CYGNUM_HAL_VECTOR_DEBUGTRAP 47
+
+#define HAL_BREAKPOINT(_label_) \
+asm volatile (" .globl " #_label_ ";" \
+ #_label_":" \
+ " trap #15" \
+ );
+
+#define HAL_BREAKINST 0x4E4F
+
+#define HAL_BREAKINST_SIZE 2
+
+
+// ----------------------------------------------------------------------------
+// Thread register state manipulation for GDB support.
+
+typedef struct {
+ cyg_uint32 d[8];
+ cyg_uint32 a[8];
+ cyg_uint32 pc;
+ cyg_uint32 sr;
+} GDB_Registers;
+
+// Translate a stack pointer as saved by the thread context macros above into
+// a pointer to a HAL_SavedRegisters structure.
+#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \
+ (_regs_) = (HAL_SavedRegisters *)(_sp_)
+
+
+// Copy a set of registers from a HAL_SavedRegisters structure into a
+// GDB ordered array.
+#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \
+ CYG_MACRO_START \
+ union __gdbreguniontype { \
+ __typeof__(_aregval_) _aregval2_; \
+ GDB_Registers *_gdbr; \
+ } __gdbregunion; \
+ __gdbregunion._aregval2_ = (_aregval_); \
+ GDB_Registers *_gdb_ = __gdbregunion._gdbr; \
+ int _i_; \
+ \
+ for( _i_ = 0; _i_ < 8; _i_++ ) \
+ { \
+ _gdb_->d[_i_] = (_regs_)->d[_i_]; \
+ _gdb_->a[_i_] = (_regs_)->a[_i_]; \
+ } \
+ \
+ _gdb_->pc = (_regs_)->pc; \
+ _gdb_->sr = (cyg_uint32) ((_regs_)->sr); \
+ CYG_MACRO_END
+
+// Copy a GDB ordered array into a HAL_SavedRegisters structure.
+#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \
+ CYG_MACRO_START \
+ union __gdbreguniontype { \
+ __typeof__(_aregval_) _aregval2_; \
+ GDB_Registers *_gdbr; \
+ } __gdbregunion; \
+ __gdbregunion._aregval2_ = (_aregval_); \
+ GDB_Registers *_gdb_ = __gdbregunion._gdbr; \
+ int _i_; \
+ \
+ for( _i_ = 0; _i_ < 8; _i_++ ) \
+ { \
+ (_regs_)->d[_i_] = _gdb_->d[_i_]; \
+ (_regs_)->a[_i_] = _gdb_->a[_i_]; \
+ } \
+ \
+ (_regs_)->pc = _gdb_->pc; \
+ (_regs_)->sr = (CYG_WORD16)(_gdb_->sr); \
+ CYG_MACRO_END
+
+
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+ defined(CYGPKG_HAL_EXCEPTIONS)
+
+// ----------------------------------------------------------------------------
+// Exception handling function.
+// This function is defined by the kernel according to this prototype. It is
+// invoked from the HAL to deal with any CPU exceptions that the HAL does
+// not want to deal with itself. It usually invokes the kernel's exception
+// delivery mechanism.
+
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+
+#endif // defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
+
+// ----------------------------------------------------------------------------
+// Minimal and sensible stack sizes: the intention is that applications
+// will use these to provide a stack size in the first instance prior to
+// proper analysis. Idle thread stack should be this big.
+
+// THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
+// THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
+// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
+
+// This is not a config option because it should not be adjusted except
+// under "enough rope" sort of disclaimers.
+
+// Stack frame overhead per call: 6 data registers, 5 address registers,
+// frame pointer, and return address. We can't guess the local variables so
+// just assume that using all of the registers averages out.
+
+#define CYGNUM_HAL_STACK_FRAME_SIZE ((6 + 5 + 1 + 1) * 4)
+
+// Stack needed for a context switch.
+// All registers + pc + sr + vector.
+
+#ifndef CYGNUM_HAL_STACK_CONTEXT_SIZE
+#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((8+8+1)*4 + (1+1)*2)
+#endif // CYGNUM_HAL_STACK_CONTEXT_SIZE
+
+// Interrupt (rounded up) + call to ISR, interrupt_end() and the DSR.
+
+#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
+ ((CYGNUM_HAL_STACK_CONTEXT_SIZE) + (2*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// We define a minimum stack size as the minimum any thread could ever
+// legitimately get away with. We can throw asserts if users ask for less
+// than this. Allow enough for four interrupt sources - clock, serial,
+// nic, and one other.
+
+// No separate interrupt stack exists. Make sure all threads contain
+// a stack sufficiently large.
+
+#define CYGNUM_HAL_STACK_SIZE_MINIMUM \
+ ((4*CYGNUM_HAL_STACK_INTERRUPT_SIZE) \
+ + (16*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// Now make a reasonable choice for a typical thread size. Pluck figures
+// from thin air and say 30 call frames with an average of 16 words of
+// automatic variables per call frame.
+
+#define CYGNUM_HAL_STACK_SIZE_TYPICAL \
+ (CYGNUM_HAL_STACK_SIZE_MINIMUM + \
+ (30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))))
+
+// -------------------------------------------------------------------------
+// Macros for switching context between two eCos instances (jump from
+// code in ROM to code in RAM or vice versa).
+
+#define CYGARC_HAL_SAVE_GP()
+#define CYGARC_HAL_RESTORE_GP()
+
+// -------------------------------------------------------------------------
+// hal_setjmp/hal_longjmp
+
+
+// We must save all of the registers that are preserved across routine
+// calls. The assembly code assumes that this structure is defined in the
+// following format. Any changes to this structure will result in changes to
+// the assembly code!!
+
+typedef struct {
+ // D registers
+ cyg_uint32 d2;
+ cyg_uint32 d3;
+ cyg_uint32 d4;
+ cyg_uint32 d5;
+ cyg_uint32 d6;
+ cyg_uint32 d7;
+
+ // A registers
+ cyg_uint32 a2;
+ cyg_uint32 a3;
+ cyg_uint32 a4;
+ cyg_uint32 a5;
+ cyg_uint32 a6;
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ // MAC registers
+ cyg_uint32 macc;
+ cyg_uint32 macsr;
+ cyg_uint32 mask;
+#endif
+
+ // SP and PC
+ cyg_uint32 sp;
+ cyg_uint32 pc;
+} hal_jmp_buf_t;
+
+// This type is used by normal routines to pass the address of the structure
+// into our routines without having to explicitly take the address
+// of the structure.
+
+typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
+
+// Define the generic setjmp and longjmp routines
+externC int hal_setjmp(hal_jmp_buf env);
+externC void hal_longjmp(hal_jmp_buf env, int val);
+#define hal_setjmp(_env) hal_setjmp(_env)
+#define hal_longjmp(_env, _val) hal_longjmp(_env, _val)
+
+// ---------------------------------------------------------------------------
+// End of hal_arch.h
+#endif // CYGONCE_HAL_ARCH_H
--- /dev/null
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+// hal_cache.h
+//
+// HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Provide ColdFire-specific cache control definitions.
+// Usage: #include <cyg/hal/hal_cache.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/var_cache.h>
+
+// ---------------------------------------------------------------------------
+// End of hal_cache.h
+#endif // ifndef CYGONCE_HAL_CACHE_H
--- /dev/null
+#ifndef CYGONCE_HAL_HAL_INTR_H
+#define CYGONCE_HAL_HAL_INTR_H
+
+//==========================================================================
+//
+// hal_intr.h
+//
+// ColdFire interrupt/exception support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Provide ColdFire-specific interrupt and exception
+// definitions.
+// Usage: #include <cyg/hal/hal_intr.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/hal/var_intr.h>
+
+#include <cyg/infra/cyg_ass.h> // CYG_FAIL
+
+// -------------------------------------------------------------------------
+// ColdFire exception vectors. These correspond to VSRs and are the values
+// to use for HAL_VSR_GET/SET.
+
+#define CYGNUM_HAL_VECTOR_RESETSP 0
+#define CYGNUM_HAL_VECTOR_RESETPC 1
+#define CYGNUM_HAL_VECTOR_BUSERR 2
+#define CYGNUM_HAL_VECTOR_ADDRERR 3
+#define CYGNUM_HAL_VECTOR_ILLINST 4
+#define CYGNUM_HAL_VECTOR_ZERODIV 5
+
+// Exception vectors 6-7 are reserved
+
+#define CYGNUM_HAL_VECTOR_PRIVVIOLATION 8
+#define CYGNUM_HAL_VECTOR_TRACE 9
+#define CYGNUM_HAL_VECTOR_L1010 10
+#define CYGNUM_HAL_VECTOR_L1111 11
+#define CYGNUM_HAL_VECTOR_DEBUG12 12
+#define CYGNUM_HAL_VECTOR_DEBUG13 13
+#define CYGNUM_HAL_VECTOR_FORMAT 14
+#define CYGNUM_HAL_VECTOR_UNINITINT 15
+
+// Exception vectors 16-23 are reserved
+
+#define CYGNUM_HAL_VECTOR_SPURINT 24
+
+#define CYGNUM_HAL_VECTOR_AUTOVEC1 25
+#define CYGNUM_HAL_VECTOR_AUTOVEC2 26
+#define CYGNUM_HAL_VECTOR_AUTOVEC3 27
+#define CYGNUM_HAL_VECTOR_AUTOVEC4 28
+#define CYGNUM_HAL_VECTOR_AUTOVEC5 29
+#define CYGNUM_HAL_VECTOR_AUTOVEC6 30
+#define CYGNUM_HAL_VECTOR_AUTOVEC7 31
+#define CYGNUM_HAL_NUMAUTOVEC 7
+
+#define CYGNUM_HAL_VECTOR_TRAPFIRST 32
+#define CYGNUM_HAL_VECTOR_TRAPLAST 47
+#define CYGNUM_HAL_NUMTRAPS 16
+
+#define CYGNUM_HAL_VECTOR_FP_BRANCH 48
+#define CYGNUM_HAL_VECTOR_FP_INEXACT 49
+#define CYGNUM_HAL_VECTOR_FP_ZERODIV 50
+#define CYGNUM_HAL_VECTOR_FP_UNDERFLOW 51
+#define CYGNUM_HAL_VECTOR_FP_OPERAND 52
+#define CYGNUM_HAL_VECTOR_FP_OVERFLOW 53
+#define CYGNUM_HAL_VECTOR_FP_NAN 54
+#define CYGNUM_HAL_VECTOR_FP_DENORM 55
+
+// Exception vectors 56-60 are reserved
+
+#define CYGNUM_HAL_VECTOR_UNSUPINST 61
+
+// Exception vectors 62-63 are reserved
+
+#define CYGNUM_HAL_VECTOR_USERINTRFIRST 64
+#define CYGNUM_HAL_VECTOR_USERINTRLAST 255
+#define CYGNUM_HAL_NUMUSERINTR 192
+
+// -------------------------------------------------------------------------
+// Interrupt and exception vector table definitions.
+
+#define CYGNUM_HAL_VSR_MIN 0
+#define CYGNUM_HAL_VSR_MAX 255
+#define CYGNUM_HAL_VSR_COUNT (CYGNUM_HAL_VSR_MAX - CYGNUM_HAL_VSR_MIN + 1)
+
+// To simplify things in interrupt handling code, we don't take into account
+// autovectored, spurious and uninitialized interrupts.
+
+#ifndef CYGNUM_HAL_ISR_RANGE_DEFINED
+#define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_VECTOR_USERINTRFIRST
+#define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_VECTOR_USERINTRLAST
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
+#endif
+
+#ifndef CYGNUM_HAL_EXCEPTION_RANGE_DEFINED
+#define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_VECTOR_BUSERR
+#define CYGNUM_HAL_EXCEPTION_MAX CYGNUM_HAL_VECTOR_UNSUPINST
+#define CYGNUM_HAL_EXCEPTION_COUNT (CYGNUM_HAL_EXCEPTION_MAX -\
+ CYGNUM_HAL_EXCEPTION_MIN + 1)
+#endif
+
+// -------------------------------------------------------------------------
+// Equivalence between ColdFire exception names and target independent
+// exception names.
+// These are the values used when passed out to an
+// external exception handler using cyg_hal_deliver_exception().
+
+#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_ILLINST
+#define CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO CYGNUM_HAL_VECTOR_ZERODIV
+#define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_BUSERR
+#define CYGNUM_HAL_EXCEPTION_CODE_ACCESS CYGNUM_HAL_VECTOR_BUSERR
+
+// -------------------------------------------------------------------------
+// Spurious interrupt definition.
+
+#ifndef CYGNUM_HAL_SPURIOUS_INTERRUPT
+#define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_VECTOR_SPURINT
+#endif
+
+// -------------------------------------------------------------------------
+// Static data used by HAL.
+
+// ISR tables
+externC volatile CYG_ADDRESS cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRESS cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// VSR table
+externC volatile CYG_ADDRESS cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
+
+// ROM VSR table
+externC CYG_ADDRESS rom_vsr_table[CYGNUM_HAL_VSR_COUNT];
+
+// -------------------------------------------------------------------------
+// Interrupt stack definitions.
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+externC void hal_interrupt_stack_call_pending_DSRs(void);
+#define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
+ hal_interrupt_stack_call_pending_DSRs()
+
+#endif
+
+// A separate stack always exist to allow the processor to initialize itself.
+// It depends on CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK macro
+// definition if this stack is used for interrupts too.
+
+#define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
+#define HAL_INTERRUPT_STACK_TOP cyg_interrupt_stack
+
+externC char HAL_INTERRUPT_STACK_BASE[];
+externC char HAL_INTERRUPT_STACK_TOP[];
+
+// --------------------------------------------------------------------------
+// Translate a vector number into an ISR table index.
+
+#ifndef HAL_TRANSLATE_VECTOR
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_- CYGNUM_HAL_ISR_MIN)
+#endif
+
+// -------------------------------------------------------------------------
+// Interrupt state storage.
+
+typedef cyg_uint16 CYG_INTERRUPT_STATE;
+
+// --------------------------------------------------------------------------
+// Interrupt and VSR attachment macros.
+
+externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+externC void hal_default_exception_handler(CYG_WORD vector,
+ HAL_SavedRegisters *regs);
+
+#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
+CYG_MACRO_START \
+ cyg_uint32 _index_; \
+ HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
+ \
+ if (cyg_hal_interrupt_handlers[_index_] \
+ == (CYG_ADDRESS) &hal_default_isr) \
+ (_state_) = 0; \
+ else \
+ (_state_) = 1; \
+CYG_MACRO_END
+
+#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
+CYG_MACRO_START \
+ cyg_uint32 _index_; \
+ HAL_TRANSLATE_VECTOR((_vector_), _index_); \
+ \
+ if (cyg_hal_interrupt_handlers[_index_] \
+ == (CYG_ADDRESS) &hal_default_isr) \
+ { \
+ cyg_hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_); \
+ cyg_hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_); \
+ cyg_hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_); \
+ } \
+CYG_MACRO_END
+
+#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
+CYG_MACRO_START \
+ cyg_uint32 _index_; \
+ HAL_INTERRUPT_MASK(_vector_); \
+ HAL_TRANSLATE_VECTOR((_vector_), _index_); \
+ if (cyg_hal_interrupt_handlers[_index_] \
+ == (CYG_ADDRESS)(_isr_)) \
+ { \
+ cyg_hal_interrupt_handlers[_index_] = \
+ (CYG_ADDRESS)&hal_default_isr; \
+ cyg_hal_interrupt_data[_index_] = 0; \
+ cyg_hal_interrupt_objects[_index_] = 0; \
+ } \
+CYG_MACRO_END
+
+#define HAL_VSR_GET( _vector_, _pvsr_ ) \
+ *((CYG_ADDRESS *)(_pvsr_)) = cyg_hal_vsr_table[(_vector_)];
+
+
+#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \
+CYG_MACRO_START \
+ if( (_poldvsr_) != NULL ) \
+ *(CYG_ADDRESS *)(_poldvsr_) = cyg_hal_vsr_table[(_vector_)]; \
+ cyg_hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_); \
+CYG_MACRO_END
+
+
+// This is an ugly name, but what it means is: grab the VSR back to eCos
+// internal handling, or if you like, the default handler. But if
+// cooperating with a ROM monitor, the default behaviour is to pass most
+// exceptions to it. This macro undoes that so that eCos handles the
+// exception. So use it with care.
+
+#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) \
+ CYG_MACRO_START \
+ if( (void*)_poldvsr_ != (void*)NULL ) \
+ *(CYG_ADDRESS *)_poldvsr_ = cyg_hal_vsr_table[_vector_]; \
+ cyg_hal_vsr_table[_vector_] = rom_vsr_table[_vector_]; \
+ CYG_MACRO_END
+
+// -------------------------------------------------------------------------
+// Interrupt control macros.
+
+// The following interrupt control macros are the default for the ColdFire
+// architecture. Some processor variants will override these definitions in
+// their var_intr.h file.
+
+#ifndef HAL_CF_SET_SR
+#define HAL_CF_SET_SR(__newsr__) \
+ CYG_MACRO_START \
+ asm volatile ("move.w %0,%%sr\n" \
+ : \
+ : "d" ((CYG_INTERRUPT_STATE)(__newsr__))); \
+ CYG_MACRO_END
+#endif // HAL_CF_SET_SR
+
+#ifndef HAL_ENABLE_INTERRUPTS
+#define HAL_ENABLE_INTERRUPTS() \
+ CYG_MACRO_START \
+ CYG_INTERRUPT_STATE _msk_; \
+ HAL_QUERY_INTERRUPTS(_msk_); \
+ HAL_CF_SET_SR((_msk_ & (CYG_INTERRUPT_STATE)0xf8ff)); \
+ CYG_MACRO_END
+#endif // HAL_ENABLE_INTERRUPTS
+
+#ifndef HAL_DISABLE_INTERRUPTS
+#define HAL_DISABLE_INTERRUPTS(_old_) \
+ CYG_MACRO_START \
+ HAL_QUERY_INTERRUPTS(_old_); \
+ HAL_CF_SET_SR((_old_ | (CYG_INTERRUPT_STATE)0x0700)); \
+ CYG_MACRO_END
+#endif //HAL_DISABLE_INTERRUPTS
+
+#ifndef HAL_RESTORE_INTERRUPTS
+#define HAL_RESTORE_INTERRUPTS(_prev_) \
+ CYG_MACRO_START \
+ CYG_INTERRUPT_STATE _msk_; \
+ HAL_QUERY_INTERRUPTS(_msk_); \
+ _msk_ &= (CYG_INTERRUPT_STATE)0xf8ff; \
+ _msk_ |= (((CYG_INTERRUPT_STATE)(_prev_)) \
+ & (CYG_INTERRUPT_STATE)0x0700); \
+ asm volatile ("move.w %0,%%sr\n" \
+ : \
+ : "d" (_msk_)); \
+ CYG_MACRO_END
+#endif // HAL_RESTORE_INTERRUPTS
+
+// Use the extra assignment to avoid warnings.
+// The compiler should optimize it out.
+#ifndef HAL_QUERY_INTERRUPTS
+#define HAL_QUERY_INTERRUPTS(__oldmask__) \
+ CYG_MACRO_START \
+ CYG_INTERRUPT_STATE _omsk_ = (CYG_INTERRUPT_STATE)(__oldmask__); \
+ asm volatile ("move.w %%sr,%0\n" \
+ : "=d" (_omsk_) \
+ : ); \
+ (__oldmask__) = (__typeof__(__oldmask__))_omsk_; \
+ CYG_MACRO_END
+#endif // HAL_QUERY_INTERRUPTS
+
+// ---------------------------------------------------------------------------
+// End of hal_intr.h
+#endif // ifndef CYGONCE_HAL_HAL_INTR_H
--- /dev/null
+#ifndef CYGONCE_HAL_HAL_IO_H
+#define CYGONCE_HAL_HAL_IO_H
+
+//=============================================================================
+//
+// hal_io.h
+//
+// HAL device IO register support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Provide ColdFire-specific IO register definitions.
+// Usage: #include <cyg/hal/hal_io.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// ---------------------------------------------------------------------------
+// IO Register address.
+// This type is for recording the address of an IO register.
+
+typedef volatile CYG_ADDRWORD HAL_IO_REGISTER;
+
+// ---------------------------------------------------------------------------
+// BYTE Register access.
+// Individual and vectorized access to 8 bit registers.
+
+#define HAL_READ_UINT8( _register_, _value_ ) \
+ CYG_MACRO_START \
+ ((_value_) = *((volatile CYG_BYTE *)(_register_))); \
+ CYG_MACRO_END
+
+#define HAL_WRITE_UINT8( _register_, _value_ ) \
+ CYG_MACRO_START \
+ (*((volatile CYG_BYTE *)(_register_)) = (_value_)); \
+ CYG_MACRO_END
+
+#define HAL_READ_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \
+ CYG_MACRO_START \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) { \
+ (_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_j_]; \
+ } \
+ CYG_MACRO_END
+
+#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \
+ CYG_MACRO_START \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) { \
+ ((volatile CYG_BYTE *)(_register_))[_j_] = (_buf_)[_i_]; \
+ } \
+ CYG_MACRO_END
+
+
+// ---------------------------------------------------------------------------
+// 16 bit access.
+// Individual and vectorized access to 16 bit registers.
+
+#define HAL_READ_UINT16( _register_, _value_ ) \
+ CYG_MACRO_START \
+ ((_value_) = *((volatile CYG_WORD16 *)(_register_))); \
+ CYG_MACRO_END
+
+#define HAL_WRITE_UINT16( _register_, _value_ ) \
+ CYG_MACRO_START \
+ (*((volatile CYG_WORD16 *)(_register_)) = (_value_)); \
+ CYG_MACRO_END
+
+#define HAL_READ_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \
+ CYG_MACRO_START \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) { \
+ (_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_j_]; \
+ } \
+ CYG_MACRO_END
+
+#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \
+ CYG_MACRO_START \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) { \
+ ((volatile CYG_WORD16 *)(_register_))[_j_] = (_buf_)[_i_]; \
+ } \
+ CYG_MACRO_END
+
+// ---------------------------------------------------------------------------
+// 32 bit access.
+// Individual and vectorized access to 32 bit registers.
+
+#define HAL_READ_UINT32( _register_, _value_ ) \
+ CYG_MACRO_START \
+ ((_value_) = *((volatile CYG_WORD32 *)(_register_))); \
+ CYG_MACRO_END
+
+#define HAL_WRITE_UINT32( _register_, _value_ ) \
+ CYG_MACRO_START \
+ (*((volatile CYG_WORD32 *)(_register_)) = (_value_)); \
+ CYG_MACRO_END
+
+#define HAL_READ_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \
+ CYG_MACRO_START \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) { \
+ (_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_]; \
+ } \
+ CYG_MACRO_END
+
+#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \
+ CYG_MACRO_START \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) { \
+ ((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_]; \
+ } \
+ CYG_MACRO_END
+
+// ---------------------------------------------------------------------------
+// End of hal_io.h
+#endif // ifndef CYGONCE_HAL_HAL_IO_H
--- /dev/null
+#ifndef CYGONCE_HAL_STARTUP_H
+#define CYGONCE_HAL_STARTUP_H
+
+//=============================================================================
+//
+// hal_startup.h
+//
+// HAL startup definitions for the ColdFire architecture
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright eCosCentric Ltd.
+//
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Provide ColdFire-specific startup definitions.
+// Usage: #include <cyg/hal/hal_startup.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_intr.h>
+
+// Include the variant-specific startup header
+#include <cyg/hal/var_startup.h>
+
+externC void hal_reset(void) __attribute__ ((section (".boot")));
+
+// ---------------------------------------------------------------------------
+// End of hal_startup.h
+#endif // CYGONCE_HAL_STARTUP_H
--- /dev/null
+//==========================================================================
+//
+// coldfire.ld
+//
+// Linker script
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Coldfire-specific linker script definitions.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+STARTUP(vectors.o)
+ENTRY(_start)
+#ifdef EXTRAS
+INPUT(extras.o)
+#endif
+#if (__GNUC__ >= 3)
+GROUP(libtarget.a libgcc.a libsupc++.a)
+#else
+GROUP(libtarget.a libgcc.a)
+#endif
+
+#define ALIGN_LMA 4
+#define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1))
+#define LMA_EQ_VMA
+#define FORCE_OUTPUT . = .
+
+#define SECTIONS_BEGIN
+
+#define SECTION_boot(_region_, _vma_, _lma_) \
+ .boot _vma_ : _lma_ \
+ { \
+ FORCE_OUTPUT; \
+ *(.boot*) \
+ . = ALIGN(4); \
+ } \
+ > _region_
+
+#define SECTION_text(_region_, _vma_, _lma_) \
+ .text _vma_ : _lma_ \
+ { \
+ _stext = .; \
+ *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) \
+ . = ALIGN(4); \
+ } \
+ > _region_ \
+ _etext = .; PROVIDE (etext = .);
+
+#define SECTION_fini(_region_, _vma_, _lma_) \
+ .fini _vma_ : _lma_ \
+ { \
+ FORCE_OUTPUT; \
+ *(.fini) \
+ . = ALIGN(4); \
+ } \
+ > _region_
+
+#define SECTION_rodata1(_region_, _vma_, _lma_) \
+ .rodata1 _vma_ : _lma_ \
+ { \
+ FORCE_OUTPUT; \
+ *(.rodata1*) \
+ . = ALIGN(4); \
+ } \
+ > _region_
+
+#define SECTION_rodata(_region_, _vma_, _lma_) \
+ .rodata _vma_ : _lma_ \
+ { \
+ FORCE_OUTPUT; \
+ *(.rodata*) \
+ . = ALIGN(4); \
+ } \
+ > _region_
+
+#define SECTION_fixup(_region_, _vma_, _lma_) \
+ .fixup _vma_ : _lma_ \
+ { \
+ __FIXUP_START__ = ABSOLUTE(.); \
+ *(.fixup) \
+ . = ALIGN(4); \
+ __FIXUP_END__ = ABSOLUTE(.); \
+ } \
+ > _region_
+
+#define SECTION_gcc_except_table(_region_, _vma_, _lma_) \
+ .gcc_except_table _vma_ : _lma_ \
+ { \
+ __EXCEPT_START__ = ABSOLUTE(.); \
+ *(.gcc_except_table) \
+ . = ALIGN(4); \
+ __EXCEPT_END__ = ABSOLUTE(.); \
+ } \
+ > _region_
+
+#define SECTION_data(_region_, _vma_, _lma_) \
+ .data _vma_ : _lma_ \
+ { \
+ __ram_data_start = ABSOLUTE(.); \
+ *(.data*) \
+ __GOT1_START__ = ABSOLUTE(.); \
+ *(.got1) \
+ __GOT1_END__ = ABSOLUTE(.); \
+ . = ALIGN (4); \
+ /* Put .ctors and .dtors next to the .got2 section, so that */ \
+ /* the pointers get relocated with -mrelocatable. */ \
+ __CTOR_LIST__ = ABSOLUTE(.); \
+ KEEP(*(SORT(.ctors*))); \
+ __CTOR_END__ = ABSOLUTE(.); \
+ __DTOR_LIST__ = ABSOLUTE(.); \
+ KEEP(*(SORT(.dtors*))) \
+ __DTOR_END__ = ABSOLUTE(.); \
+ . = ALIGN(4); \
+ KEEP(*( SORT (.ecos.table.*))); \
+ . = ALIGN (4); \
+ *( .2ram.*) ; \
+ __GOT2_START__ = ABSOLUTE(.); \
+ *(.got2) \
+ __GOT2_END__ = ABSOLUTE(.); \
+ __GOT_START = ABSOLUTE(.); \
+ _GLOBAL_OFFSET_TABLE_ = ABSOLUTE(. + 32768); \
+ _SDA_BASE_ = ABSOLUTE(.); \
+ *(.got.plt) *(.got) \
+ __GOT_END__ = ABSOLUTE(.); \
+ *(.dynamic) \
+ *(.eh_frame) \
+ /* We want the small data sections together, so single-instruction */ \
+ /* offsets can access them all, and initialized data all before */ \
+ /* uninitialized, so we can shorten the on-disk segment size. */ \
+ __SDATA_START__ = ABSOLUTE(.); \
+ *(.sdata) *(.sdata.*) \
+ __SDATA2_START__ = ABSOLUTE(.); \
+ *(.sdata2*) \
+ . = ALIGN(4); \
+ __ram_data_end = ABSOLUTE(.); \
+ __ram_data_size = ABSOLUTE (.) - ABSOLUTE(__ram_data_start); \
+ } \
+ > _region_ \
+ __rom_data_start = LOADADDR(.data); \
+ __rom_data_size = SIZEOF(.data); \
+ __rom_data_end = __rom_data_start + __rom_data_size;
+
+#define SECTION_bss(_region_, _vma_, _lma_) \
+ .bss _vma_ : _lma_ \
+ { \
+ __bss_start = ABSOLUTE (.); \
+ FORCE_OUTPUT; \
+ *(.dynbss*) *(.bss*) *(COMMON) *(.sbss*) *(.scommon*) \
+ . = ALIGN(4); \
+ __bss_end = ABSOLUTE (.); \
+ __bss_size = ABSOLUTE (.) - ABSOLUTE(__bss_start); \
+ } \
+ > _region_
+
+#define SECTION_stab \
+ .stab 0 (NOLOAD) : \
+ { \
+ *(.stab) \
+ }
+
+#define SECTION_stabstr \
+ .stabstr 0 (NOLOAD) : \
+ { \
+ *(.stabstr) \
+ }
+
+#define SECTION_comment \
+ .comment 0 (NOLOAD) : \
+ { \
+ *(.comment) \
+ }
+
+#define SECTION_uninvar(_region_, _vma_, _lma_) \
+ .uninvar _vma_ : _lma_ \
+ { \
+ __uninvar_start = ABSOLUTE (.); \
+ FORCE_OUTPUT; \
+ *(.uninvar); \
+ . = ALIGN(4); \
+ __uninvar_end = ABSOLUTE (.); \
+ __uninvar_size = ABSOLUTE (.) - ABSOLUTE(__uninvar_start); \
+ } \
+ > _region_
+
+#define SECTION_romvec(_region_, _vma_, _lma_) \
+ .romvec _vma_ : _lma_ \
+ { \
+ __romvec_start = ABSOLUTE (.); \
+ FORCE_OUTPUT; \
+ KEEP(*(.romvec)); \
+ . = ALIGN(4); \
+ __romvec_end = ABSOLUTE (.); \
+ __romvec_size = ABSOLUTE (.) - ABSOLUTE(__romvec_start); \
+ } \
+ > _region_
+
+#define SECTION_ramvec(_region_, _vma_, _lma_) \
+ .ramvec _vma_ : _lma_ \
+ { \
+ __ramvec_start = ABSOLUTE (.); \
+ FORCE_OUTPUT; \
+ KEEP(*(.ramvec)); \
+ . = ALIGN(4); \
+ __ramvec_end = ABSOLUTE (.); \
+ __ramvec_size = ABSOLUTE (.) - ABSOLUTE(__ramvec_start); \
+ } \
+ > _region_
+
+#define SECTION_virtual_vec_table(_region_, _vma_, _lma_) \
+ .virtual_vec_table _vma_ : _lma_ \
+ { \
+ __virtual_vec_table_start = ABSOLUTE (.); \
+ . += 0x100; \
+ __virtual_vec_table_end = ABSOLUTE (.); \
+ __virtual_vec_table_size = ABSOLUTE (.) - ABSOLUTE(__virtual_vec_table_start); \
+ } \
+ > _region_
+
+#define SECTIONS_END \
+ SECTION_stab \
+ SECTION_stabstr \
+ SECTION_comment \
+ . = ALIGN(0x4); _end = .; PROVIDE (end = .);
+
+#include <pkgconf/system.h>
+#include CYGHWR_MEMORY_LAYOUT_LDI
+
+hal_virtual_vector_table = __virtual_vec_table_start;
--- /dev/null
+//========================================================================
+//
+// coldfire_stub.c
+//
+// Helper functions for stub
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Helper functions for stub, generic to all ColdFire
+// processors.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <stddef.h>
+#include <string.h> // memcpy, memset
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#include <cyg/hal/hal_stub.h>
+
+#include <cyg/hal/hal_stub.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id
+#endif
+
+// Given a trap value TRAP, return the corresponding signal.
+int __computeSignal (unsigned int trap_number)
+{
+ switch (trap_number)
+ {
+
+ case CYGNUM_HAL_VECTOR_BUSERR:
+ case CYGNUM_HAL_VECTOR_ADDRERR:
+ return SIGBUS;
+
+ case CYGNUM_HAL_VECTOR_ILLINST:
+ case CYGNUM_HAL_VECTOR_UNSUPINST:
+ return SIGILL;
+
+ case CYGNUM_HAL_VECTOR_ZERODIV:
+ case CYGNUM_HAL_VECTOR_FP_BRANCH:
+ case CYGNUM_HAL_VECTOR_FP_INEXACT:
+ case CYGNUM_HAL_VECTOR_FP_ZERODIV:
+ case CYGNUM_HAL_VECTOR_FP_UNDERFLOW:
+ case CYGNUM_HAL_VECTOR_FP_OPERAND:
+ case CYGNUM_HAL_VECTOR_FP_OVERFLOW:
+ case CYGNUM_HAL_VECTOR_FP_NAN:
+ case CYGNUM_HAL_VECTOR_FP_DENORM:
+ // Although not quite accurate, use this signal also for
+ // integer division.
+ return SIGFPE;
+
+ case CYGNUM_HAL_VECTOR_PRIVVIOLATION:
+ return SIGILL;
+ case CYGNUM_HAL_VECTOR_TRACE:
+ // Instruction trace
+ return SIGTRAP;
+
+ case CYGNUM_HAL_VECTOR_L1010:
+ case CYGNUM_HAL_VECTOR_L1111:
+ case CYGNUM_HAL_VECTOR_UNINITINT:
+ case CYGNUM_HAL_VECTOR_SPURINT:
+ return SIGTRAP;
+
+ case CYGNUM_HAL_VECTOR_TRAPFIRST ... CYGNUM_HAL_VECTOR_TRAPLAST:
+ return SIGTRAP;
+
+ case CYGNUM_HAL_VECTOR_AUTOVEC1 ... CYGNUM_HAL_VECTOR_AUTOVEC7:
+ case CYGNUM_HAL_VECTOR_USERINTRFIRST ... CYGNUM_HAL_VECTOR_USERINTRLAST:
+ // External interrupt
+ return SIGINT;
+
+ default:
+ return SIGTERM;
+ }
+}
+
+
+// Return the trap number corresponding to the last-taken trap.
+int __get_trap_number (void)
+{
+ // The vector is not not part of the GDB register set so get it
+ // directly from the saved context.
+ return HAL_CF_EXCEPTION_VECTOR(_hal_registers->fmt_vec_word);
+}
+
+
+// Set the currently-saved pc register value to PC.
+void set_pc (target_register_t pc)
+{
+ put_register (PC, pc);
+}
+
+
+// Return the offset of a register in the GDB_Registers structure.
+static int reg_offset(regnames_t reg)
+{
+ switch(reg)
+ {
+ case D0 ... A7:
+ return reg * 4;
+
+ case SR:
+ return offsetof(GDB_Registers, sr);
+
+ default:
+ case PC:
+ return offsetof(GDB_Registers, pc);
+ }
+}
+
+
+// Return the currently-saved value corresponding to register REG of
+// the exception context.
+target_register_t get_register(regnames_t reg)
+{
+ target_register_t val;
+ int offset = reg_offset(reg);
+
+ if (REGSIZE(reg) > sizeof(target_register_t))
+ return -1;
+
+ val = _registers[offset/sizeof(target_register_t)];
+
+ return val;
+}
+
+
+// Store VALUE in the register corresponding to WHICH in the exception
+// context.
+void put_register(regnames_t which, target_register_t value)
+{
+ int offset = reg_offset(which);
+
+ if (REGSIZE(which) > sizeof(target_register_t))
+ return;
+
+ _registers[offset/sizeof(target_register_t)] = value;
+}
+
+
+// Write the contents of register WHICH into VALUE as raw bytes. This
+// is only used for registers larger than sizeof(target_register_t).
+// Return non-zero if it is a valid register.
+int get_register_as_bytes(regnames_t which, char *value)
+{
+ int offset = reg_offset(which);
+
+ memcpy (value, (char *)_registers + offset, REGSIZE(which));
+ return 1;
+}
+
+
+// Alter the contents of saved register WHICH to contain VALUE. This
+// is only used for registers larger than sizeof(target_register_t).
+// Return non-zero if it is a valid register.
+int put_register_as_bytes(regnames_t which, char *value)
+{
+ int offset = reg_offset(which);
+
+ memcpy ((char *)_registers + offset, value, REGSIZE(which));
+ return 1;
+}
+
+
+// ---------------------------------------------------------------------
+// Single-step support
+
+// Set things up so that the next user resume will execute one instruction.
+// This may be done by setting breakpoints or setting a single step flag
+// in the saved user registers, for example.
+
+#define SR_TRACE 0x8000
+
+void __single_step(void)
+{
+ target_register_t sr = get_register (SR);
+
+ // Set trace flag in the exception context.
+ sr |= SR_TRACE;
+
+ put_register (SR, sr);
+}
+
+
+// Clear the single-step state.
+void __clear_single_step(void)
+{
+ target_register_t sr = get_register (SR);
+
+ // Clear single-step flag in the exception context.
+ sr &= ~SR_TRACE;
+
+ put_register (SR, sr);
+}
+
+
+void __install_breakpoints(void)
+{
+ // NOP since single-step HW exceptions are used instead of
+ // breakpoints.
+}
+
+
+void __clear_breakpoints(void)
+{
+ // NOP since single-step HW exceptions are used instead of
+ // breakpoints.
+}
+
+
+// If the breakpoint we hit is in the breakpoint() instruction, return a
+// non-zero value.
+int __is_breakpoint_function(void)
+{
+ return (get_register(PC) == (target_register_t) &CYG_LABEL_NAME(_breakinst));
+}
+
+
+// Skip the current instruction. Since this is only called by the
+// stub when the PC points to a breakpoint or trap instruction,
+// we can safely just skip 2.
+void __skipinst(void)
+{
+ put_register (PC, get_register (PC) + HAL_BREAKINST_SIZE);
+}
+
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
--- /dev/null
+|=============================================================================
+|
+| context.S
+|
+| ColdFire architecture context switch code
+|
+|=============================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| 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.
+| -------------------------------------------
+|###ECOSGPLCOPYRIGHTEND####
+|=============================================================================
+|#####DESCRIPTIONBEGIN####
+|
+| Author(s): Enrico Piria
+| Contributors:
+| Date: 2005-25-06
+| Purpose: This file contains implementations of the thread context
+| switch routines. It also contains the longjmp() and setjmp()
+| routines.
+|
+|####DESCRIPTIONEND####
+|========================================================================
+
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/cf_offsets.inc>
+#include <cyg/hal/arch.inc>
+
+
+| ----------------------------------------------------------------------------
+| hal_thread_switch_context - Switch between two threads
+|
+| externC void hal_thread_switch_context(CYG_ADDRESS to, CYG_ADDRESS from)
+|
+| INPUT:
+| 0(%sp) : return address
+| 4(%sp) : to - address of sp of next thread to execute
+| 8(%sp) : from - address of sp save location of current thread
+|
+| OUTPUT:
+| None
+|
+| RETURN VALUE:
+| None
+|
+| d0, d1, a0, a1 are ours to abuse. Other registers are not touched.
+
+FUNC_START(hal_thread_switch_context)
+
+ ctx_save_registers
+
+ | Read to and from parameters from the stack
+ move.l CYGARC_CF_CONTEXT_SIZE+4(%sp),%a0
+ move.l CYGARC_CF_CONTEXT_SIZE+8(%sp),%a1
+
+ | Store this thread's current stack pointer to *from
+ move.l %sp,(%a1)
+
+ | Load the stack pointer for the next thread from *to
+ move.l (%a0),%sp
+
+ ctx_restore_registers
+
+ | Return to caller
+ rts
+
+
+| ----------------------------------------------------------------------------
+| hal_thread_load_context - Load thread context
+|
+| externC void hal_thread_load_context(CYG_ADDRESS to)
+|
+| INPUT:
+| 4(%sp) : to - address of sp of next thread to execute
+|
+| OUTPUT:
+| None
+|
+| RETURN VALUE:
+| None
+|
+| d0, d1, a0, a1 are ours to abuse.
+
+FUNC_START(hal_thread_load_context)
+
+ | Read the to parameter from the stack and switch to that stack
+ | pointer
+ move.l 4(%sp),%a0
+ move.l (%a0),%sp
+
+ | Load all of the preserved registers from the stack
+ movem.l CYGARC_CFREG_DREGS(%sp),%d0-%d7
+ movem.l CYGARC_CFREG_AREGS(%sp),%a0-%a6
+
+ | Starting SR
+ move.w CYGARC_CF_SR(%sp), %d0
+ move.w %d0,%sr
+
+ | Deallocate context frame
+ lea CYGARC_CF_CONTEXT_SIZE(%sp),%sp
+
+ | Return
+ rts
+
+
+| ----------------------------------------------------------------------------
+| The following routines are based on the hal_jmp_buf structure layout, defined
+| in hal_arch.h
+
+| ----------------------------------------------------------------------------
+| hal_setjmp - setjmp for the ColdFire architecture
+|
+| externC int hal_setjmp(hal_jmp_buf env)
+|
+| INPUT:
+| 0(%sp) : return address
+| 4(%sp) : env - address of a hal_jmp_buf structure
+|
+| OUTPUT:
+| None
+|
+| RETURN VALUE:
+| This routine always returns zero in d0.l.
+|
+| d0, d1, a0, a1 are ours to abuse.
+
+FUNC_START(hal_setjmp)
+
+ | Get a pointer to the register buffer
+ move.l 4(%sp),%a0
+
+ | Store all of the preserved registers
+ movem.l %d2-%d7,CYGARC_JMPBUF_REG_D2(%a0)
+ movem.l %a2-%a6,CYGARC_JMPBUF_REG_A2(%a0)
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ | Store MAC registers
+
+ | Store MACSR register
+ move.l %macsr,%d0
+ move.l %d0,CYGARC_JMPBUF_REG_MACSR(%a0)
+
+ | Switch to integer mode. This allows to save the contents of ACC
+ | without rounding
+ and.l #0x000000df,%d0
+ move.l %d0,%macsr
+
+ | Store ACC register
+ move.l %acc,%d0
+ move.l %d0,CYGARC_JMPBUF_REG_MACC(%a0)
+
+ | Store MASK register
+ move.l %mask,%d0
+ move.l %d0,CYGARC_JMPBUF_REG_MASK(%a0)
+#endif
+
+ | Store the stack pointer
+ move.l %sp,CYGARC_JMPBUF_REG_SP(%a0)
+
+ | Store the return address into the structure
+ move.l (%sp),CYGARC_JMPBUF_REG_PC(%a0)
+
+ | Load a zero return value
+ clr.l %d0
+
+ | Return
+ rts
+
+
+| ----------------------------------------------------------------------------
+| hal_longjmp - longjmp for the ColdFire architecture
+|
+| externC void hal_longjmp(hal_jmp_buf env, int val)
+|
+| INPUT:
+| 0(%sp): return address
+| 4(%sp): env - address of a hal_jmp_buf structure
+| 8(%sp): val - the non-zero value to return
+|
+| OUTPUT:
+| None
+|
+| RETURN VALUE:
+| This routine always returns the value from the val parameter in d0.l
+| and to the location of the PC in the env structure.
+
+FUNC_START(hal_longjmp)
+
+ | Load the return value parameter
+ move.l 8(%sp),%d0
+
+ | Get a pointer to the buffer to read our state from
+ move.l 4(%sp),%a0
+
+ | Load all of the preserved registers
+ movem.l CYGARC_JMPBUF_REG_D2(%a0),%d2-%d7
+ movem.l CYGARC_JMPBUF_REG_A2(%a0),%a2-%a6
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ | Load MAC registers
+
+ | Load MACSR register
+ move.l CYGARC_JMPBUF_REG_MACSR(%a0),%d1
+ move.l %d1,%macsr
+
+ | Load ACC register
+ move.l CYGARC_JMPBUF_REG_MACC(%a0),%d1
+ move.l %d1,%acc
+
+ | Load MASK register
+ move.l CYGARC_JMPBUF_REG_MASK(%a0),%d1
+ move.l %d1,%mask
+#endif
+
+ | Load the stack pointer
+ move.l CYGARC_JMPBUF_REG_SP(%a0),%sp
+
+ | Load return address and store it on stack
+ move.l CYGARC_JMPBUF_REG_PC(%a0),(%sp)
+
+ | Return to caller
+ rts
--- /dev/null
+//==========================================================================
+//
+// hal_misc.c
+//
+// HAL miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Miscellaneous routine and variable definitions.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h> // diag_printf
+
+#include <cyg/hal/hal_arch.h> // HAL header
+
+#include <cyg/hal/hal_intr.h> // VSR/ISR defines
+
+// -------------------------------------------------------------------------
+// ISR table
+
+volatile CYG_ADDRESS cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+volatile CYG_ADDRESS cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// -------------------------------------------------------------------------
+// VSR table
+
+externC void __handle_exception(void);
+
+externC HAL_SavedRegisters * _hal_registers;
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+externC void* volatile __mem_fault_handler;
+#endif
+
+// Defined in variant HAL
+externC void hal_interrupt_update_level(void);
+
+// --------------------------------------------------------------------------
+// Default exception handler.
+
+void hal_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
+{
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+ // If we caught an exception inside the stubs, see if we were expecting it
+ // and if so jump to the saved address.
+ if (__mem_fault_handler) {
+ regs->pc = (CYG_ADDRWORD)__mem_fault_handler;
+ // Caught an exception inside stubs
+ return;
+ }
+
+ // Set the pointer to the registers of the current exception
+ // context. At entry the GDB stub will expand the
+ // HAL_SavedRegisters structure into a (bigger) register array.
+ _hal_registers = regs;
+
+ __handle_exception();
+
+#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+ defined(CYGPKG_HAL_EXCEPTIONS)
+
+ // We should decode the vector and pass a more appropriate
+ // value as the second argument. For now we simply pass a
+ // pointer to the saved registers. We should also divert
+ // breakpoint and other debug vectors into the debug stubs.
+
+ cyg_hal_deliver_exception(vector, (CYG_ADDRWORD)regs);
+
+#else
+
+ CYG_FAIL("Exception!!!");
+
+#endif
+
+ return;
+}
+
+// --------------------------------------------------------------------------
+// Default ISR handler.
+
+cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ CYG_FAIL("Unexpected ISR");
+ return 0;
+}
+
+// --------------------------------------------------------------------------
+// Default spurious interrupt handler. This routine is called with all
+// interrupts disabled.
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
+
+void hal_spurious_interrupt(HAL_SavedRegisters *regs) CYGBLD_ATTRIB_WEAK;
+
+void hal_spurious_interrupt(HAL_SavedRegisters *regs)
+{
+ CYG_FAIL("Spurious interrupt!!");
+}
+
+#endif
+
+// --------------------------------------------------------------------------
+// Idle thread action.
+
+void hal_idle_thread_action(cyg_uint32 count)
+{
+}
+
+// -----------------------------------------------------------------------
+// Determine the index of the ls bit of the supplied mask.
+
+cyg_uint32 hal_lsbit_index(cyg_uint32 mask)
+{
+ cyg_uint32 n = mask;
+
+ static const signed char tab[64] =
+ { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
+ 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
+ 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
+ 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
+ };
+
+ n &= ~(n-1UL);
+ n = (n<<16)-n;
+ n = (n<<6)+n;
+ n = (n<<4)+n;
+
+ return tab[n>>26];
+}
+
+// -----------------------------------------------------------------------
+// Determine the index of the ms bit of the supplied mask.
+
+cyg_uint32 hal_msbit_index(cyg_uint32 mask)
+{
+ cyg_uint32 x = mask;
+ cyg_uint32 w;
+
+ // Phase 1: make word with all ones from that one to the right
+ x |= x >> 16;
+ x |= x >> 8;
+ x |= x >> 4;
+ x |= x >> 2;
+ x |= x >> 1;
+
+ // Phase 2: calculate number of "1" bits in the word
+ w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+ w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+ w = w + (w >> 4);
+ w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
+ return (cyg_uint32)((w + (w >> 16)) & 0xFF) - 1;
+
+}
--- /dev/null
+//==========================================================================
+//
+// hal_mk_defs.c
+//
+// HAL "make defs" program
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: gthomas, jskov
+// Date: 2005-25-06
+// Purpose: ColdFire architecture dependent definition generator
+// Description: This file contains code that can be compiled by the target
+// compiler and used to generate machine specific definitions
+// suitable for use in assembly code.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h> // HAL header
+#include <cyg/hal/hal_intr.h> // HAL header
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# include <cyg/kernel/instrmnt.h>
+#endif
+
+// This program is used to generate definitions needed by
+// assembly language modules.
+//
+// This technique was first used in the OSF Mach kernel code:
+// generate asm statements containing #defines,
+// compile this file to assembler, and then extract the
+// #defines from the assembly-language output.
+
+#define DEFINE(sym, val) \
+ asm volatile("\n\t.equ\t" #sym ",%0" : : "i" (val))
+
+int
+main(void)
+{
+ // Exception/interrupt/context save buffer
+ DEFINE(CYGARC_CFREG_AREGS, offsetof(HAL_SavedRegisters, a[0]));
+ DEFINE(CYGARC_CFREG_DREGS, offsetof(HAL_SavedRegisters, d[0]));
+ DEFINE(CYGARC_CFREG_A0, offsetof(HAL_SavedRegisters, a[0]));
+ DEFINE(CYGARC_CFREG_A1, offsetof(HAL_SavedRegisters, a[1]));
+ DEFINE(CYGARC_CFREG_A2, offsetof(HAL_SavedRegisters, a[2]));
+ DEFINE(CYGARC_CFREG_A6, offsetof(HAL_SavedRegisters, a[6]));
+ DEFINE(CYGARC_CFREG_D0, offsetof(HAL_SavedRegisters, d[0]));
+ DEFINE(CYGARC_CFREG_D1, offsetof(HAL_SavedRegisters, d[1]));
+ DEFINE(CYGARC_CFREG_D2, offsetof(HAL_SavedRegisters, d[2]));
+ DEFINE(CYGARC_CFREG_PC, offsetof(HAL_SavedRegisters, pc));
+ DEFINE(CYGARC_CFREG_SP, offsetof(HAL_SavedRegisters, a[7]));
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ DEFINE(CYGARC_CFREG_MACC, offsetof(HAL_SavedRegisters, macc));
+ DEFINE(CYGARC_CFREG_MACSR, offsetof(HAL_SavedRegisters, macsr));
+ DEFINE(CYGARC_CFREG_MASK, offsetof(HAL_SavedRegisters, mask));
+#endif
+
+ DEFINE(CYGARC_CF_CONTEXT_SIZE, sizeof(HAL_SavedRegisters));
+
+ // Below only saved on exceptions/interrupts
+ DEFINE(CYGARC_CF_FMTVECWORD, offsetof(HAL_SavedRegisters, fmt_vec_word));
+ DEFINE(CYGARC_CF_SR, offsetof(HAL_SavedRegisters, sr));
+ DEFINE(CYGARC_CF_EXCEPTION_SIZE, sizeof(HAL_SavedRegisters));
+ DEFINE(CYGARC_CF_EXCEPTION_DECREMENT, offsetof(HAL_SavedRegisters, fmt_vec_word));
+
+ // Some other exception related definitions
+ DEFINE(CYGNUM_HAL_ISR_MIN, CYGNUM_HAL_ISR_MIN);
+ DEFINE(CYGNUM_HAL_ISR_COUNT, CYGNUM_HAL_ISR_COUNT);
+ DEFINE(CYGNUM_HAL_SPURIOUS_INTERRUPT, CYGNUM_HAL_SPURIOUS_INTERRUPT);
+ DEFINE(CYGNUM_HAL_VECTOR_DEBUGTRAP, CYGNUM_HAL_VECTOR_DEBUGTRAP);
+
+ // setjmp/longjmp related definitions
+ DEFINE(CYGARC_JMPBUF_REG_D2, offsetof(hal_jmp_buf_t, d2));
+ DEFINE(CYGARC_JMPBUF_REG_A2, offsetof(hal_jmp_buf_t, a2));
+ DEFINE(CYGARC_JMPBUF_REG_SP, offsetof(hal_jmp_buf_t, sp));
+ DEFINE(CYGARC_JMPBUF_REG_PC, offsetof(hal_jmp_buf_t, pc));
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ DEFINE(CYGARC_JMPBUF_REG_MACC, offsetof(hal_jmp_buf_t, macc));
+ DEFINE(CYGARC_JMPBUF_REG_MACSR, offsetof(hal_jmp_buf_t, macsr));
+ DEFINE(CYGARC_JMPBUF_REG_MASK, offsetof(hal_jmp_buf_t, mask));
+#endif
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------
+// EOF hal_mk_defs.c
--- /dev/null
+//==========================================================================
+//
+// hal_startup.c
+//
+// ColdFire architecture HAL startup code
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Architecture startup code.
+// Description: This module contains code that sets up the hardware and the
+// memory sections. All the code must be contained in the
+// section called ".boot", in order for the ROMRAM startup
+// to work properly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_startup.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/hal/hal_if.h> // hal_if_init
+#include <cyg/hal/hal_intr.h> // Interrupt definitions
+#include <cyg/hal/hal_stub.h> // initialize_stub
+
+externC void cyg_start(void);
+externC void hal_ctrlc_isr_init(void);
+
+static void hal_vsr_init(void) __attribute__ ((section (".boot")));
+static void hal_isr_init(void) __attribute__ ((section (".boot")));
+static void hal_init_ram_sections(void) __attribute__ ((section (".boot")));
+static void cyg_hal_invoke_constructors(void) __attribute__ ((section (".boot")));
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+externC unsigned char __romram_copy_source[];
+externC unsigned char __romram_copy_dest[];
+externC unsigned char __romram_copy_length[];
+
+#endif
+
+
+// -------------------------------------------------------------------------
+// Reset vector routine.
+
+void hal_reset(void)
+{
+ // Do any variant-specific reset initialization
+ var_reset();
+
+ // Do any platform-specific reset initialization
+ plf_reset();
+
+ // Initialize the RAM sections that the rest of the C code requires
+ hal_init_ram_sections();
+
+ // All program sections are now in place
+
+ // Make sure that every instruction above this one has been output by
+ // the compiler
+ HAL_REORDER_BARRIER();
+
+ // Now it is safe to use a stack in RAM
+ asm volatile ("lea cyg_interrupt_stack, %sp");
+
+ // It is now safe to call C functions which may rely on initialized
+ // data
+ hal_vsr_init();
+ hal_isr_init();
+
+ // Initialize variant HAL private data
+ var_init_data();
+
+ // Initialize platform HAL private data
+ plf_init_data();
+
+ // Initialize the virtual vector table
+ hal_if_init();
+
+ // Call C++ constructors
+ cyg_hal_invoke_constructors();
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ initialize_stub();
+#endif
+
+ // Init Ctrl-C debug ISR
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+ hal_ctrlc_isr_init();
+#endif
+
+ // Call cyg_start. This routine should not return.
+ cyg_start();
+}
+
+
+// -------------------------------------------------------------------------
+// Initialize the vector table.
+
+static void hal_vsr_init(void)
+{
+ unsigned int i;
+
+ // If we are starting up from ROM, or we are starting in
+ // RAM and NOT using a ROM monitor, initialize the VSR and ISR tables.
+#if defined(CYG_HAL_STARTUP_ROM) || \
+ defined(CYG_HAL_STARTUP_ROMRAM) || \
+ (defined(CYG_HAL_STARTUP_RAM) && \
+ !defined(CYGSEM_HAL_USE_ROM_MONITOR))
+
+ // Initialize the HAL's vector table with the ROM vector table
+ for (i = 0; i < CYGNUM_HAL_VSR_COUNT; i++)
+ cyg_hal_vsr_table[i] = rom_vsr_table[i];
+
+#elif defined(CYG_HAL_STARTUP_RAM) && defined(CYGSEM_HAL_USE_ROM_MONITOR)
+
+ // We only take control of the interrupt vectors,
+ // the rest are left to the ROM for now.
+ cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_UNINITINT] =
+ rom_vsr_table[CYGNUM_HAL_VECTOR_UNINITINT];
+
+ cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_SPURINT] =
+ rom_vsr_table[CYGNUM_HAL_VECTOR_SPURINT];
+
+ for(i = 0; i < CYGNUM_HAL_NUMAUTOVEC; i++)
+ cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_AUTOVEC1 + i] =
+ rom_vsr_table[CYGNUM_HAL_VECTOR_AUTOVEC1 + i];
+
+ for(i = 0; i < CYGNUM_HAL_NUMUSERINTR; i++)
+ cyg_hal_vsr_table[CYGNUM_HAL_VECTOR_USERINTRFIRST + i] =
+ rom_vsr_table[CYGNUM_HAL_VECTOR_USERINTRFIRST + i];
+
+#endif
+}
+
+
+// -------------------------------------------------------------------------
+// Initialize the ISRs.
+
+static void hal_isr_init(void)
+{
+ int i;
+
+ // Initialize all ISR entries to default
+ for (i = 0; i < CYGNUM_HAL_ISR_COUNT; i++)
+ {
+ cyg_hal_interrupt_handlers[i] = (CYG_ADDRESS) &hal_default_isr;
+ cyg_hal_interrupt_data[i] = (CYG_ADDRWORD) 0;
+ cyg_hal_interrupt_objects[i] = (CYG_ADDRESS) 0;
+ }
+}
+
+
+// -------------------------------------------------------------------------
+// Initialize the RAM sections
+// For an efficient copy, we suppose that the sections are aligned at a
+// 4-byte boundary and are a multiple of 4 bytes. Linker scripts should
+// guarantee this.
+
+static void hal_init_ram_sections(void)
+{
+ cyg_uint32 *m;
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+ {
+ // Initialize the RAM data section from the ROM image of the data
+ // section.
+ cyg_uint32 *p = (cyg_uint32 *) __romram_copy_dest;
+ cyg_uint32 *q = (cyg_uint32 *) __romram_copy_source;
+ cyg_uint32 length = 0;
+
+ while (length < (cyg_uint32) __romram_copy_length)
+ {
+ *p++ = *q++;
+ length += 4;
+ }
+ }
+#endif
+
+ // Initialize the bss sections to zero
+ m = (cyg_uint32 *) __bss_start;
+ while (m != (cyg_uint32 *) __bss_end)
+ *m++ = 0x0;
+}
+
+
+// -------------------------------------------------------------------------
+// Call static constructors.
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+cyg_bool cyg_hal_stop_constructors;
+#endif
+
+typedef void (*pfunc) (void);
+extern pfunc __CTOR_LIST__[];
+extern pfunc __CTOR_END__[];
+
+static void cyg_hal_invoke_constructors(void)
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ static pfunc *p = &__CTOR_END__[-1];
+
+ cyg_hal_stop_constructors = 0;
+ for (; p >= __CTOR_LIST__; p--) {
+ (*p) ();
+ if (cyg_hal_stop_constructors) {
+ p--;
+ break;
+ }
+ }
+#else
+ pfunc *p;
+
+ for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--)
+ (*p) ();
+#endif
+}
--- /dev/null
+|==========================================================================
+|
+| vectors.S
+|
+| ColdFire exception vectors
+|
+|==========================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| 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.
+| -------------------------------------------
+|###ECOSGPLCOPYRIGHTEND####
+|=============================================================================
+|#####DESCRIPTIONBEGIN####
+|
+| Author(s): Enrico Piria
+| Contributors: Wade Jensen
+| Date: 2005-25-06
+| Purpose: ColdFire exception vectors
+| Description: This file contains the first level default VSRs
+| that save and restore state for both exceptions and
+| interrupts.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <cyg/hal/cf_offsets.inc>
+#include <cyg/hal/arch.inc>
+#include <cyg/hal/variant.inc>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif
+
+| ----------------------------------------------------------------------------
+| Hardware reset vector
+
+ .section ".boot","x"
+ .balign 4
+ .globl cyg_hal_reset_vsr
+cyg_hal_reset_vsr:
+
+ | Define the entry point for the linker.
+ .globl _start
+_start:
+
+ | Make sure that all interrupts are masked.
+ hal_cpu_int_disable
+
+ | Initial setup. Just do the minimum to be able to perform
+ | initialization in C.
+
+ | Initialize CPU variant
+ hal_cpu_init
+
+ | Platform specific hardware initialization.
+ | This may include memory controller initialization.
+ hal_hardware_init
+
+ | Setup boot stack
+ hal_boot_stack_init
+
+ | Set up the initial frame pointer.
+ lea 0,%fp
+ link %fp,#0
+
+ | Call the C routine to complete the reset process.
+ .extern hal_reset
+ jsr hal_reset
+
+ | If we return, stop.
+9:
+ stop #0x2000
+ bra 9b
+
+
+| ----------------------------------------------------------------------------
+| Default exception vector handler
+|
+| The default handler for all machine exceptions. We save the
+| machine state and call the default C exception handler. This routine passes a
+| pointer to the saved state to the C exception handler. The stack pointer in
+| the saved state points to the the sp before the exception.
+| The format/vector word in the exception stack contains the vector
+| number.
+
+| void hal_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs);
+
+ .text
+ .balign 4
+ .globl cyg_hal_default_exception_vsr
+cyg_hal_default_exception_vsr:
+
+ | Disable all interrupts
+ hal_cpu_int_disable
+
+ | Preserve the entire state.
+ | Allocate space for all registers (including the stack pointer).
+ | Write all registers to the stack space.
+ lea.l -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
+ movem.l %d0-%d7,CYGARC_CFREG_DREGS(%sp)
+ movem.l %a0-%a6,CYGARC_CFREG_AREGS(%sp)
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ save_mac_registers %d0
+#endif
+
+ | Write the original stack pointer value to the stack.
+ | The format/vector word, sr, and pc are already on the stack.
+ find_original_sp %d0
+ move.l %d0,CYGARC_CFREG_SP(%sp)
+
+ | Calculate the vector number. The format/vector word on the stack
+ | contains the vector number.
+ move.w CYGARC_CF_FMTVECWORD(%sp),%d0
+ and.l #0x000003fc,%d0
+ lsr.l #2,%d0
+
+ | Pass a pointer to the saved state to the exception handler.
+ pea.l (%sp)
+
+ | Push the vector number parameter.
+ move.l %d0,-(%sp)
+
+ | Call the default exception handler. This routine may modify
+ | the exception context.
+ .extern hal_exception_handler
+ jsr hal_exception_handler
+
+ | Remove the vector number and the state pointer from the stack.
+ addq.l #2*4,%sp
+
+ | Get a pointer to the location following the exception context.
+ find_original_sp %d0
+
+ | Restore all of the registers that we do not need in the following
+ | code. We will copy all registers that are not restored here
+ | to the new stack before restoring them.
+
+#ifdef CYGHWR_HAL_COLDFIRE_MAC
+ restore_mac_registers %d0
+#endif
+
+ movem.l CYGARC_CFREG_D2(%sp),%d2-%d7
+ movem.l CYGARC_CFREG_A1(%sp),%a1-%a6
+
+ | Load the address of the new SP.
+ move.l CYGARC_CFREG_SP(%sp),%d1
+
+ | We now have:
+ | d0.l : original stack pointer
+ | d1.l : final stack pointer
+
+ | ColdFire programmer's manual doesn't tell if rte instruction expects
+ | the stack frame to be aligned at 32-bit boundaries.
+ | So, we align the new stack value, and adjust the format field
+ | accordingly. At the end of rte instruction the stack will thus point
+ | to the desired location.
+
+ | Compare the new stack address to the end of the exception context.
+ | This will tell us the order that we need to copy the exception
+ | stack and the remaining registers from the old exception context to
+ | the new one. The order is important because the stack frames might
+ | overlap.
+ cmp.l %d0,%d1
+
+ | If the new SP and the old one coincide.
+ beq 2f
+
+ | If the new SP is at a higher address than the old one.
+ bgt 1f
+
+ | The new SP is at a lower address than the old one. Copy from the
+ | lowest address to the highest address.
+
+ | Align stack at longword boundary
+ move.l %d1,%d0
+ and.l #0xfffffffc,%d0
+ move.l %d0,%a0
+
+ | Allocate new frame
+ sub.l #CYGARC_CF_CONTEXT_SIZE,%a0
+
+ | Copy D0, D1, A0, FVW, SR, and PC from the old stack to the new stack.
+ | Note that we copy in ascending order.
+
+ | Copy D0, D1, A0
+ move.l CYGARC_CFREG_D0(%sp),CYGARC_CFREG_D0(%a0)
+ move.l CYGARC_CFREG_D1(%sp),CYGARC_CFREG_D1(%a0)
+ move.l CYGARC_CFREG_A0(%sp),CYGARC_CFREG_A0(%a0)
+
+ | Based on target SP address, construct new format field
+ and.l #0x00000003,%d1
+ or.l #0x4,%d1
+ lsl.l #8,%d1
+ lsl.l #4,%d1
+
+ | Load old format field
+ move.w CYGARC_CF_FMTVECWORD(%sp),%d0
+
+ | Clear old format field
+ and.l #0x0fff,%d0
+
+ | Write the new one
+ or.l %d1,%d0
+ move.w %d0,CYGARC_CF_FMTVECWORD(%a0)
+
+ | Copy SR and PC
+ move.w CYGARC_CF_SR(%sp),CYGARC_CF_SR(%a0)
+ move.l CYGARC_CFREG_PC(%sp),CYGARC_CFREG_PC(%a0)
+
+ | A0 points to the top of the new stack
+ move.l %a0,%sp
+
+ | Restore remaining registers and exit
+ jmp 2f
+
+1:
+
+ | The new SP is at a higher address than the old one. Copy from the
+ | highest address to the lowest address.
+
+ | Align stack at longword boundary
+ move.l %d1,%d0
+ and.l #0xfffffffc,%d0
+ move.l %d0,%a0
+
+ | Allocate new frame
+ sub.l #CYGARC_CF_CONTEXT_SIZE,%a0
+
+ | Copy D0, D1, A0, FVW, SR, and PC from the old stack to the new stack.
+ | Note that we copy in descending order.
+
+ | Copy PC and SR
+ move.l CYGARC_CFREG_PC(%sp),CYGARC_CFREG_PC(%a0)
+ move.w CYGARC_CF_SR(%sp),CYGARC_CF_SR(%a0)
+
+ | Based on target SP address, construct new format field
+ and.l #0x00000003,%d1
+ or.l #0x4,%d1
+ lsl.l #8,%d1
+ lsl.l #4,%d1
+
+ | Load old format field
+ move.w CYGARC_CF_FMTVECWORD(%sp),%d0
+
+ | Clear old format field
+ and.l #0x0fff,%d0
+
+ | Write the new one
+ or.l %d1,%d0
+ move.w %d0,CYGARC_CF_FMTVECWORD(%a0)
+
+ | Copy A0, D1, D0
+ move.l CYGARC_CFREG_A0(%sp),CYGARC_CFREG_A0(%a0)
+ move.l CYGARC_CFREG_D1(%sp),CYGARC_CFREG_D1(%a0)
+ move.l CYGARC_CFREG_D0(%sp),CYGARC_CFREG_D0(%a0)
+
+ | A0 points to the top of the new stack
+ move.l %a0,%sp
+
+2:
+ | Restore remaining registers
+ move.l CYGARC_CFREG_D0(%sp),%d0
+ move.l CYGARC_CFREG_D1(%sp),%d1
+ move.l CYGARC_CFREG_A0(%sp),%a0
+ add.l #CYGARC_CF_EXCEPTION_DECREMENT,%sp
+
+ | Return from exception
+ rte
+
+
+| ----------------------------------------------------------------------------
+| Spurious interrupt vector handler
+|
+| Used for spurious and uninitialized interrupts.
+| It is unknown at which priority spurious interrupts are generated. So, the
+| safest thing to do is to disable all interrupts while processing spurious
+| ones.
+
+ .text
+ .balign 4
+ .globl cyg_hal_default_spurious_vsr
+cyg_hal_default_spurious_vsr:
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
+
+ | Disable all interrupts. On the first instruction, interrupt sampling
+ | is always disabled.
+ hal_cpu_int_disable
+
+ | Preserve all registers that this handler needs to preserve.
+ | The C code will preserve all other registers.
+ int_pres_regs
+
+ | Pass a pointer to the saved state to the interrupt handler.
+ pea.l (%sp)
+
+ | Call spurious interrupt handler
+ .extern hal_spurious_interrupt
+ jsr hal_spurious_interrupt
+
+ | Remove the arguments from the stack.
+ addq.l #4,%sp
+
+ | Restore the preserved registers for the current thread.
+ int_rest_regs
+
+#endif /* ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS */
+
+ | Just return from interrupt.
+ rte
+
+
+| ----------------------------------------------------------------------------
+| User interrupt vector handler
+|
+| Control is transferred here from a user interrupt vector (#64-255).
+| Before branching to common code, load a value to translate the
+| vector table offset to the ISR table offset.
+
+ .text
+ .balign 4
+ .globl cyg_hal_default_interrupt_vsr
+cyg_hal_default_interrupt_vsr:
+
+ | Disable all interrupts. On the first instruction, interrupt sampling
+ | is always disabled.
+ hal_cpu_int_disable
+
+ | Preserve all registers that this handler needs to preserve.
+ | The C code will preserve all other registers.
+ int_pres_regs
+
+ | It is safe to use breakpoints below this point.
+ .globl _cyg_hal_default_interrupt_vsr_bp_safe
+_cyg_hal_default_interrupt_vsr_bp_safe:
+
+ | Adding this value to the vector table offset will result in the
+ | corresponding offset into the ISR table.
+ move.l #(-CYGNUM_HAL_ISR_MIN)*4,%d2
+
+ | d2.l: Contains a value to translate the vector table offset to
+ | the ISR table offset.
+
+ | Calculate the vector offset. The format/vector word on the stack
+ | contains the vector number. Mask off all unused bits. The bit
+ | position of the vector number field makes it automatically multiplied
+ | by four.
+ move.w CYGARC_CF_FMTVECWORD(%sp),%d1
+ and.l #0x000003fc,%d1
+
+ | Calculate the ISR table offset. Add the vector table offset to the
+ | translation value.
+ add.l %d1,%d2
+
+ | Calculate the vector number using the vector table offset.
+ asr.l #2,%d1
+
+ | d2.l: Contains the offset into the ISR table.
+ | d1.l: Contains the vector number.
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+
+ | If we are supporting Ctrl-C interrupts from GDB, we must squirrel
+ | away a pointer to the saved interrupt state here so that we can
+ | plant a breakpoint at some later time.
+
+ .extern hal_saved_interrupt_state
+ move.l %sp,(hal_saved_interrupt_state)
+
+#endif
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+
+ | Lock the scheduler if we are using the kernel.
+ .extern cyg_scheduler_sched_lock
+ addq.l #1,cyg_scheduler_sched_lock
+
+#endif /* CYGFUN_HAL_COMMON_KERNEL_SUPPORT */
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+ | a0 = sp. We'll need it later
+ move.l %sp,%a0
+
+ cmp.l #__interrupt_stack_base,%sp
+
+ | If sp < base : not on istack
+ blt 1f
+
+ cmp.l #__interrupt_stack,%sp
+
+ | If sp <= top : already on istack
+ ble 2f
+
+1:
+ | Switch to istack
+ lea __interrupt_stack,%sp
+
+2:
+ | Save old SP on istack
+ pea (%a0)
+
+#endif
+
+#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
+
+ .extern cyg_instrument
+
+ | Save d1
+ move.l %d1,-(%sp)
+
+ | arg2 = 0
+ move.l #0,-(%sp)
+
+ | arg1 = vector number
+ move.l %d1,-(%sp)
+
+ | type = INTR,RAISE
+ move.l #0x0301,-(%sp)
+
+ | Call instrumentation
+ jsr cyg_instrument
+
+ | Remove args from stack
+ add.l #12,%sp
+
+ | Restore %d1
+ move.l (%sp)+,%d1
+
+#endif
+
+
+#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
+
+ | If interrupt nesting is enabled, we have to determine the IPL of the
+ | current interrupt. We inline the following macro, which is defined
+ | by ColdFire variants. The vector number of the current interrupt
+ | is passed in d0, and the return value is in d0.
+ | Registers a0-a1/d0-d1 are for use by the macro, other registers
+ | must be saved explicitly before being used.
+
+ | Save %d1
+ move.l %d1,-(%sp)
+
+ | Pass d1 as argument to macro
+ move.l %d1,%d0
+
+ | Retrieve IPL, which will be contained in d0
+ hal_variant_retrieve_ipl
+
+ | Shift IPL up to the same position occupied in sr
+ lsl.l #8,%d0
+
+ | Transform d0 in a mask to be applied to sr
+ or.l #0xfffff0ff,%d0
+
+ | Update sr. Use d1 as working register
+ move.w %sr,%d1
+ and.l %d0,%d1
+ move.w %d1,%sr
+
+ | Restore d1
+ move.l (%sp)+,%d1
+
+#endif
+
+ | We need to call the following routines. The isr address, data, and
+ | intr are all from the ISR table. The interrupt_end routine is
+ | only called if we are using the kernel. regs points to the saved
+ | registers on the stack. isr_ret is the return value from the ISR.
+ | vector is the vector number.
+
+ | static cyg_uint32 isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+
+ | externC void interrupt_end(cyg_uint32 isr_ret, Cyg_Interrupt *intr,
+ | HAL_SavedRegisters *regs)
+
+
+ | Push the data value from the table.
+ .extern cyg_hal_interrupt_data
+ lea cyg_hal_interrupt_data,%a0
+ move.l (%a0,%d2.l),-(%sp)
+
+ | Get the address of the ISR from the table.
+ .extern cyg_hal_interrupt_handlers
+ lea cyg_hal_interrupt_handlers,%a0
+ move.l (%a0,%d2.l),%a0
+
+ | Push the vector number parameter.
+ move.l %d1,-(%sp)
+
+ | Call the ISR.
+ jsr (%a0)
+
+ | Remove the isr parameters from the stack.
+ addq.l #4*2,%sp
+
+ | d0.l now contains the return value from the ISR.
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+ | If we are returning from the last nested interrupt, move back
+ | to the thread stack. interrupt_end() must be called on the
+ | thread stack since it potentially causes a context switch.
+ | Since we have arranged for the top of stack location to
+ | contain the sp we need to go back to here, just pop it off
+ | and put it in SP.
+
+ move.l (%sp),%sp | sp = *sp
+
+#endif
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+
+ | We only need to call interrupt_end() when there is a kernel
+ | present to do any tidying up. To keep the following code simple,
+ | we enable all interrupts before calling DSRs only if a common
+ | interrupt stack is in use.
+
+ | Push the regs pointer.
+ pea (%sp)
+
+ | Push the intr object pointer from the table.
+ .extern cyg_hal_interrupt_objects
+ lea cyg_hal_interrupt_objects,%a0
+ move.l (%a0,%d2.l),-(%sp)
+
+ | Push ISR return value
+ move.l %d0,-(%sp)
+
+ | Even when this is not the last nested interrupt, we must call
+ | interrupt_end() to post the DSR and decrement the scheduler
+ | lock.
+
+ | Call the interrupt_end C routine.
+ .extern interrupt_end
+ jsr interrupt_end
+
+ | Remove the isr_ret, intr, and regs parameters from the stack.
+ lea (4*3)(%sp),%sp
+
+#endif /* ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT */
+
+ | Restore the preserved registers for the current thread.
+ int_rest_regs
+
+ | Restore the SR and PC.
+ rte
+
+
+| ----------------------------------------------------------------------------
+| Execute pending DSRs on the interrupt stack with interrupts enabled.
+| Note: this can only be called from code running on a thread stack
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+ .extern cyg_interrupt_call_pending_DSRs
+
+FUNC_START(hal_interrupt_stack_call_pending_DSRs)
+ | Change to interrupt stack, save state and set up stack for
+ | calls to C code.
+ | By virtue of GNU C calling conventions, we are free to use registers
+ | %d0-%d1 and %a0-%a1 without saving them.
+
+ | a0 = sp
+ move.l %sp, %a0
+
+ | Switch to istack
+ lea __interrupt_stack,%sp
+
+ | Save old SP on istack
+ pea (%a0)
+
+ | Save sr
+ move.w %sr,%d0
+ move.l %d0,-(%sp)
+
+ | Enable interrupts
+ hal_cpu_int_enable %d0
+
+ | Call into kernel which will execute DSRs
+ jsr cyg_interrupt_call_pending_DSRs
+
+ move.l (%sp)+,%d0
+
+ | Restore previous interrupt state
+ hal_cpu_int_merge %d0,%d1
+
+ | Restore sp
+ move.l (%sp),%sp
+
+ | return to caller
+ rts
+
+#endif
+
+
+| ----------------------------------------------------------------------------
+| Interrupt and reset stack
+|
+| WARNING: Do not put this in any memory section that gets initialized.
+| Doing so may cause the C code to initialize its own stack.
+
+ .section ".uninvar","aw",@nobits
+
+ .balign 16
+ .global cyg_interrupt_stack_base
+cyg_interrupt_stack_base:
+__interrupt_stack_base:
+ .skip CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+ .balign 16
+ .global cyg_interrupt_stack
+cyg_interrupt_stack:
+__interrupt_stack:
+ .skip 0x10
+
--- /dev/null
+2006-05-09 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/pkgconf/mlt_coldfire_m5272c3_*.h: Added CYGMEM_REGION_RAM*
+ so that the test cases compile.
+
+2005-06-24 Enrico Piria <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+ * src/plf_mk_defs.c:
+ * src/plf_startup.c:
+ * include/hal_memmap.h:
+ * include/platform.inc:
+ * include/plf_intr.h:
+ * include/plf_serial.h:
+ * include/plf_startup.h:
+ * include/plf_stub.h:
+ * include/pkgconf/mlt_coldfire_m5272c3_ram.h:
+ * include/pkgconf/mlt_coldfire_m5272c3_ram.ldi:
+ * include/pkgconf/mlt_coldfire_m5272c3_rom.h:
+ * include/pkgconf/mlt_coldfire_m5272c3_rom.ldi:
+ * cdl/hal_coldfire_m5272c3.cdl:
+ Rework of the original M5272C3 platform HAL contributed by Wade Jensen.
+
+//===========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_coldfire_m5272c3.cdl
+#
+# Freescale M5272C3 evaluation board HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Enrico Piria
+## Contributors: Wade Jensen
+## Date: 2005-25-06
+##
+######DESCRIPTIONEND####
+##========================================================================
+
+cdl_package CYGPKG_HAL_COLDFIRE_M5272C3 {
+ display "Freescale M5272C3 evaluation board"
+ parent CYGPKG_HAL_COLDFIRE_MCF5272
+ define_header hal_coldfire_m5272c3.h
+ include_dir cyg/hal
+
+ description "The Freescale M5272C3 evaluation board platform HAL
+ package should be used when targeting the actual hardware for
+ the Freescale M5272C3 evaluation board platform."
+
+ compile plf_startup.c
+
+ implements CYGINT_HAL_DEBUG_GDB_STUBS
+ implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+ implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_coldfire.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_coldfire_mcf5272.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_coldfire_m5272c3.h>"
+ puts $::cdl_system_header "#define HAL_PLATFORM_BOARD \"Freescale M5272C3\""
+ puts $::cdl_system_header "#define HAL_PLATFORM_EXTRA \"\""
+ }
+
+ # The "-o file" is a workaround for CR100958 - without it the
+ # output file would end up in the source directory under CygWin.
+ # n.b. grep does not behave itself under win32
+ make -priority 1 {
+ <PREFIX>/include/cyg/hal/plf_offsets.inc : <PACKAGE>/src/plf_mk_defs.c
+ $(CC) $(ACTUAL_CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_offsets.tmp -o plf_mk_defs.tmp -S $<
+ fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 plf_offsets.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm plf_offsets.tmp plf_mk_defs.tmp
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ legal_values {"RAM" "ROM" "ROMRAM"}
+ default_value {"RAM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+
+ description "
+ This option is used to control where the application program will
+ run, either from RAM or ROM (flash) memory. ROM based applications
+ must be self contained, while RAM applications will typically assume
+ the existence of a debug environment, such as GDB stubs.
+ ROMRAM bootstrap is similar to ROM bootstrap, but everything
+ is copied to RAM before execution starts, thus improving performace,
+ but at the cost of an increased RAM footprint."
+ }
+
+ cdl_option CYGHWR_HAL_ROM_LMA {
+ display "Load address for ROM image"
+ active_if { CYG_HAL_STARTUP == "ROM" || CYG_HAL_STARTUP == "ROMRAM" }
+ flavor data
+ legal_values 0xFFE00000 0xFFF00000
+ default_value 0xFFF00000
+
+ description "This option lets you decide in which half of flash
+ memory to download the ROM image. As a safety measure,
+ the default is to use the upper half (starting at
+ 0xFFF00000), thus preserving the ROM monitor shipped with
+ the board. This option is meaningful only when ROM or
+ ROMRAM startup is choosed."
+ }
+
+ cdl_option CYGHWR_HAL_SYSTEM_CLOCK_MHZ {
+ display "System clock speed in MHz"
+ flavor data
+ legal_values 66 48
+ default_value 66
+
+ description "This option identifies the system clock that the
+ processor uses. This value is used to set clock dividers
+ for some devices."
+ }
+
+ cdl_option CYGHWR_EXT_SRAM_INSTALLED {
+ display "External 512Kb SRAM module"
+ flavor bool
+ default_value 0
+
+ description "If this option is enabled, chip-select module 2 is
+ configured to access the optional external 512Kb SRAM module."
+ }
+
+ cdl_option CYGHWR_INSTALLED_SDRAM_SIZE {
+ display "Megabytes of SDRAM installed"
+ flavor data
+ legal_values 16 4
+ default_value 16
+
+ description "This option selects the size of the SDRAM installed.
+ Note that the linker scripts have been written for a board with
+ 16 Mb of RAM. If you modify this option, you will have to change
+ them by hand."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ calculated 2
+ description "
+ Port 0 is the terminal serial port; port 1 is the auxiliary
+ serial port."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ This option chooses which port will be used to connect to a host
+ via the GDB remote protocol."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "Debug serial port baud rate"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 19200
+ description "
+ This option controls the baud rate used for the GDB connection."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ This option chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ active_if CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 19200
+
+ description "This option selects the baud rate used for the
+ diagnostic port. Note: this should match the value chosen
+ for the GDB port if the diagnostic and GDB port are the
+ same."
+ }
+
+ # Real-time clock/counter specifics
+ cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants."
+ flavor none
+
+ description "Set the periodic timer on the MCF5272 to 10 ms or
+ 10000000 ns."
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ default_value 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ default_value 100
+ }
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ default_value 4125
+ description "
+ The default value is calculated as:
+ 10 ms / ((1 / (66 MHz)) * 16 * 10)."
+ }
+ }
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+
+ description "Global build options including control over compiler
+ flags, linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "m68k-elf" }
+
+ description "This option specifies the command prefix used
+ when invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { "-m5206e -malign-int -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -finit-priority" }
+ description "This option controls the global compiler flags
+ which are used to compile all packages by default.
+ Individual packages may define options which
+ override these global flags."
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { "-m5206e -g -nostdlib -Wl,--gc-sections -Wl,-static" }
+
+ description "This option controls the global linker flags.
+ Individual packages may define options which
+ override these global flags."
+ }
+
+ cdl_option CYGBLD_BUILD_GDB_STUBS {
+ display "Build GDB stub ROM image"
+ default_value 0
+ requires { CYG_HAL_STARTUP == "ROM" || CYG_HAL_STARTUP == "ROMRAM" }
+ requires CYGSEM_HAL_ROM_MONITOR
+ requires CYGBLD_BUILD_COMMON_GDB_STUBS
+ requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+ requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+ no_define
+
+ description "This option enables the building of the GDB
+ stubs for the board. The common HAL controls
+ take care of most of the build process, but the
+ final conversion from ELF image to binary data is
+ handled by the platform CDL, allowing relocation
+ of the data if necessary."
+
+ make -priority 320 {
+ <PREFIX>/bin/gdb_module.srec : <PREFIX>/bin/gdb_module.img
+ $(OBJCOPY) -S -O srec $< $@
+ }
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "coldfire_m5272c3_ram" : \
+ (CYG_HAL_STARTUP == "ROMRAM") ? "coldfire_m5272c3_romram" : \
+ "coldfire_m5272c3_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_coldfire_m5272c3_ram.ldi>" : \
+ (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_coldfire_m5272c3_romram.ldi>" : \
+ "<pkgconf/mlt_coldfire_m5272c3_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { (CYG_HAL_STARTUP == "RAM") ? "<pkgconf/mlt_coldfire_m5272c3_ram.h>" : \
+ (CYG_HAL_STARTUP == "ROMRAM") ? "<pkgconf/mlt_coldfire_m5272c3_romram.h>" : \
+ "<pkgconf/mlt_coldfire_m5272c3_rom.h>" }
+ }
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+ requires { CYG_HAL_STARTUP == "RAM" }
+ parent CYGPKG_HAL_ROM_MONITOR
+
+ description "Support can be enabled for boot ROMs or ROM
+ monitors which contain GDB stubs. This support
+ changes various eCos semantics such as the encoding of
+ diagnostic output, and the overriding of hardware
+ interrupt vectors."
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM" || CYG_HAL_STARTUP == "ROMRAM" }
+
+ description "Enable this option if this program is to be used as
+ a ROM monitor, i.e. applications will be loaded into
+ RAM on the board, and this ROM monitor may process
+ exceptions or interrupts generated from the
+ application. This enables features such as utilizing
+ a separate interrupt stack when exceptions are
+ generated."
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_MEMMAP_H
+#define CYGONCE_HAL_MEMMAP_H
+
+//=============================================================================
+//
+// hal_memmap.h
+//
+// Platform specific memory section definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Memory section definitions specific to the M5272C3 board
+// Usage: Included via CYGHWR_MEMORY_LAYOUT_H
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// WARNING: DO NOT CHANGE THE TYPE OF THESE LABELS. THE LINKER DEFINES
+// THESE AND WE WANT TO USE THE VARIABLE ADDRESSES NOT THE VARIABLES
+// THEMSELVES.
+
+#define SECTION_DEC(_name_) \
+ externC unsigned char __ ## _name_ ## _start[]; \
+ externC unsigned char __ ## _name_ ## _end[]; \
+ externC unsigned char __ ## _name_ ## _size[];
+
+SECTION_DEC(bss)
+SECTION_DEC(ram_data)
+SECTION_DEC(rom_data)
+SECTION_DEC(uninvar)
+SECTION_DEC(romvec)
+SECTION_DEC(ramvec)
+
+// ---------------------------------------------------------------------------
+// End of hal_memmap.h
+#endif // CYGONCE_HAL_MEMMAP_H
--- /dev/null
+#ifndef CYGONCE_MLT_COLDFIRE_RAM_H
+#define CYGONCE_MLT_COLDFIRE_RAM_H
+
+//=============================================================================
+//
+// mlt_coldfire_m5272c3_ram.h
+//
+// Platform specific memory section definitions for RAM startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Memory section definitions specific to the M5272C3 board,
+// used for RAM startup configuration.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// eCos memory layout
+
+#include <cyg/hal/hal_memmap.h>
+
+#define CYGMEM_REGION_sdram (0x00000000)
+#define CYGMEM_REGION_sdram_SIZE (0x01000000)
+
+#define CYGMEM_REGION_devs (0x10000000)
+#define CYGMEM_REGION_devs_SIZE (0x00001800)
+
+#define CYGMEM_REGION_sram (0x20000000)
+#define CYGMEM_REGION_sram_SIZE (0x00001000)
+
+#define CYGMEM_REGION_ext_sram (0x30000000)
+#define CYGMEM_REGION_ext_sram_SIZE (0x00080000)
+
+#define CYGMEM_REGION_flash (0xFFE00000)
+#define CYGMEM_REGION_flash_SIZE (0x00200000)
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x01000000 - (size_t) CYG_LABEL_NAME (__heap1))
+externC unsigned char CYG_LABEL_NAME (__heap1) [];
+
+// These symbols are required by the test cases. Normally the memory tool would generate them,
+// but this file was been generated by hand and so is a little
+// different to normal.
+#define CYGMEM_REGION_ram CYGMEM_REGION_sdram
+#define CYGMEM_REGION_ram_SIZE CYGMEM_REGION_sdram_SIZE
+
+// ---------------------------------------------------------------------------
+// End of mlt_coldfire_m5272c3_ram.h
+#endif // CYGONCE_MLT_COLDFIRE_RAM_H
--- /dev/null
+//===========================================================================
+//
+// mlt_coldfire_m5272c3_ram.ldi
+//
+// RAM startup linker control script
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Linker script specific to the M5272C3 board, used for
+// RAM startup.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+ sdram : ORIGIN = 0x00000000, LENGTH = 0x01000000
+ devs : ORIGIN = 0x10000000, LENGTH = 0x00001800
+ sram : ORIGIN = 0x20000000, LENGTH = 0x00001000
+ ext_sram : ORIGIN = 0x30000000, LENGTH = 0x00080000
+ flash : ORIGIN = 0xFFE00000, LENGTH = 0x00200000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+
+ SECTION_ramvec (sdram, 0x00000000 (NOLOAD), LMA_EQ_VMA)
+ SECTION_virtual_vec_table (sdram, ALIGN(0x4) (NOLOAD), LMA_EQ_VMA)
+
+ // Reserve some space to the ROM monitor
+ SECTION_romvec (sdram, 0x00020000, LMA_EQ_VMA)
+ SECTION_boot (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_text (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_fini (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_rodata1 (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_rodata (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_fixup (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_data (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_bss (sdram, ALIGN(0x4) (NOLOAD), LMA_EQ_VMA)
+ SECTION_uninvar (sdram, ALIGN(0x4) (NOLOAD), LMA_EQ_VMA)
+
+ // The heap starts here.
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x4);
+
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_MLT_COLDFIRE_ROM_H
+#define CYGONCE_MLT_COLDFIRE_ROM_H
+
+//=============================================================================
+//
+// mlt_coldfire_m5272c3_rom.h
+//
+// Platform specific memory section definitions for ROM startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Memory section definitions specific to the M5272C3 board,
+// used for ROM startup configuration.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// eCos memory layout
+
+#include <cyg/hal/hal_memmap.h>
+
+#define CYGMEM_REGION_sdram (0x00000000)
+#define CYGMEM_REGION_sdram_SIZE (0x01000000)
+
+#define CYGMEM_REGION_devs (0x10000000)
+#define CYGMEM_REGION_devs_SIZE (0x00001800)
+
+#define CYGMEM_REGION_sram (0x20000000)
+#define CYGMEM_REGION_sram_SIZE (0x00001000)
+
+#define CYGMEM_REGION_ext_sram (0x30000000)
+#define CYGMEM_REGION_ext_sram_SIZE (0x00080000)
+
+#define CYGMEM_REGION_flash (0xFFE00000)
+#define CYGMEM_REGION_flash_SIZE (0x00200000)
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x01000000 - (size_t) CYG_LABEL_NAME (__heap1))
+externC unsigned char CYG_LABEL_NAME (__heap1) [];
+
+// These symbols are required by the test cases. Normally the memory tool would generate them,
+// but this file was been generated by hand and so is a little
+// different to normal.
+#define CYGMEM_REGION_ram CYGMEM_REGION_sdram
+#define CYGMEM_REGION_ram_SIZE CYGMEM_REGION_sdram_SIZE
+
+// ---------------------------------------------------------------------------
+// End of mlt_coldfire_m5272c3_rom.h
+#endif // CYGONCE_MLT_COLDFIRE_ROM_H
--- /dev/null
+//===========================================================================
+//
+// mlt_coldfire_m5272c3_rom.ldi
+//
+// ROM startup linker control script
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Linker script specific to the M5272C3 board, used for
+// ROM startup.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.inc>
+#include CYGBLD_HAL_PLATFORM_H
+
+MEMORY
+{
+ sdram : ORIGIN = 0x00000000, LENGTH = 0x01000000
+ devs : ORIGIN = 0x10000000, LENGTH = 0x00001800
+ sram : ORIGIN = 0x20000000, LENGTH = 0x00001000
+ ext_sram : ORIGIN = 0x30000000, LENGTH = 0x00080000
+ flash : ORIGIN = 0xFFE00000, LENGTH = 0x00200000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+
+#if (CYGHWR_HAL_ROM_LMA == 0xFFF00000)
+ SECTION_romvec (flash, 0xFFF00000, LMA_EQ_VMA)
+#else
+ SECTION_romvec (flash, 0xFFE00000, LMA_EQ_VMA)
+#endif
+
+ SECTION_boot (flash, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_text (flash, ALIGN (0x4),LMA_EQ_VMA)
+ SECTION_fini (flash, ALIGN (0x4),LMA_EQ_VMA)
+ SECTION_rodata1 (flash, ALIGN (0x4),LMA_EQ_VMA)
+ SECTION_rodata (flash, ALIGN (0x4),LMA_EQ_VMA)
+ SECTION_fixup (flash, ALIGN (0x4),LMA_EQ_VMA)
+ SECTION_gcc_except_table (flash, ALIGN (0x4),LMA_EQ_VMA)
+
+ SECTION_ramvec (sdram, 0x00000000 (NOLOAD), LMA_EQ_VMA)
+ SECTION_virtual_vec_table (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+ SECTION_data (sdram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+ SECTION_uninvar (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+
+ // The heap starts here.
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x4);
+
+ CYG_LABEL_DEFN(__romram_copy_source) = LOADADDR(.data);
+ CYG_LABEL_DEFN(__romram_copy_dest) = ADDR(.data);
+ CYG_LABEL_DEFN(__romram_copy_length) = SIZEOF(.data);
+
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_MLT_COLDFIRE_ROMRAM_H
+#define CYGONCE_MLT_COLDFIRE_ROMRAM_H
+
+//=============================================================================
+//
+// mlt_coldfire_m5272c3_romram.h
+//
+// Platform specific memory section definitions for ROMRAM startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Memory section definitions specific to the M5272C3 board,
+// used for ROMRAM startup configuration.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// eCos memory layout
+
+#include <cyg/hal/hal_memmap.h>
+
+#define CYGMEM_REGION_sdram (0x00000000)
+#define CYGMEM_REGION_sdram_SIZE (0x01000000)
+
+#define CYGMEM_REGION_devs (0x10000000)
+#define CYGMEM_REGION_devs_SIZE (0x00001800)
+
+#define CYGMEM_REGION_sram (0x20000000)
+#define CYGMEM_REGION_sram_SIZE (0x00001000)
+
+#define CYGMEM_REGION_ext_sram (0x30000000)
+#define CYGMEM_REGION_ext_sram_SIZE (0x00080000)
+
+#define CYGMEM_REGION_flash (0xFFE00000)
+#define CYGMEM_REGION_flash_SIZE (0x00200000)
+
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x01000000 - (size_t) CYG_LABEL_NAME (__heap1))
+externC unsigned char CYG_LABEL_NAME (__heap1) [];
+
+// These symbols are required by the test cases. Normally the memory tool would generate them,
+// but this file was been generated by hand and so is a little
+// different to normal.
+#define CYGMEM_REGION_ram CYGMEM_REGION_sdram
+#define CYGMEM_REGION_ram_SIZE CYGMEM_REGION_sdram_SIZE
+
+// ---------------------------------------------------------------------------
+// End of mlt_coldfire_m5272c3_romram.h
+#endif // CYGONCE_MLT_COLDFIRE_ROMRAM_H
--- /dev/null
+//===========================================================================
+//
+// mlt_coldfire_m5272c3_romram.ldi
+//
+// ROMRAM startup linker control script
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Linker script specific to the M5272C3 board, used for
+// ROMRAM startup.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.inc>
+#include CYGBLD_HAL_PLATFORM_H
+
+MEMORY
+{
+ sdram : ORIGIN = 0x00000000, LENGTH = 0x01000000
+ devs : ORIGIN = 0x10000000, LENGTH = 0x00001800
+ sram : ORIGIN = 0x20000000, LENGTH = 0x00001000
+ ext_sram : ORIGIN = 0x30000000, LENGTH = 0x00080000
+ flash : ORIGIN = 0xFFE00000, LENGTH = 0x00200000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+
+#if (CYGHWR_HAL_ROM_LMA == 0xFFF00000)
+ SECTION_romvec (flash, 0xFFF00000, LMA_EQ_VMA)
+#else
+ SECTION_romvec (flash, 0xFFE00000, LMA_EQ_VMA)
+#endif
+
+ SECTION_boot (flash, ALIGN(0x4), FOLLOWING(.romvec))
+
+ SECTION_ramvec (sdram, 0x00000000 (NOLOAD), LMA_EQ_VMA)
+ SECTION_virtual_vec_table (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+
+ SECTION_text (sdram, ALIGN (0x4),FOLLOWING(.boot))
+ SECTION_fini (sdram, ALIGN (0x4),FOLLOWING(.text))
+ SECTION_rodata1 (sdram, ALIGN (0x4),FOLLOWING(.fini))
+ SECTION_rodata (sdram, ALIGN (0x4),FOLLOWING(.rodata1))
+ SECTION_fixup (sdram, ALIGN (0x4),FOLLOWING(.rodata))
+ SECTION_gcc_except_table (sdram, ALIGN (0x4),FOLLOWING(.fixup))
+ SECTION_data (sdram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+ SECTION_uninvar (sdram, ALIGN (0x4) (NOLOAD), LMA_EQ_VMA)
+
+ // The heap starts here.
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x4);
+
+ CYG_LABEL_DEFN(__romram_copy_source) = LOADADDR(.text);
+ CYG_LABEL_DEFN(__romram_copy_dest) = ADDR(.text);
+ CYG_LABEL_DEFN(__romram_copy_length) = SIZEOF(.text) + SIZEOF(.fini) + SIZEOF(.rodata1) + SIZEOF(.rodata) + SIZEOF(.fixup) + SIZEOF(.gcc_except_table) + SIZEOF(.data);
+
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_INC
+#define CYGONCE_HAL_PLATFORM_INC
+
+|=============================================================================
+|
+| platform.inc
+|
+| M5272C3 board assembler header file
+|
+|=============================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| 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.
+| -------------------------------------------
+|###ECOSGPLCOPYRIGHTEND###
+|=============================================================================
+|#####DESCRIPTIONBEGIN####
+|
+| Author(s): Enrico Piria
+| Contributors:
+| Date: 2005-25-06
+| Purpose: Assembler macro definitions specific to the M5272C3 board.
+| Usage: Included by "variant.inc". Do not use directly.
+|
+|####DESCRIPTIONEND####
+|========================================================================
+
+#include <cyg/hal/plf_offsets.inc>
+
+|-------------------------------------------------------------------------------
+| Platform initialization macros
+
+ .macro hal_hardware_init
+ | Initialize RAMBAR: locate SRAM and validate it.
+ move.l #CYGMEM_REGION_sram,%d0
+ add.l #0x21,%d0
+ movec %d0,%rambar0
+ .endm
+
+
+ | Setup stack for startup routines. Use SRAM module.
+ .macro hal_boot_stack_init
+ | Point Stack Pointer into SRAM temporarily.
+ move.l #CYGMEM_REGION_sram,%d0
+ add.l #CYGMEM_REGION_sram_SIZE,%d0
+ move.l %d0,%sp
+ .endm
+
+|-----------------------------------------------------------------------------
+| End of platform.inc
+#endif // CYGONCE_HAL_PLATFORM_INC
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_INTR_H
+#define CYGONCE_HAL_PLF_INTR_H
+
+//==========================================================================
+//
+// plf_intr.h
+//
+// Platform specific interrupt and clock support
+//
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Interrupt and clock definitions specific to the M5272C3 board.
+// Usage: Included via "var_intr.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// ---------------------------------------------------------------------------
+// Reset
+
+#ifndef CYGHWR_HAL_RESET_DEFINED
+
+externC void cyg_hal_reset_vsr( void );
+
+#define CYGHWR_HAL_RESET_DEFINED
+#define HAL_PLATFORM_RESET() cyg_hal_reset_vsr()
+
+#define HAL_PLATFORM_RESET_ENTRY &cyg_hal_reset_vsr
+
+#endif // CYGHWR_HAL_RESET_DEFINED
+
+// ---------------------------------------------------------------------------
+// End of plf_intr.h
+#endif // CYGONCE_HAL_PLF_INTR_H
--- /dev/null
+#ifndef CYGONCE_PLF_SERIAL_H
+#define CYGONCE_PLF_SERIAL_H
+
+//=============================================================================
+//
+// plf_serial.h
+//
+// Platform specific definitions for diagnstic ouput via serial port
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Definitions for diagnostic output via serial port
+// Usage: #include <cyg/hal/plf_serial.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#define MCF5272_UART_UMR_8BNP (0x13)
+#define MCF5272_UART_UMR_1S (0x07)
+
+#define MCF5272_UART_USR_RRDY (1<<0)
+#define MCF5272_UART_USR_FFUL (1<<1)
+#define MCF5272_UART_USR_TXRDY (1<<2)
+#define MCF5272_UART_USR_TXEMP (1<<3)
+#define MCF5272_UART_USR_OE (1<<4)
+#define MCF5272_UART_USR_PE (1<<5)
+#define MCF5272_UART_USR_FE (1<<6)
+#define MCF5272_UART_USR_RB (1<<7)
+
+#define MCF5272_UART_UCSR_CLKIN (0xDD)
+
+#define MCF5272_UART_UCR_RMR (0x01<<4)
+#define MCF5272_UART_UCR_RRX (0x02<<4)
+#define MCF5272_UART_UCR_RTX (0x03<<4)
+#define MCF5272_UART_UCR_RES (0x04<<4)
+#define MCF5272_UART_UCR_RBC (0x05<<4)
+#define MCF5272_UART_UCR_TXEN (1<<2)
+#define MCF5272_UART_UCR_TXDE (1<<3)
+#define MCF5272_UART_UCR_RXEN (1<<0)
+#define MCF5272_UART_UCR_RXDE (1<<1)
+
+#define MCF5272_UART_UCR_TXRXEN \
+ (MCF5272_UART_UCR_TXEN | \
+ MCF5272_UART_UCR_RXEN)
+
+#define MCF5272_UART_UIMR_FFULL (0x02)
+
+#define MCF5272_UART_UTF_TXB (0x1F)
+
+#define MCF5272_UART_UOP0_RTS (0x01)
+#define MCF5272_UART_UOP1_RTS (0x01)
+
+#define MCF5272_GPIO_PBCNT_URT0_EN (0x00000155)
+#define MCF5272_GPIO_PBCNT_URT0_DE (0x00000000)
+#define MCF5272_GPIO_PBCNT_URT0_MSK (0x000003FF)
+
+#define MCF5272_GPIO_PDCNT_URT1_EN (0x000002AA)
+#define MCF5272_GPIO_PDCNT_URT1_DE (0x00000000)
+#define MCF5272_GPIO_PDCNT_URT1_MSK (0x000003FF)
+
+// ---------------------------------------------------------------------------
+// End of plf_serial.h
+#endif // CYGONCE_PLF_SERIAL_H
--- /dev/null
+#ifndef CYGONCE_PLF_STARTUP_H
+#define CYGONCE_PLF_STARTUP_H
+
+//=============================================================================
+//
+// plf_startup.h
+//
+// M5272C3 platform startup header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: M5272C3 platform startup header.
+// Usage: Included via "var_startup.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Platform specific reset vector initialization routine
+externC void plf_reset(void) __attribute__ ((section (".boot")));
+
+// Platform specific data initialization routine
+externC void plf_init_data(void) __attribute__ ((section (".boot")));
+
+// ---------------------------------------------------------------------------
+// End of plf_startup.h
+#endif // CYGONCE_PLF_STARTUP_H
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//========================================================================
+//
+// plf_stub.h
+//
+// Platform specific definitions for generic stub
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: GDB stub definitions specific to the M5272C3 board.
+// Usage: #include <cyg/hal/plf_stub.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM
+
+#include <cyg/hal/coldfire_stub.h> // architecture stub support
+
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int,(baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() CYG_EMPTY_STATEMENT
+
+// ---------------------------------------------------------------------------
+// Stub initializer
+
+#define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+// ---------------------------------------------------------------------------
+// End of plf_stub.h
+#endif // CYGONCE_HAL_PLF_STUB_H
--- /dev/null
+//==========================================================================
+//
+// plf_mk_defs.c
+//
+// "make defs" program for M5272C3 platform
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: gthomas, jskov
+// Date: 2005-25-06
+// Purpose: Definition generator for M5272C3 board.
+// Description: This file contains code that can be compiled by the target
+// compiler and used to generate machine specific definitions
+// suitable for use in assembly code.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+// This program is used to generate definitions needed by
+// assembly language modules.
+//
+// This technique was first used in the OSF Mach kernel code:
+// generate asm statements containing #defines,
+// compile this file to assembler, and then extract the
+// #defines from the assembly-language output.
+
+#define DEFINE(sym, val) \
+ asm volatile("\n\t.equ\t" #sym ",%0" : : "i" (val))
+
+int
+main(void)
+{
+ // Memory layout values
+ DEFINE(CYGMEM_REGION_sdram, CYGMEM_REGION_sdram);
+ DEFINE(CYGMEM_REGION_sdram_SIZE, CYGMEM_REGION_sdram_SIZE);
+ DEFINE(CYGMEM_REGION_devs, CYGMEM_REGION_devs);
+ DEFINE(CYGMEM_REGION_devs_SIZE, CYGMEM_REGION_devs_SIZE);
+ DEFINE(CYGMEM_REGION_sram, CYGMEM_REGION_sram);
+ DEFINE(CYGMEM_REGION_sram_SIZE, CYGMEM_REGION_sram_SIZE);
+ DEFINE(CYGMEM_REGION_flash, CYGMEM_REGION_flash);
+ DEFINE(CYGMEM_REGION_flash_SIZE, CYGMEM_REGION_flash_SIZE);
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------
+// EOF hal_mk_defs.c
--- /dev/null
+//==========================================================================
+//
+// plf_startup.c
+//
+// M5272C3 platform HAL startup code
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Platform startup code.
+// Description: This module contains code that sets up the platform specific
+// hardware and data. All the code must be contained in the
+// section called ".boot", in order for the ROMRAM startup
+// to work properly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_startup.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/coldfire_regs.h>
+
+static void plf_init_sim(void) __attribute__ ((section (".boot")));
+static void plf_init_intc(void) __attribute__ ((section (".boot")));
+static void plf_init_cs(void) __attribute__ ((section (".boot")));
+static void plf_init_sdramc(void) __attribute__ ((section (".boot")));
+static void plf_init_cache_acr(void) __attribute__ ((section (".boot")));
+
+
+// Platform-specific reset vector initialization routine
+void plf_reset(void)
+{
+ plf_init_sim();
+ plf_init_intc();
+ plf_init_cs();
+ plf_init_sdramc();
+
+ // Call a routine to set up the cache and ACRs for this specific
+ // platform.
+ plf_init_cache_acr();
+}
+
+
+// Initialize the cache and access control registers.
+// The reset procedure already invalidated the cache and ACRs.
+// This routine only needs to enable the ACRs that it will use.
+static void plf_init_cache_acr(void)
+{
+ // Enable the instruction cache with the following options:
+ // Enable CPUSHL invalidation.
+ // No freeze.
+ // Invalidate all cache lines (flush).
+ // No external arbiter control.
+ // Disable non-cacheable instruction bursting.
+ // Default memory is cacheable.
+ // Enable buffered writes.
+ // Read and write access permitted by default.
+ // Instruction fetch size is cache line.
+
+#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
+ CYGARC_MOVEC((CYG_WORD32) 0x81000102, CYGARC_REG_CACR);
+#endif
+
+ // Leave the access control registers disabled.
+}
+
+
+// Initialize SIM module and system configuration registers
+void plf_init_sim(void)
+{
+ // Set up the mapping of our internal registers. The LSB indicates that
+ // the register contents are valid.
+ CYGARC_MOVEC((CYG_WORD32)(CYGMEM_REGION_devs | 1), CYGARC_REG_MBAR);
+
+ // Initialize System Config Register
+ // Setup Watch Dog Timeout
+ HAL_WRITE_UINT16(&MCF5272_DEVS->cfg.scr, MCF5272_SIM_SCR_HWWD_1024);
+
+ // Initialize System Protection Register
+ // Enable all bus error exceptions
+ HAL_WRITE_UINT16(&MCF5272_DEVS->cfg.spr,
+ (0 | MCF5272_SIM_SPR_ADC | MCF5272_SIM_SPR_ADCEN
+ | MCF5272_SIM_SPR_WPV | MCF5272_SIM_SPR_WPVEN
+ | MCF5272_SIM_SPR_SMV | MCF5272_SIM_SPR_SMVEN
+ | MCF5272_SIM_SPR_SBE | MCF5272_SIM_SPR_SBEEN
+ | MCF5272_SIM_SPR_HWT | MCF5272_SIM_SPR_HWTEN
+ | MCF5272_SIM_SPR_RPV | MCF5272_SIM_SPR_RPVEN
+ | MCF5272_SIM_SPR_EXT | MCF5272_SIM_SPR_EXTEN
+ | MCF5272_SIM_SPR_SUV | MCF5272_SIM_SPR_SUVEN
+ )) ;
+}
+
+
+// Initialize interrupt controller
+void plf_init_intc(void)
+{
+ int i;
+
+ // Initialize the vector base register in the interrupt controller.
+ HAL_WRITE_UINT8(&MCF5272_DEVS->intc.ipvr, HAL_PROG_INT_VEC_BASE);
+
+ // Initialize the interrupt control register.
+ // Disable all interrupts by setting all priorities to zero.
+ for (i = 0; i < 4; i++)
+ {
+ HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[i], 0x88888888);
+ }
+
+ // Initialize the processor's vector base register (align to 1M boundary).
+ CYGARC_MOVEC((CYG_WORD32) __ramvec_start & 0xFFF00000, CYGARC_REG_VBR);
+}
+
+
+// Initialize chip-select modules
+void plf_init_cs(void)
+{
+ // ChipSelect 0 - 2MB FLASH
+ // At startup, CS0 is configured so that addresses starting at 0xXXX00000
+ // are aliased to 0x00000000, so, in ROM startup configuration, code can
+ // be placed starting at VMA address 0xFFE00000. When we are here,
+ // the PC points to addresses in 0xFFE00000 space, and we can safely
+ // reconfigure CS0 to respond uniquely to those addresses.
+ HAL_WRITE_UINT32(&MCF5272_DEVS->cs[0].csbr, (0
+ | MCF5272_CS_BR_BASE(CYGMEM_REGION_flash)
+ | MCF5272_CS_BR_SRAM
+ | MCF5272_CS_BR_PS_16
+ | MCF5272_CS_BR_EN));
+
+ HAL_WRITE_UINT32(&MCF5272_DEVS->cs[0].csor,
+ (0 | MCF5272_CS_OR_MASK_2M
+ | MCF5272_CS_OR_WS(5)));
+
+#ifdef CYGHWR_EXT_SRAM_INSTALLED
+ // Chip Select 2 - 512KB SRAM
+ HAL_WRITE_UINT32(&MCF5272_DEVS->cs[2].csbr, (0
+ | MCF5272_CS_BR_BASE(CYGMEM_REGION_ext_sram)
+ | MCF5272_CS_BR_SRAM
+ | MCF5272_CS_BR_PS_32
+ | MCF5272_CS_BR_EN));
+
+ HAL_WRITE_UINT32(&MCF5272_DEVS->cs[2].csor, (0
+ | MCF5272_CS_OR_MASK_512K
+ | MCF5272_CS_OR_WS(0)));
+#endif // CYGHWR_EXT_SRAM_INSTALLED
+
+ // ChipSelect 7 - 16MB SDRAM
+ HAL_WRITE_UINT32(&MCF5272_DEVS->cs[7].csbr, (0
+ | MCF5272_CS_BR_BASE(CYGMEM_REGION_sdram)
+ | MCF5272_CS_BR_SDRAM
+ | MCF5272_CS_BR_PS_LINE
+ | MCF5272_CS_BR_EN));
+
+ HAL_WRITE_UINT32(&MCF5272_DEVS->cs[7].csor, (0
+#if (CYGHWR_INSTALLED_SDRAM_SIZE == 4)
+ | MCF5272_CS_OR_MASK_4M
+#else
+ | MCF5272_CS_OR_MASK_16M
+#endif
+ | MCF5272_CS_OR_WS(0x1F)));
+}
+
+
+// Initialize SDRAM controller
+void plf_init_sdramc(void)
+{
+ cyg_uint16 sdcr;
+
+
+ HAL_READ_UINT16(&MCF5272_DEVS->sdramc.sdcr, sdcr);
+
+ // Do not initialize SDRAM if it is already active
+ if (!(sdcr & MCF5272_SDRAMC_SDCCR_ACT))
+ {
+#if (CYGHWR_HAL_SYSTEM_CLOCK_MHZ == 66)
+ HAL_WRITE_UINT16(&MCF5272_DEVS->sdramc.sdtr, (0
+ | MCF5272_SDRAMC_SDCTR_RTP_66MHz
+ | MCF5272_SDRAMC_SDCTR_RC(0)
+ | MCF5272_SDRAMC_SDCTR_RP(1)
+ | MCF5272_SDRAMC_SDCTR_RCD(1)
+ | MCF5272_SDRAMC_SDCTR_CLT_2));
+#else
+ // Clock frequency must be 48 Mhz
+ HAL_WRITE_UINT16(&MCF5272_DEVS->sdramc.sdtr, (0
+ | MCF5272_SDRAMC_SDCTR_RTP_48MHz
+ | MCF5272_SDRAMC_SDCTR_RC(0)
+ | MCF5272_SDRAMC_SDCTR_RP(1)
+ | MCF5272_SDRAMC_SDCTR_RCD(0)
+ | MCF5272_SDRAMC_SDCTR_CLT_2));
+#endif
+
+ HAL_WRITE_UINT16(&MCF5272_DEVS->sdramc.sdcr, (0
+ | MCF5272_SDRAMC_SDCCR_MCAS_A9
+#if (CYGHWR_INSTALLED_SDRAM_SIZE == 4)
+ | MCF5272_SDRAMC_SDCCR_BALOC_A21
+#else
+ | MCF5272_SDRAMC_SDCCR_BALOC_A22
+#endif
+ | MCF5272_SDRAMC_SDCCR_REG
+ | MCF5272_SDRAMC_SDCCR_INIT));
+
+ // Start SDRAM controller with a memory write
+ *((volatile char *) CYGMEM_REGION_sdram) = 0;
+
+ // Wait until controller is ready
+ do
+ {
+ HAL_READ_UINT16(&MCF5272_DEVS->sdramc.sdcr, sdcr);
+ } while(!(sdcr & MCF5272_SDRAMC_SDCCR_ACT));
+ }
+}
+
+
+// Platform specific data initialization routine
+void plf_init_data(void)
+{
+ // Nothing to do
+}
--- /dev/null
+2005-06-24 Enrico Piria <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+ * src/var_misc.c:
+ * src/var_startup.c:
+ * src/hal_diag.c:
+ * src/variant.S:
+ * include/hal_diag.h:
+ * include/mcf5272_devs.h:
+ * include/var_arch.h:
+ * include/var_basetype.h:
+ * include/var_cache.h:
+ * include/var_intr.h:
+ * include/var_regs.h:
+ * include/var_startup.h:
+ * include/variant.inc:
+ * cdl/hal_coldfire_mcf5272.cdl:
+ Rework of the original MCF5272 variant HAL contributed by Wade Jensen.
+
+//===========================================================================
+//####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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_coldfire_mcf5272.cdl
+#
+# MCF5272 variant architectural HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
+##
+## 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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Enrico Piria
+## Contributors: Wade Jensen
+## Date: 2005-25-06
+##
+######DESCRIPTIONEND####
+##========================================================================
+
+cdl_package CYGPKG_HAL_COLDFIRE_MCF5272 {
+ display "MCF5272 ColdFire variant HAL"
+ parent CYGPKG_HAL_COLDFIRE
+ requires CYGPKG_HAL_COLDFIRE
+ implements CYGINT_HAL_COLDFIRE_VARIANT
+ implements CYGARC_HAL_COLDFIRE_V2_CORE
+ implements CYGARC_HAL_COLDFIRE_MAC
+ implements CYGARC_HAL_COLDFIRE_ISA_A
+ hardware
+ include_dir cyg/hal
+ define_header hal_coldfire_mcf5272.h
+
+ description "The ColdFire 5272 variant HAL package provides
+ generic support for the ColdFire 5272 processor. It is also
+ necessary to select a specific target platform HAL package."
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/hal_coldfire.h>"
+ }
+
+ compile var_startup.c var_misc.c variant.S
+
+ cdl_option CYGHWR_HAL_COLDFIRE_MAC {
+ display "MAC support"
+ flavor bool
+ default_value 0
+ description "
+ Enable or disable support for MAC operations. MAC registers will be
+ saved during context switches, during exceptions, and in the
+ setjmp/longjmp routines. If you don't use the MAC unit, you can
+ leave this option disabled."
+ }
+
+ # With this calculated option, code for diagnostic/debug output is compiled
+ # only if it is really needed.
+ cdl_option CYGBLD_HAL_COLDFIRE_MCF5272_DIAG {
+ display "Compile HAL diagnostic output code"
+ flavor bool
+ no_define
+ calculated { is_active(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) ||
+ is_active(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) }
+ compile hal_diag.c
+ description "
+ This calculated option is enabled only when code for
+ diagnostic/debug output is really needed."
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_HAL_DIAG_H
+#define CYGONCE_HAL_HAL_DIAG_H
+
+//=============================================================================
+//
+// hal_diag.h
+//
+// HAL support for kernel diagnostic routines
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Provide ColdFire-specific diagnostic system definitions.
+// Usage: #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+// We suppose that CYGSEM_HAL_VIRTUAL_VECTOR_DIAG is always defined
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+// ---------------------------------------------------------------------------
+// End of hal_diag.h
+#endif // CYGONCE_HAL_HAL_DIAG_H
--- /dev/null
+#ifndef CYGONCE_MCF5272_DEVS_H
+#define CYGONCE_MCF5272_DEVS_H
+
+//=============================================================================
+//
+// mcf5272_devs.h
+//
+// Definitions for the MCF5272 on-chip peripherals
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria, Wade Jensen
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Definitions for the MCF5272 on-chip peripherals.
+// Usage: #include <cyg/hal/mcf5272_devs.h>
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// General configuration registers
+typedef struct
+{
+
+ // Module base address register
+ cyg_uint32 mbar;
+
+ // System configuration register
+ cyg_uint16 scr;
+
+ // System protection register
+ cyg_uint16 spr;
+
+ // Power management register
+ cyg_uint32 pmr;
+
+ // Gap
+ cyg_uint16 _res1;
+
+ // Active low power register
+ cyg_uint16 alpr;
+
+ // Device identification register
+ cyg_uint32 dir;
+
+ // Gap
+ cyg_uint32 _res2[3];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_cfg_t;
+
+// Configuration registers macros
+
+#define MCF5272_SIM_SCR_HWWD_1024 0x0003
+
+#define MCF5272_SIM_SPR_ADC 0x8000
+#define MCF5272_SIM_SPR_ADCEN 0x0080
+#define MCF5272_SIM_SPR_WPV 0x4000
+#define MCF5272_SIM_SPR_WPVEN 0x0040
+#define MCF5272_SIM_SPR_SMV 0x2000
+#define MCF5272_SIM_SPR_SMVEN 0x0020
+#define MCF5272_SIM_SPR_SBE 0x1000
+#define MCF5272_SIM_SPR_SBEEN 0x0010
+#define MCF5272_SIM_SPR_HWT 0x0800
+#define MCF5272_SIM_SPR_HWTEN 0x0008
+#define MCF5272_SIM_SPR_RPV 0x0400
+#define MCF5272_SIM_SPR_RPVEN 0x0004
+#define MCF5272_SIM_SPR_EXT 0x0200
+#define MCF5272_SIM_SPR_EXTEN 0x0002
+#define MCF5272_SIM_SPR_SUV 0x0100
+#define MCF5272_SIM_SPR_SUVEN 0x0001
+
+// ---------------------------------------------------------------------------
+
+// Interrupt controller registers
+typedef struct
+{
+
+ // Interrupt control register 1-4
+ cyg_uint32 icr[4];
+
+ // Interrupt source register
+ cyg_uint32 isr;
+
+ // Programmable interrupt transition register
+ cyg_uint32 pitr;
+
+ // Programmable interrupt wakeup register
+ cyg_uint32 piwr;
+
+ // Gap
+ cyg_uint8 _res1[3];
+
+ // Programmable interrupt vector register
+ cyg_uint8 ipvr;
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_int_t;
+
+// Interrupt controller related macros
+
+#define MCF5272_SIM_PITR_INT1_POS_EDGE (0x80000000)
+#define MCF5272_SIM_PITR_INT2_POS_EDGE (0x40000000)
+#define MCF5272_SIM_PITR_INT3_POS_EDGE (0x20000000)
+#define MCF5272_SIM_PITR_INT4_POS_EDGE (0x10000000)
+#define MCF5272_SIM_PITR_INT5_POS_EDGE (0x00000040)
+#define MCF5272_SIM_PITR_INT6_POS_EDGE (0x00000020)
+
+#define MCF5272_SIM_PIWR_INT1_WAKE (0x80000000)
+#define MCF5272_SIM_PIWR_INT2_WAKE (0x40000000)
+#define MCF5272_SIM_PIWR_INT3_WAKE (0x20000000)
+#define MCF5272_SIM_PIWR_INT4_WAKE (0x10000000)
+#define MCF5272_SIM_PIWR_TMR0_WAKE (0x08000000)
+#define MCF5272_SIM_PIWR_TMR1_WAKE (0x04000000)
+#define MCF5272_SIM_PIWR_TMR2_WAKE (0x02000000)
+#define MCF5272_SIM_PIWR_TMR3_WAKE (0x01000000)
+#define MCF5272_SIM_PIWR_UART1_WAKE (0x00800000)
+#define MCF5272_SIM_PIWR_UART2_WAKE (0x00400000)
+#define MCF5272_SIM_PIWR_PLIP_WAKE (0x00200000)
+#define MCF5272_SIM_PIWR_PLIA_WAKE (0x00100000)
+#define MCF5272_SIM_PIWR_USB0_WAKE (0x00080000)
+#define MCF5272_SIM_PIWR_USB1_WAKE (0x00040000)
+#define MCF5272_SIM_PIWR_USB2_WAKE (0x00020000)
+#define MCF5272_SIM_PIWR_USB3_WAKE (0x00010000)
+#define MCF5272_SIM_PIWR_USB4_WAKE (0x00008000)
+#define MCF5272_SIM_PIWR_USB5_WAKE (0x00004000)
+#define MCF5272_SIM_PIWR_USB6_WAKE (0x00002000)
+#define MCF5272_SIM_PIWR_USB7_WAKE (0x00001000)
+#define MCF5272_SIM_PIWR_DMA_WAKE (0x00000800)
+#define MCF5272_SIM_PIWR_ERX_WAKE (0x00000400)
+#define MCF5272_SIM_PIWR_ETX_WAKE (0x00000200)
+#define MCF5272_SIM_PIWR_ENTC_WAKE (0x00000100)
+#define MCF5272_SIM_PIWR_QSPI_WAKE (0x00000080)
+#define MCF5272_SIM_PIWR_INT5_WAKE (0x00000040)
+#define MCF5272_SIM_PIWR_INT6_WAKE (0x00000020)
+#define MCF5272_SIM_PIWR_SWTO_WAKE (0x00000010)
+
+// ---------------------------------------------------------------------------
+
+// Chip-select module
+typedef struct
+{
+
+ // CS base register
+ cyg_uint32 csbr;
+
+ // CS option register
+ cyg_uint32 csor;
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_cs_t;
+
+// Chip-select modules related macros
+
+#define MCF5272_CS_BR_BASE(a) ((a) & 0xFFFFF000)
+
+#define MCF5272_CS_OR_MASK_128M (0xF8000000)
+#define MCF5272_CS_OR_MASK_64M (0xFC000000)
+#define MCF5272_CS_OR_MASK_32M (0xFE000000)
+#define MCF5272_CS_OR_MASK_16M (0xFF000000)
+#define MCF5272_CS_OR_MASK_8M (0xFF800000)
+#define MCF5272_CS_OR_MASK_4M (0xFFC00000)
+#define MCF5272_CS_OR_MASK_2M (0xFFE00000)
+#define MCF5272_CS_OR_MASK_1M (0xFFF00000)
+#define MCF5272_CS_OR_MASK_512K (0xFFF80000)
+#define MCF5272_CS_OR_MASK_256K (0xFFFC0000)
+#define MCF5272_CS_OR_MASK_128K (0xFFFE0000)
+#define MCF5272_CS_OR_MASK_64K (0xFFFF0000)
+#define MCF5272_CS_OR_MASK_32K (0xFFFF8000)
+#define MCF5272_CS_OR_MASK_16K (0xFFFFC000)
+#define MCF5272_CS_OR_MASK_8K (0xFFFFE000)
+#define MCF5272_CS_OR_MASK_4K (0xFFFFF000)
+#define MCF5272_CS_OR_WS_MASK (0x007C)
+#define MCF5272_CS_OR_WS(a) (((a) & 0x1F) << 2)
+#define MCF5272_CS_OR_BRST (0x0100)
+#define MCF5272_CS_OR_WR_ONLY (0x0003)
+#define MCF5272_CS_OR_RD_ONLY (0x0001)
+
+#define MCF5272_CS_BR_PS_8 (0x0100)
+#define MCF5272_CS_BR_PS_16 (0x0200)
+#define MCF5272_CS_BR_PS_32 (0x0000)
+#define MCF5272_CS_BR_PS_LINE (0x0300)
+#define MCF5272_CS_BR_ROM (0x0000)
+#define MCF5272_CS_BR_SRAM (0x0000)
+#define MCF5272_CS_BR_SRAM_8 (0x0C00)
+#define MCF5272_CS_BR_SDRAM (0x0400)
+#define MCF5272_CS_BR_ISA (0x0800)
+#define MCF5272_CS_BR_SV (0x0080)
+#define MCF5272_CS_BR_EN (0x0001)
+
+// ---------------------------------------------------------------------------
+
+// General purpose I/O module
+typedef struct
+{
+
+ // Port A control register
+ cyg_uint32 pacnt;
+
+ // Port A data direction register
+ cyg_uint16 paddr;
+
+ // Port A data register
+ cyg_uint16 padat;
+
+ // Port B control register
+ cyg_uint32 pbcnt;
+
+ // Port B data direction register
+ cyg_uint16 pbddr;
+
+ // Port B data register
+ cyg_uint16 pbdat;
+
+ // Gap
+ cyg_uint32 _res1;
+
+ // Port C data direction register
+ cyg_uint16 pcddr;
+
+ // Port C data register
+ cyg_uint16 pcdat;
+
+ // Port D control register
+ cyg_uint32 pdcnt;
+
+ // Gap
+ cyg_uint16 _res2;
+ cyg_uint16 _res3;
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_gpio_t;
+
+// GPIO ports related macros
+
+#define MCF5272_GPIO_DDR_IN (0)
+#define MCF5272_GPIO_DDR_OUT (1)
+
+#define MCF5272_GPIO_PBCNT_ETH_EN (0x55550000)
+#define MCF5272_GPIO_PBCNT_ETH_DE (0x00000000)
+#define MCF5272_GPIO_PBCNT_ETH_MSK (0xFFFF0000)
+
+#define MCF5272_GPIO_PBCNT_TA_EN (0x00000400)
+#define MCF5272_GPIO_PBCNT_TA_DE (0x00000000)
+#define MCF5272_GPIO_PBCNT_TA_MSK (0x00000C00)
+
+#define MCF5272_GPIO_PBCNT_URT0_EN (0x00000155)
+#define MCF5272_GPIO_PBCNT_URT0_DE (0x00000000)
+#define MCF5272_GPIO_PBCNT_URT0_MSK (0x000003FF)
+
+#define MCF5272_GPIO_PDCNT_INT4_EN (0x00000C00)
+#define MCF5272_GPIO_PDCNT_INT4_DE (0x00000000)
+#define MCF5272_GPIO_PDCNT_INT4_MSK (0x00000C00)
+
+#define MCF5272_GPIO_PDCNT_URT1_EN (0x000002AA)
+#define MCF5272_GPIO_PDCNT_URT1_DE (0x00000000)
+#define MCF5272_GPIO_PDCNT_URT1_MSK (0x000003FF)
+
+// ---------------------------------------------------------------------------
+
+// UART module
+typedef struct
+{
+
+ // UART mode register
+ cyg_uint8 umr;
+
+ // Gap
+ cyg_uint8 _res1[3];
+
+ // UART status register (R) and clock-select register (W)
+ cyg_uint8 usr_ucsr;
+
+ // Gap
+ cyg_uint8 _res2[3];
+
+ // UART command register
+ cyg_uint8 ucr;
+
+ // Gap
+ cyg_uint8 _res3[3];
+
+ // UART receiver buffers (R) and transmitter buffers (W)
+ cyg_uint8 urb_utb;
+
+ // Gap
+ cyg_uint8 _res4[3];
+
+ // UART input port change register (R) and auxiliary control register (W)
+ cyg_uint8 uipcr_uacr;
+
+ // Gap
+ cyg_uint8 _res5[3];
+
+ // UART interrupt status register (R) and interrupt mask register (W)
+ cyg_uint8 uisr_uimr;
+
+ // Gap
+ cyg_uint8 _res6[3];
+
+ // UART divider upper register
+ cyg_uint8 udu;
+
+ // Gap
+ cyg_uint8 _res7[3];
+
+ // UART divider lower register
+ cyg_uint8 udl;
+
+ // Gap
+ cyg_uint8 _res8[3];
+
+ // UART autobaud register MSB
+ cyg_uint8 uabu;
+
+ // Gap
+ cyg_uint8 _res9[3];
+
+ // UART autobaud register LSB
+ cyg_uint8 uabl;
+
+ // Gap
+ cyg_uint8 _res10[3];
+
+ // UART transmitter FIFO register
+ cyg_uint8 utf;
+
+ // Gap
+ cyg_uint8 _res11[3];
+
+ // UART receiver FIFO register
+ cyg_uint8 urf;
+
+ // Gap
+ cyg_uint8 _res12[3];
+
+ // UART fractional precision divider register
+ cyg_uint8 ufpd;
+
+ // Gap
+ cyg_uint8 _res13[3];
+
+ // UART input port register
+ cyg_uint8 uip;
+
+ // Gap
+ cyg_uint8 _res14[3];
+
+ // UART output port register 1
+ cyg_uint8 uop1;
+
+ // Gap
+ cyg_uint8 _res15[3];
+
+ // UART output port register 0
+ cyg_uint8 uop0;
+
+ // Gap
+ cyg_uint8 _res16[3];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_uart_t;
+
+// ---------------------------------------------------------------------------
+
+// SDRAM controller
+typedef struct
+{
+
+ // Gap
+ cyg_uint8 _res1[2];
+
+ // SDRAM configuration register
+ cyg_uint16 sdcr;
+
+ // Gap
+ cyg_uint8 _res2[2];
+
+ // SDRAM timing register
+ cyg_uint16 sdtr;
+
+ // Gap
+ cyg_uint8 _res3[120];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_sdramctrl_t;
+
+// SDRAM controller related macros
+
+#define MCF5272_SDRAMC_SDCCR_MCAS_A7 (0x0 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A8 (0x1 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A9 (0x2 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A10 (0x3 << 13)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A19 (0x0 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A20 (0x1 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A21 (0x2 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A22 (0x3 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A23 (0x4 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A24 (0x5 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A25 (0x6 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A26 (0x7 << 8)
+#define MCF5272_SDRAMC_SDCCR_GSL (0x00000080)
+#define MCF5272_SDRAMC_SDCCR_REG (0x00000010)
+#define MCF5272_SDRAMC_SDCCR_INV (0x00000008)
+#define MCF5272_SDRAMC_SDCCR_SLEEP (0x00000004)
+#define MCF5272_SDRAMC_SDCCR_ACT (0x00000002)
+#define MCF5272_SDRAMC_SDCCR_INIT (0x00000001)
+
+#define MCF5272_SDRAMC_SDCTR_RTP_66MHz (0x3D << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_48MHz (0x2B << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_33MHz (0x1D << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_25MHz (0x16 << 10)
+#define MCF5272_SDRAMC_SDCTR_RC(x) ((x & 0x3) << 8)
+#define MCF5272_SDRAMC_SDCTR_RP(x) ((x & 0x3) << 4)
+#define MCF5272_SDRAMC_SDCTR_RCD(x) ((x & 0x3) << 2)
+#define MCF5272_SDRAMC_SDCTR_CLT_2 (0x00000001)
+#define MCF5272_SDRAMC_SDCTR_CLT_3 (0x00000002)
+#define MCF5272_SDRAMC_SDCTR_CLT_4 (0x00000003)
+
+// ---------------------------------------------------------------------------
+
+// Timer module
+typedef struct
+{
+
+ // Timer mode register
+ cyg_uint16 tmr;
+
+ // Gap
+ cyg_uint16 _res1;
+
+ // Timer reference register
+ cyg_uint16 trr;
+
+ // Gap
+ cyg_uint16 _res2;
+
+ // Timer capture register
+ cyg_uint16 tcap;
+
+ // Gap
+ cyg_uint16 _res3;
+
+ // Timer counter register
+ cyg_uint16 tcn;
+
+ // Gap
+ cyg_uint16 _res4;
+
+ // Timer event register
+ cyg_uint16 ter;
+
+ // Gap
+ cyg_uint16 _res5;
+
+ // Gap
+ cyg_uint32 _res6[3];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_timer_t;
+
+// Related macros
+
+#define MCF5272_TIMER_TMR_PS (0xFF00)
+#define MCF5272_TIMER_TMR_PS_BIT (8)
+#define MCF5272_TIMER_TMR_CE (0x00C0)
+#define MCF5272_TIMER_TMR_CE_BIT (6)
+#define MCF5272_TIMER_TMR_OM (0x0020)
+#define MCF5272_TIMER_TMR_OM_BIT (5)
+#define MCF5272_TIMER_TMR_ORI (0x0010)
+#define MCF5272_TIMER_TMR_ORI_BIT (4)
+#define MCF5272_TIMER_TMR_FRR (0x0008)
+#define MCF5272_TIMER_TMR_FRR_BIT (3)
+#define MCF5272_TIMER_TMR_CLK (0x0006)
+#define MCF5272_TIMER_TMR_CLK_BIT (1)
+#define MCF5272_TIMER_TMR_RST (0x0001)
+#define MCF5272_TIMER_TMR_RST_BIT (0)
+#define MCF5272_TIMER_TER_REF (0x0002)
+#define MCF5272_TIMER_TER_REF_BIT (1)
+#define MCF5272_TIMER_TER_CAP (0x0001)
+#define MCF5272_TIMER_TER_CAP_BIT (0)
+
+// ---------------------------------------------------------------------------
+
+// Watchdog timer
+typedef struct
+{
+
+ // Watchdog reset reference register
+ cyg_uint16 wrrr;
+
+ // Gap
+ cyg_uint16 _res1;
+
+ // Watchdog interrupt reference register
+ cyg_uint16 wirr;
+
+ // Gap
+ cyg_uint16 _res2;
+
+ // Watchdog counter register
+ cyg_uint16 wcr;
+
+ // Gap
+ cyg_uint16 _res3;
+
+ // Watchdog event register
+ cyg_uint16 wer;
+
+ // Gap
+ cyg_uint16 _res4;
+
+ // Gap
+ cyg_uint32 _res5[28];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_sim_wdtmr_t;
+
+// ---------------------------------------------------------------------------
+
+// Fast Ethernet Controller module
+typedef struct
+{
+
+ // Ethernet control register
+ cyg_uint32 ecr;
+
+ // Ethernet interrupt event register
+ cyg_uint32 eir;
+
+ // Ethernet interrupt mask register
+ cyg_uint32 eimr;
+
+ // Interrupt vector status register
+ cyg_uint32 ivsr;
+
+ // Receive descriptor active register
+ cyg_uint32 rdar;
+
+ // Transmit descriptor active register
+ cyg_uint32 tdar;
+
+ // Gap
+ cyg_uint8 _res2[0x0880 - 0x0858];
+
+ // MII management frame register
+ cyg_uint32 mmfr;
+
+ // MII speed control register
+ cyg_uint32 mscr;
+
+ // Gap
+ cyg_uint8 _res3[0x08cc - 0x0888];
+
+ // FIFO receive bound register
+ cyg_uint32 frbr;
+
+ // FIFO receive start register
+ cyg_uint32 frsr;
+
+ // Gap
+ cyg_uint8 _res4[0x08e4 - 0x08d4];
+
+ // Transmit FIFO watermark
+ cyg_uint32 tfwr;
+
+ // Gap
+ cyg_uint8 _res5[0x08ec - 0x08e8];
+
+ // Transmit FIFO start register
+ cyg_uint32 tfsr;
+
+ // Gap
+ cyg_uint8 _res6[0x0944 - 0x08f0];
+
+ // Receive control register
+ cyg_uint32 rcr;
+
+ // Maximum frame length register
+ cyg_uint32 mflr;
+
+ // Gap
+ cyg_uint8 _res7[0x0984 - 0x094c];
+
+ // Transmit control register
+ cyg_uint32 tcr;
+
+ // Gap
+ cyg_uint8 _res8[0x0c00 - 0x0988];
+
+ // RAM perfect match address low register
+ cyg_uint32 malr;
+
+ // RAM perfect match address high register
+ cyg_uint32 maur;
+
+ // Hash table high register
+ cyg_uint32 htur;
+
+ // Hash table low register
+ cyg_uint32 htlr;
+
+ // Pointer to receive descriptor ring
+ cyg_uint32 erdsr;
+
+ // Pointer to transmit descriptor ring
+ cyg_uint32 etdsr;
+
+ // Maximum receive buffer size
+ cyg_uint32 emrbr;
+
+ // Gap
+ cyg_uint8 _res9[0x0c40 - 0x0c1c];
+
+ // FIFO RAM space
+ cyg_uint8 efifo[0x0e00 - 0x0c40];
+
+ // Gap
+ cyg_uint8 _res10[0x1000 - 0x0e00];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_fec_t;
+
+// ---------------------------------------------------------------------------
+
+// On-chip peripherals: this structure defines each register's offset from the
+// current value of the MBAR register.
+typedef struct
+{
+
+ // 0x0000: System Integration Module (SIM) general configuration registers
+ mcf5272_sim_cfg_t cfg;
+
+ // 0x0020: SIM interrupt controller registers
+ mcf5272_sim_int_t intc;
+
+ // 0x0040: SIM chip-select modules
+ mcf5272_sim_cs_t cs[8];
+
+ // 0x0080: SIM general purpose I/O control registers
+ mcf5272_sim_gpio_t gpio;
+
+ // 0x00a0: QSPI module
+ // TODO: a specific data structure is needed
+ cyg_uint32 qspi[8];
+
+ // 0x00c0: PWM module
+ // TODO: a specific data structure is needed
+ cyg_uint32 pwm[8];
+
+ // 0x00e0: DMA controller
+ // TODO: a specific data structure is needed
+ cyg_uint32 dmac[8];
+
+ // 0x0100: UART modules
+ mcf5272_uart_t uart[2];
+
+ // 0x0180: SIM SDRAM controller
+ mcf5272_sim_sdramctrl_t sdramc;
+
+ // 0x0200: timer module
+ mcf5272_timer_t timer[4];
+
+ // 0x0280: SIM watchdog timer module
+ mcf5272_sim_wdtmr_t wdtimer;
+
+ // 0x0300: physical layer interface controller
+ // TODO: a specific data structure is needed
+ cyg_uint32 plic[336];
+
+ // 0x0840: ethernet module
+ mcf5272_fec_t fec;
+
+ // 0x1000: USB module
+ // TODO: a specific data structure is needed
+ cyg_uint32 usb[512];
+
+} __attribute__ ((aligned (4), packed)) mcf5272_devs_t;
+
+// ---------------------------------------------------------------------------
+// End of mcf5272_devs.h
+#endif // CYGONCE_MCF5272_DEVS_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+
+//=============================================================================
+//
+// var_arch.h
+//
+// Processor variant specific definitions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Definitions specific to the MCF5272 processor.
+// Usage: Included by "hal_arch.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/mcf5272_devs.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+
+// Declare the global pointer to the peripheral registers.
+// Everyone should use the MCF5272_DEVS macro so it can be easily changed.
+#define MCF5272_DEVS ((volatile mcf5272_devs_t *) CYGMEM_REGION_devs)
+
+// ---------------------------------------------------------------------------
+// End of var_arch.h
+#endif // CYGONCE_HAL_VAR_ARCH_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_BASETYPE_H
+#define CYGONCE_HAL_VAR_BASETYPE_H
+
+//=============================================================================
+//
+// var_basetype.h
+//
+// Standard types for this architecture variant
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Type definitions specific to the MCF5272 processor.
+// Usage: Included by "basetype.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+// Use defaults for this architecture.
+
+// ---------------------------------------------------------------------------
+// End of var_basetype.h
+#endif // CYGONCE_HAL_VAR_BASETYPE_H
--- /dev/null
+#ifndef CYGONCE_VAR_CACHE_H
+#define CYGONCE_VAR_CACHE_H
+
+//=============================================================================
+//
+// var_cache.h
+//
+// Variant HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Definitions specific to the MCF5272 processor cache.
+// Usage: Included via "hal_cache.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/coldfire_regs.h>
+
+// We currently just enable the instruction cache on startup. There is
+// no data cache.
+
+// ----------------------------------------------------------------------------
+// Cache dimensions - these vary between the ColdFire sub-models
+
+// Data cache
+#define HAL_DCACHE_SIZE 0 // Size of data cache in bytes
+
+// Size of a data cache line. Leave this value even if there is no data cache
+// on 5272, otherwise some tests won't compile.
+#define HAL_DCACHE_LINE_SIZE 16
+
+#define HAL_DCACHE_WAYS 1 // Associativity of the cache
+
+// Instruction cache
+#define HAL_ICACHE_SIZE 1024 // Size of cache in bytes
+#define HAL_ICACHE_LINE_SIZE 16 // Size of a cache line
+#define HAL_ICACHE_WAYS 1 // Associativity of the cache
+
+#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+// ----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+// Note: Any locked lines will not be invalidated.
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Query the state of the data cache
+#define HAL_DCACHE_IS_ENABLED(_state_)
+
+// Set the data cache refill burst size
+//#define HAL_DCACHE_BURST_SIZE(_size_)
+
+// Set the data cache write mode
+//#define HAL_DCACHE_WRITE_MODE( _mode_ )
+
+//#define HAL_DCACHE_WRITETHRU_MODE 0
+//#define HAL_DCACHE_WRITEBACK_MODE 1
+
+
+// Load the contents of the given address range into the data cache
+// and then lock the cache so that it stays there.
+#define HAL_DCACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+#define HAL_DCACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+#define HAL_DCACHE_UNLOCK_ALL()
+
+// ----------------------------------------------------------------------------
+// Data cache line control
+
+// Allocate cache lines for the given address range without reading its
+// contents from memory.
+//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory and invalidate the cache entries
+// for the given address range.
+#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+
+// Invalidate cache lines in the given range without writing to memory.
+#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory for the given address range.
+#define HAL_DCACHE_STORE( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of reading
+// from it later.
+#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of writing
+// to it later.
+#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
+
+// Allocate and zero the cache lines associated with the given range.
+#define HAL_DCACHE_ZERO( _base_ , _size_ )
+
+// ----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE() CYGARC_MOVEC((CYG_WORD32)0x80000102, CYGARC_REG_CACR)
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE() CYGARC_MOVEC((CYG_WORD32)0x00000102, CYGARC_REG_CACR)
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL() CYGARC_MOVEC((CYG_WORD32)0x81000102, CYGARC_REG_CACR)
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC() CYGARC_MOVEC((CYG_WORD32)0x81000102, CYGARC_REG_CACR)
+
+// Query the state of the instruction cache
+//#define HAL_ICACHE_IS_ENABLED(_state_)
+
+// Set the instruction cache refill burst size
+//#define HAL_ICACHE_BURST_SIZE(_size_)
+
+
+// Load the contents of the given address range into the instruction cache
+// and then lock the cache so that it stays there.
+#define HAL_ICACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+#define HAL_ICACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+#define HAL_ICACHE_UNLOCK_ALL()
+
+// ----------------------------------------------------------------------------
+// Instruction cache line control
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
+
+// ---------------------------------------------------------------------------
+// End of var_cache.h
+#endif // ifndef CYGONCE_VAR_CACHE_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_INTR_H
+#define CYGONCE_HAL_VAR_INTR_H
+
+//==========================================================================
+//
+// var_intr.h
+//
+// MCF5272 processor variant interrupt, exception and clock support
+//
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors: Wade Jensen
+// Date: 2005-25-06
+// Purpose: Provide interrupt, exception and clock definitions specific
+// to the MCF5272 processor.
+// Usage: Included via "hal_intr.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+// Include any platform specific interrupt definitions.
+#include <cyg/hal/plf_intr.h>
+
+// Include for the device addresses (MCF5272_DEVS).
+#include <cyg/hal/var_arch.h>
+
+// Include for HAL I/O macros
+#include <cyg/hal/hal_io.h>
+
+// --------------------------------------------------------------------------
+// Interrupt controller management
+
+// This chip has a programmable interrupt vector base which is different
+// from the vector base register (VBR). All interrupts from the interrupt
+// controller are offset from the programmable interrupt vector register
+// (PIVR). However, the only legal value is 64.
+
+#define HAL_PROG_INT_VEC_BASE 64
+
+// Vector numbers defined by the interrupt controller.
+// These are all relative to the interrupt vector base number.
+#define CYGNUM_HAL_INTERRUPT_USR_SPURINT (0 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT1 (1 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT2 (2 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT3 (3 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT4 (4 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR0 (5 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR1 (6 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR2 (7 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_TMR3 (8 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_UART1 (9 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_UART2 (10 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_PLIP (11 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_PLIA (12 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB0 (13 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB1 (14 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB2 (15 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB3 (16 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB4 (17 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB5 (18 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB6 (19 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_USB7 (20 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_DMA (21 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_ERX (22 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_ETX (23 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_ENTC (24 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_QSPI (25 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT5 (26 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_EXTINT6 (27 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_SWTO (28 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_RES1 (29 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_RES2 (30 + HAL_PROG_INT_VEC_BASE)
+#define CYGNUM_HAL_INTERRUPT_RES3 (31 + HAL_PROG_INT_VEC_BASE)
+
+// -------------------------------------------------------------------------
+// Interrupt and exception vector table definitions. We need to redifine
+// CYGNUM_HAL_ISR_MIN because the first usable vector is 65
+
+#define CYGNUM_HAL_ISR_RANGE_DEFINED
+#define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_INTERRUPT_EXTINT1
+#define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_INTERRUPT_RES3
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
+
+// -------------------------------------------------------------------------
+// Spurious interrupt definition. The MCF5272 returns vector number 64,
+// instead of 24, for spurious interrupts
+
+#define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_INTERRUPT_USR_SPURINT
+
+// --------------------------------------------------------------------------
+// Interrupt controller definitions.
+
+// Interrupt priority tables
+externC volatile cyg_uint8 cyg_hal_ILVL_table[CYGNUM_HAL_ISR_COUNT];
+externC volatile cyg_uint8 cyg_hal_IMASK_table[CYGNUM_HAL_ISR_COUNT];
+
+externC void hal_interrupt_set_level(int vector, int level);
+externC void hal_interrupt_mask(int vector);
+externC void hal_interrupt_unmask(int vector);
+
+// Mask the interrupt associated with the given vector.
+#define HAL_INTERRUPT_MASK( _vector_ ) \
+ hal_interrupt_mask(_vector_)
+
+// Unmask the interrupt associated with the given vector.
+#define HAL_INTERRUPT_UNMASK( _vector_ ) \
+ hal_interrupt_unmask(_vector_)
+
+// Set the priority level of an interrupt.
+#define HAL_INTERRUPT_SET_LEVEL( _vector_, _prilevel_ ) \
+ hal_interrupt_set_level(_vector_, _prilevel_)
+
+// Acknowledge the interrupt by writing a 1 to the corresponding
+// interrupt pending bit. Write 0 to all other interrupt pending bits. Leave
+// all priority levels unchanged. Disable all interrupts while we access the
+// hardware registers.
+#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \
+CYG_MACRO_START \
+ cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
+ cyg_uint32 _icr = _vec_offset / 8; \
+ cyg_uint32 _icr_msk = 0x80000000 >> ((_vec_offset % 8) * 4); \
+ cyg_uint32 _icr_oldval; \
+ CYG_INTERRUPT_STATE _intr_state; \
+ \
+ HAL_DISABLE_INTERRUPTS(_intr_state); \
+ HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[_icr], _icr_oldval); \
+ HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[_icr], \
+ _icr_oldval & (_icr_msk | 0x77777777)); \
+ HAL_RESTORE_INTERRUPTS(_intr_state); \
+CYG_MACRO_END
+
+// Set/clear the interrupt transition register bit. Disable all
+// interrupts while we access the hardware registers.
+#define HAL_INTERRUPT_CONFIGURE( _vector_, _leveltriggered_, _up_ ) \
+CYG_MACRO_START \
+ if (!(_leveltriggered_)) \
+ { \
+ cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
+ cyg_uint32 _itr_bit = 0x80000000 >> _vec_offset; \
+ cyg_uint32 _pitr_oldval; \
+ CYG_INTERRUPT_STATE _intr_state; \
+ \
+ HAL_DISABLE_INTERRUPTS(_intr_state); \
+ HAL_READ_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval); \
+ if (_up_) \
+ { \
+ HAL_WRITE_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval | _itr_bit); \
+ } \
+ else \
+ { \
+ HAL_WRITE_UINT32(&MCF5272_DEVS->intc.pitr, _pitr_oldval & (~_itr_bit)); \
+ } \
+ HAL_RESTORE_INTERRUPTS(_intr_state); \
+ } \
+CYG_MACRO_END
+
+// --------------------------------------------------------------------------
+// Clock control
+
+// The MCF5272 has 4 timers, numbered 0...3. Define the timer number that we
+// want to use for the OS clock.
+#define CYGNUM_HAL_RTC_TIMER_NUM (3)
+
+// The vector used by the real-time clock
+#define CYGNUM_HAL_INTERRUPT_RTC (CYGNUM_HAL_INTERRUPT_TMR3)
+
+// Initialize the timer to generate an interrupt every 10 ms. Use the
+// system clock divided by 16 as the source. Using 10 as the prescaler
+// gives a 2.4 us counter. When this counter reaches _period_, generate
+// an interrupt.
+#define HAL_CLOCK_INITIALIZE(_period_) \
+CYG_MACRO_START \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tmr, \
+ 0x0000); \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].trr, \
+ (_period_)); \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, 0); \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].ter, 0x0003); \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tmr, \
+ (((10)-1) << MCF5272_TIMER_TMR_PS_BIT) | \
+ (0 << MCF5272_TIMER_TMR_CE_BIT) | \
+ (0 << MCF5272_TIMER_TMR_OM_BIT) | \
+ (1 << MCF5272_TIMER_TMR_ORI_BIT) | \
+ (0 << MCF5272_TIMER_TMR_FRR_BIT) | \
+ (2 << MCF5272_TIMER_TMR_CLK_BIT) | \
+ (1 << MCF5272_TIMER_TMR_RST_BIT)); \
+CYG_MACRO_END
+
+// We must clear the bit in the timer event register before we can get
+// another interrupt.
+#define HAL_CLOCK_RESET( _vector_, _period_ ) \
+CYG_MACRO_START \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, 0); \
+HAL_WRITE_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].ter, 0x0002); \
+CYG_MACRO_END
+
+// Read the current counter from the timer
+#define HAL_CLOCK_READ( _pvalue_ ) \
+CYG_MACRO_START \
+HAL_READ_UINT16(&MCF5272_DEVS->timer[CYGNUM_HAL_RTC_TIMER_NUM].tcn, \
+ *(_pvalue_)); \
+CYG_MACRO_END
+
+// Measure clock latency
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY
+#define HAL_CLOCK_LATENCY( _pvalue_ ) \
+CYG_MACRO_START \
+ register cyg_int32 result; \
+ HAL_CLOCK_READ( &result ); \
+ *_pvalue_ = result - CYGNUM_HAL_RTC_PERIOD; \
+CYG_MACRO_END
+#endif
+
+// ---------------------------------------------------------------------------
+// End of var_intr.h
+#endif // ifndef CYGONCE_HAL_VAR_INTR_H
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_REGS_H
+#define CYGONCE_HAL_VAR_REGS_H
+
+//==========================================================================
+//
+// var_regs.h
+//
+// ColdFire MCF5272 variant CPU definitions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Provide register definitions for the MCF5272.
+// Description:
+// Usage: Included via "coldfire_regs.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// CPU space registers definitions
+
+#define CYGARC_REG_CACR 0x002
+#define CYGARC_REG_ACR0 0x004
+#define CYGARC_REG_ACR1 0x005
+#define CYGARC_REG_VBR 0x801
+#define CYGARC_REG_ROMBAR0 0xC00
+#define CYGARC_REG_RAMBAR0 0xC04
+#define CYGARC_REG_MBAR 0xC0F
+
+// ---------------------------------------------------------------------------
+// End of var_regs.h
+#endif // ifdef CYGONCE_HAL_VAR_REGS_H
--- /dev/null
+#ifndef CYGONCE_VAR_STARTUP_H
+#define CYGONCE_VAR_STARTUP_H
+
+//=============================================================================
+//
+// var_startup.h
+//
+// ColdFire MCF5272 CPU variant startup header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: ColdFire MCF5272 CPU variant startup header.
+// Description:
+// Usage: Included via "hal_startup.h". Do not use directly.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// Include the platform-specific startup header.
+#include <cyg/hal/plf_startup.h>
+
+// Variant specific hardware initialization routine
+externC void var_reset(void) __attribute__ ((section (".boot")));
+
+// Variant specific data initialization routine
+externC void var_init_data(void) __attribute__ ((section (".boot")));
+
+// ---------------------------------------------------------------------------
+// End of var_startup.h
+#endif // CYGONCE_VAR_STARTUP_H
--- /dev/null
+#ifndef CYGONCE_HAL_VARIANT_INC
+#define CYGONCE_HAL_VARIANT_INC
+
+|==========================================================================
+|
+| variant.inc
+|
+| MCF5272 variant assembler header file
+|
+|==========================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| 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.
+| -------------------------------------------
+|###ECOSGPLCOPYRIGHTEND####
+|=============================================================================
+|#####DESCRIPTIONBEGIN####
+|
+| Author(s): Enrico Piria
+| Contributors:
+| Date: 2005-25-06
+| Purpose: MCF5272 variant definitions.
+| Description: This file contains the definitions specific to the
+| CPU variant, used in the architecture HAL assembler file.
+| Usage: Included by "vectors.S". Do not use directly.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+#include <cyg/hal/platform.inc>
+
+
+| -----------------------------------------------------------------------------
+| CPU specific macros. These provide a common assembler interface to
+| operations that may have CPU specific implementations on different
+| variants of the architecture.
+
+| CPU initialization macro
+ .macro hal_cpu_init
+
+ | Invalidate and disable the cache and ACRs.
+ move.l #0x01000000,%d0
+ movec %d0,%cacr
+
+ move.l #0x0,%d0
+ movec %d0,%acr0
+ movec %d0,%acr1
+ .endm
+
+
+| ----------------------------------------------------------------------------
+| This macro retrieves the IPL of the current interrupt from the
+| interrupt controller register. This is needed because on inetrrupt entry
+| all interrupts are disabled by writing to the status register, and thus
+| loosing the current IPL.
+| Input: interrupt vector number in d0
+| Output: IPL associated to interrupt in d0
+
+ .macro hal_variant_retrieve_ipl
+
+ | Subtract minimum interrupt vector number
+ sub.l #CYGNUM_HAL_ISR_MIN,%d0
+
+ | Load IPL table address in a0
+ lea cyg_hal_ILVL_table,%a0
+
+ | Retrieve IPL level for current interrupt
+ move.b (%a0,%d0.l),%d0
+
+ .endm
+
+| ----------------------------------------------------------------------------
+| end of variant.inc
+#endif // ifndef CYGONCE_HAL_VARIANT_INC
--- /dev/null
+//==========================================================================
+//
+// hal_diag.c
+//
+// HAL diagnostic I/O support routines for the MCF5272
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Code to manage the serial ports for diagnostic output.
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_UART1
+#include <cyg/hal/hal_if.h> // __comm_control_cmd_t
+#include <cyg/hal/hal_io.h> // HAL I/O macros
+#include <cyg/hal/hal_misc.h> // cyg_hal_is_break
+#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
+
+#include <cyg/hal/plf_serial.h>
+
+
+typedef struct {
+ CYG_ADDRWORD base; // [Pointer] to Port base address
+ unsigned int vector; // UART interrupt vector
+ CYG_WORD msec_timeout; // Timeout in msec
+} channel_data_t;
+
+static channel_data_t ports[] = {
+ {
+ (CYG_ADDRWORD) (&((mcf5272_devs_t *) 0)->uart[0]),
+ CYGNUM_HAL_INTERRUPT_UART1,
+ 1000
+ },
+
+ {
+ (CYG_ADDRWORD) (&((mcf5272_devs_t *) 0)->uart[1]),
+ CYGNUM_HAL_INTERRUPT_UART2,
+ 1000
+ }
+};
+
+
+static cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data);
+
+static void
+cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch);
+
+static void
+cyg_hal_plf_serial_init_channel(channel_data_t *port);
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch);
+
+static cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch);
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len);
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len);
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data);
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...);
+
+
+// ----------------------------------------------------------------------------
+// Early initialization of comm. channels.
+void
+cyg_hal_plf_comms_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ cyg_uint32 portcnt;
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+#if (defined(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) && \
+ CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 0) || \
+ (defined(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) && \
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0)
+
+ // UART0 pins are multplexed with GPIO port B. Enable them in
+ // port B control register.
+ HAL_READ_UINT32(&MCF5272_DEVS->gpio.pbcnt, portcnt);
+ HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pbcnt, ((portcnt &
+ ~(MCF5272_GPIO_PBCNT_URT0_MSK)) |
+ (MCF5272_GPIO_PBCNT_URT0_EN)));
+
+ // Init channel 0
+ cyg_hal_plf_serial_init_channel(&ports[0]);
+
+ // Setup procs in the vector table for channel 0
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &ports[0]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+#if (defined(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) && \
+ CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 1) || \
+ (defined(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) && \
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1)
+
+ // UART1 pins need to be enabled in port D control register.
+ HAL_READ_UINT32(&MCF5272_DEVS->gpio.pdcnt, portcnt);
+ HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pdcnt, ((portcnt &
+ ~(MCF5272_GPIO_PDCNT_URT1_MSK)) |
+ (MCF5272_GPIO_PDCNT_URT1_EN)));
+
+ // Init channel 1
+ cyg_hal_plf_serial_init_channel(&ports[1]);
+
+ // Setup procs in the vector table for channel 0
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &ports[1]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+#endif
+
+ // Restore original console
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+
+void cyg_hal_plf_serial_init_channel(channel_data_t *port)
+{
+ CYG_WORD16 clk_div;
+ volatile mcf5272_uart_t *base =
+ (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+ // Initialize variable to prevent compiler warnings
+ unsigned int baud_rate = 1200;
+
+
+#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+ if( (port-&ports[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL )
+ baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD;
+#endif
+#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+ if( (port-&ports[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL )
+ baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
+#endif
+
+ // Before we do anything else, make sure we have enabled RTS in case
+ // the device we are using relies on hardware flow control.
+ // Note that this step is our only attempt at hardware flow control.
+ HAL_WRITE_UINT8(&base->uop1, MCF5272_UART_UOP1_RTS);
+
+ // Initialize UART
+
+ // Reset Transmitter
+ HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RTX);
+
+ // Reset Receiver
+ HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RRX);
+
+ // Reset Mode Register
+ HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RMR);
+
+ HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RES);
+ HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RBC);
+
+ // Mode register 1 sets the UART to 8 data bits with no parity, and
+ // mode register 2 forces 1 stop bit. Also, interrupt generation
+ // on RxRDY signal is enabled by default.
+ // Reading or write to the mode register switches it from umr1 to umr2.
+ // To set it to umr1, we must write a reset mode register command to the
+ // command register.
+ HAL_WRITE_UINT8(&base->umr, MCF5272_UART_UMR_8BNP);
+ HAL_WRITE_UINT8(&base->umr, MCF5272_UART_UMR_1S);
+
+ // Select a prescaled (by 1/16) CLKIN for the clock source
+ HAL_WRITE_UINT8(&base->usr_ucsr, MCF5272_UART_UCSR_CLKIN);
+
+ // Calculate baud settings
+ clk_div = (CYG_WORD16)
+ ((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
+ (baud_rate * 32));
+ HAL_WRITE_UINT8(&base->udu, clk_div >> 8);
+ HAL_WRITE_UINT8(&base->udl, clk_div & 0x00ff);
+
+ // Enable the transmitter and receiver
+ HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_TXRXEN);
+
+ // Set interrupt priority to highest maskable level
+ HAL_INTERRUPT_SET_LEVEL(port->vector, 6);
+}
+
+
+cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data)
+{
+ cyg_uint8 ch;
+
+
+ while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+ return ch;
+}
+
+
+void cyg_hal_plf_serial_putc(void *__ch_data, cyg_uint8 ch)
+{
+ channel_data_t *port = (channel_data_t *) __ch_data;
+ volatile mcf5272_uart_t *base =
+ (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+ cyg_uint8 usr_ucsr, utf;
+
+
+ // Loop until the transmit data holding register is empty
+ do
+ {
+ HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
+ } while (!(usr_ucsr & MCF5272_UART_USR_TXRDY));
+
+ // Write the character to the transmit buffer
+ HAL_WRITE_UINT8(&base->urb_utb, ch);
+
+ // Loop until the transmit data FIFO and the shift register are empty
+ do
+ {
+ HAL_READ_UINT8(&base->utf, utf);
+ HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
+ } while ((utf & MCF5272_UART_UTF_TXB) ||
+ (!(usr_ucsr & MCF5272_UART_USR_TXEMP)));
+}
+
+static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ while(__len-- > 0)
+ cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+}
+
+
+static void cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+}
+
+
+static cyg_bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+ channel_data_t *port = (channel_data_t *) __ch_data;
+ volatile mcf5272_uart_t *base =
+ (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+ cyg_uint8 usr_ucsr;
+
+
+ // Read status
+ HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
+
+ // Check if a character is present
+ if (usr_ucsr & MCF5272_UART_USR_RRDY)
+ {
+ // Read character
+ HAL_READ_UINT8(&base->urb_utb, *ch);
+ return true;
+ }
+
+ return false;
+}
+
+
+static cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+ int delay_count;
+ cyg_bool res;
+
+
+ delay_count = ((channel_data_t *)__ch_data)->msec_timeout;
+
+ for(;;) {
+ res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+ if (res || 0 == delay_count--)
+ break;
+
+ CYGACC_CALL_IF_DELAY_US(100);
+ }
+
+ return res;
+}
+
+
+static int cyg_hal_plf_serial_control(void *__ch_data,
+ __comm_control_cmd_t __func, ...)
+{
+ static int irq_state = 0;
+ channel_data_t *port = (channel_data_t *) __ch_data;
+ volatile mcf5272_uart_t *base =
+ (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+ int ret = 0;
+
+
+ switch (__func) {
+ case __COMMCTL_IRQ_ENABLE:
+ irq_state = 1;
+
+ HAL_WRITE_UINT8(&base->uisr_uimr, MCF5272_UART_UIMR_FFULL);
+ HAL_INTERRUPT_UNMASK(port->vector);
+ break;
+ case __COMMCTL_IRQ_DISABLE:
+ ret = irq_state;
+ irq_state = 0;
+
+ HAL_INTERRUPT_MASK(port->vector);
+ HAL_WRITE_UINT8(&base->uisr_uimr, 0);
+ break;
+ case __COMMCTL_DBG_ISR_VECTOR:
+ ret = port->vector;
+ break;
+ case __COMMCTL_SET_TIMEOUT:
+ {
+ va_list ap;
+
+ va_start(ap, __func);
+
+ ret = port->msec_timeout;
+ port->msec_timeout = va_arg(ap, cyg_uint32);
+
+ va_end(ap);
+ }
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+
+static int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+ channel_data_t *port = (channel_data_t *) __ch_data;
+ volatile mcf5272_uart_t *base =
+ (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
+ char c;
+
+
+ // Disable the interrupt temporarily
+ HAL_WRITE_UINT8(&base->uisr_uimr, 0);
+
+ *__ctrlc = 0;
+
+ // Read character
+ HAL_READ_UINT8(&base->urb_utb, c);
+ if( cyg_hal_is_break( &c , 1 ) )
+ {
+ *__ctrlc = 1;
+ }
+
+ // Re-enable RxRDY interrupt
+ HAL_WRITE_UINT8(&base->uisr_uimr, MCF5272_UART_UIMR_FFULL);
+
+ return CYG_ISR_HANDLED;
+}
--- /dev/null
+//==========================================================================
+//
+// var_misc.c
+//
+// Miscellaneous functions specific to the processor variant
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Miscellaneous functions specific to the MCF5272 processor.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+// -------------------------------------------------------------------------
+// VSR table
+
+// For the MCF5272, we can point the VBR directly to the VSR table.
+// However, the table must be on a 1 MB boundary. Locate the VSR table where
+// the linker tells us to.
+
+volatile CYG_ADDRESS cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT]
+ __attribute__ ((section (".ramvec")));
+
+// -------------------------------------------------------------------------
+// Function prototypes
+
+static void hal_update_interrupt_controller(int vector);
+
+// -------------------------------------------------------------------------
+// Interrupt controller management
+//
+// With the MCF5272 interrupt controller, it is not possible to mask an
+// interrupt while retaining its associated priority. Moreover, if we enabled
+// the use of interrupts with different priorities, we don't have a means to
+// retrieve the priority of the current interrupt, after having raised the
+// IPL to the maximum, in the first instruction of the HAL ISR handler.
+// So, we use an auxiliary table (cyg_hal_ILVL_table) that records all the
+// priorities set for the various interrupts.
+// The purpose of the cyg_hal_IMASK_table table is to record wether an
+// interrupt is currently masked (0) or not (1).
+
+volatile cyg_uint8 cyg_hal_ILVL_table[CYGNUM_HAL_ISR_COUNT];
+volatile cyg_uint8 cyg_hal_IMASK_table[CYGNUM_HAL_ISR_COUNT];
+
+
+// Update priority table and interrupt controller
+void hal_interrupt_set_level(int vector, int level)
+{
+ cyg_uint32 index;
+
+ CYG_ASSERT((0 <= (level) && 7 >= (level)), "Illegal level");
+ CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+ && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+
+ HAL_TRANSLATE_VECTOR(vector, index);
+ cyg_hal_ILVL_table[index] = (cyg_uint8) level;
+
+ hal_update_interrupt_controller(vector);
+}
+
+// Update mask table and interrupt controller
+void hal_interrupt_mask(int vector)
+{
+ cyg_uint32 index;
+
+ CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+ && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+
+ HAL_TRANSLATE_VECTOR(vector, index);
+ cyg_hal_IMASK_table[index] = 0;
+
+ hal_update_interrupt_controller(vector);
+}
+
+// Update mask table and interrupt controller
+void hal_interrupt_unmask(int vector)
+{
+ cyg_uint32 index;
+
+ CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+ && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+
+ HAL_TRANSLATE_VECTOR(vector, index);
+ cyg_hal_IMASK_table[index] = 1;
+
+ hal_update_interrupt_controller(vector);
+}
+
+
+// Set the priority in the interrupt control register.
+// Disable all interrupts while we access the hardware registers.
+static void hal_update_interrupt_controller(int vector)
+{
+ cyg_uint32 index;
+ cyg_uint8 level;
+ cyg_uint32 vec_offset;
+ cyg_uint32 icr, icr_msk_offset, icr_msk, icr_val, icr_oldval;
+ CYG_INTERRUPT_STATE intr_state;
+
+ HAL_TRANSLATE_VECTOR(vector, index);
+ level = cyg_hal_IMASK_table[index] ? cyg_hal_ILVL_table[index] : 0;
+
+ vec_offset = (vector) - HAL_PROG_INT_VEC_BASE - 1;
+ icr = vec_offset / 8;
+ icr_msk_offset = ((8-1)*4) - (vec_offset % 8) * 4;
+ icr_msk = 0x0F << (icr_msk_offset);
+ icr_val = (0x08 | (level & 0x07)) << icr_msk_offset;
+
+ HAL_DISABLE_INTERRUPTS(intr_state);
+ HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_oldval);
+ icr_val |= icr_oldval & 0x77777777 & ~icr_msk;
+ HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_val);
+ HAL_RESTORE_INTERRUPTS(intr_state);
+}
+// -------------------------------------------------------------------------
+// End of var_misc.c
--- /dev/null
+//==========================================================================
+//
+// var_startup.c
+//
+// Functions for the processor variant startup
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria
+// Contributors:
+// Date: 2005-25-06
+// Purpose: Functions needed for MCF5272 startup.
+// Description: This module contains code that sets up the variant specific
+// hardware and data. All the code must be contained in the
+// section called ".boot", in order for the ROMRAM startup
+// to work properly.
+//
+//####DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_startup.h>
+
+
+// Variant specific initialization routine.
+// This routine must be called with interrupts disabled.
+void var_reset(void)
+{
+ // Nothing to do
+}
+
+// Variant specific data initialization routine
+void var_init_data(void)
+{
+ int i;
+
+ // Initialize priority and mask tables
+ for(i = 0; i < CYGNUM_HAL_ISR_COUNT; i++)
+ {
+ cyg_hal_IMASK_table[i] = 0;
+ cyg_hal_ILVL_table[i] = 0;
+ }
+}
--- /dev/null
+|==========================================================================
+|
+| variant.S
+|
+| MCF5272 variant code
+|
+|==========================================================================
+|###ECOSGPLCOPYRIGHTBEGIN####
+| -------------------------------------------
+| This file is part of eCos, the Embedded Configurable Operating System.
+| Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+| Copyright (C) 2006 eCosCentric Ltd.
+|
+| 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.
+| -------------------------------------------
+|###ECOSGPLCOPYRIGHTEND####
+|=============================================================================
+|#####DESCRIPTIONBEGIN####
+|
+| Author(s): Enrico Piria
+| Contributors:
+| Date: 2005-25-06
+| Purpose: MCF5272 variant code.
+| Description: This file contains the VSR table for the MCF5272, and
+| other definitions used by the rest of the ColdFire HAL.
+|
+|####DESCRIPTIONEND####
+|==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/cf_offsets.inc>
+
+
+| ----------------------------------------------------------------------------
+| ROM vector table
+
+ .section ".romvec","ax"
+
+ .extern cyg_interrupt_stack
+ .extern cyg_hal_reset_vsr
+ .extern cyg_hal_default_exception_vsr
+ .extern cyg_hal_default_spurious_vsr
+ .extern cyg_hal_default_interrupt_vsr
+
+ .globl rom_vsr_table
+rom_vsr_table:
+
+ | 0 - Initial SSP
+ .long cyg_interrupt_stack
+
+ | 1 - Initial PC
+ .long cyg_hal_reset_vsr
+
+ | 2-14 - Default exception handlers
+ .rept 14-2+1
+ .long cyg_hal_default_exception_vsr
+ .endr
+
+ | 15 - Uninitialized interrupt. It should never happen, because
+ | we configure interrupt controller at startup.
+ .long cyg_hal_default_spurious_vsr
+
+ | 16-23 - Reserved, treat as exceptions
+ .rept 23-16+1
+ .long cyg_hal_default_exception_vsr
+ .endr
+
+ | 24 - Spurious interrupt
+ .long cyg_hal_default_spurious_vsr
+
+ | 25-31 - Autovectored interrupts 1-7. Not used in MCF5272.
+ .rept 31-25+1
+ .long cyg_hal_default_interrupt_vsr
+ .endr
+
+ | 32-63 - Default exception handlers
+ .rept 63-32+1
+ .long cyg_hal_default_exception_vsr
+ .endr
+
+ | 64 - User spurious interrupt. The MCF5272 interrupt controller
+ | returns this vector number instead of vector 24
+ .long cyg_hal_default_spurious_vsr
+
+ | 65-255 - User interrupt vectors
+ .rept 255-65+1
+ .long cyg_hal_default_interrupt_vsr
+ .endr
--- /dev/null
+2008-07-01 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/vectors.S:
+ * include/arch.inc:
+ * include/hal_arch.h: Introduced CYGPKG_HAL_FR30_LMA_OFFSET for supporting
+ remapping a flash chip during initialisation.
+
+2007-07-09 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/context.S:
+ * src/fr30_stub.c:
+ * src/hal_misc.c:
+ * src/vectors.S:
+ * include/arch.inc:
+ * include/basetype.h:
+ * include/fr30.inc:
+ * include/fr30_stub.h:
+ * include/hal_arch.h:
+ * include/hal_cache.h:
+ * include/hal_intr.h:
+ * include/hal_io.h:
+ * cdl/hal_fr30.cdl: Initial fr30 ecos port
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_fr30.cdl
+#
+# fr30 architectural HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## 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): larsi
+# Original data:
+# Contributors:
+# Date: 2006-05-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_FR30 {
+ display "fr30 architecture"
+ parent CYGPKG_HAL
+ hardware
+ include_dir cyg/hal
+ define_header hal_fr30.h
+ description "
+ The fr30 architecture HAL package provides generic
+ support for Fujitsu's fr30/fr50/fr60 processor architecture.
+ It is also necessary to select a specific target platform HAL
+ package. If you have a fr50 device, choose the MB91360 variant."
+
+ cdl_interface CYGINT_HAL_FR30_VARIANT {
+ display "Number of variant implementations in this configuration"
+ requires 1 == CYGINT_HAL_FR30_VARIANT
+ }
+
+ compile hal_misc.c context.S vectors.S fr30_stub.c
+
+ make {
+ <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
+ $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 vectors.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm vectors.tmp
+ }
+}
--- /dev/null
+#ifndef CYGONCE_HAL_ARCH_INC
+#define CYGONCE_HAL_ARCH_INC
+##=============================================================================
+##
+## arch.inc
+##
+## fr30 assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## 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): larsi
+## Contributors: larsi
+## Date: 2006-06-20
+## Purpose: Architecture definitions.
+## Description: This file contains various definitions and macros that are
+## useful for writing assembly code for the fr30 CPU family.
+## Usage:
+## #include <cyg/hal/arch.inc>
+## ...
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <cyg/hal/fr30.inc>
+
+#include <cyg/hal/variant.inc>
+
+##-----------------------------------------------------------------------------
+## define some .equ's to access c-code #define's from assembler code
+.equ CYGNUM_ASM_CALL_IF_TABLE_SIZE, CYGNUM_CALL_IF_TABLE_SIZE
+
+##-----------------------------------------------------------------------------
+## CPU specific macros. These provide a common assembler interface to
+## operations that may have CPU specific implementations on different
+## variants of the architecture
+
+#ifndef CYGPKG_HAL_FR30_CPU_INIT_DEFINED
+ # Initialize CPU
+ .macro hal_cpu_init
+ .endm
+#endif /* !CYGPKG_HAL_FR30_CPU_INIT_DEFINED */
+
+.macro hal_cpu_int_enable
+ orccr #0x10
+.endm
+
+.macro hal_cpu_int_disable
+ andccr #0xef
+.endm
+
+
+# Merge the interrupt enable state of the status register in
+# \sr with the current sr.
+
+.macro hal_cpu_int_merge sr
+ FIXME hal_cpu_int_merge not implemented yet
+.endm
+
+##-----------------------------------------------------------------------------
+# Default FR30 interrupt controller macros. Every FR30 has an integrated
+# interrupt controller, which we use here. This should be enough if there is
+# no special external interrupt controller (which I did not see yet).
+
+#ifndef CYGPKG_HAL_FR30_INTC_DEFINED
+
+#ifndef CYGPKG_HAL_FR30_INTC_INIT_DEFINED
+# initialize all interrupts to disabled. This is done automatically during
+# CPU reset and the macro is not used during ECOS startup. It is not
+# supplied here but would be setting all ICRs to 31 (to disable the particular
+# interrupt and maybe setting ILM in PS to 0.
+ .macro hal_intc_init
+ .endm
+#endif
+
+
+# Normally interrupts are decoded by hardware and can not be software decoded,
+# so this is empty here.
+
+ .macro hal_intc_decode vnum
+ .endm
+
+# Also translation interrupt number <--> vector number is done automatically
+# in hardware, so the macros are not supplied here.
+
+#endif
+
+#------------------------------------------------------------------------------
+# These defines are for the ISR and VSR tables which are defined in assembler
+# code. (currently in variant.S / vectors.S) and have to be the same like in
+# hal_intr.h
+
+#define CYGNUM_HAL_VECTOR_INTRFIRST 15
+#define CYGNUM_HAL_VECTOR_INTRLAST 63
+#define CYGNUM_HAL_VECTOR_NUMINTRS (CYGNUM_HAL_VECTOR_INTRLAST-CYGNUM_HAL_VECTOR_INTRFIRST+1)
+
+// Common interrupt vectors
+#ifndef CYGNUM_HAL_ISR_MIN
+#define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_VECTOR_INTRFIRST
+#define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_VECTOR_INTRLAST
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_VECTOR_NUMINTRS)
+#endif
+
+// The default size of the VSR table is 256 entries.
+#ifndef CYGNUM_HAL_VSR_MIN
+#define CYGNUM_HAL_VSR_MIN 0
+#define CYGNUM_HAL_VSR_MAX 255
+#define CYGNUM_HAL_VSR_COUNT 256
+#endif
+
+#------------------------------------------------------------------------------
+# Register save and restore macros. These expect a pointer to a CPU save state
+# area in the register \ptr. The GPR indicated by \reg will be saved into its
+# slot in that structure.
+
+# TODO do this macros if needed, look at MIPS arch.inc for inspiration
+
+
+#------------------------------------------------------------------------------
+# Stack switching macros
+
+
+
+#------------------------------------------------------------------------------
+# MEMC macros.
+
+
+#------------------------------------------------------------------------------
+# Cache macros.
+
+#ifndef CYGPKG_HAL_FR30_CACHE_DEFINED
+
+ .macro hal_cache_init
+
+ .endm
+
+#endif
+
+#------------------------------------------------------------------------------
+# Diagnostics macros.
+
+#------------------------------------------------------------------------------
+# Timer initialization.
+
+#ifndef CYGPKG_HAL_FR30_TIMER_DEFINED
+
+ .macro hal_timer_init
+ .endm
+
+#endif
+
+#------------------------------------------------------------------------------
+# Difference of the flash memory from the linkers LMA (loadmemoryaddress) after
+# the new mapping in (mapping is done in hal_fr30_ram_startup_trampoline).
+
+#ifndef CYGPKG_HAL_FR30_LMA_OFFSET
+
+#define CYGPKG_HAL_FR30_LMA_OFFSET 0x0
+
+#endif
+
+
+#endif // ifndef CYGONCE_HAL_ARCH_INC
+# end of arch.inc
--- /dev/null
+#ifndef CYGONCE_HAL_BASETYPE_H
+#define CYGONCE_HAL_BASETYPE_H
+
+//=============================================================================
+//
+// basetype.h
+//
+// Standard types for this architecture.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors:larsi
+// Date: 2006-06-15
+// Purpose: Define architecture base types.
+// Usage: Included by "cyg_type.h", do not use directly
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Characterize the architecture
+
+#define CYG_BYTEORDER CYG_MSBFIRST // BIG endian
+
+// ---------------------------------------------------------------------------
+// Override the alignment definitions from cyg_type.h
+
+#ifndef CYGARC_ALIGNMENT
+#define CYGARC_ALIGNMENT 4
+#endif
+
+// The corresponding power of two alignment
+#ifndef CYGARC_P2ALIGNMENT
+#define CYGARC_P2ALIGNMENT 2
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_BASETYPE_H
+// End of basetype.h
--- /dev/null
+##=============================================================================
+##
+## fr30.inc
+##
+## fr30 assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## 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): larsi
+## Contributors:larsi
+## Date: 2006-06-15
+## Purpose: fr30 definitions.
+## Description: This file contains various definitions and macros that are
+## useful for writing assembly code for the fr30
+## Usage:
+## #include <cyg/hal/fr30.inc>
+## ...
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#------------------------------------------------------------------------------
+# Exception, interrupt and thread context save area layout
+# The layout of this structure is also defined in "hal_arch.h", for C
+# code. Do not change this without changing that (or vice versa).
+
+#------------------------------------------------------------------------------
+# end of fr30.inc
--- /dev/null
+//========================================================================
+//
+// fr30_stub.h
+//
+// FR30-specific definitions for remote debugging via gdb
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Fujitsu FR30-specific definitions for gdb stubs support
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#ifndef CYGONCE_HAL_FR30_STUB_H
+#define CYGONCE_HAL_FR30_STUB_H
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_IO_SERIAL
+#include <pkgconf/io_serial.h>
+#endif
+
+#include <cyg/hal/hal_diag.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM, externC
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL() HAL_DIAG_INIT()
+
+#define HAL_STUB_PLATFORM_GET_CHAR() \
+((cyg_int8)({ \
+ cyg_int8 _ch_; \
+ HAL_DIAG_READ_CHAR(_ch_); \
+ _ch_; \
+}))
+
+#define HAL_STUB_PLATFORM_PUT_CHAR(c) HAL_DIAG_WRITE_CHAR((c))
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int,(baud))
+
+#define HAL_STUB_PLATFORM_RESET() HAL_DIAG_INIT()
+
+#define HAL_STUB_PLATFORM_INIT() HAL_DIAG_INIT()
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#define FR30_GENREGS 16
+#define FR30_DEDICATEDREGS 8
+#define FR30_REGSIZE 4 /* bytes */
+
+// only NUMREGS and REGSIZE are the really needed macros
+
+#define NUMREGS (FR30_GENREGS + FR30_DEDICATEDREGS)
+#define REGSIZE( _x_ ) FR30_REGSIZE
+
+
+typedef unsigned long target_register_t;
+
+enum regnames {
+ R0, R1, R2, R3, R4, R5, R6, R7,
+ R8, R9, R10, R11, R12, R13, R14, SP,
+ PC, PS, TBR, RP, SSP, USP, MDH, MDL
+};
+
+typedef enum regnames regnames_t;
+
+// Override generic stubs get_register() and use arch-specific version
+#define CYGARC_STUB_REGISTER_ACCESS_DEFINED
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+#define HAL_GET_PROFILE_INFO( _thepc_, _thesp_ ) \
+ CYG_MACRO_START \
+ extern HAL_SavedRegisters *hal_saved_interrupt_state; \
+ if ( hal_saved_interrupt_state ) { \
+ (_thepc_) = (char *)(hal_saved_interrupt_state->pc); \
+ (_thesp_) = (char *)(hal_saved_interrupt_state->sp); \
+ } \
+ CYG_MACRO_END
+#endif
+
+/* Given a trap value TRAP, return the corresponding signal. */
+externC int __computeSignal (unsigned int trap_number);
+
+/* Return the trap number corresponding to the last-taken trap. */
+externC int __get_trap_number (void);
+
+/* Return the currently-saved value corresponding to register REG. */
+externC target_register_t get_register (regnames_t reg);
+
+/* Store VALUE in the register corresponding to WHICH. */
+externC void put_register (regnames_t which, target_register_t value);
+
+/* Set the currently-saved pc register value to PC. This also updates NPC
+ as needed. */
+externC void set_pc (target_register_t pc);
+
+/* Set things up so that the next user resume will execute one instruction.
+ This may be done by setting breakpoints or setting a single step flag
+ in the saved user registers, for example. */
+externC void __single_step (void);
+
+/* Clear the single-step state. */
+externC void __clear_single_step (void);
+
+/* If the breakpoint we hit is in the breakpoint() instruction, return a
+ non-zero value. */
+externC int __is_breakpoint_function (void);
+
+/* Skip the current instruction. */
+externC void __skipinst (void);
+
+externC void __install_breakpoints (void);
+
+externC void __clear_breakpoints (void);
+
+#endif // ifndef CYGONCE_HAL_FR30_STUB_H
+
+// EOF fr30_stub.h
--- /dev/null
+#ifndef CYGONCE_HAL_HAL_ARCH_H
+#define CYGONCE_HAL_HAL_ARCH_H
+
+//=============================================================================
+//
+// hal_arch.h
+//
+// Architecture specific abstractions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors:
+// Date: 2006-05-28
+// Purpose: Define architecture abstractions
+// Usage: #include <cyg/hal/hal_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/var_arch.h>
+
+#define CYG_HAL_FR30_REG CYG_ADDRWORD
+
+//-----------------------------------------------------------------------------
+// Processor saved states. This structure is also defined in fr30.inc for
+// assembly code. Do not change this without changing that (or vice versa).
+
+typedef struct HAL_SavedRegisters
+{
+ cyg_uint32 r[16]; // general purpose registers with
+ // r[13]: virtual accumulator (AC)
+ // r[14]: frame pointer (FP)
+ // r[15]: stack pointer (SP) r15 is not saved here!
+ cyg_uint32 pc; // program counter
+ cyg_uint32 ps; // program status (with ILM, SCR, CCR)
+ cyg_uint32 tbr; // table base register (not neccessary,
+ // as it is used system-wide not per thread)
+ cyg_uint32 rp; // return pointer
+ // ssp is used system-wide for EIT processing and does not need to be saved here
+ // and therefore we don't store usp, because we have it already in r15
+ cyg_uint32 ssp; // system stack pointer
+ cyg_uint32 usp; // user stack pointer
+ cyg_uint32 mdh; // multiplication and division regs /
+ cyg_uint32 mdl; // with high and low words
+
+ cyg_uint32 last_trap; // the last taken trap (for GDB stubs)
+
+} HAL_SavedRegisters;
+
+
+//-----------------------------------------------------------------------------
+// Exception handling function.
+// This function is defined by the kernel according to this prototype. It is
+// invoked from the HAL to deal with any CPU exceptions that the HAL does
+// not want to deal with itself. It usually invokes the kernel's exception
+// delivery mechanism. FIXME
+// declared in src/hal_misc.c
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+
+//-----------------------------------------------------------------------------
+// Bit manipulation routines
+// declared in src/hal_misc.c
+
+externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
+externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
+
+#define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask);
+
+#define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask);
+
+//-----------------------------------------------------------------------------
+// Context Initialization
+// Initialize the context of a thread.
+// Arguments:
+// _sparg_ name of variable containing current sp, will be written with new sp
+// _thread_ thread object address, passed as argument to entry point
+// _entry_ entry point address.
+// _id_ bit pattern used in initializing registers, for debugging.
+
+#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \
+ CYG_MACRO_START \
+ register CYG_WORD _sp_ = ((CYG_WORD)_sparg_); \
+ register HAL_SavedRegisters *_regs_; \
+ int _i_; \
+ _regs_ = (HAL_SavedRegisters *)(((_sp_) - sizeof(HAL_SavedRegisters)) & ~(CYGARC_ALIGNMENT - 1)); \
+ for( _i_ = 0; _i_ <= 14; _i_++ ) (_regs_)->r[_i_] = (_id_)|_i_; \
+ (_regs_)->r[15] = (CYG_HAL_FR30_REG)(_regs_); /* r15 = USP = top of stack*/ \
+ (_regs_)->r[04] = (CYG_HAL_FR30_REG)(_thread_); /* R4 = arg1 = thread ptr */ \
+ (_regs_)->pc = (CYG_WORD)(_entry_); /* PC = entry point */ \
+ (_regs_)->ps = (CYG_HAL_FR30_REG)0x1f0030; /* 0x000F0030; set flags */ \
+ (_regs_)->tbr = (CYG_HAL_FR30_REG)0x10ffc00; /*system standard tbr value*/ \
+ (_regs_)->rp = (CYG_HAL_FR30_REG)0x0; /* return pointer = 0x0 */ \
+ (_regs_)->ssp = (CYG_HAL_FR30_REG)0x0; /* R4 = arg1 = thread ptr */ \
+ (_regs_)->usp = (CYG_HAL_FR30_REG)(_regs_); /* r15 = USP = top of stack*/ \
+ (_regs_)->mdh = (CYG_HAL_FR30_REG)0; /* mdh = 0 */ \
+ (_regs_)->mdl = (CYG_HAL_FR30_REG)0; /* mdl = 0 */ \
+ (_sparg_) = (CYG_ADDRESS)_regs_; \
+ CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Context switch macros.
+// The arguments are pointers to locations where the stack pointer
+// of the current thread is to be stored, and from where the sp of the
+// next thread is to be fetched.
+// declared in src/hal_misc.c
+
+externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
+externC void hal_thread_load_context( CYG_ADDRESS to )
+ __attribute__ ((noreturn));
+
+#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \
+ hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_);
+
+#define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \
+ hal_thread_load_context( (CYG_ADDRESS)_tspptr_ );
+
+//-----------------------------------------------------------------------------
+// Execution reorder barrier.
+// When optimizing the compiler can reorder code. In multithreaded systems
+// where the order of actions is vital, this can sometimes cause problems.
+// This macro may be inserted into places where reordering should not happen.
+
+#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
+
+//-----------------------------------------------------------------------------
+// Breakpoint support
+// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen
+// if executed.
+// HAL_BREAKINST is the value of the breakpoint instruction and
+// HAL_BREAKINST_SIZE is its size in bytes.
+
+#define HAL_BREAKPOINT(_label_) \
+CYG_MACRO_START \
+ asm volatile (" .globl " #_label_ ";\n" \
+ #_label_":\n" \
+ "int #0x9\n" \
+ ); \
+CYG_MACRO_END
+
+// 0x9F30 is the INTE instruction (vector no.9, TBR offset 0x3D8)
+// 0x1f09 is the INT# 9 instruction (vector no.9, TBR offset 0x3D8)
+#define HAL_BREAKINST 0x1f09
+#define HAL_BREAKINST_SIZE 2
+#define HAL_BREAKINST_TYPE unsigned short
+
+//-----------------------------------------------------------------------------
+// Thread register state manipulation for GDB support.
+
+// Default to a 32 bit register size for GDB register dumps.
+#ifndef CYG_HAL_GDB_REG
+#define CYG_HAL_GDB_REG CYG_WORD32
+#endif
+
+// Register layout expected by GDB
+typedef struct
+{
+ CYG_HAL_FR30_REG r[16]; // was: r[0] GPR regs
+ CYG_HAL_FR30_REG pc;
+ CYG_HAL_FR30_REG ps;
+ CYG_HAL_FR30_REG tbr;
+ CYG_HAL_FR30_REG rp;
+ CYG_HAL_FR30_REG ssp;
+ CYG_HAL_FR30_REG usp;
+ CYG_HAL_FR30_REG mdh;
+ CYG_HAL_FR30_REG mdl;
+} GDB_Registers;
+
+// Translate a stack pointer as saved by the thread context macros above into
+// a pointer to a HAL_SavedRegisters structure declared in src/fr30_stub.h
+
+#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \
+ (_regs_) = (HAL_SavedRegisters *)(_sp_)
+
+// Copy a set of registers from a HAL_SavedRegisters structure into a
+// GDB ordered array.
+#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \
+ CYG_MACRO_START \
+ GDB_Registers *_gdb_ = (GDB_Registers *)(_aregval_); \
+ int _i_; \
+ \
+ for( _i_ = 0; _i_ < 16; _i_++ ) { \
+ _gdb_->r[_i_] = (_regs_)->r[_i_]; \
+ } \
+ \
+ _gdb_->pc = (_regs_)->pc; \
+ _gdb_->ps = (_regs_)->ps; \
+ _gdb_->tbr = (_regs_)->tbr; \
+ _gdb_->rp = (_regs_)->rp; \
+ _gdb_->ssp = (_regs_)->ssp; \
+ _gdb_->usp = (_regs_)->usp; \
+ _gdb_->mdh = (_regs_)->mdh; \
+ _gdb_->mdl = (_regs_)->mdl; \
+ CYG_MACRO_END
+
+// Copy a set of registers from a GDB_Registers structure into a
+// HAL_SavedRegisters structure.
+#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \
+ CYG_MACRO_START \
+ GDB_Registers *_gdb_ = (GDB_Registers *)(_aregval_); \
+ int _i_; \
+ \
+ for( _i_ = 0; _i_ < 16; _i_++ ) \
+ (_regs_)->r[_i_] = _gdb_->r[_i_]; \
+ \
+ (_regs_)->pc = _gdb_->pc; \
+ (_regs_)->ps = _gdb_->ps; \
+ (_regs_)->tbr = _gdb_->tbr; \
+ (_regs_)->rp = _gdb_->rp; \
+ (_regs_)->ssp = _gdb_->ssp; \
+ (_regs_)->usp = _gdb_->usp; \
+ (_regs_)->mdh = _gdb_->mdh; \
+ (_regs_)->mdl = _gdb_->mdl; \
+ CYG_MACRO_END
+
+
+// -------------------------------------------------------------------------
+// hal_setjmp/hal_longjmp
+
+
+// We must save all of the registers that are preserved across routine
+// calls. The assembly code assumes that this structure is defined in the
+// following format. Any changes to this structure will result in changes to
+// the assembly code!!
+
+typedef struct {
+ // registers
+ cyg_uint32 r8;
+ cyg_uint32 r9;
+ cyg_uint32 r10;
+ cyg_uint32 r11;
+ cyg_uint32 r14;
+
+ // SP and PC
+ cyg_uint32 r15; //USP
+ cyg_uint32 pc;
+} hal_jmp_buf_t;
+
+// This type is used by normal routines to pass the address of the structure
+// into our routines without having to explicitly take the address
+// of the structure.
+
+typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
+
+// Define the generic setjmp and longjmp routines
+externC int hal_setjmp(hal_jmp_buf env);
+externC void hal_longjmp(hal_jmp_buf env, int val);
+//-----------------------------------------------------------------------------
+// Idle thread code.
+// This macro is called in the idle thread loop, and gives the HAL the
+// chance to insert code. Typical idle thread behaviour might be to halt the
+// processor. (contains an empty function call at the moment)
+// declared in src/hal_misc.c
+
+externC void hal_idle_thread_action(cyg_uint32 loop_count);
+
+#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
+
+//-----------------------------------------------------------------------------
+// Minimal and sensible stack sizes: the intention is that applications
+// will use these to provide a stack size in the first instance prior to
+// proper analysis. Idle thread stack should be this big.
+//
+// THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
+// THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
+// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
+
+// This is not a config option because it should not be adjusted except
+// under "enough rope" sort of disclaimers.
+
+// Stack frame overhead per call. 13 registers (which is a maximum FIXME),
+// frame pointer, and return address. We can't guess the local variables so
+// just assume that using all of the registers averages out.
+
+#define CYGNUM_HAL_STACK_FRAME_SIZE ((13 + 1 + 1) * 4)
+
+// Stack needed for a context switch.
+// it should be sizeof(HAL_SavedRegisters)
+// All registers + PC + PS + RP + MDH + MDL
+
+#ifndef CYGNUM_HAL_STACK_CONTEXT_SIZE
+#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((16+1+1+1+1+1)*4)
+#endif // CYGNUM_HAL_STACK_CONTEXT_SIZE
+
+// Interrupt + call to ISR, interrupt_end() and the DSR
+
+#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
+((CYGNUM_HAL_STACK_CONTEXT_SIZE) + (4*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// We define a minimum stack size as the minimum any thread could ever
+// legitimately get away with. We can throw asserts if users ask for less
+// than this. Allow enough for four interrupt sources - clock, serial,
+// nic, and one other
+
+#define CYGNUM_HAL_STACK_SIZE_MINIMUM \
+((4*CYGNUM_HAL_STACK_INTERRUPT_SIZE) \
+ + (16*CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// Now make a reasonable choice for a typical thread size. Pluck figures
+// from thin air and say 30 call frames with an average of 16 words of
+// automatic variables per call frame
+
+#define CYGNUM_HAL_STACK_SIZE_TYPICAL \
+(CYGNUM_HAL_STACK_SIZE_MINIMUM + \
+ (30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))))
+
+//--------------------------------------------------------------------------
+// Memory access macros
+
+#define CYGARC_CACHED_ADDRESS(x) (x)
+#define CYGARC_UNCACHED_ADDRESS(x) (x)
+#define CYGARC_PHYSICAL_ADDRESS(x) (x)
+#define CYGARC_VIRTUAL_ADDRESS(x) (x)
+
+//--------------------------------------------------------------------------
+// Macros for switching context between two eCos instances (jump from
+// code in ROM to code in RAM or vice versa).
+
+#define CYGARC_HAL_SAVE_GP()
+#define CYGARC_HAL_RESTORE_GP()
+
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_ARCH_H
+// End of hal_arch.h
--- /dev/null
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+// hal_cache.h
+//
+// HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+// cache control operations.
+// Usage:
+// #include <cyg/hal/hal_cache.h>
+// ...
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Cache dimensions
+
+// Data cache
+#define HAL_DCACHE_SIZE 4096 // Size of data cache in bytes
+#define HAL_DCACHE_LINE_SIZE 16 // Size of a data cache line
+#define HAL_DCACHE_WAYS 2 // Associativity of the cache
+
+// Instruction cache
+#define HAL_ICACHE_SIZE 4096 // Size of cache in bytes
+#define HAL_ICACHE_LINE_SIZE 16 // Size of a cache line
+#define HAL_ICACHE_WAYS 2 // Associativity of the cache
+
+#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Query the state of the data cache
+#define HAL_DCACHE_IS_ENABLED(_state_) \
+CYG_MACRO_START \
+_state_ = 1; \
+CYG_MACRO_END
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Query the state of the instruction cache
+#define HAL_ICACHE_IS_ENABLED(_state_) \
+CYG_MACRO_START \
+_state_ = 1; \
+CYG_MACRO_END
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+//-----------------------------------------------------------------------------
+// Instruction cache line control
+
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
--- /dev/null
+#ifndef CYGONCE_HAL_HAL_INTR_H
+#define CYGONCE_HAL_HAL_INTR_H
+
+//==========================================================================
+//
+// hal_intr.h
+//
+// FR30 HAL Interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors: larsi
+// Date: 2006-06-09
+// Purpose: Define Interrupt support
+// Description: The macros defined here provide the HAL APIs for handling
+// interrupts and the clock.
+//
+// Usage:
+// #include <cyg/hal/hal_intr.h>
+// ...
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_fr30.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/var_intr.h>
+
+//--------------------------------------------------------------------------
+// Exception vectors.
+// Standard exception,interrupt and trap(EIT) vectors supported by FR30 CPUs
+// These values are the ones to use for HAL_VSR_GET/SET
+// The FR30 vector table lies in reversed in memory, therefore we do
+// the 255-x thing here.
+
+#define CYGNUM_HAL_VECTOR_RESET 0
+// Values from 1 - 8 are system reserved
+#define CYGNUM_HAL_VECTOR_MODE_VECTOR 1
+#define CYGNUM_HAL_VECTOR_COPR_NOT_FOUND 7
+#define CYGNUM_HAL_VECTOR_COPR_ERROR 8
+#define CYGNUM_HAL_VECTOR_BREAKPOINT 9
+#define CYGNUM_HAL_VECTOR_INTE CYGNUM_HAL_VECTOR_BREAKPOINT
+// Values 10 and 11 are system reserved
+#define CYGNUM_HAL_VECTOR_INSTR_BREAK_EXCEPTION 10
+#define CYGNUM_HAL_VECTOR_OPERAND_BREAK_TRAP 11
+#define CYGNUM_HAL_VECTOR_DEBUG 12
+#define CYGNUM_HAL_VECTOR_STEP_TRACE CYGNUM_HAL_VECTOR_DEBUG
+// Value 13 is system reserved
+#define CYGNUM_HAL_VECTOR_NMI_INTR_TOOL 13
+// Value 14 undefined instruction exception
+#define CYGNUM_HAL_VECTOR_OPCODE 14
+// NMI (special non maskable interrupt)
+#define CYGNUM_HAL_VECTOR_NMI 15
+// interrupts
+// Note that these defines are for C code and have to be the same like those in
+// arch.inc for assembler code !
+#define CYGNUM_HAL_VECTOR_INTRFIRST 15
+#define CYGNUM_HAL_VECTOR_INTRLAST 63
+#define CYGNUM_HAL_VECTOR_NUMINTRS (CYGNUM_HAL_VECTOR_INTRLAST-CYGNUM_HAL_VECTOR_INTRFIRST+1)
+// Values 64 and 65 are reserved for system
+// traps
+#define CYGNUM_HAL_VECTOR_TRAPFIRST 80
+#define CYGNUM_HAL_VECTOR_SYSTEM_CALL CYGNUM_HAL_VECTOR_TRAPFIRST
+#define CYGNUM_HAL_VECTOR_TRAPLAST 255
+#define CYGNUM_HAL_VECTOR_NUMTRAPS (CYGNUM_HAL_VECTOR_TRAPLAST-CYGNUM_HAL_VECTOR_TRAPFIRST+1)
+
+// The default size of the VSR table is 256 entries.
+#ifndef CYGNUM_HAL_VSR_MIN
+#define CYGNUM_HAL_VSR_MIN 0
+#define CYGNUM_HAL_VSR_MAX 255
+#define CYGNUM_HAL_VSR_COUNT 256
+#endif
+
+// For ecos fr30 interrupts are interrupts and fr30 exceptions and
+// fr30 traps are both exceptions
+
+// Common interrupt vectors
+#ifndef CYGNUM_HAL_ISR_MIN
+#define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_VECTOR_INTRFIRST
+#define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_VECTOR_INTRLAST
+#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_VECTOR_NUMINTRS)
+#endif
+// Common exception vectors. (so these are fr30 exceptions and traps)
+#define CYGNUM_HAL_EXCEPTION_RESET CYGNUM_HAL_VECTOR_RESET
+#define CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL CYGNUM_HAL_VECTOR_COPR_NOT_FOUND
+#define CYGNUM_HAL_EXCEPTION_FPU CYGNUM_HAL_VECTOR_COPR_ERROR
+#define CYGNUM_HAL_EXCEPTION_TRAP CYGNUM_HAL_VECTOR_INTE
+// #define CYGNUM_HAL_EXCEPTION_INTERRUPT CYGNUM_HAL_VECTOR_BREAKPOINT
+// #define CYGNUM_HAL_EXCEPTION_TRAP CYGNUM_HAL_VECTOR_STEP_TRACE
+#define CYGNUM_HAL_EXCEPTION_SINGLE_STEP CYGNUM_HAL_VECTOR_STEP_TRACE
+#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_OPCODE
+
+// common interrupt vectors
+// I am sure more defines can be moved from variant to architecture HAL here
+#define CYGNUM_HAL_INTERRUPT_NMI 15
+
+// here we define exceptions and traps as the fr30 docs termini
+#define CYGNUM_HAL_EXCEPTION_FR30_MIN 0
+#define CYGNUM_HAL_EXCEPTION_FR30_MAX 14
+#define CYGNUM_HAL_EXCEPTION_FR30_COUNT (CYGNUM_HAL_EXCEPTION_FR30_MAX - CYGNUM_HAL_EXCEPTION_FR30_MIN + 1)
+
+#define CYGNUM_HAL_TRAP_FR30_MIN 80
+#define CYGNUM_HAL_TRAP_FR30_MAX 255
+#define CYGNUM_HAL_TRAP_FR30_COUNT (CYGNUM_HAL_TRAP_FR30_MAX - CYGNUM_HAL_TRAP_FR30_MIN + 1)
+
+// here we define the ecos ones
+// nicht mehr aktuell:(calculated from fr30 ones) FIXME maybe have to
+// change to correspons to durchgaengig vector numbers. In this table
+// exceptions are unterbrochen from interrupts
+#define CYGNUM_HAL_EXCEPTION_MIN 0
+#define CYGNUM_HAL_EXCEPTION_MAX 255
+#define CYGNUM_HAL_EXCEPTION_COUNT \
+ ( CYGNUM_HAL_EXCEPTION_MAX - CYGNUM_HAL_EXCEPTION_MIN + 1 )
+
+//--------------------------------------------------------------------------
+// Interrupt levels
+// Lower numbers mean stronger interrupt levels
+// values 0 - 14 are system reserved and can not be set by a program
+// (setting them would add 16 to the value automatically)
+// value 15 is for NMI
+// value 31 disables the interrupt
+
+#ifndef CYGHWR_HAL_INTERRUPT_LEVELS_DEFINED
+
+#define CYGNUM_HAL_INTERRUPT_LEVEL_0 16
+#define CYGNUM_HAL_INTERRUPT_LEVEL_1 17
+#define CYGNUM_HAL_INTERRUPT_LEVEL_2 18
+#define CYGNUM_HAL_INTERRUPT_LEVEL_3 19
+#define CYGNUM_HAL_INTERRUPT_LEVEL_4 20
+#define CYGNUM_HAL_INTERRUPT_LEVEL_5 21
+#define CYGNUM_HAL_INTERRUPT_LEVEL_6 22
+#define CYGNUM_HAL_INTERRUPT_LEVEL_7 23
+#define CYGNUM_HAL_INTERRUPT_LEVEL_8 24
+#define CYGNUM_HAL_INTERRUPT_LEVEL_9 25
+#define CYGNUM_HAL_INTERRUPT_LEVEL_10 26
+#define CYGNUM_HAL_INTERRUPT_LEVEL_11 27
+#define CYGNUM_HAL_INTERRUPT_LEVEL_12 28
+#define CYGNUM_HAL_INTERRUPT_LEVEL_13 29
+#define CYGNUM_HAL_INTERRUPT_LEVEL_14 30
+#define CYGNUM_HAL_INTERRUPT_LEVEL_15 31
+#define CYGNUM_HAL_INTERRUPT_LEVEL_DISABLE \
+ CYGNUM_HAL_INTERRUPT_LEVEL_15
+
+#define CYGHWR_HAL_INTERRUPT_LEVELS_DEFINED
+
+#endif
+
+//--------------------------------------------------------------------------
+// Static data used by HAL
+
+// ISR tables
+externC volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// VSR table
+externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
+
+//--------------------------------------------------------------------------
+// Interrupt state storage
+
+typedef cyg_uint32 CYG_INTERRUPT_STATE;
+
+//---------------------------------------------------------------------------
+// Default ISR
+externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+#define HAL_DEFAULT_ISR hal_default_isr
+
+//--------------------------------------------------------------------------
+// CPU interrupt enable/disable macros
+
+#define HAL_ENABLE_INTERRUPTS() \
+CYG_MACRO_START \
+ asm volatile ("orccr #0x10;\n") ; \
+CYG_MACRO_END
+
+#define HAL_DISABLE_INTERRUPTS(_old_) \
+CYG_MACRO_START \
+ register int x ; \
+ asm volatile ("st r1, @-r15 ;\n" \
+ "MOV PS, r1 ;\n" \
+ "LDI:8 #0x10,%0 ;\n" \
+ "AND r1, %0 ;\n" \
+ "LSR #1,%0 ;\n" \
+ "ld @r15+, r1 ;\n" \
+ "ANDCCR #0xEF \n" \
+ : "=r" (x) \
+ ); \
+ (_old_) = (x); \
+CYG_MACRO_END
+
+#define HAL_RESTORE_INTERRUPTS(_old_) \
+CYG_MACRO_START \
+ register int x = _old_; \
+ asm volatile ( "CMP #8, %0 ;\n" \
+ "BEQ 0f ;\n" \
+ "ANDCCR #0xEF ;\n" \
+ "BRA 1f;\n" \
+ "0:\n" \
+ "ORCCR #0x10 ;\n" \
+ "1:\n" \
+ : /* No outputs */ \
+ : "r"(x) \
+ ); \
+CYG_MACRO_END
+
+// 5th bit (0x10 / #10H) is interrupt flag
+// it is shifted right to be able to work with 4 bit immediate in the other macros
+#define HAL_QUERY_INTERRUPTS(_old_) \
+CYG_MACRO_START \
+ register int x ; \
+ asm volatile ("MOV PS,__tmp_reg__ ;\n" \
+ "LDI:8 #10H,%0 ;\n" \
+ "AND __tmp_reg__,%0 ;\n" \
+ "LSR #1,%0 ;\n" \
+ : "=r" (x) \
+ ); \
+ (_old_) = (x); \
+CYG_MACRO_END
+
+//---------------------------------------------------------------------------
+// Interrupt and VSR attachment macros
+
+
+#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
+ CYG_MACRO_START \
+ cyg_uint32 _index_; \
+ HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
+ \
+ if (hal_interrupt_handlers[_index_] \
+ ==(CYG_ADDRESS)HAL_DEFAULT_ISR) \
+ (_state_) = 0; \
+ else \
+ (_state_) = 1; \
+ CYG_MACRO_END
+
+#ifndef HAL_INTERRUPT_ATTACH
+externC void __default_interrupt_vsr(void);
+#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
+ CYG_MACRO_START \
+ cyg_uint32 _index_; \
+ HAL_TRANSLATE_VECTOR((_vector_), _index_); \
+ \
+ HAL_VSR_SET( _vector_, &__default_interrupt_vsr , NULL); \
+ if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \
+ { \
+ hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_); \
+ hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_); \
+ hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_); \
+ } \
+ CYG_MACRO_END
+#endif /* HAL_INTERRUPT_ATTACH */
+
+#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
+ CYG_MACRO_START \
+ cyg_uint32 _index_; \
+ HAL_TRANSLATE_VECTOR((_vector_), _index_); \
+ \
+ if (hal_interrupt_handlers[_index_] \
+ == (CYG_ADDRESS)(_isr_)) \
+ { \
+ hal_interrupt_handlers[_index_] = \
+ (CYG_ADDRESS)HAL_DEFAULT_ISR; \
+ hal_interrupt_data[_index_] = 0; \
+ hal_interrupt_objects[_index_] = 0; \
+ } \
+ CYG_MACRO_END
+
+#define HAL_VSR_GET( _vector_, _pvsr_ ) \
+ *((CYG_ADDRESS *)(_pvsr_)) = hal_vsr_table[(_vector_)];
+
+
+#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \
+ CYG_MACRO_START \
+ CYG_ADDRESS *__poldvsr = (CYG_ADDRESS *)(_poldvsr_); \
+ if( __poldvsr != NULL ) \
+ *__poldvsr = hal_vsr_table[(_vector_)]; \
+ hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_); \
+ CYG_MACRO_END
+
+// This is an ugly name, but what it means is: grab the VSR back to eCos
+// internal handling, or if you like, the default handler. But if
+// cooperating with GDB and CygMon, the default behaviour is to pass most
+// exceptions to CygMon. This macro undoes that so that eCos handles the
+// exception. So use it with care.
+
+externC void __default_exception_vsr(void);
+externC void __default_interrupt_vsr(void);
+
+#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) \
+CYG_MACRO_START \
+ HAL_VSR_SET( _vector_, _vector_ > CYGNUM_HAL_EXCEPTION_MAX \
+ ? (CYG_ADDRESS)__default_interrupt_vsr \
+ : (CYG_ADDRESS)__default_exception_vsr, \
+ _poldvsr_ ); \
+CYG_MACRO_END
+
+//--------------------------------------------------------------------------
+// Vector translation.
+// For chained interrupts we only have a single vector though which all
+// are passed. For unchained interrupts we have a vector per interrupt.
+
+#ifndef HAL_TRANSLATE_VECTOR
+
+#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
+
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0
+
+#else
+
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_)
+
+#endif
+
+#endif
+
+//--------------------------------------------------------------------------
+// Clock control.
+// This code uses the 16 bit reload timer 1. The defines are used to specify
+// the IO adress of the registers, that are different in FR30 variants.
+
+#ifndef CYGHWR_HAL_CLOCK_CONTROL_DEFINED
+
+extern CYG_WORD32 cyg_hal_clock_period;
+
+#define CYGHWR_HAL_CLOCK_PERIOD_DEFINED
+
+#define HAL_CLOCK_INITIALIZE( _period_ ) \
+CYG_MACRO_START \
+ HAL_WRITE_UINT16( CYG_HAL_FR30_RTC_TMRLR , _period_); \
+ HAL_WRITE_UINT16( CYG_HAL_FR30_RTC_TMCSR , 0x081b); \
+ cyg_hal_clock_period = _period_; \
+CYG_MACRO_END
+
+// This clears the interrupt request for reload timer 1 (RTC)
+#define HAL_CLOCK_RESET( _vector_, _period_ ) \
+CYG_MACRO_START \
+asm volatile("ldi:8 #0x57, r0;\n" \
+ "bandl #0xb, @r0;\n" \
+ : : :"r0"); \
+CYG_MACRO_END
+
+#define HAL_CLOCK_READ( _pvalue_ ) \
+CYG_MACRO_START \
+ CYG_FAIL("clock_read"); \
+ register CYG_WORD32 result; \
+ HAL_READ_UINT16( CYG_HAL_FR30_RTC_TMR, result); \
+ *(_pvalue_) = cyg_hal_clock_period - result; \
+CYG_MACRO_END
+
+#define CYGHWR_HAL_CLOCK_CONTROL_DEFINED
+
+#endif
+
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && \
+ !defined(HAL_CLOCK_LATENCY)
+#define HAL_CLOCK_LATENCY( _pvalue_ ) \
+CYG_MACRO_START \
+ register CYG_WORD32 _cval_; \
+ HAL_CLOCK_READ(&_cval_); \
+ *(_pvalue_) = _cval_ - cyg_hal_clock_period; \
+CYG_MACRO_END
+#endif
+
+//----------------------------------------------------------------------------
+// Reset
+// this clears BIT4 in STCR(0x481), which should issue a reset
+
+#define HAL_PLATFORM_RESET() \
+ asm volatile ( \
+ "ldi:20 #0x481, r0;\n" \
+ "bandh #1, @r0;\n" \
+ : : :"r0");
+
+externC void _start(void);
+#define HAL_PLATFORM_RESET_ENTRY (&_start)
+
+//--------------------------------------------------------------------------
+// Microsecond delay
+// This uses reload timer 2, because timer 0 and 1 can cause DMA transfers.
+// Timer 2 is only used for delay service. We maybe support it out of the
+// scheduler clock in the future.
+
+externC void hal_delay_us(cyg_int32 usecs);
+#define HAL_DELAY_US(_millis_) hal_delay_us(_millis_);
+
+//---------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_HAL_INTR_H
+// End of hal_intr.h
--- /dev/null
+#ifndef CYGONCE_HAL_HAL_IO_H
+#define CYGONCE_HAL_HAL_IO_H
+
+//=============================================================================
+//
+// hal_io.h
+//
+// HAL device IO register support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Define IO register support
+// Description: The macros defined here provide the HAL APIs for handling
+// device IO control registers.
+//
+// Usage:
+// #include <cyg/hal/hal_io.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/plf_io.h>
+
+//-----------------------------------------------------------------------------
+// IO Register address.
+// This type is for recording the address of an IO register.
+
+typedef volatile CYG_ADDRWORD HAL_IO_REGISTER;
+
+//-----------------------------------------------------------------------------
+// HAL IO macros.
+#ifndef HAL_IO_MACROS_DEFINED
+
+//-----------------------------------------------------------------------------
+// BYTE Register access.
+// Individual and vectorized access to 8 bit registers.
+
+#define HAL_READ_UINT8( _register_, _value_ ) \
+ asm volatile ("ldub @%1, %0": "=r" (_value_): "r" (_register_));
+// ((_value_) = *((volatile CYG_BYTE *)(_register_)))
+
+#define HAL_WRITE_UINT8( _register_, _value_ ) \
+ asm volatile ("stb %0, @%1": : "r" (_value_), "r" (_register_));
+// (*((volatile CYG_BYTE *)(_register_)) = (_value_))
+
+#define HAL_READ_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \
+{ \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \
+ (_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_j_]; \
+}
+
+#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \
+{ \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \
+ ((volatile CYG_BYTE *)(_register_))[_j_] = (_buf_)[_i_]; \
+}
+
+//-----------------------------------------------------------------------------
+// 16 bit access.
+// Individual and vectorized access to 16 bit registers.
+
+#define HAL_READ_UINT16( _register_, _value_ ) \
+ asm volatile ("lduh @%1, %0": "=r" (_value_): "r" (_register_));
+
+#define HAL_WRITE_UINT16( _register_, _value_ ) \
+ asm volatile ("sth %0, @%1": : "r" (_value_), "r" (_register_));
+
+#define HAL_READ_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \
+{ \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \
+ (_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_j_]; \
+}
+
+#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \
+{ \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \
+ ((volatile CYG_WORD16 *)(_register_))[_j_] = (_buf_)[_i_]; \
+}
+
+//-----------------------------------------------------------------------------
+// 32 bit access.
+// Individual and vectorized access to 32 bit registers.
+
+#define HAL_READ_UINT32( _register_, _value_ ) \
+ asm volatile ("ld @%1, %0": "=r" (_value_): "r" (_register_));
+
+#define HAL_WRITE_UINT32( _register_, _value_ ) \
+ asm volatile ("st %0, @%1": : "r" (_value_), "r" (_register_));
+
+#define HAL_READ_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \
+{ \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \
+ (_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_]; \
+}
+
+#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \
+{ \
+ cyg_count32 _i_,_j_; \
+ for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \
+ ((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_]; \
+}
+
+#define HAL_IO_MACROS_DEFINED
+
+#endif
+
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_HAL_IO_H
+// End of hal_io.h
--- /dev/null
+##=============================================================================
+##
+## context.S
+##
+## FR30 context switch and longjmp setjmp code
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## 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): larsi
+## Contributors:larsi
+## Date: 2006-06-03
+## Purpose: fr30 context switch code
+## Description: This file contains implementations of the thread context
+## switch routines. It also contains the longjmp() and setjmp()
+## routines.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/fr30.inc>
+
+#include <cyg/hal/arch.inc>
+
+#------------------------------------------------------------------------------
+# function declaration macro
+
+#define FUNC_START(name) \
+ .globl name; \
+name:
+
+#------------------------------------------------------------------------------
+# hal_thread_switch_context
+# Switch thread contexts
+#
+# a timer interrupt should have caused this function to be called
+# so interrupts are forbidden and we are in SSP mode (S flag=1)
+#
+# R4 and R5 contain our arguments.
+# R5 is _fspptr_ (old USP), R4 is _tspptr_ (new USP).
+# @(SSP) has the return address of the call to this function.
+# In @(SSP,4) the PS and in @(SSP,8) the PC are saved by hardware.
+# Before we RETI, we have to switch S flag in CCR to 0
+# to use SSP for returning. Interrupts have to be
+# reenabled before returning, but this is done by restoring PS.
+
+
+ .globl hal_thread_switch_context
+hal_thread_switch_context:
+
+# at first switch to USP (set bit 5 in CCR in PS)
+ st r0, @-r15 ; push last_trap, cannot guarantee that it is
+ ; the right value, but that should not matter
+ ; as it is only for GDB
+ st mdl, @-r15
+ st mdh, @-r15
+
+ st r0, @-r15 ; store usp
+
+ st r0, @-r15 ; store ssp
+ st rp, @-r15
+ st tbr, @-r15
+ st ps, @-r15
+ st rp, @-r15 ; rp is our new pc when load_context executes
+
+ st r15, @-r15 ; store original r15 here
+
+ stm1 (r8, r9, r10, r11, r12, r13, r14)
+ stm0 (r0, r1, r2, r3 , r4 , r5 , r6 , r7)
+
+# we should be finished saving context here
+
+ st r15, @r5 ; store pointer to saved context
+
+#------------------------------------------------------------------------------
+# hal_thread_load_context
+# Load thread context
+.globl hal_thread_load_context
+hal_thread_load_context:
+
+ ld @r4, r15
+
+ ldm0 (r0, r1, r2, r3, r4, r5, r6, r7)
+ ldm1 (r8, r9, r10, r11, r12, r13, r14)
+ ld @r15+, mdl
+ ld @r15+, rp
+ ld @r15+, ps
+ ld @r15+, tbr
+# TODO addsp to skip stack positions
+ ld @r15+, mdl
+ ld @r15+, mdl
+ ld @r15+, mdl
+ ld @r15+, mdh
+ ld @r15+, mdl
+ addsp 4
+ ret
+
+#------------------------------------------------------------------------------
+# HAL longjmp, setjmp implementations
+# hal_setjmp saves only to callee save registers r8, r9, r10, r11, r14, r15
+# into buffer supplied in r4
+# Note: These definitions are repeated in hal_arch.h. If changes are required
+# remember to update both sets.
+# setjmp/longjmp for FR30. The jmpbuf looks like this:
+#
+# Register jmpbuf offset
+# r8 0x00
+# r9 0x04
+# r10 0x08
+# r11 0x0c
+# r14 (FP) 0x10
+# r15 (SP) 0x14
+# pc (rp) 0x18
+
+ .macro save reg
+ st \reg, @r4
+ addn #4, r4
+ .endm
+
+ .macro restore reg
+ ld @r4, \reg
+ addn #4, r4
+ .endm
+
+
+ .text
+ .global hal_setjmp
+ .type hal_setjmp,@function
+hal_setjmp:
+ save r8
+ save r9
+ save r10
+ save r11
+ save r14
+ save r15
+ mov rp, r5
+ st r5, @r4
+
+# Return 0 to caller.
+ ldi:8 #0, r4
+ ret
+
+ .global hal_longjmp
+hal_longjmp:
+ restore r8
+ restore r9
+ restore r10
+ restore r11
+ restore r14
+ restore r15
+ ld @r4, r4
+ mov r4, rp
+
+# If caller attempted to return 0, return 1 instead.
+
+ mov r5, r4
+ or r4, r4
+ bne 1f
+ ldi:8 #1, r4
+1:
+ ret
+
+#-----------------------------------------------------------------------------
+# End of context.S
--- /dev/null
+//========================================================================
+//
+// fr30_stub.c
+//
+// Fujitsu FR30-specific code for remote debugging via gdb
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose:
+// Description: Helper functions for gdb stub for FR30 processors
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+#include <stddef.h>
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+
+#include <cyg/hal/hal_stub.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id
+#endif
+
+/* Given a trap value TRAP, return the corresponding signal. */
+
+int __computeSignal (unsigned int trap_number)
+{
+ switch (trap_number)
+ {
+
+ case CYGNUM_HAL_VECTOR_COPR_NOT_FOUND:
+ case CYGNUM_HAL_VECTOR_COPR_ERROR:
+ return SIGFPE;
+
+ // step trace TRAP
+ case CYGNUM_HAL_VECTOR_DEBUG:
+ // INTE
+ case CYGNUM_HAL_VECTOR_BREAKPOINT:
+ return SIGTRAP;
+ /* System call instruction executed */
+ case CYGNUM_HAL_VECTOR_SYSTEM_CALL ... CYGNUM_HAL_VECTOR_TRAPLAST:
+ return SIGSYS;
+ /* External interrupt */
+ case CYGNUM_HAL_INTERRUPT_0 ... CYGNUM_HAL_INTERRUPT_DELAYED_IRQ:
+ return SIGINT;
+ // Illegal or reserved instruction
+ case CYGNUM_HAL_VECTOR_OPCODE:
+ return SIGILL;
+
+ // Marks port does think to return SIGTRAP as default.
+ default:
+ return SIGTERM;
+ }
+}
+
+/* Return the trap number corresponding to the last-taken trap. */
+
+int __get_trap_number (void)
+{
+ // The vector is not not part of the GDB register set so get it
+ // directly from the save context.
+ return _hal_registers->last_trap;
+}
+
+/* Set the currently-saved pc register value to PC. This also updates NPC
+ as needed. */
+
+void set_pc (target_register_t pc)
+{
+ put_register (PC, pc);
+}
+
+/*----------------------------------------------------------------------
+ * Single-step support
+ */
+
+/* Set things up so that the next user resume will execute one instruction.
+ This may be done by setting breakpoints or setting a single step flag
+ in the saved user registers, for example. */
+
+void __single_step (void)
+{
+ /* Trying to use processors single stepping.
+ This means to set T flag in PS register. */
+ put_register (PS, get_register (PS) | 0x100);
+}
+
+/* Clear the single-step state. */
+void __clear_single_step (void)
+{
+ put_register (PS, get_register (PS) & ~0x100);
+}
+
+void __install_breakpoints ()
+{
+ /* if (instrBuffer.targetAddr != NULL)
+ {
+ instrBuffer.savedInstr = *instrBuffer.targetAddr;
+ *instrBuffer.targetAddr = __break_opcode ();
+ } */
+
+ /* Install the breakpoints in the breakpoint list */
+ __install_breakpoint_list();
+
+ // No need to flush caches here; Generic stub code will handle this.
+}
+
+void __clear_breakpoints (void)
+{
+ __clear_breakpoint_list();
+}
+
+/* If the breakpoint we hit is in the breakpoint() instruction, return a
+ non-zero value. */
+
+int
+__is_breakpoint_function ()
+{
+ return get_register (PC) == (target_register_t)&_breakinst;
+}
+
+/* Skip the current instruction. Since this is only called by the
+ stub when the PC points to a breakpoint or trap instruction,
+ we can safely just skip 2. */
+
+void __skipinst (void)
+{
+ put_register (PC, get_register (PC) + 2);
+}
+
+/* Get a register out of the GDB register structure */
+target_register_t
+get_register (regnames_t reg)
+{
+ GDB_Registers* gdb_regs;
+
+ gdb_regs = (GDB_Registers*)_registers;
+
+ if (reg >= R0 && reg <= MDL)
+ return gdb_regs->r[reg];
+
+ return 0xdeadbeef;
+}
+
+/* Put a register into the GDB register structure */
+void
+put_register (regnames_t reg, target_register_t value)
+{
+ GDB_Registers* gdb_regs;
+
+ gdb_regs = (GDB_Registers*)_registers;
+
+ if (reg >= R0 && reg <= MDL) {
+ gdb_regs->r[reg] = value;
+ } else {
+ CYG_FAIL("Attempt to write to non-existent register ");
+ }
+}
+
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+// EOF openrisc_stub.c
--- /dev/null
+//==========================================================================
+//
+// hal_misc.c
+//
+// HAL miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/hal/hal_arch.h> // HAL header
+#include <cyg/hal/hal_intr.h> // VSR/ISR defines
+#include <cyg/hal/hal_misc.h>
+
+/*------------------------------------------------------------------------*/
+/* If required, define a variable to store the clock period. */
+
+#ifdef CYGHWR_HAL_CLOCK_PERIOD_DEFINED
+
+CYG_WORD32 cyg_hal_clock_period;
+
+#endif
+
+
+/*****************************************************************************
+hal_default_exception_handler -- First level C exception handler
+
+ The assembly default VSR handler calls this routine to handle the
+exception. When this routine returns, the state is restored to the state
+pointed to by regs.
+
+ We declare this routine as weak so that other handlers can easily
+become the default exception handler.
+
+INPUT:
+
+ vector: The exception vector number.
+
+ regs: A pointer to the saved state.
+
+OUTPUT:
+
+RETURN VALUE:
+
+ None
+
+*****************************************************************************/
+
+externC void
+hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
+ __attribute__ ((weak));
+
+void hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
+{
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ externC void __handle_exception(void);
+ externC HAL_SavedRegisters * _hal_registers;
+
+ // Set the pointer to the registers of the current exception
+ // context. At entry the GDB stub will expand the
+ // HAL_SavedRegisters structure into a (bigger) register array.
+ _hal_registers = regs;
+
+ __handle_exception();
+
+#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+ defined(CYGPKG_HAL_EXCEPTIONS)
+
+ // We should decode the vector and pass a more appropriate
+ // value as the second argument. For now we simply pass a
+ // pointer to the saved registers. We should also divert
+ // breakpoint and other debug vectors into the debug stubs.
+
+ cyg_hal_deliver_exception(vector, (CYG_ADDRWORD)regs);
+
+#else
+
+ CYG_FAIL("Exception!!!");
+
+#endif
+
+ return;
+}
+
+//---------------------------------------------------------------------------
+// Default arch ISR
+
+externC cyg_uint32
+hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ CYG_FAIL("Spurious Interrupt!!!");
+ return 0;
+}
+
+//---------------------------------------------------------------------------
+// Idle thread action
+
+void
+hal_idle_thread_action( cyg_uint32 count )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Monitor initialization. This means to init the vsr vector table.
+// TODO maybe init hal_vsr_table through defining it in assembler code
+
+#ifndef CYGPKG_HAL_FR30_MON_DEFINED
+void hal_mon_init(void){
+ int i;
+ /* 0 - 14 exceptions */
+ for(i = 0; i < CYGNUM_HAL_VECTOR_INTRFIRST; i++){
+ hal_vsr_table[i] = (CYG_ADDRESS)__default_exception_vsr;
+ }
+ /* 15 - xx interrupts */
+ for( ; i < CYGNUM_HAL_VECTOR_INTRLAST; i++){
+ hal_vsr_table[i] = (CYG_ADDRESS)__default_interrupt_vsr;
+ }
+ /* xx+1 - 255 exceptions (fr30 traps) */
+ for( ; i < CYGNUM_HAL_VSR_MAX; i++){
+ hal_vsr_table[i] = (CYG_ADDRESS)__default_exception_vsr;
+ }
+}
+#endif
+
+//---------------------------------------------------------------------------
+// Determine the index of the ls bit of the supplied mask.
+
+cyg_uint32
+hal_lsbit_index(cyg_uint32 mask)
+{
+ cyg_uint32 n = mask;
+
+ static const signed char tab[64] =
+ { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
+ 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
+ 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
+ 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
+ };
+
+ n &= ~(n-1UL);
+ n = (n<<16)-n;
+ n = (n<<6)+n;
+ n = (n<<4)+n;
+
+ return tab[n>>26];
+}
+
+//---------------------------------------------------------------------------
+// Determine the index of the ms bit of the supplied mask. FIXME: since we
+// have hardware support for it, use it! (bit search module)
+
+cyg_uint32
+hal_msbit_index(cyg_uint32 mask)
+{
+ cyg_uint32 x = mask;
+ cyg_uint32 w;
+
+ // Phase 1: make word with all ones from that one to the right.
+ x |= x >> 16;
+ x |= x >> 8;
+ x |= x >> 4;
+ x |= x >> 2;
+ x |= x >> 1;
+
+ // Phase 2: calculate number of "1" bits in the word.
+ w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+ w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+ w = w + (w >> 4);
+ w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
+ return (cyg_uint32)((w + (w >> 16)) & 0xFF);
+
+}
+
+/*------------------------------------------------------------------------*/
+/* C++ support - run initial constructors */
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+cyg_bool cyg_hal_stop_constructors;
+#endif
+
+typedef void (*pfunc) (void);
+extern pfunc __CTOR_LIST__[];
+extern pfunc __CTOR_END__[];
+
+void
+ cyg_hal_invoke_constructors (void)
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ static pfunc *p = &__CTOR_END__[-1];
+
+ cyg_hal_stop_constructors = 0;
+ for (; p >= __CTOR_LIST__; p--) {
+ (*p) ();
+ if (cyg_hal_stop_constructors) {
+ p--;
+ break;
+ }
+ }
+#else
+ pfunc *p;
+ for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--) {
+ (*p) ();
+ }
+#endif
+}
+
+//---------------------------------------------------------------------------
--- /dev/null
+##=============================================================================
+##
+## vectors.S
+##
+## fr30 startup code and exception and interrupt vectors
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## 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): larsi
+## Contributors:larsi
+## Date: 2006-06-26
+## Purpose: fr30 exception vectors
+## Description: This file defines the code placed into the exception
+## vectors. It also contains the startup code and first
+## level default VSRs that save and restore state for
+## both exceptions and interrupts.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif /* CYGPKG_KERNEL */
+
+#include <cyg/hal/arch.inc>
+
+#==============================================================================
+
+ .file "vectors.S"
+
+#==============================================================================
+# Real startup code. We jump here from the various reset vectors to set up the
+# world.
+
+ .text
+ .globl _start
+
+_start:
+
+# disable interrupts and set priority to lowest (=disable)
+ andccr #0xef
+ stilm #0x0
+
+ hal_diag_init_led
+#ifdef CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
+ hal_flash_init
+#endif
+ hal_cpu_init
+
+#ifdef CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
+ hal_memc_init
+#endif
+
+ hal_intc_init
+
+ hal_cache_init
+
+ hal_timer_init
+
+# Zero the BSS. If the BSS is not a whole number of words
+# long we will write up to 3 extra bytes at the end.
+# (This should not be a problem usually).
+ ldi:32 #__bss_end - 8, r12
+ ldi:32 #__bss_start - 4, r13
+ eor r0, r0 ; zero r0
+2:
+ add #0x4, r13
+ cmp r12, r13
+ ble:d 2b
+ st r0, @r13
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+# In a ROM booted system, we also need to copy the data section
+# out to the RAM.
+
+ ldi:32 #__rom_data_start - 4 + CYGPKG_HAL_FR30_LMA_OFFSET, r11
+ ldi:32 #__ram_data_start - 4, r9
+ ldi:32 #__ram_data_end - 8, r10
+3:
+ add #0x4, r11
+ add #0x4, r9
+ ld @r11, r0
+ cmp r10, r9
+ ble:d 3b
+ st r0, @r9
+
+#endif
+
+
+ # Set up the stacks
+ # Begin with interrupt (system) stack
+
+ ldi:32 #__interrupt_stack, r11
+ mov r11, ssp
+
+ # and now continue with user stack
+
+ orccr #0x20
+ ldi:32 #__user_stack, r11
+ mov r11, usp
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+# If we are here, initialize the hal_vsr_table. RAM startup
+# configurations can assume that Redboot has already set it up.
+
+ .extern hal_mon_init
+ ldi:32 #hal_mon_init, r11
+ call @r11
+
+#endif
+
+ .extern hal_variant_init
+ ldi:32 #hal_variant_init, r11
+ call @r11
+
+ .extern hal_platform_init
+ ldi:32 #hal_platform_init, r11
+ call @r11
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ // This is here so we can debug the constructors.
+ .extern initialize_stub
+ ldi:32 #initialize_stub, r11
+ call @r11
+#endif
+
+ .extern cyg_hal_invoke_constructors
+ ldi:32 #cyg_hal_invoke_constructors, r11
+ call @r11
+
+# TODO integrate into hal_intr.h
+# set irq 25 priority (for reload timer 1)
+ ldi:20 #0x449, r4
+ ldi:8 #0x10, r5
+ stb r5, @r4
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INITIAL_BREAK
+ .extern breakpoint
+ call breakpoint
+#endif
+
+
+ .extern cyg_start
+ ldi:32 #cyg_start, r11
+ call @r11
+
+# Hmm. Not expecting to return from cyg_start, endless nop loop
+1: nop
+ call 1b
+
+#==============================================================================
+# Default exception VSR
+
+ .align 2, 0xcc
+ .globl __default_exception_vsr
+__default_exception_vsr:
+
+ ## We enter here with the CPU state still in the registers and:
+ ## @(ssp,8) PS pushed by hardware
+ ## @(ssp,4) PC pushed by hardware
+ ## @(ssp) old register r0 content pushed by trampoline
+ ## r0 now contains the vector number
+
+# at first switch to USP (set bit 5 in CCR in PS)
+ orccr #0x20
+
+ st r0, @-r15
+ st mdl, @-r15
+ st mdh, @-r15
+
+ mov r0, mdh ; save exception/interrupt number
+ mov r15, r0
+ addn #+12, r0
+ mov r0, mdl ; save r15 also in mdl
+
+ st r0, @-r15 ; store usp
+ mov ssp, r0
+ st r0, @-r15 ; store ssp (TODO maybe have to sub 12 before)
+ st rp, @-r15
+ st tbr, @-r15
+ addsp #-8 ; skip 2 positions for PS and PC
+ mov r15, r0 ; save stack position to later store PS and PC
+
+ st mdl, @-r15 ; store original r15 here
+ stm1 (r8, r9, r10, r11, r12, r13, r14)
+ stm0 (r1, r2, r3, r4, r5, r6, r7)
+
+ mov ssp, r14
+ ld @r14, r1 ; get original r0 content
+ st r1, @-r15 ; and store it
+
+ ld @(r14,4), r2 ; get hardware pushed PC
+ st r2, @r0 ; and store it
+ ld @(r14,8), r3 ; get hardware pushed PS
+ addn #4, r0 ; and
+ st r3, @r0 ; store it
+
+# we should be finished saving context here
+
+# Call exception handler
+ .extern hal_default_exception_handler
+
+ ldi:32 #hal_default_exception_handler, r11
+ mov r15, r5 ; pointer to saved state as second argument
+ call:d @r11
+ mov mdh, r4 ; exception number as first argument
+
+__default_exception_vsr_return:
+
+
+ ## At this point, the user stack (USP) contains:
+ ## @(usp,0x60) trap number
+ ## @(usp,0x5c) mdl
+ ## @(usp,0x58) mdh
+ ## @(usp,0x54) usp
+ ## @(usp,0x50) ssp
+ ## @(usp,0x4c) rp
+ ## @(usp,0x48) tbr
+ ## @(usp,0x44) ps
+ ## @(usp,0x40) pc
+ ## @(usp,0x3c) r15
+ ## @(usp,0x38) r14
+ ## @(usp,0x34) r13
+ ## @(usp,0x30) r12
+ ## @(usp,0x2c) r11
+ ## @(usp,0x28) r10
+ ## @(usp,0x24) r9
+ ## @(usp,0x20) r8
+ ## @(usp,0x1c) r7
+ ## @(usp,0x18) r6
+ ## @(usp,0x14) r5
+ ## @(usp,0x10) r4
+ ## @(usp,0xc) r3
+ ## @(usp,8) r2
+ ## @(usp,4) r1
+ ## @(usp) r0
+ ##
+ ## and system stack (SSP) contains:
+ ## @(ssp,8) PS
+ ## @(ssp,4) PC
+ ## @(ssp) old r0 content
+
+# we can reuse the code from __default_interrupt_vsr
+ ldi:32 #hal_exception_return, r0
+ jmp @r0
+
+#==============================================================================
+# Default interrupt VSR
+#
+#
+
+ .align 2, 0xcc
+ .globl __default_interrupt_vsr
+__default_interrupt_vsr:
+
+ ## We enter here with the CPU state still in the registers and:
+ ## r0 vector number
+ ## @(ssp) old register r0 content pushed by trampoline
+ ## @(ssp,4) PS pushed by hardware
+ ## @(ssp,8) PC pushed by hardware
+
+ # begin to save registers (to USP)
+ orccr #0x20
+
+ st mdl, @-r15
+ st mdh, @-r15
+ st rp, @-r15
+
+ stm1 (r8, r9, r10, r11, r12, r13)
+ stm0 (r1, r2, r3 , r4 , r5 , r6, r7)
+
+ andccr #0xdf
+ ld @r15+, r8 ; read old r0 content from SSP
+ ld @r15+, r9 ; read pc pushed by hardware
+ ld @r15+, r10 ; read ps pushed by hardware
+ orccr #0x20
+
+ st r8, @-r15 ; push old r0 content to USP
+
+# we should be finished saving irq context here
+
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
+# Increment scheduler lock
+ .extern cyg_scheduler_sched_lock
+ ldi:32 #cyg_scheduler_sched_lock, r1
+ ld @r1, r2
+ addn #1, r2
+ st r2, @r1
+#endif
+
+# Call hal_interrupt_handlers[vector](vector, cyg_hal_interrupt_data[vector])
+ mov r0, r8 ; copy the vector
+ lsl #2, r8 ; multiply vector by 4
+
+ ldi:32 #hal_interrupt_handlers, r13 ; load handlers table
+ ld @(r13, r8), r1 ; current handler
+ ldi:32 #hal_interrupt_data, r13 ; load data table
+ ld @(r13, r8), r5 ; current data, second argument
+ call:d @r1
+ mov r0, r4 ; exception number as argument
+
+# At this point:
+# r15 = stack pointer /*(should be usable as pointer to HAL_SavedRegisters)*/
+# r4 = ISR return code (returned by call)
+# r8 = ISR table offset (saved across call)
+# r0 = vector number (NOT saved across call, but we don't need it)
+
+/*
+ # If we are returning from the last nested interrupt, move back
+ # to the thread stack. interrupt_end() must be called on the
+ # thread stack since it potentially causes a context switch.
+
+ hal_from_intstack
+*/
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+
+# Call interrupt_end(return_value, hal_interrupt_objects[vector], regs)
+# - r4 is the return value from the ISR
+# - regs points to saved CPU context
+
+ ldi:32 #hal_interrupt_objects, r13 ; load objects table
+ ld @(r13, r8), r5 ; current object, second argument
+ ldi:32 #interrupt_end, r12
+ call:d @r12
+ mov r15, r6 ; third argument TODO is not in
+ ; HAL_Saved_Registers format
+
+#endif
+
+##.globl hal_exception_return
+hal_exception_return:
+
+# Now pull saved state from stack and return to
+# what thread was originally doing.
+
+# at first store return values to SSP
+ andccr #0xdf
+ st r10, @-r15 ; store ps
+ st r9, @-r15 ; store pc
+ orccr #0x20
+
+# and then restore normal registers from USP
+ ldm0 (r0, r1, r2 , r3 , r4 , r5, r6, r7)
+ ldm1 (r8, r9, r10, r11, r12, r13)
+
+ ld @r15+, rp
+ ld @r15+, mdh
+ ld @r15+, mdl
+
+ andccr #0xdf
+ reti
+
+
+#==============================================================================
+# Exception trampolines
+# TBR table points to these short code sequences here that push the vector
+# number on to the stack and then indirect via the VSR table to a handler.
+# (__default_interrupt_vsr)
+
+ .text
+
+# macro to create exception handler (no error code)
+
+.macro hal_fr30_exception_noerr idx
+ .globl hal_fr30_exception_noerr_\idx
+hal_fr30_exception_noerr_\idx:
+ st r0, @-r15
+ ldi:32 #hal_vsr_table + \idx * 4, r0
+ ld @r0, r0
+ jmp:d @r0
+ ldi:8 #\idx, r0
+.endm
+
+ # Now generate all the default exception VSR trampolines.
+
+# hal_fr30_exception_noerr 1 no trampoline needed for reset and mode vector
+ hal_fr30_exception_noerr 2
+ hal_fr30_exception_noerr 3
+ hal_fr30_exception_noerr 4
+ hal_fr30_exception_noerr 5
+ hal_fr30_exception_noerr 6
+ hal_fr30_exception_noerr 7
+ hal_fr30_exception_noerr 8
+ hal_fr30_exception_noerr 9
+ hal_fr30_exception_noerr 10
+ hal_fr30_exception_noerr 11
+ hal_fr30_exception_noerr 12
+ hal_fr30_exception_noerr 13
+ hal_fr30_exception_noerr 14
+
+#==============================================================================
+# IRQ handler trampolines
+
+# macro to create exception handler (no error code)
+
+.macro hal_fr30_irq_handler idx
+ .globl hal_fr30_irq_\idx
+hal_fr30_irq_\idx:
+ st r0, @-r15
+ ldi:32 #hal_vsr_table + \idx * 4, r0
+ ld @r0, r0
+ jmp:d @r0
+ ldi:8 #\idx, r0
+.endm
+
+ hal_fr30_irq_handler 15
+ hal_fr30_irq_handler 16
+ hal_fr30_irq_handler 17
+ hal_fr30_irq_handler 18
+ hal_fr30_irq_handler 19
+ hal_fr30_irq_handler 20
+ hal_fr30_irq_handler 21
+ hal_fr30_irq_handler 22
+ hal_fr30_irq_handler 23
+ hal_fr30_irq_handler 24
+ hal_fr30_irq_handler 25
+ hal_fr30_irq_handler 26
+ hal_fr30_irq_handler 27
+ hal_fr30_irq_handler 28
+ hal_fr30_irq_handler 29
+ hal_fr30_irq_handler 30
+ hal_fr30_irq_handler 31
+ hal_fr30_irq_handler 32
+ hal_fr30_irq_handler 33
+ hal_fr30_irq_handler 34
+ hal_fr30_irq_handler 35
+ hal_fr30_irq_handler 36
+ hal_fr30_irq_handler 37
+ hal_fr30_irq_handler 38
+ hal_fr30_irq_handler 39
+ hal_fr30_irq_handler 40
+ hal_fr30_irq_handler 41
+ hal_fr30_irq_handler 42
+ hal_fr30_irq_handler 43
+ hal_fr30_irq_handler 44
+ hal_fr30_irq_handler 45
+ hal_fr30_irq_handler 46
+ hal_fr30_irq_handler 47
+ hal_fr30_irq_handler 48
+ hal_fr30_irq_handler 49
+ hal_fr30_irq_handler 50
+ hal_fr30_irq_handler 51
+ hal_fr30_irq_handler 52
+ hal_fr30_irq_handler 53
+ hal_fr30_irq_handler 54
+ hal_fr30_irq_handler 55
+ hal_fr30_irq_handler 56
+ hal_fr30_irq_handler 57
+ hal_fr30_irq_handler 58
+ hal_fr30_irq_handler 59
+ hal_fr30_irq_handler 60
+ hal_fr30_irq_handler 61
+ hal_fr30_irq_handler 62
+ hal_fr30_irq_handler 63
+
+
+ .data
+//
+// "Vectors" - fixed location data items
+// This section contains any data which might be shared between
+// an eCos application and any other environment, e.g. the debug
+// ROM.
+//
+ .section ".fixed_vectors"
+// Space for the virtual vectors
+ .balign 4
+// Vectors used to communicate between eCos and ROM environments
+ .globl hal_virtual_vector_table
+hal_virtual_vector_table:
+ .rept 64 // CYGNUM_CALL_IF_TABLE_SIZE
+ .long 0
+ .endr
+
+ .globl hal_vsr_table
+hal_vsr_table:
+ .rept CYGNUM_HAL_VSR_COUNT // exceptions & interrupts
+ .long 0
+ .endr
+
+#==============================================================================
+# Initial and interrupt stack
+
+ .section ".bss"
+
+ .balign 4
+ .global cyg_interrupt_stack_base
+cyg_interrupt_stack_base:
+__interrupt_stack_base:
+ .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+ .byte 0
+ .endr
+ .balign 4
+ .global cyg_interrupt_stack
+cyg_interrupt_stack:
+__interrupt_stack:
+ .long 0,0,0,0,0,0,0,0
+
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ .global __stub_stack_base
+__stub_stack_base:
+ .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+ .byte 0
+ .endr
+ .balign 4
+ .global __stub_stack
+__stub_stack:
+
+ .long 0,0,0,0,0,0,0,0
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+ .balign 4
+__user_stack_base:
+// FIXME TODO import symbolic constant from C-code
+ .rept 4532
+ .byte 0
+ .endr
+ .balign 4
+__user_stack:
+ .long 0
+
+#------------------------------------------------------------------------------
+# end of vectors.S
--- /dev/null
+2008-07-01 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/fr30_md91301.ld: Reworked memory layout for flash support.
+ * src/hal_diag.c: Little updates in serial0 configuration registers.
+ * src/variant.S: Made it possible for the platform to override
+ variants rom vectors.
+ * include/variant.inc: Moved macros for sdram config addresses to platform.
+
+2007-07-09 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/fr30_md91301.ld:
+ * src/hal_diag.c:
+ * src/var_misc.c:
+ * include/hal_diag.h:
+ * include/var_arch.h:
+ * include/variant.inc:
+ * include/var_intr.h:
+ * cdl/hal_fr30_mb91301.cdl: Initial fr30 ecos port
+
+//===========================================================================
+//####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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# hal_fr30_mb91301.cdl
+#
+# FR30/mb91301 variant architectural HAL package configuration data
+#
+# ====================================================================
+#####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): larsi
+# Original data: bartv, nickg
+# Contributors:
+# Date: 2006-07-09
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_FR30_MB91301 {
+ display "MB91301 variant"
+ parent CYGPKG_HAL_FR30
+ implements CYGINT_HAL_FR30_VARIANT
+ hardware
+ include_dir cyg/hal
+ define_header hal_fr30_mb91301.h
+ description "
+ The MB91301 architecture HAL package provides generic support
+ for this processor architecture. It is also necessary to
+ select a specific target platform HAL package."
+
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/hal_fr30.h>"
+ }
+
+ cdl_component CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ {
+ display "System clock speed in MHz"
+ flavor data
+ calculated { (CYGHWR_HAL_FR30_MB91301_CRYSTAL_SPEED * \
+ CYGHWR_HAL_FR30_MB91301_CLKR) }
+ description "This is the resulting base clock speed for the board.
+ It is calculated
+ CLKR * CRYSTAL_SPEED.
+ This is NOT the CPU Frequency."
+
+ cdl_option CYGHWR_HAL_FR30_MB91301_CRYSTAL_SPEED {
+ display "Crystal speed in Mhz"
+ flavor data
+ description "You have to enter the speed of the mounted crystal here.
+ The resulting base clock is calculated:
+ CLKR * CRYSTAL_SPEED / CLKB_DIVIDER"
+ legal_values 1 to 17
+ default_value 15
+ }
+
+ cdl_option CYGHWR_HAL_FR30_MB91301_CLKR {
+ display "Main PLL multiply-by rate"
+ flavor data
+ description "Using this value you can set the resulting base clock
+ speed. It is calculated:
+ CLKR * CRYSTAL_SPEED.
+ DO NOT DO A SETTING HIGHER THAN 4 UNLESS YOU EXACTLY
+ KNOW WHAT YOU A DOING! "
+ legal_values 1 to 8
+ default_value 4
+ }
+
+ cdl_option CYGHWR_HAL_FR30_MB91301_CLKB_DIVIDER {
+ display "Base clock divider"
+ flavor data
+ description "Using this value you can limit the base clock speed.
+ You set the divider. The resulting base clock speed
+ is calculated:
+ CLKB = system clock / divider
+ CPU, internal memory and internal buses use this base clock!
+ A value other than 1 can cause problems when using the stop
+ mode of the CPU.
+ See Fujitsu MB91301 hardware manual Chapter 5 for
+ constraints on setting this value!"
+ legal_values 1 to 16
+ default_value 1
+ }
+
+ cdl_option CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER {
+ display "Peripheral clock divider"
+ flavor data
+ description "Using this value you can set the peripheral clock
+ speed. You set the divider. The resulting peripheral clock
+ speed is calculated:
+ CLKP = system clock / divider
+ See Fujitsu MB91301 hardware manual Chapter 5 for constraints on setting
+ this value!"
+ legal_values 1 to 16
+ default_value 4
+ }
+
+ cdl_option CYGHWR_HAL_FR30_MB91301_CLKT_DIVIDER {
+ display "External buses clock divider"
+ flavor data
+ description "Using this value you can set the external buses clock
+ speed. You set the divider. The resulting external buses
+ clock speed is calculated:
+ CLKT = system clock / divider
+ See Fujitsu MB91301 hardware manual Chapter 5 for constraints on setting
+ this value!"
+ legal_values 1 to 16
+ default_value 1
+ }
+
+ }
+
+
+ # Real-time clock/counter specifics
+ cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants."
+ flavor none
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ default_value 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ default_value 100
+ }
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ default_value {(CYGHWR_HAL_FR30_MB91301_CRYSTAL_SPEED * CYGHWR_HAL_FR30_MB91301_CLKR * 1000000) / (CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER * CYGNUM_HAL_RTC_DENOMINATOR * 32)}
+ description "
+ The tick timer facility is used
+ to drive the eCos kernel RTC. Reload Timer 1 is used. The count
+ register decrements at the CLKP clock speed. We use prescaler 32.
+ By default we want 100 Hz."
+ }
+ }
+
+
+ compile hal_diag.c var_misc.c variant.S
+
+ make {
+ <PREFIX>/lib/target.ld: <PACKAGE>/src/fr30_mb91301.ld
+ $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 target.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm target.tmp
+ }
+
+ cdl_option CYGBLD_LINKER_SCRIPT {
+ display "Linker script"
+ flavor data
+ no_define
+ calculated { "src/fr30_mb91301.ld" }
+ }
+
+}
--- /dev/null
+/*=============================================================================
+//
+// hal_diag.h
+//
+// HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage: #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+
+#else // old way of doing diagnostic I/O
+
+/*---------------------------------------------------------------------------*/
+/* functions implemented in hal_diag.c (old way without virtual vectors) */
+
+externC void hal_diag_init(void);
+externC void hal_diag_write_char(char c);
+externC void hal_diag_read_char(char *c);
+
+/*---------------------------------------------------------------------------*/
+
+#define HAL_DIAG_INIT() hal_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_)
+
+#endif /* CYGSEM_HAL_VIRTUAL_VECTOR_DIAG */
+
+/*---------------------------------------------------------------------------*/
+// serial port0 defines
+#define CYG_HAL_FR30_MB91301_SMR0 0x63
+#define CYG_HAL_FR30_MB91301_SCR0 0x62
+#define CYG_HAL_FR30_MB91301_SIDR0 0x61
+#define CYG_HAL_FR30_MB91301_SODR0 0x61
+#define CYG_HAL_FR30_MB91301_SSR0 0x60
+#define CYG_HAL_FR30_MB91301_UTIM0 0x64
+#define CYG_HAL_FR30_MB91301_UTIMR0 0x64
+#define CYG_HAL_FR30_MB91301_DRCL0 0x66
+#define CYG_HAL_FR30_MB91301_UTIMC0 0x67
+
+/*---------------------------------------------------------------------------*/
+// serial port1 defines
+#define CYG_HAL_FR30_MB91301_SMR1 0x6b
+#define CYG_HAL_FR30_MB91301_SCR1 0x6a
+#define CYG_HAL_FR30_MB91301_SIDR1 0x69
+#define CYG_HAL_FR30_MB91301_SODR1 0x69
+#define CYG_HAL_FR30_MB91301_SSR1 0x68
+#define CYG_HAL_FR30_MB91301_UTIM1 0x6c
+#define CYG_HAL_FR30_MB91301_UTIMR1 0x6c
+#define CYG_HAL_FR30_MB91301_DRCL1 0x6e
+#define CYG_HAL_FR30_MB91301_UTIMC1 0x6f
+
+#define CYG_HAL_FR30_MB91301_PDRJ 0x13
+#define CYG_HAL_FR30_MB91301_DDRJ 0x403
+#define CYG_HAL_FR30_MB91301_PFRJ 0x413
+
+/*---------------------------------------------------------------------------*/
+// LED
+#define CYG_HAL_FR30_MB91301_PDRG 0x10
+#define CYG_HAL_FR30_MB91301_DDRG 0x400
+#define CYG_HAL_FR30_MB91301_PFRG 0x410
+// our MB91302A does not have PCRG (pull up resistor register G)
+// but it is here anyway
+#define CYG_HAL_FR30_MB91301_PCRG 0x420
+
+// externC void hal_diag_init_led(void);
+externC void hal_diag_led(cyg_uint8);
+
+/*---------------------------------------------------------------------------*/
+/* end of hal_diag.h */
+#endif /* CYGONCE_HAL_DIAG_H */
--- /dev/null
+#ifndef CYGONCE_HAL_VAR_ARCH_H
+#define CYGONCE_HAL_VAR_ARCH_H
+
+//==========================================================================
+//
+// var_arch.h
+//
+// Architecture specific abstractions
+//
+//==========================================================================
+//####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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Define architecture abstractions
+// Description: This file contains any extra or modified definitions for
+// this variant of the architecture.
+// Usage: #include <cyg/hal/var_arch.h>
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_VAR_ARCH_H
+// End of var_arch.h
--- /dev/null
+#ifndef CYGONCE_HAL_IMP_INTR_H
+#define CYGONCE_HAL_IMP_INTR_H
+
+//==========================================================================
+//
+// var_intr.h
+//
+// MB91301 Interrupt and clock support
+//
+//==========================================================================
+//####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): larsi
+// Contributors: larsi
+// Date: 2006-07-14
+// Purpose: MB91301 Interrupt support
+// Description: The macros defined here provide the HAL APIs for handling
+// interrupts and the clock for variants of the MB91301
+// architecture.
+//
+// Usage:
+// #include <cyg/hal/imp_intr.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/plf_intr.h>
+
+//--------------------------------------------------------------------------
+// Interrupt vectors.
+
+#ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
+
+#define CYGNUM_HAL_INTERRUPT_0 16
+#define CYGNUM_HAL_INTERRUPT_1 17
+#define CYGNUM_HAL_INTERRUPT_2 18
+#define CYGNUM_HAL_INTERRUPT_3 19
+#define CYGNUM_HAL_INTERRUPT_4 20
+#define CYGNUM_HAL_INTERRUPT_5 21
+#define CYGNUM_HAL_INTERRUPT_6 22
+#define CYGNUM_HAL_INTERRUPT_7 23
+#define CYGNUM_HAL_INTERRUPT_RELOAD_TIMER0 24
+#define CYGNUM_HAL_INTERRUPT_RELOAD_TIMER1 25
+#define CYGNUM_HAL_INTERRUPT_RELOAD_TIMER2 26
+#define CYGNUM_HAL_INTERRUPT_UART0_RX 27
+#define CYGNUM_HAL_INTERRUPT_UART1_RX 28
+#define CYGNUM_HAL_INTERRUPT_UART2_RX 29
+#define CYGNUM_HAL_INTERRUPT_UART0_TX 30
+#define CYGNUM_HAL_INTERRUPT_UART1_TX 31
+#define CYGNUM_HAL_INTERRUPT_UART2_TX 32
+#define CYGNUM_HAL_INTERRUPT_DMAC0 33
+#define CYGNUM_HAL_INTERRUPT_DMAC1 34
+#define CYGNUM_HAL_INTERRUPT_DMAC2 35
+#define CYGNUM_HAL_INTERRUPT_DMAC3 36
+#define CYGNUM_HAL_INTERRUPT_DMAC4 37
+#define CYGNUM_HAL_INTERRUPT_AD 38
+#define CYGNUM_HAL_INTERRUPT_PPG0 39
+#define CYGNUM_HAL_INTERRUPT_PPG1 40
+#define CYGNUM_HAL_INTERRUPT_PPG2 41
+#define CYGNUM_HAL_INTERRUPT_PPG3 42
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 43
+#define CYGNUM_HAL_INTERRUPT_UTIMER0 44
+#define CYGNUM_HAL_INTERRUPT_UTIMER1 45
+#define CYGNUM_HAL_INTERRUPT_UTIMER2 46
+#define CYGNUM_HAL_INTERRUPT_TIMEBASE_OVERFLOW 47
+#define CYGNUM_HAL_INTERRUPT_I2C0 48
+#define CYGNUM_HAL_INTERRUPT_I2C1 49
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 50
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 51
+#define CYGNUM_HAL_INTERRUPT_FREERUN_TIMER 52
+#define CYGNUM_HAL_INTERRUPT_ICU0 53
+#define CYGNUM_HAL_INTERRUPT_ICU1 54
+#define CYGNUM_HAL_INTERRUPT_ICU2 55
+#define CYGNUM_HAL_INTERRUPT_ICU3 56
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 57
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 58
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 59
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 60
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 61
+// system reserved #define CYGNUM_HAL_INTERRUPT_ 62
+#define CYGNUM_HAL_INTERRUPT_DELAYED_IRQ 63
+
+// The interrupt vector used by the RTC, aka tick timer
+#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_RELOAD_TIMER1
+
+#define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
+
+#endif
+
+//--------------------------------------------------------------------------
+// Interrupt controller access.
+
+// currently only external interrupts are masked using the external
+// interrupt controller. This means only vectors 16 to 23 are valid.
+// Other interrupts may be masked in the future
+// using the mask mechanism for interrupt levels, if needed.
+
+#ifndef CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
+
+#define CYG_HAL_FR30_MB91301_ENIR 0x41
+#define CYG_HAL_FR30_MB91301_EIRR 0x40
+#define CYG_HAL_FR30_MB91301_ELVR 0x42
+#define CYG_HAL_FR30_MB91301_ICR00 0x440
+
+// Array which stores the configured priority levels for the configured
+// interrupts.
+// this will be useful, if we implement masking of non external interrupts
+// externC volatile CYG_BYTE hal_interrupt_level[CYGNUM_HAL_ISR_COUNT];
+
+
+#define HAL_INTERRUPT_MASK( _vector_ ) \
+{ \
+ CYG_WORD32 _ilr_; \
+ if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) && \
+ (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){ \
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ ); \
+ _ilr_ &= ~(1<<((_vector_)>>4)); \
+ HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ ); \
+ } \
+ /* Handle RTC masking special */ \
+ if (_vector_ == CYGNUM_HAL_INTERRUPT_RTC) \
+ asm volatile("ldi:8 #0x57, r0;\n" \
+ "bandl #0x7, @r0;\n" \
+ : : :"r0"); \
+}
+
+#define HAL_INTERRUPT_UNMASK( _vector_ ) \
+{ \
+ CYG_WORD32 _ilr_; \
+ if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) && \
+ (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){ \
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ ); \
+ _ilr_ |= (1<<((_vector_)>>4)); \
+ HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_ENIR, _ilr_ ); \
+ } \
+ /* Handle RTC unmasking special */ \
+ if (_vector_ == CYGNUM_HAL_INTERRUPT_RTC) \
+ asm volatile("ldi:8 #0x57, r0;\n" \
+ "borl #0x8, @r0;\n" \
+ : : :"r0"); \
+}
+
+#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \
+{ \
+ CYG_WORD32 _ilr_; \
+ if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) && \
+ (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){ \
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_EIRR, _ilr_ ); \
+ _ilr_ &= ~(1<<((_vector_)>>4)); \
+ HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_EIRR, _ilr_ ); \
+ } \
+ /* Handle RTC acknowledging special */ \
+ if (_vector_ == CYGNUM_HAL_INTERRUPT_RTC) \
+ asm volatile("ldi:8 #0x57, r0;\n" \
+ "bandl #0xb, @r0;\n" \
+ : : :"r0"); \
+}
+
+#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) \
+{ \
+ /* subtract 15 from vector */ \
+ cyg_uint32 _v_ = _vector_ >> 4; \
+ cyg_uint16 _val_ = 0; \
+ cyg_uint16 _reg_; \
+ \
+ if ((_vector_ >= CYGNUM_HAL_INTERRUPT_7) && \
+ (_vector_ <= CYGNUM_HAL_INTERRUPT_0)){ \
+ \
+ /* set bits according to requirements */ \
+ if( _up_ ) _val_ |= 1; \
+ if( !(_level_) ) _val_ |= 2; \
+ \
+ /* get old ELVR */ \
+ HAL_READ_UINT16( CYG_HAL_FR30_MB91301_ELVR, _reg_ ); \
+ \
+ /* clear old value and set new */ \
+ _reg_ &= ~(3 << _v_); \
+ _reg_ |= _val_ << _v_; \
+ HAL_WRITE_UINT16( CYG_HAL_FR30_MB91301_ELVR, _reg_ ); \
+ } \
+}
+
+#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) \
+{ \
+ /* subtract 15 from vector */ \
+ cyg_uint32 _v_ = _vector_ >> 4; \
+ CYG_WORD32 _ilr_; \
+/* HAL_READ_UINT8( CYG_HAL_FR30_MB91301_ICR00 + _vector_, _ilr_ );*/ \
+/* reading before writing is only needed, if UINT8 writing is not */ \
+/* possible to IO 0x440 */ \
+ _ilr_ = (_level_); \
+ HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_ICR00 + _vector_, _ilr_ ); \
+/* for later use: */ \
+/* hal_interrupt_level[_vector_] = _level_; */ \
+}
+
+#define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
+
+#endif
+
+//--------------------------------------------------------------------------
+// Clock control registers
+
+// MB91301 series has 3 built-in timer channels.
+// Timer 2 is used for delay and timer 1 for RTC/*delay*/.
+// Timer 0 and 1 can activate DMA and this feature is propably needed by
+// the application. Timer 0 is free to use by the application.
+
+#define CYG_HAL_FR30_DLY_TMCSR 0x5e
+#define CYG_HAL_FR30_DLY_TMR 0x5a
+#define CYG_HAL_FR30_DLY_TMRLR 0x58
+#define CYG_HAL_FR30_RTC_TMCSR 0x56
+#define CYG_HAL_FR30_RTC_TMR 0x52
+#define CYG_HAL_FR30_RTC_TMRLR 0x50
+
+
+
+//--------------------------------------------------------------------------
+// Control-C support.
+
+#if defined(CYGDBG_HAL_FR30_DEBUG_GDB_CTRLC_SUPPORT)
+
+#define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_DUART
+
+externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+#define HAL_CTRLC_ISR hal_ctrlc_isr
+
+#endif
+
+//--------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_IMP_INTR_H
+// End of imp_intr.h
--- /dev/null
+#ifndef CYGONCE_HAL_VARIANT_INC
+#define CYGONCE_HAL_VARIANT_INC
+##=============================================================================
+##
+## variant.inc
+##
+## MB91301 family assembler header file
+##
+##=============================================================================
+#####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): larsi
+## Contributors:larsi
+## Date: 2006-07-24
+## Purpose: MB91301 family definitions.
+## Description: This file contains various definitions and macros that are
+## useful for writing assembly code for the TX39 CPU family.
+## Usage:
+## #include <cyg/hal/variant.inc>
+## ...
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/fr30.inc>
+
+#include <cyg/hal/platform.inc>
+
+##-----------------------------------------------------------------------------
+## Define CPU variant for architecture HAL.
+
+#define CYG_HAL_FR30_MB91301
+
+##-----------------------------------------------------------------------------
+## Indicate that the ISR tables are defined in variant.S
+
+#ifndef CYG_HAL_FR30_ISR_TABLES_DEFINED
+#define CYG_HAL_FR30_ISR_TABLES_DEFINED
+#endif
+
+##-----------------------------------------------------------------------------
+## CPU initialisation, we set the clock to PLL 48 Mhz (12 * 4Mhz) here.
+## PLL lock waiting time is implemented as a busy loop.
+
+#ifndef CYGPKG_HAL_FR30_CPU_INIT_DEFINED
+#define CYGPKG_HAL_FR30_CPU_INIT_DEFINED
+#
+# busy wait loop
+# pollutes r11, r12
+#
+.macro wait_loop no=0x1
+ ldi:20 #\no, r12
+ ldi:8 #0x1, r11
+8:
+ sub r11, r12
+ bne 8b
+.endm
+
+##-----------------------------------------------------------------------------
+## Clock Modulator control registers
+
+ .equ FR30_MB91301_CMCR, 0x164
+ .equ FR30_MB91301_CMCRH, 0x164
+ .equ FR30_MB91301_CMCRL, 0x165
+ .equ FR30_MB91301_CMPR, 0x166
+ .equ FR30_MB91301_CMLS0, 0x168
+ .equ FR30_MB91301_CMLS1, 0x16a
+ .equ FR30_MB91301_CMLS2, 0x16c
+ .equ FR30_MB91301_CMLT0, 0x170
+ .equ FR30_MB91301_CMLT1, 0x172
+ .equ FR30_MB91301_CMLT2, 0x174
+ .equ FR30_MB91301_CMAC, 0x176
+ .equ FR30_MB91301_CMACH, 0x178
+ .equ FR30_MB91301_CMACL, 0x179
+ .equ FR30_MB91301_CMTS, 0x17a
+ .equ FR30_MB91301_CMTSH, 0x17a
+ .equ FR30_MB91301_CMTSL, 0x17b
+ .equ FR30_MB91301_ICR31, 0x45f
+
+##-----------------------------------------------------------------------------
+## Registers for Clock Generation and Reset
+
+ .equ FR30_MB91301_RSRR, 0x480
+ .equ FR30_MB91301_STCR, 0x481
+ .equ FR30_MB91301_TBCR, 0x482
+ .equ FR30_MB91301_CTBR, 0x483
+ .equ FR30_MB91301_CLKR, 0x484
+ .equ FR30_MB91301_WPR, 0x485
+ .equ FR30_MB91301_DIVR0, 0x486
+ .equ FR30_MB91301_DIVR1, 0x487
+
+##-----------------------------------------------------------------------------
+## ext bus interface registers
+## part used for flash
+
+ .equ FR30_MB91301_ASR0, 0x640
+ .equ FR30_MB91301_ACR0, 0x642
+ .equ FR30_MB91301_AWR0, 0x660
+ .equ FR30_MB91301_CSER, 0x680
+
+ .equ FR30_MB91301_PDR9, 0x9
+ .equ FR30_MB91301_DDR9, 0x609
+ .equ FR30_MB91301_PFR9, 0x619
+ .equ FR30_MB91301_PCR9, 0x629
+
+ .equ FR30_MB91301_PDR8, 0x8
+ .equ FR30_MB91301_DDR8, 0x608
+ .equ FR30_MB91301_PFR8, 0x618
+ .equ FR30_MB91301_PCR8, 0x628
+
+## part used for sdram
+ .equ FR30_MB91301_ASR6, 0x658
+ .equ FR30_MB91301_ACR6, 0x65a
+ .equ FR30_MB91301_AWR6, 0x66c
+ .equ FR30_MB91301_MCRA, 0x670
+ .equ FR30_MB91301_MCRB, 0x671
+ .equ FR30_MB91301_RCR, 0x684
+
+
+##-----------------------------------------------------------------------------
+## registers for serial0 and U-timer settings
+##
+ .equ FR30_MB91301_PDRJ, 0x13
+ .equ FR30_MB91301_DDRJ, 0x403
+ .equ FR30_MB91301_PFRJ, 0x413
+ .equ FR30_MB91301_UTIM0, 0x64
+ .equ FR30_MB91301_UTIMR0, 0x64
+ .equ FR30_MB91301_UTIMC0, 0x67
+ .equ FR30_MB91301_DRCL, 0x66
+ .equ FR30_MB91301_SMR0, 0x63
+ .equ FR30_MB91301_SCR0, 0x62
+ .equ FR30_MB91301_SIDR0, 0x61
+ .equ FR30_MB91301_SODR0, 0x61
+ .equ FR30_MB91301_SSR0, 0x60
+
+##-----------------------------------------------------------------------------
+## registers for clock settings
+##
+ .equ FR30_MB91301_RTC_TMRLR, 0x50
+ .equ FR30_MB91301_RTC_TMR, 0x52
+ .equ FR30_MB91301_RTC_TMCSR, 0x56
+
+
+
+##------------------------------------------------------------------------------
+## CPU initialisation macro
+## This is mainly for setting clock speeds.
+##------------------------------------------------------------------------------
+.macro hal_cpu_init
+
+ ldi:8 #0x00, r0
+
+ ldi:20 #FR30_MB91301_CLKR, r10 ; PLLx4 and enable it, still use source
+ ldi:8 (CYGHWR_HAL_FR30_MB91301_CLKR - 1) * 16 + 4, r1 ;
+ stb r1, @r10 ; oscillation as clock source
+
+ ldi:20 #FR30_MB91301_TBCR, r11 ; set time base counter to
+ ldi:8 #0x18, r1 ; about 60 ms and disable
+ stb r1, @r11 ; its interrupt (we poll below)
+
+ ldi:20 #FR30_MB91301_CTBR, r12 ; and
+ ldi:8 #0xa5, r2 ; start
+ ldi:8 #0x5a, r3 ; the
+ stb r2, @r12 ; time base
+ stb r3, @r12 ; counter
+
+ ldi:20 #FR30_MB91301_STCR, r13 ; set oscillation stabilisation time
+ ldi:8 #0x17, r1 ; to about 250 us
+ stb r1, @r13 ;
+
+ ldi:20 #FR30_MB91301_DIVR0, r12 ; set CLKB divider
+ ldi:8 (CYGHWR_HAL_FR30_MB91301_CLKB_DIVIDER - 1) * 16 + (CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER - 1), r1 ; and
+ stb r1, @r12 ; CLKP divider
+
+ ldi:20 #FR30_MB91301_DIVR1, r13 ; CLKT divider
+ ldi:8 (CYGHWR_HAL_FR30_MB91301_CLKT_DIVIDER - 1) * 16, r1
+ stb r1, @r13 ;
+
+ ldi:8 #0x80, r2 ; wait the rest
+1: ; of the
+ ldub @r11, r3 ; time base counter time
+ and r2, r3 ; (we set it to
+ beq 1b ; 60 ms above)
+
+ ldi:8 #0x36, r1 ; and now we are ready to
+ stb r1, @r10 ; switch clock to PLL
+
+.endm
+
+#endif /* !CYGPKG_HAL_FR30_CPU_INIT_DEFINED */
+
+##-----------------------------------------------------------------------------
+## FR30 interrupt handling.
+## nothing is here because the intc is initialized correctly by hardware reset
+## if something is needed it should be implemented in arch.inc with define'd
+## adresses to the registers. It should be the same for all FR30s
+
+
+##------------------------------------------------------------------------------
+## Diagnostics macros.
+## Indicate that the diagnostic macros are defined in variant.S / hal_diag.c
+
+#ifndef CYGPKG_HAL_FR30_DIAG_DEFINED
+
+##-----------------------------------------------------------------------------
+## registers for led settings
+##
+
+ .equ FR30_MB91301_PDRG, 0x10
+ .equ FR30_MB91301_DDRG, 0x400
+ .equ FR30_MB91301_PFRG, 0x410
+## our MB91301A does not have PCRG (pull up resistor register G)
+## but it is here anyway
+ .equ FR30_MB91301_PCRG, 0x420
+
+
+.macro hal_diag_init_led
+ ldi:8 #0xff, r4
+ ldi:20 #FR30_MB91301_DDRG, r5
+ stb r4, @r5
+ ldi:8 #0x00, r13
+ ldi:20 #FR30_MB91301_PFRG, r5
+ stb r13, @r5
+ dmovb r13, @FR30_MB91301_PDRG
+.endm
+
+##
+## switch on led on "hardcoded" value supplied after this macro
+## pollutes r13
+##
+.macro hal_diag_led led=0x0
+##st r13, @-r15
+ ldi:8 #\led , r13
+ dmovb r13, @FR30_MB91301_PDRG
+##ld @r15+, r13
+.endm
+
+##------------------------------------------------------------------------------
+## UARTa macros
+##
+
+## output a value to UART a
+## the value has to be in r4
+## register r1 will be polluted
+.macro uarta_putc
+ ldi:8 #FR30_MB91301_SODR0, r1
+ stb r4, @r1
+.endm
+
+
+## wait for the data in UART a SODR0 register to be drained
+## registers r1, r2, r3 will be polluted
+.macro uarta_drain
+ ldi:8 #FR30_MB91301_SSR0, r3 ;
+ ldi:8 #0x08, r1 ; TDRE bit of SSR0
+1: ;
+ ldub @r3, r2 ;
+ and r1, r2 ;
+ beq 1b
+.endm
+
+## receive a value from UART a
+## value is returned in r4
+## register r1, r2 and r3 will be polluted
+.macro uarta_getc
+ ldi:8 #FR30_MB91301_SSR0, r3 ;
+ ldi:8 #0x10, r1 ; RDRF bit of SSR0
+2:
+ ldub @r3, r2 ;
+ and r1, r2 ;
+ beq 2b ; wait until a byte is received
+
+ ldi:8 #FR30_MB91301_SIDR0, r3 ;
+ ldub @r3, r4 ; and get the value
+.endm
+
+#define CYGPKG_HAL_FR30_DIAG_DEFINED
+
+#endif
+
+#------------------------------------------------------------------------------
+# Timer initialization.
+
+#ifndef CYGPKG_HAL_FR30_TIMER_DEFINED
+
+ .macro hal_timer_init
+
+ # load reload value into reload register
+ ldi:8 #FR30_MB91301_RTC_TMRLR, r4
+ ldi:20 #CYGNUM_HAL_RTC_PERIOD, r5
+ sth r5, @r4
+ # set parameters to TODO
+ ldi:8 #FR30_MB91301_RTC_TMCSR, r4
+ ldi:20 #0x0813, r5
+ sth r5, @r4
+ .endm
+
+#define CYGPKG_HAL_FR30_TIMER_DEFINED
+
+#endif
+
+#------------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_VARIANT_INC
+# end of variant.inc
--- /dev/null
+//=============================================================================
+//
+// MLT linker script for Fujitsu FR30
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+
+#include <pkgconf/system.h>
+
+STARTUP(vectors.o)
+ENTRY(_start)
+#ifdef EXTRAS
+INPUT(extras.o)
+#endif
+#if (__GNUC__ >= 3)
+// GROUP(libtarget.a libgcc.a libsupc++.a)
+GROUP(libtarget.a libgcc.a)
+#else
+GROUP(libtarget.a libgcc.a)
+#endif
+
+#define ALIGN_LMA 4
+#define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1))
+#define LMA_EQ_VMA
+#define FORCE_OUTPUT . = .
+
+#define SECTIONS_BEGIN \
+ /* Debug information */ \
+ .debug_aranges 0 : { *(.debug_aranges) } \
+ .debug_pubnames 0 : { *(.debug_pubnames) } \
+ .debug_info 0 : { *(.debug_info) } \
+ .debug_abbrev 0 : { *(.debug_abbrev) } \
+ .debug_line 0 : { *(.debug_line) } \
+ .debug_frame 0 : { *(.debug_frame) } \
+ .debug_str 0 : { *(.debug_str) } \
+ .debug_loc 0 : { *(.debug_loc) } \
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+#define SECTION_fixed_vectors(_region_, _vma_, _lma_) \
+ .fixed_vectors _vma_ : _lma_ \
+ { FORCE_OUTPUT; KEEP (*(.fixed_vectors)) } \
+ > _region_
+
+#define SECTION_rom_vectors(_region_, _vma_, _lma_) \
+ .rom_vectors _vma_ : _lma_ \
+ { FORCE_OUTPUT; KEEP (*(.rom_vectors)) } \
+ > _region_
+
+#define SECTION_rom_startup(_region_, _vma_, _lma_) \
+ .rom_startup_trampoline _vma_ : _lma_ \
+ { FORCE_OUTPUT; KEEP(*(.rom_startup_trampoline*)) } \
+ > _region_
+
+#define SECTION_ram_startup(_region_, _vma_, _lma_) \
+ .ram_startup_trampoline _vma_ : _lma_ \
+ { __ram_trampoline_start = ABSOLUTE (.); FORCE_OUTPUT; KEEP(*(.ram_startup_trampoline*)) } \
+ > _region_ \
+ __rom_trampoline_start = LOADADDR (.ram_startup_trampoline); \
+ __rom_trampoline_end = LOADADDR (.ram_startup_trampoline) + SIZEOF(.ram_startup_trampoline);
+
+#define SECTION_text(_region_, _vma_, _lma_) \
+ .text _vma_ : _lma_ \
+ { _stext = ABSOLUTE(.); \
+ PROVIDE (__stext = ABSOLUTE(.)); \
+ *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) \
+ *(.glue_7) *(.glue_7t) \
+ } > _region_ \
+ _etext = .; PROVIDE (__etext = .);
+
+#define SECTION_fini(_region_, _vma_, _lma_) \
+ .fini _vma_ : _lma_ \
+ { FORCE_OUTPUT; *(.fini) } \
+ > _region_
+
+#define SECTION_rodata(_region_, _vma_, _lma_) \
+ .rodata _vma_ : _lma_ \
+ { FORCE_OUTPUT; *(.rodata*) } \
+ > _region_
+
+#define SECTION_rodata1(_region_, _vma_, _lma_) \
+ .rodata1 _vma_ : _lma_ \
+ { FORCE_OUTPUT; *(.rodata1) } \
+ > _region_
+
+#define SECTION_fixup(_region_, _vma_, _lma_) \
+ .fixup _vma_ : _lma_ \
+ { FORCE_OUTPUT; *(.fixup) } \
+ > _region_
+
+#define SECTION_gcc_except_table(_region_, _vma_, _lma_) \
+ .gcc_except_table _vma_ : _lma_ \
+ { FORCE_OUTPUT; *(.gcc_except_table) } \
+ > _region_
+
+#define SECTION_sram(_region_, _vma_, _lma_) \
+ .sram _vma_ : _lma_ \
+ { FORCE_OUTPUT; *(.sram*) } \
+ > _region_
+
+#define SECTION_data(_region_, _vma_, _lma_) \
+ .data _vma_ : _lma_ \
+ { __ram_data_start = ABSOLUTE (.); *(.data*) *(.data1) \
+ . = ALIGN (8); \
+ KEEP(*( SORT (.ecos.table.*))) ; \
+ . = ALIGN (8); \
+ __CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); \
+ __DTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); \
+ *(.sdata*) \
+ *(.eh_frame) \
+ . = ALIGN (8); *(.2ram.*) \
+ /* Global pointer stuff */ \
+ . = ALIGN(8); _gp = . + 2048; __global = _gp; \
+ _GOT_START_ = ABSOLUTE (.); *(.got) _GOT_END_ = ABSOLUTE (.); \
+ _GOT_PLT_START_ = ABSOLUTE (.); *(.got_plt) _GOT_PLT_END_ = ABSOLUTE (.); \
+ _GOT1_START_ = ABSOLUTE (.); *(.got1) _GOT1_END_ = ABSOLUTE (.); \
+ _GOT2_START_ = ABSOLUTE (.); *(.got2) _GOT2_END_ = ABSOLUTE (.); \
+ _DYNAMIC_ = ABSOLUTE (.); *(.dynamic) _DYNAMIC_ = ABSOLUTE (.); \
+ } \
+ > _region_ \
+ __rom_data_start = LOADADDR (.data); \
+ __ram_data_end = .; PROVIDE (__ram_data_end = .); _edata = .; PROVIDE (edata = .); \
+ __rom_data_end = LOADADDR (.data) + SIZEOF(.data);
+
+#define SECTION_bss(_region_, _vma_, _lma_) \
+ .bss _vma_ : _lma_ \
+ { __bss_start = ABSOLUTE (.); \
+ *(.scommon) *(.dynbss) *(.sbss) *(.sbss.*) *(.bss*) *(.bss.*) *(COMMON) \
+ __bss_end = ABSOLUTE (.); } \
+ > _region_
+
+#define SECTIONS_END . = ALIGN(4); _end = .; PROVIDE (end = .);
+
+#include <pkgconf/hal_fr30.h>
+#include CYGHWR_MEMORY_LAYOUT_LDI
--- /dev/null
+/*=============================================================================
+//
+// hal_diag.c
+//
+// HAL diagnostic output code
+//
+//=============================================================================
+//####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): larsi
+// Contributors:larsi
+// Date: 2006-07-26
+// Purpose: HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/hal_misc.h>
+/*---------------------------------------------------------------------------*/
+
+//#define CYG_KERNEL_DIAG_LCD
+#define CYG_KERNEL_DIAG_SERIAL0 // For ROM start but see immediately below:
+
+#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)
+#undef CYG_KERNEL_DIAG_SERIAL0
+#undef CYG_KERNEL_DIAG_LCD
+#define CYG_KERNEL_DIAG_CYGMON
+#define CYG_KERNEL_DIAG_GDB
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#if defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON)
+
+/*---------------------------------------------------------------------------*/
+// LED diag function
+/*
+void hal_diag_init_led(){
+// we only init the first 4 leds here
+ asm volatile(
+ "ldi:8 #0xf, r4;\n"
+ "ldi:20 #CYG_HAL_FR30_MB91360_DDRJ, r5;\n"
+ "stb r4, @r5;\n"
+ "ldi:20 #CYG_HAL_FR30_MB91360_PFRJ, r5;\n"
+ "stb r4, @r5;\n"
+ : : :"r4", "r5"
+ );
+}
+*/
+// static cyg_uint8 leds = 0;
+
+void hal_diag_init(void){
+
+ // PJ2(SCK0) & PJ1(SOT0) output, PJ0(SIN0) input
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, 0x6);
+ // PJ2(SCK0) & PJ1(SOT0) & PJ0(SIN0) to peripheral operation
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, 0x7);
+
+ // set up U-Timer
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_UTIMC0, 0x02);
+ // 115200 bps
+ HAL_WRITE_UINT16(CYG_HAL_FR30_MB91301_UTIMR0, 0x7);
+
+ // setup UART
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_SCR0, 0x13);
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_SMR0, 0x30);
+}
+
+
+void hal_diag_led(cyg_uint8 leds)
+{
+
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PDRG, leds);
+
+}
+
+/*---------------------------------------------------------------------------*/
+
+void hal_diag_write_char_serial0( char c)
+{
+ cyg_uint8 ssr;
+
+ do
+ {
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
+ } while (!(ssr & BIT3));
+
+ HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_SODR0, c );
+
+}
+
+void hal_diag_write_hex_serial0(unsigned int c)
+{
+ unsigned char chr;
+ int i;
+
+ hal_diag_write_char_serial0('0');
+ hal_diag_write_char_serial0('x');
+
+ for(i = 28; i >= 0; i = i - 4)
+ {
+ chr = (c >> i) & 0xf;
+ if (chr >= 10) chr = chr + 55; /* for A-F */
+ else chr = chr + 48; /* for 0-9 */
+ hal_diag_write_char_serial0(chr);
+ }
+ hal_diag_write_char_serial0('\n');
+ hal_diag_write_char_serial0('\r');
+}
+
+
+void hal_diag_drain(void)
+{
+ cyg_uint8 ssr;
+
+ do
+ {
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
+ } while (!(ssr & BIT3));
+}
+
+void hal_diag_read_char_serial0(char *c)
+{
+ cyg_uint8 ssr;
+
+ do
+ {
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
+ } while (!(ssr & BIT4));
+
+ HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SIDR0, *c );
+
+}
+
+
+#if defined(CYG_KERNEL_DIAG_CYGMON)
+void hal_diag_dumb_write_char(char c)
+#else
+void hal_diag_write_char(char c)
+#endif
+{
+#ifdef CYG_KERNEL_DIAG_GDB
+ static char line[100];
+ static int pos = 0;
+// register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR;
+
+ // No need to send CRs
+ if( c == '\r' ) return;
+
+ line[pos++] = c;
+
+ if( c == '\n' || pos == sizeof(line) )
+ {
+
+ // Disable interrupts. This prevents GDB trying to interrupt us
+ // while we are in the middle of sending a packet. The serial
+ // receive interrupt will be seen when we re-enable interrupts
+ // later.
+ CYG_INTERRUPT_STATE oldstate;
+ HAL_DISABLE_INTERRUPTS(oldstate);
+
+ while(1)
+ {
+ static char hex[] = "0123456789ABCDEF";
+ cyg_uint8 csum = 0;
+ int i;
+ char c1;
+
+ hal_diag_write_char_serial0('$');
+ hal_diag_write_char_serial0('O');
+ csum += 'O';
+ for( i = 0; i < pos; i++ )
+ {
+ char ch = line[i];
+ char h = hex[(ch>>4)&0xF];
+ char l = hex[ch&0xF];
+ hal_diag_write_char_serial0(h);
+ hal_diag_write_char_serial0(l);
+ csum += h;
+ csum += l;
+ }
+ hal_diag_write_char_serial0('#');
+ hal_diag_write_char_serial0(hex[(csum>>4)&0xF]);
+ hal_diag_write_char_serial0(hex[csum&0xF]);
+
+ hal_diag_read_char_serial0( &c1 );
+
+ if( c1 == '+' ) break;
+
+ {
+ extern void cyg_hal_user_break(CYG_ADDRWORD *regs);
+ extern cyg_bool cyg_hal_is_break(char *buf, int size);
+ if( cyg_hal_is_break( &c1 , 1 ) )
+ cyg_hal_user_break( NULL );
+ }
+
+ break;
+ }
+
+ pos = 0;
+
+ // Wait for all data from serial line to drain
+ // and clear ready-to-send indication.
+ hal_diag_drain_serial0();
+
+ // And re-enable interrupts
+ HAL_RESTORE_INTERRUPTS( oldstate );
+
+ }
+#else
+ hal_diag_write_char_serial0(c);
+#endif
+}
+
+
+void hal_diag_read_char(char *c)
+{
+ for(;;)
+ {
+#if defined(CYG_KERNEL_DIAG_GDB) && defined(CYGSEM_HAL_USE_ROM_MONITOR)
+
+ typedef void rom_read_fn(char *c);
+ rom_read_fn *fn = ((rom_read_fn **)0x80000100)[62];
+
+ fn(c);
+
+#else
+ hal_diag_read_char_serial0(c);
+
+#endif
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+ if( *c == 3 )
+ {
+ // Ctrl-C: breakpoint.
+ extern void breakpoint(void);
+ breakpoint();
+ continue;
+ }
+#elif defined(CYGSEM_HAL_USE_ROM_MONITOR)
+ if( *c == 3 )
+ {
+ // Ctrl-C: breakpoint.
+
+// HAL_BREAKPOINT(_breakinst);
+ typedef void bpt_fn(void);
+ bpt_fn *bfn = ((bpt_fn **)0x80000100)[61];
+
+ bfn();
+ continue;
+ }
+#endif
+
+ break;
+ }
+}
+
+#endif // defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON)
+
+
+#if defined(CYG_KERNEL_DIAG_CYGMON) // only
+
+/* This code has been imported from the BSP module. The definitions have
+ * been left as-is, even though there was scope for doing more, to avoid
+ * too much drift from the original sources
+ */
+
+struct bsp_comm_procs {
+ void *ch_data;
+ void (*__write)(void *ch_data, const char *buf, int len);
+ int (*__read)(void *ch_data, char *buf, int len);
+ void (*__putc)(void *ch_data, char ch);
+ int (*__getc)(void *ch_data);
+ int (*__control)(void *ch_data, int func, ...);
+};
+
+// This is pointed to by entry BSP_NOTVEC_BSP_COMM_PROCS:
+typedef struct {
+ int version; /* version number for future expansion */
+ void *__ictrl_table;
+ void *__exc_table;
+ void *__dbg_vector;
+ void *__kill_vector;
+ struct bsp_comm_procs *__console_procs;
+ struct bsp_comm_procs *__debug_procs;
+ void *__flush_dcache;
+ void *__flush_icache;
+ void *__cpu_data;
+ void *__board_data;
+ void *__sysinfo;
+ int (*__set_debug_comm)(int __comm_id);
+ int (*__set_console_comm)(int __comm_id);
+ int (*__set_serial_baud)(int __comm_id, int baud);
+ void *__dbg_data;
+ void (*__reset)(void);
+ int __console_interrupt_flag;
+} bsp_shared_t;
+
+/*
+ * Core Exception vectors.
+ */
+#define BSP_EXC_INT 0
+#define BSP_EXC_TLBMOD 1
+#define BSP_EXC_TLBL 2
+#define BSP_EXC_TLBS 3
+#define BSP_EXC_ADEL 4
+#define BSP_EXC_ADES 5
+#define BSP_EXC_IBE 6
+#define BSP_EXC_DBE 7
+#define BSP_EXC_SYSCALL 8
+#define BSP_EXC_BREAK 9
+#define BSP_EXC_ILL 10
+#define BSP_EXC_CPU 11
+#define BSP_EXC_OV 12
+#define BSP_EXC_TRAP 13
+#define BSP_EXC_VCEI 14
+#define BSP_EXC_FPE 15
+#define BSP_EXC_RSV16 16
+#define BSP_EXC_RSV17 17
+#define BSP_EXC_RSV18 18
+#define BSP_EXC_RSV19 19
+#define BSP_EXC_RSV20 20
+#define BSP_EXC_RSV21 21
+#define BSP_EXC_RSV22 22
+#define BSP_EXC_WATCH 23
+#define BSP_EXC_RSV24 24
+#define BSP_EXC_RSV25 25
+#define BSP_EXC_RSV26 26
+#define BSP_EXC_RSV27 27
+#define BSP_EXC_RSV28 28
+#define BSP_EXC_RSV29 29
+#define BSP_EXC_RSV30 30
+#define BSP_EXC_VCED 31
+/* tx39 debug exception */
+#define BSP_EXC_DEBUG 32
+#define BSP_EXC_TLB 33
+#define BSP_EXC_NMI 34
+/*
+ * Hack for eCos on tx39 to set an async breakpoint.
+ */
+#define BSP_VEC_BP_HOOK 35
+
+#define BSP_EXC_XTLB 36
+#define BSP_EXC_CACHE 37
+
+#define BSP_MAX_EXCEPTIONS 38
+
+/*
+ * Another hack for tx39 eCos compatibility.
+ */
+#if defined(__CPU_R3900__)
+#define BSP_VEC_MT_DEBUG 15
+#else
+#define BSP_VEC_MT_DEBUG 38
+#endif
+
+#define BSP_VEC_STUB_ENTRY 39
+#define BSP_VEC_BSPDATA 40
+#define BSP_VEC_MAGIC 41
+#define BSP_VEC_IRQ_CHECK 42
+
+#define BSP_VEC_PAD 43
+#define NUM_VTAB_ENTRIES 44
+
+
+#define BSP_MAGIC_VAL 0x55aa4321
+
+#define SYS_interrupt 1000
+
+// These vectors should be called with:
+//
+// k0 - Exception Number
+
+#define CYGMON_VECTOR_TABLE_BASE 0x80000100
+#define CYGMON_VECTOR_TABLE ((CYG_ADDRESS *)CYGMON_VECTOR_TABLE_BASE)
+
+#if 0 // UNUSED
+static int
+hal_bsp_set_debug_comm(int arg)
+{
+ bsp_shared_t *shared;
+
+ shared = (bsp_shared_t *)
+ (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
+
+ if (0 != shared->__set_debug_comm) {
+ return (*(shared->__set_debug_comm))(arg);
+ }
+ return 0;
+}
+
+static int
+hal_bsp_set_console_comm(int arg)
+{
+ bsp_shared_t *shared;
+
+ shared = (bsp_shared_t *)
+ (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
+
+ if (0 != shared->__set_console_comm) {
+ return (*(shared->__set_console_comm))(arg);
+ }
+ return 0;
+}
+#endif // 0 UNUSED
+
+static void bsp_trap(int trap_num);
+
+static int
+hal_bsp_console_write(const void *p, int len)
+{
+ bsp_shared_t *shared;
+ struct bsp_comm_procs *com;
+ int magic;
+
+ /*hal_bsp_set_console_comm(0);*/
+
+ /* If this is not a BSP-based CygMon, return 0 */
+ magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]);
+ if (magic != BSP_MAGIC_VAL)
+ return 0;
+
+ shared = (bsp_shared_t *)
+ (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
+
+ com = shared->__console_procs;
+
+ if (0 != com) {
+ shared->__console_interrupt_flag = 0;
+ com->__write(com->ch_data, p, len);
+ if (shared->__console_interrupt_flag) {
+ /* debug interrupt; stop here */
+ bsp_trap(SYS_interrupt);
+ }
+
+ return 1;
+ }
+ return 0;
+}
+
+static void
+bsp_trap(int trap_num)
+{
+ asm("syscall\n");
+}
+
+
+static void
+hal_dumb_serial_write(const char *p, int len)
+{
+ int i;
+ for ( i = 0 ; i < len; i++ ) {
+ hal_diag_dumb_write_char(p[i]);
+ }
+}
+/*
+void hal_diag_write_char(char c)
+{
+ static char line[100];
+ static int pos = 0;
+
+ // No need to send CRs
+ if( c == '\r' ) return;
+
+ line[pos++] = c;
+
+ if( c == '\n' || pos == sizeof(line) ) {
+ CYG_INTERRUPT_STATE old;
+
+ // Disable interrupts. This prevents GDB trying to interrupt us
+ // while we are in the middle of sending a packet. The serial
+ // receive interrupt will be seen when we re-enable interrupts
+ // later.
+
+ HAL_DISABLE_INTERRUPTS(old);
+
+ if ( ! hal_bsp_console_write( line, pos ) )
+ // then there is no function registered, just spew it out serial
+ hal_dumb_serial_write( line, pos );
+
+ pos = 0;
+
+ // And re-enable interrupts
+ HAL_RESTORE_INTERRUPTS(old);
+
+ }
+}*/
+
+int
+hal_diag_irq_check(int vector)
+{
+ typedef int irq_check_fn(int irq_nr);
+ irq_check_fn *fn = (irq_check_fn *)(CYGMON_VECTOR_TABLE[ BSP_VEC_IRQ_CHECK ]);
+ int magic;
+
+
+ /* If this is not a BSP-based CygMon, return 0 */
+ magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]);
+ if (magic != BSP_MAGIC_VAL)
+ return 0;
+
+#if defined(CYGPKG_HAL_MIPS_TX3904)
+ /* convert vector to BSP irq number */
+ if (vector == 16)
+ vector = 2;
+ else
+ vector += 3;
+#endif
+
+ return fn(vector);
+}
+
+#endif // defined(CYG_KERNEL_DIAG_CYGMON) *only*
+
+
+/*---------------------------------------------------------------------------*/
+/* End of hal_diag.c */
--- /dev/null
+//==========================================================================
+//
+// var_misc.c
+//
+// HAL implementation miscellaneous functions
+//
+//==========================================================================
+//####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): larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: HAL miscellaneous functions
+// Description: This file contains miscellaneous functions provided by the
+// HAL.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // Base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/hal/hal_misc.h>
+/*------------------------------------------------------------------------*/
+// Array which stores the configured priority levels for the configured
+// interrupts.
+
+/* this may be useful later when interrupt masking of internal interrupt
+ sources is implemented
+
+volatile CYG_BYTE hal_interrupt_level[CYGNUM_HAL_ISR_COUNT];
+*/
+/*------------------------------------------------------------------------*/
+
+void hal_variant_init(void)
+{
+}
+
+//--------------------------------------------------------------------------
+// Microsecond delay
+// This uses reload timer 2, because timer 0 and 1 can cause DMA transfers
+// and may be used by the application.
+// Timer is initialized with 32 prescaler. If we need more precise delay
+// this has to change.
+
+void hal_delay_us(cyg_int32 n){
+#define TIMER_TIME CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER / 32
+
+ unsigned int calc(unsigned long long n){
+ return n * TIMER_TIME / 1000000;
+ }
+
+ cyg_uint16 timer_status;
+
+ n = 21;//calc(n);
+ // stop eventually running counter and initialize
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x812);
+
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMRLR, 0xFFFF);
+ while(n > 0xffff){
+ // start counting
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x813);
+ n = n - 0xffff;
+ // look for underflow
+ do {
+ HAL_READ_UINT16(CYG_HAL_FR30_DLY_TMCSR, timer_status);
+ } while (!(timer_status & BIT2));
+ // clear underflow bit
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x813);
+ }
+ // clear count enable bit
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x810);
+ // set new remaining count value
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMRLR, n);
+ // start counting
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x813);
+ // look for underflow
+ do {
+ HAL_READ_UINT16(CYG_HAL_FR30_DLY_TMCSR, timer_status);
+ } while (!(timer_status & BIT2));
+ // clear underflow and count enable bits
+ HAL_WRITE_UINT16(CYG_HAL_FR30_DLY_TMCSR, 0x810);
+}
+
+/*------------------------------------------------------------------------*/
+/* End of var_misc.c */
--- /dev/null
+##=============================================================================
+##
+## variant.S
+##
+## FR30 MB91301 variant code
+##
+##=============================================================================
+#####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): larsi
+## Contributors:larsi
+## Date: 2006-07-22
+## Purpose: FR30 MB91301 variant code
+## Description: Variant specific code for MB91301 processor family.
+##
+##
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+#endif
+
+#include <cyg/hal/arch.inc>
+
+#==============================================================================
+# Vector table for storage in flash
+# base address is 0x000FFC00, which stores the vector address for number 255
+# address 0x000FFFFC is the last vector, the reset vector, which is not
+# alterable. Vectors 255 to 80 are used by the INT instruction and set to 0
+# here for now ...
+
+#ifndef CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED
+#define CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+ .section ".rom_vectors","ax"
+
+ .balign 4
+ .global hal_fr30_vector_table
+hal_fr30_vector_table:
+ .rept 255-80 + 1
+ .long 0x0
+ .endr
+ .rept 79-67 + 1
+ .long 0x0
+ .endr
+
+ .long 0x0
+ .long 0x0
+ .long 0x0
+# number 63 first interrupt source
+ .long hal_fr30_irq_63
+ .long hal_fr30_irq_62
+ .long hal_fr30_irq_61
+ .long hal_fr30_irq_60
+ .long hal_fr30_irq_59
+ .long hal_fr30_irq_58
+ .long hal_fr30_irq_57
+ .long hal_fr30_irq_56
+ .long hal_fr30_irq_55
+ .long hal_fr30_irq_54
+ .long hal_fr30_irq_53
+ .long hal_fr30_irq_52
+ .long hal_fr30_irq_51
+ .long hal_fr30_irq_50
+ .long hal_fr30_irq_49
+ .long hal_fr30_irq_48
+ .long hal_fr30_irq_47
+ .long hal_fr30_irq_46
+ .long hal_fr30_irq_45
+ .long hal_fr30_irq_44
+ .long hal_fr30_irq_43
+ .long hal_fr30_irq_42
+ .long hal_fr30_irq_41
+ .long hal_fr30_irq_40
+ .long hal_fr30_irq_39
+ .long hal_fr30_irq_38
+ .long hal_fr30_irq_37
+ .long hal_fr30_irq_36
+ .long hal_fr30_irq_35
+ .long hal_fr30_irq_34
+ .long hal_fr30_irq_33
+ .long hal_fr30_irq_32
+ .long hal_fr30_irq_31
+ .long hal_fr30_irq_30
+ .long hal_fr30_irq_29
+ .long hal_fr30_irq_28
+ .long hal_fr30_irq_27
+ .long hal_fr30_irq_26
+ .long hal_fr30_irq_25
+ .long hal_fr30_irq_24
+ .long hal_fr30_irq_23
+ .long hal_fr30_irq_22
+ .long hal_fr30_irq_21
+ .long hal_fr30_irq_20
+ .long hal_fr30_irq_19
+ .long hal_fr30_irq_18
+ .long hal_fr30_irq_17
+ .long hal_fr30_irq_16
+ .long hal_fr30_irq_15
+ .long hal_fr30_exception_noerr_14
+ .long hal_fr30_exception_noerr_13
+ .long hal_fr30_exception_noerr_12
+ .long hal_fr30_exception_noerr_11
+ .long hal_fr30_exception_noerr_10
+ .long hal_fr30_exception_noerr_9
+ .long hal_fr30_exception_noerr_8
+ .long hal_fr30_exception_noerr_7
+ .long hal_fr30_exception_noerr_6
+ .long hal_fr30_exception_noerr_5
+ .long hal_fr30_exception_noerr_4
+ .long hal_fr30_exception_noerr_3
+ .long hal_fr30_exception_noerr_2
+
+# mode vector (only the first of the four byte is relevant)
+ .byte 0x1
+ .byte 0
+ .byte 0
+ .byte 0
+
+# reset vector
+ .long _start
+
+#endif /*CYG_HAL_STARTUP_ROM || CYG_HAL_STARTUP_ROMRAM*/
+#endif /*CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED*/
+
+##-----------------------------------------------------------------------------
+# Interrupt vector tables.
+# These tables contain the isr, data and object pointers used to deliver
+# interrupts to user code.
+
+ .extern hal_default_isr
+
+ .data
+ .balign 4
+
+ .globl hal_interrupt_handlers
+hal_interrupt_handlers:
+ .rept CYGNUM_HAL_ISR_COUNT
+ .long hal_default_isr
+ .endr
+
+ .globl hal_interrupt_data
+hal_interrupt_data:
+ .rept CYGNUM_HAL_ISR_COUNT
+ .long 0
+ .endr
+
+ .globl hal_interrupt_objects
+hal_interrupt_objects:
+ .rept CYGNUM_HAL_ISR_COUNT
+ .long 0
+ .endr
+
+##-----------------------------------------------------------------------------
+## end of variant.S
+
--- /dev/null
+2008-07-01 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/platform.S: Startup routines for remapping the flash during
+ startup. Defined own rom_vector table.
+ * src/ser.c: Little updates that could cause problems after a reset with
+ wrong settings in the serial configuration registers.
+ * include/pkgconf/mlt_fr30_skmb91302_rom.h:
+ * include/pkgconf/mlt_fr30_skmb91302_rom.ldi: Reworked memory layout for
+ flash support.
+
+
+2007-07-09 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/platform.S:
+ * src/plf_misc.c:
+ * src/plf_stub.c:
+ * src/ser.c:
+ * misc/redboot_RAM.ecm:
+ * misc/redboot_ROM.ecm:
+ * include/pkgconf/mlt_fr30_skmb91302_ram.h:
+ * include/pkgconf/mlt_fr30_skmb91302_ram.ldi:
+ * include/pkgconf/mlt_fr30_skmb91302_rom.h:
+ * include/pkgconf/mlt_fr30_skmb91302_rom.ldi:
+ * include/platform.inc:
+ * include/plf_cache.h:
+ * include/plf_intr.h:
+ * include/plf_io.h:
+ * include/plf_stub.h:
+ * cdl/hal_fr30_skmb91302.cdl: Initial fr30 ecos port
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric
+//
+// 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####
+//===========================================================================
+
--- /dev/null
+# ====================================================================
+#
+# hal_fr30_skmb91302.cdl
+#
+# Fujitsu Starterkit MB91302 board HAL package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
+cdl_package CYGPKG_HAL_FR30_MB91301_SKMB91302 {
+ display "Fujitsu Starterkit MB91302 board"
+ parent CYGPKG_HAL_FR30
+ requires CYGPKG_HAL_FR30_MB91301
+ define_header hal_fr30_skmb91302.h
+ include_dir cyg/hal
+
+ description "Fujitsu Starterkit MB91302 board platform HAL
+ package should be used when targeting the actual hardware for
+ the Fujitsu Starterkit MB91302 board platform."
+
+ compile platform.S plf_misc.c ser.c
+ implements CYGINT_HAL_DEBUG_GDB_STUBS
+ implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+ implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/hal_fr30_mb91301.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_fr30.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H <pkgconf/hal_fr30_mb91301.h>"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_fr30_skmb91302.h>"
+ }
+
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ legal_values {"RAM" "ROM" "ROMRAM"}
+ default_value {"ROM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+
+ description "Should the system run from RAM, ROM, or copy itself from ROM
+ and RAM and then run in RAM?"
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ calculated 2
+ description "The MB91302 board has 3 serial ports. Only the first
+ 2 have mounted 9 pin connectors. The 3rd is not
+ connected and should therefore not be used."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+ display "Default console channel."
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ calculated 0
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "This option chooses which port will be used to connect
+ to a host running GDB."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT
+ description "
+ This option chooses which port will be used for diagnostic output."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+ display "Diagnostic serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 57600
+ description "
+ This option selects the baud rate used for the diagnostic port.
+ Note: this should match the value chosen for the GDB port if the
+ diagnostic and GDB port are the same."
+ }
+
+ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+ display "GDB serial port baud rate"
+ flavor data
+ legal_values 9600 19200 38400 57600 115200
+ default_value 57600
+ description "
+ This option selects the baud rate used for the diagnostic port.
+ Note: this should match the value chosen for the GDB port if the
+ diagnostic and GDB port are the same."
+ }
+
+ cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+
+ description "Global build options including control over compiler
+ flags, linker flags and choice of toolchain."
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "fr30-unknown-elf" }
+ description "This option specifies the command prefix used
+ when invoking the build tools."
+
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { "-Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -finit-priority -fomit-frame-pointer" }
+ description "This option controls the global compiler flags
+ which are used to compile all packages by default.
+ Individual packages may define options which
+ override these global flags."
+
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { " -g -nostdlib -Wl,--gc-sections -Wl,-static" }
+ description "This option controls the global linker flags.
+ Individual packages may define options which
+ override these global flags."
+
+ }
+
+ cdl_option CYGBLD_BUILD_GDB_STUBS {
+ display "Build GDB stub ROM image"
+ default_value 0
+ requires { CYG_HAL_STARTUP == "ROM" }
+ requires CYGSEM_HAL_ROM_MONITOR
+ requires CYGBLD_BUILD_COMMON_GDB_STUBS
+ requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+ requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+ no_define
+ description "This option enables the building of the GDB
+ stubs for the board. The common HAL controls
+ takes care of most of the build process, but the
+ final conversion from ELF image to binary data is
+ handled by the platform CDL, allowing relocation
+ of the data if necessary."
+
+ make -priority 320 {
+ <PREFIX>/bin/gdb_module.srec : <PREFIX>/bin/gdb_module.img
+ $(OBJCOPY) -O srec $< $@
+ }
+ }
+ }
+
+ cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { CYG_HAL_STARTUP == "RAM" ? "mlt_fr30_skmb91302_ram" : \
+ "mlt_fr30_skmb91302_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { CYG_HAL_STARTUP == "RAM" ? "<pkgconf/mlt_fr30_skmb91302_ram.ldi>" : \
+ "<pkgconf/mlt_fr30_skmb91302_rom.ldi>" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { CYG_HAL_STARTUP == "RAM" ? "<pkgconf/mlt_fr30_skmb91302_ram.h>" : \
+ "<pkgconf/mlt_fr30_skmb91302_rom.h>" }
+ }
+ }
+
+ cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor bool
+ default_value { CYG_HAL_STARTUP == "RAM" ? 1 : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Allow coexistence with ROM monitor (CygMon or GDB stubs) by
+ only initializing interrupt vectors on startup, thus leaving
+ exception handling to the ROM monitor."
+ }
+
+ cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM" }
+
+ description "Enable this option if this program is to be used as
+ a ROM monitor, i.e. applications will be loaded into
+ RAM on the board, and this ROM monitor may process
+ exceptions or interrupts generated from the
+ application. This enables features such as utilizing
+ a separate interrupt stack when exceptions are
+ generated."
+
+ }
+
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid Redboot
+ configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ default_value 1
+ no_define
+ description "This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ <PREFIX>/bin/redboot.srec : <PREFIX>/bin/redboot.elf
+ $(OBJCOPY) --strip-all $< $(@:.srec=.img)
+ $(OBJCOPY) -O srec $< $@
+ }
+ }
+ }
+
+}
--- /dev/null
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x2000000)
+#define CYGMEM_REGION_ram_SIZE (0x800000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x03F00000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+ ram : ORIGIN = 0x3F000, LENGTH = 0x1000
+ sdram : ORIGIN = 0x2000000, LENGTH = 0x800000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+// SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixed_vectors (sdram, 0x2000000, LMA_EQ_VMA)
+ SECTION_text (sdram, 0x2008000, LMA_EQ_VMA)
+ SECTION_fini (sdram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_rodata (sdram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_fixup (sdram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_gcc_except_table (sdram, ALIGN (0x4), LMA_EQ_VMA)
+ SECTION_data (sdram, ALIGN(0x4), FOLLOWING (.gcc_except_table))
+// SECTION_data (sdram, ALIGN(0x4), LMA_EQ_VMA)
+ SECTION_bss (sdram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x1000);
+ SECTIONS_END
+}
--- /dev/null
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#endif
+#define CYGMEM_REGION_ram (0x2000000)
+#define CYGMEM_REGION_ram_SIZE (0x800000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#ifndef __ASSEMBLER__
+extern char CYG_LABEL_NAME (__heap1) [];
+#endif
+#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
+#define CYGMEM_SECTION_heap1_SIZE (0x03F00000 - (size_t) CYG_LABEL_NAME (__heap1))
--- /dev/null
+// eCos memory layout - Fri Oct 20 05:56:24 2000
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.inc>
+
+MEMORY
+{
+ ram : ORIGIN = 0x18000, LENGTH = 0x1000
+ rom1 : ORIGIN = 0x80000, LENGTH = 0x7fc00 // Length = 511 kB
+ ints : ORIGIN = 0xFFC00, LENGTH = 0x400
+ rom2 : ORIGIN = 0x1100000, LENGTH = 0x700000
+ sdram : ORIGIN = 0x2000000, LENGTH = 0x800000
+}
+
+SECTIONS
+{
+ SECTIONS_BEGIN
+ SECTION_rom_startup(rom1, 0x80000, LMA_EQ_VMA)
+ SECTION_ram_startup(ram, 0x18000, FOLLOWING(.rom_startup_trampoline))
+ SECTION_rom_vectors (ints, 0xffc00 , LMA_EQ_VMA)
+ SECTION_text (rom2, 0x1100000, AT(0x100000))
+ SECTION_fini (rom2, ALIGN (0x4), FOLLOWING (.text))
+ SECTION_rodata (rom2, ALIGN (0x4), FOLLOWING (.fini))
+ SECTION_fixup (rom2, ALIGN (0x4), FOLLOWING (.rodata))
+ SECTION_gcc_except_table (rom2, ALIGN (0x4), FOLLOWING (.fixup))
+ SECTION_fixed_vectors (sdram, 0x2000000, LMA_EQ_VMA)
+ SECTION_data (sdram, ALIGN(0x4), FOLLOWING (.gcc_except_table))
+ SECTION_bss (sdram, ALIGN (0x4), LMA_EQ_VMA)
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x1000);
+ SECTIONS_END
+}
--- /dev/null
+#ifndef CYGONCE_HAL_PLATFORM_INC
+#define CYGONCE_HAL_PLATFORM_INC
+##=============================================================================
+##
+## platform.inc
+##
+## Fujitsu Starterkit MB91302 board assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2007 eCosCentric Ltd.
+##
+## 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): larsi
+## Contributors:
+## Date: 2007-07-09
+## Purpose: Fujitsu Starterkit MB91302 board definitions.
+## Description: This file contains various definitions and macros that are
+## useful for writing assembly code for the skmb91302 board.
+## Usage:
+## #include <cyg/hal/platform.inc>
+##
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <cyg/hal/fr30.inc>
+
+
+##------------------------------------------------------------------------------
+## ext Bus (memory controller) initialisation macros
+##
+## flash part
+
+
+#define CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
+## flash init is empty for this platform because it is initialized in the
+## special hal_fr30_ram_startup_trampoline to map flash to 0x1000000
+.macro hal_flash_init
+.endm
+
+## and the following macro is used in the special
+## hal_fr30_ram_startup_trampoline for flash initialisation
+.macro hal_flash_init_from_ram
+
+ ldi:20 #FR30_MB91301_ASR0, r10 ; CS0 area starts at
+ ldi:20 0x100, r0 ; 0x01000000
+ sth r0, @r10 ;
+
+ ldi:20 #FR30_MB91301_ACR0, r11 ; configuration parameters for CS0
+ ldi:20 #0x7422, r1 ; 8MB(0x0-0x7FFFFF),16bit data bus,
+ sth r1, @r11 ; pre-fetch off, single access,
+ ; write enable, big endian,
+ ; normal access(asynchronous),
+ ; WR pin enabled for write,
+ ; wait by RDY pin disabled
+
+ ldi:20 #FR30_MB91301_AWR0, r12 ; first access auto-wait 3cyc
+ ldi:20 #0x3378, r2 ; inpage access auto-wait 3cyc
+ sth r2, @r12 ; read/write idle 1cyc
+ ; write recover 3cyc
+ ; async write strobe outp enabled
+ ; CS delay enabled
+ ; CS read/write setup delay 0
+ ; RD/WR -> CS hold extension 0 cyc
+
+ ldi:20 #FR30_MB91301_PFR9, r13 ; WRn, BAAE, ASXE enable
+ ldi:8 #0x7e, r3 ;
+ stb r3, @r13 ;
+
+## following would chip select enable
+## we only use cs0 until here, which is already set by reset
+
+.endm
+
+
+## sdram part
+
+
+#define CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
+
+.macro hal_memc_init
+
+## The following instruction is without function. It is only to reference
+## hal_fr30_rom_startup_trampoline, because when not referenced the linker
+## does not include the file platform.S in the link. If somewhen some other
+## referenced code appears in platform.S the instruction here can be deleted
+## (including the surrounding macro)!
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+ ldi:32 #hal_fr30_rom_startup_trampoline, r10
+#endif
+
+ ldi:20 #FR30_MB91301_ASR6, r10 ; CS6 area starts at
+ ldi:20 0x200, r0 ; 0x02000000
+ sth r0, @r10 ;
+
+ ldi:20 #FR30_MB91301_ACR6, r11 ; configuration parameters for CS6
+ ldi:20 #0x7868, r1 ; 64MB(0x2000000-0x27FFFFF),32bit data bus,
+ sth r1, @r11 ; pre-fetch on, single access(no burst),
+ ; write enable, big endian,
+ ; FCRAM setting
+
+ ldi:20 #FR30_MB91301_AWR6, r12 ; first access auto-wait 1cyc ??
+ ldi:20 #0x1159, r2 ; inpage access auto-wait 1cyc ??
+ sth r2, @r12 ; read/write idle 1cyc ??
+ ; write recover 1cyc ??
+ ; async write strobe outp enabled ??
+ ; CS delay disabled ??
+ ; CS read/write setup delay 0 ??
+ ; RD/WR -> CS hold extension 1 cyc ??
+ ; see Hardware Manual page 156ff
+
+ ldi:20 #FR30_MB91301_MCRA, r13 ; 8 columns, single write,
+ ldi:8 #0x07, r3 ; 4 banks for burst write,
+ stb r3, @r13 ; 4 active banks
+
+ ldi:20 #FR30_MB91301_PFR9, r10 ; enable WRn, BAAE, ASXE,
+ ldi:8 #0x7e, r0 ; sysclk, MCKE, MCKEE
+ stb r0, @r10
+
+ ldi:20 #FR30_MB91301_PFR8, r11 ; enable WR3XE, WR2XE, WR1XE
+ ldi:8 #0xe0, r1
+ stb r1, @r11
+
+ ldi:20 #FR30_MB91301_CSER, r12 ; switch on CS6 & CS0
+ ldi:8 #0x41, r2
+ stb r2, @r12
+
+ ldi:20 #FR30_MB91301_RCR, r13 ; power on SDRAM I/F
+ ldi:20 #0xe247, r3 ; 0xe247 -> 0xe24f
+ sth r3, @r13
+ ldi:20 #0xe24f, r3
+ sth r3, @r13
+
+.endm
+
+#------------------------------------------------------------------------------
+## Vector table for storage. platform.S defines a vector table and wants to
+## override the one from variant.S with this define
+
+#define CYGPKG_HAL_FR30_ROM_VECTORS_DEFINED
+
+#------------------------------------------------------------------------------
+# Difference of the flash memory from the linkers LMA (loadmemoryaddress) after
+# the new mapping in (mapping is done in hal_fr30_ram_startup_trampoline).
+
+#define CYGPKG_HAL_FR30_LMA_OFFSET 0x1000000
+
+
+
+#------------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_PLATFORM_INC
+# end of platform.inc
--- /dev/null
+#ifndef CYGONCE_PLF_CACHE_H
+#define CYGONCE_PLF_CACHE_H
+
+//=============================================================================
+//
+// plf_cache.h
+//
+// HAL cache control API
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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:
+// Date: 2007-07-09
+// Purpose: Cache control API
+// Description: The macros defined here provide the HAL APIs for handling
+// cache control operations.
+// Usage:
+// #include <cyg/hal/plf_cache.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/plf_cache.h>
+
+//=============================================================================
+
+// Nothing here at present.
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_PLF_CACHE_H
+// End of plf_cache.h
+
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_INTR_H
+#define CYGONCE_HAL_PLF_INTR_H
+
+//==========================================================================
+//
+// plf_intr.h
+//
+// Fujitsu Starterkit MB91302 board interrupt and clock support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd
+//
+// 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:
+// Date: 2007-07-09
+// Purpose: Define Interrupt support
+// Description: The macros defined here provide the HAL APIs for handling
+// interrupts and the clock for the Fujitsu Starterkit MB91302 board.
+//
+// Usage:
+// #include <cyg/hal/plf_intr.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Interrupt controller stuff.
+
+
+//--------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_PLF_INTR_H
+// End of plf_intr.h
--- /dev/null
+#ifndef CYGONCE_PLF_IO_H
+#define CYGONCE_PLF_IO_H
+
+//=============================================================================
+//
+// plf_io.h
+//
+// Platform specific IO support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): hmt, jskov, nickg
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Fujitsu Starterkit MB91302 board IO support macros
+// Description:
+// Usage: #include <cyg/hal/plf_io.h>
+//
+// Note: Based on information in
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_intr.h> // Interrupt vectors
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_PLF_IO_H
--- /dev/null
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+// plf_stub.h
+//
+// Platform header for GDB stub support.
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2007 eCosCentric Ltd.
+//
+// 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): jskov
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Platform HAL stub support for Fujitsu Starterkit MB91302 boards.
+// Usage: #include <cyg/hal/plf_stub.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM
+
+#include <cyg/hal/fr30_stub.h> // architecture stub support
+
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+// Syscall support.
+#ifdef CYGPKG_CYGMON
+// Cygmon provides syscall handling for this board
+#define SIGSYSCALL SIGSYS
+extern int __get_syscall_num (void);
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
--- /dev/null
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+ description "" ;
+ hardware phytec91f364g ;
+ template redboot ;
+ package -hardware CYGPKG_HAL_FR30 current ;
+ package -hardware CYGPKG_HAL_FR30_MB91301_SKMB91302 current ;
+ package -template CYGPKG_HAL current ;
+ package -template CYGPKG_INFRA current ;
+ package -template CYGPKG_REDBOOT current ;
+};
+
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+ user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+ user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+ inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+ inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+ inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+ inferred_value 0
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+ user_value RAM
+};
+
+cdl_option CYGBLD_BUILD_REDBOOT {
+ user_value 1
+};
+
+#cdl_option CYGSEM_REDBOOT_FLASH_CONFIG {
+# user_value 1
+#};
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+ user_value 1
+};
+
+cdl_option CYGBLD_REDBOOT_FLASH_BOOT_OFFSET {
+ inferred_value 0x1C00000
+};
--- /dev/null
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+ description "" ;
+ hardware phytec91f364g ;
+ template redboot ;
+ package -hardware CYGPKG_HAL_FR30 current ;
+ package -hardware CYGPKG_HAL_FR30_MB91301_SKMB91302 current ;
+ package -template CYGPKG_HAL current ;
+ package -template CYGPKG_INFRA current ;
+ package -template CYGPKG_REDBOOT current ;
+};
+
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+ user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+ user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+ inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+ inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+ inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+ inferred_value 0
+};
+
+cdl_option CYGSEM_HAL_ROM_MONITOR {
+ user_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+ user_value ROM
+};
+
+cdl_option CYGBLD_BUILD_REDBOOT {
+ user_value 1
+};
+
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+ user_value 1
+};
+
+cdl_option CYGBLD_REDBOOT_FLASH_BOOT_OFFSET {
+ inferred_value 0x1C00000
+};
--- /dev/null
+##=============================================================================
+##
+## platform.S
+##
+## Fujitsu Starterkit MB91302 platform code
+##
+##=============================================================================
+#####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): larsi
+## Contributors:
+## Date: 2007-07-09
+## Purpose: Fujitsu Starterkit MB91302 platform code
+## Description: Platform specific code for Fujitsu Starterkit MB91302 board.
+##
+##
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+#endif
+
+#include <cyg/hal/arch.inc>
+
+##-----------------------------------------------------------------------------
+## platforms special entry point.
+## it copies the code from hal_fr30_ram_startup_trampoline until
+## hal_fr30_ram_startup_trampoline_end to ram and jumps there. The code there
+## is for mapping the flash to 0x1000000 and then jumping to real entry
+## (_start).
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+ .section ".rom_startup_trampoline","ax"
+
+ .balign 4
+ .global hal_fr30_rom_startup_trampoline
+hal_fr30_rom_startup_trampoline:
+ # disable interrupts and set priority to lowest (=disable)
+ andccr #0xef
+ stilm #0x0
+
+ ldi:32 #__rom_trampoline_start - 4, r11
+ ldi:32 #__ram_trampoline_start - 4, r13
+ ldi:32 #__rom_trampoline_end - 8, r12
+1:
+ add #0x4, r11
+ add #0x4, r13
+ ld @r11, r0
+ cmp r12, r11
+ ble:d 1b
+ st r0, @r13
+
+## jump to the code in ram
+ ldi:32 #hal_fr30_ram_startup_trampoline, r0
+ jmp @r0
+
+#endif
+
+##-----------------------------------------------------------------------------
+# Platform Initialization.
+# This code is copied to a location in RAM on startup and is executed there.
+# It maps the the FLASH chip to 0x1000000 and sets the TBR to the new location
+# of the hardware vector table (hal_fr30_vector_table). So we can reach the full
+# range of the FLASH and it can be used for flashfilesystem. After that it jumps
+# to the real application.
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+ .section ".ram_startup_trampoline","ax"
+
+ .balign 4
+ .global hal_fr30_ram_startup_trampoline
+hal_fr30_ram_startup_trampoline:
+ hal_flash_init_from_ram
+
+## map TBR to the new location (for vector tables)
+ ldi:32 #0x10ffc00, r0
+ mov r0, tbr
+
+## jump to real startup
+ ldi:32 #_start, r0
+ jmp @r0
+
+#endif
+
+
+#==============================================================================
+# Vector table for storage in flash, version for skmb91302 platform.
+# it differs from variants/archs version in that uses a different reset vector
+# that points to the special startup procedure that jumps to the normal entry
+# (_start) later.
+# base address is 0x000FFC00 and 0x10ffc00 after remapping the flash.
+# This address stores the vector address for number 255
+# address 0x000FFFFC (0x10ffffc) is the last vector, the reset vector, which
+# is not alterable. Vectors 255 to 80 are used by the INT instruction and set
+# to 0 here for now ...
+
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
+
+ .section ".rom_vectors","ax"
+
+ .balign 4
+ .global hal_fr30_vector_table
+hal_fr30_vector_table:
+ .rept 255-80 + 1
+ .long 0x0
+ .endr
+ .rept 79-67 + 1
+ .long 0x0
+ .endr
+
+ .long 0x0
+ .long 0x0
+ .long 0x0
+# number 63 first interrupt source
+ .long hal_fr30_irq_63
+ .long hal_fr30_irq_62
+ .long hal_fr30_irq_61
+ .long hal_fr30_irq_60
+ .long hal_fr30_irq_59
+ .long hal_fr30_irq_58
+ .long hal_fr30_irq_57
+ .long hal_fr30_irq_56
+ .long hal_fr30_irq_55
+ .long hal_fr30_irq_54
+ .long hal_fr30_irq_53
+ .long hal_fr30_irq_52
+ .long hal_fr30_irq_51
+ .long hal_fr30_irq_50
+ .long hal_fr30_irq_49
+ .long hal_fr30_irq_48
+ .long hal_fr30_irq_47
+ .long hal_fr30_irq_46
+ .long hal_fr30_irq_45
+ .long hal_fr30_irq_44
+ .long hal_fr30_irq_43
+ .long hal_fr30_irq_42
+ .long hal_fr30_irq_41
+ .long hal_fr30_irq_40
+ .long hal_fr30_irq_39
+ .long hal_fr30_irq_38
+ .long hal_fr30_irq_37
+ .long hal_fr30_irq_36
+ .long hal_fr30_irq_35
+ .long hal_fr30_irq_34
+ .long hal_fr30_irq_33
+ .long hal_fr30_irq_32
+ .long hal_fr30_irq_31
+ .long hal_fr30_irq_30
+ .long hal_fr30_irq_29
+ .long hal_fr30_irq_28
+ .long hal_fr30_irq_27
+ .long hal_fr30_irq_26
+ .long hal_fr30_irq_25
+ .long hal_fr30_irq_24
+ .long hal_fr30_irq_23
+ .long hal_fr30_irq_22
+ .long hal_fr30_irq_21
+ .long hal_fr30_irq_20
+ .long hal_fr30_irq_19
+ .long hal_fr30_irq_18
+ .long hal_fr30_irq_17
+ .long hal_fr30_irq_16
+ .long hal_fr30_irq_15
+ .long hal_fr30_exception_noerr_14
+ .long hal_fr30_exception_noerr_13
+ .long hal_fr30_exception_noerr_12
+ .long hal_fr30_exception_noerr_11
+ .long hal_fr30_exception_noerr_10
+ .long hal_fr30_exception_noerr_9
+ .long hal_fr30_exception_noerr_8
+ .long hal_fr30_exception_noerr_7
+ .long hal_fr30_exception_noerr_6
+ .long hal_fr30_exception_noerr_5
+ .long hal_fr30_exception_noerr_4
+ .long hal_fr30_exception_noerr_3
+ .long hal_fr30_exception_noerr_2
+
+# mode vector (only the first of the four byte is relevant)
+ .byte 0x1
+ .byte 0
+ .byte 0
+ .byte 0
+
+# reset vector
+ .long hal_fr30_rom_startup_trampoline
+
+#endif /*CYG_HAL_STARTUP_ROM || CYG_HAL_STARTUP_ROMRAM*/
+
+
+##-----------------------------------------------------------------------------
+## end of platform.S
--- /dev/null
+//==========================================================================
+//
+// plf_misc.c
+//
+// HAL platform miscellaneous functions
+//
+//==========================================================================
+//####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, larsi
+// Contributors: nickg, jlarmour, dmoseley
+// Date: 2007-07-09
+// Purpose: HAL miscellaneous functions
+// Description: This file contains miscellaneous functions provided by the
+// HAL.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // Base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_arch.h> // architectural definitions
+
+#include <cyg/hal/hal_intr.h> // Interrupt handling
+
+#include <cyg/hal/hal_cache.h> // Cache handling
+
+#include <cyg/hal/hal_if.h>
+
+
+/*------------------------------------------------------------------------*/
+
+void hal_platform_init(void)
+{
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT)
+ // Set up eCos/ROM interfaces
+ hal_if_init();
+#endif
+
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+ (defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) || \
+ defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs))
+
+{
+ extern CYG_ADDRESS hal_virtual_vector_table[32];
+ void patch_dbg_syscalls( void * );
+ patch_dbg_syscalls( (void *)(&hal_virtual_vector_table[0]) );
+}
+#endif
+
+}
+
+/*------------------------------------------------------------------------*/
+/* Reset support */
+
+
+/*------------------------------------------------------------------------*/
+/* Syscall support */
+#ifdef CYGPKG_CYGMON
+// Cygmon provides syscall handling for this board
+#include <cyg/hal/hal_stub.h>
+int __get_syscall_num (void)
+{
+ return SIGSYS;
+}
+#endif
+
+
+/*------------------------------------------------------------------------*/
+/* End of plf_misc.c */
--- /dev/null
+//=============================================================================
+//
+// plf_stub.c
+//
+// Platform specific code for GDB stub support.
+//
+//=============================================================================
+//####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): msalter, larsi
+// Contributors:
+// Date: 2007-07-09
+// Purpose: Platform specific code for GDB stub support.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/hal/hal_stub.h>
+
+#include <cyg/hal/hal_io.h> // HAL IO macros
+#include <cyg/hal/hal_diag.h> // diag output. FIXME
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+
+//-----------------------------------------------------------------------------
+// Stub init
+
+void hal_plf_stub_init(void)
+{
+// extern CYG_ADDRESS hal_virtual_vector_table[64];
+ extern void init_thread_syscall( void *);
+ extern void install_async_breakpoint(void *epc);
+ void (*oldvsr)(void);
+ extern void __default_exception_vsr(void);
+
+ // Ensure that the breakpoint VSR points to the default VSR. This will pass
+ // it on to the stubs.
+ HAL_VSR_SET( CYGNUM_HAL_VECTOR_BREAKPOINT, __default_exception_vsr, &oldvsr );
+
+ // Install async breakpoint handler into vector table.
+ hal_virtual_vector_table[35] = (CYG_ADDRESS)install_async_breakpoint;
+
+#if !defined(CYGPKG_KERNEL) && defined(CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT)
+ // Only include this code if we do not have a kernel. Otherwise
+ // the kernel supplies the functionality for the app we are linked
+ // with.
+
+ // Prepare for application installation of thread info function in
+ // vector table.
+ hal_virtual_vector_table[15] = 0;
+ init_thread_syscall( (void *)&hal_virtual_vector_table[15] );
+#endif
+}
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+//-----------------------------------------------------------------------------
+// End of plf_stub.c
--- /dev/null
+//=============================================================================
+//
+// ser.c
+//
+// Simple (polling) driver for the Fujitsu MB91302 on-chip serial port
+//
+//=============================================================================
+//####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): larsi
+// Contributors:
+// Date: 2007-01-10
+// Description: Simple driver for the MB91302 internal serial port
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/system.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_if.h> // interface API
+#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h> // Helper functions
+#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
+
+// We have no control over baud rate
+// #if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==57600
+// #define CYG_DEV_SERIAL_BAUD_DIVISOR BAUD_57600
+// #endif
+
+// #ifndef CYG_DEV_SERIAL_BAUD_DIVISOR
+// #error Missing/incorrect serial baud rate defined - CDL error?
+// #endif
+
+#define CYG_HAL_FR30_MB91301_SMR0 0x63
+#define CYG_HAL_FR30_MB91301_SCR0 0x62
+#define CYG_HAL_FR30_MB91301_SIDR0 0x61
+#define CYG_HAL_FR30_MB91301_SODR0 0x61
+#define CYG_HAL_FR30_MB91301_SSR0 0x60
+#define CYG_HAL_FR30_MB91301_UTIM0 0x64
+#define CYG_HAL_FR30_MB91301_UTIMR0 0x64
+#define CYG_HAL_FR30_MB91301_DRCL 0x66
+#define CYG_HAL_FR30_MB91301_UTIMC0 0x67
+
+
+#define CYG_HAL_FR30_MB91301_SER0_BASE 0x60
+#define CYG_HAL_FR30_MB91301_SER1_BASE 0x68
+#define CYG_HAL_FR30_MB91301_SER2_BASE 0x70
+
+#define CYG_HAL_FR30_MB91301_SMR_OFFSET 0x03
+#define CYG_HAL_FR30_MB91301_SCR_OFFSET 0x02
+#define CYG_HAL_FR30_MB91301_SIDR_OFFSET 0x01
+#define CYG_HAL_FR30_MB91301_SODR_OFFSET 0x01
+#define CYG_HAL_FR30_MB91301_SSR_OFFSET 0x00
+#define CYG_HAL_FR30_MB91301_UTIM_OFFSET 0x04
+#define CYG_HAL_FR30_MB91301_UTIMR_OFFSET 0x04
+#define CYG_HAL_FR30_MB91301_DRCL_OFFSET 0x06
+#define CYG_HAL_FR30_MB91301_UTIMC_OFFSET 0x07
+
+#define CYG_HAL_FR30_MB91301_PDRG 0x10
+#define CYG_HAL_FR30_MB91301_DDRG 0x400
+#define CYG_HAL_FR30_MB91301_PFRG 0x410
+#define CYG_HAL_FR30_MB91301_PDRJ 0x13
+#define CYG_HAL_FR30_MB91301_DDRJ 0x403
+#define CYG_HAL_FR30_MB91301_PFRJ 0x413
+
+
+//-----------------------------------------------------------------------------
+typedef struct {
+ cyg_uint8 base;
+ cyg_int32 msec_timeout;
+ int isr_vector;
+} channel_data_t;
+
+static channel_data_t channels[2] = {
+ { CYG_HAL_FR30_MB91301_SER0_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART0_RX},
+ { CYG_HAL_FR30_MB91301_SER1_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART1_RX}/*,
+ { CYG_HAL_FR30_MB91301_SER2_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART2_RX}*/
+};
+
+//-----------------------------------------------------------------------------
+// function for calculating and setting the baudrate
+
+static void cyg_hal_plf_serial_set_baudrate_internal(cyg_uint8 port, int baudrate){
+
+ float n, nn;
+ int t, tt;
+
+ n = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) (32 * baudrate) - 1;
+ nn = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) (32 * baudrate) - 1.5;
+
+ /* rounding */
+ t = n;
+ tt = nn;
+ if ( (n-t) > (1 - (n-t)) ) t++;
+ if ( (nn-tt) > (1 - (nn-tt)) ) tt++;
+
+ /* check which is better t or tt */
+
+ /* back calculation of baudrate from t and tt */
+ n = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) ((2*t+2) * 16);
+ nn = (CYGHWR_HAL_FR30_MB91301_SYSTEM_CLOCK_MHZ * 1000000 / CYGHWR_HAL_FR30_MB91301_CLKP_DIVIDER) / (float) ((2*tt+3) * 16);
+
+ /* taking difference between wanted baudrate and back calculated br */
+ if ((baudrate - n) < 0)
+ n = n - baudrate;
+ else
+ n = baudrate - n;
+
+ if ((baudrate - nn) < 0)
+ nn = nn - baudrate;
+ else
+ nn = baudrate - nn;
+
+ /* and finally take the best */
+ if (n < nn){
+ /* UCC1 = 0 */
+ HAL_WRITE_UINT16(port + CYG_HAL_FR30_MB91301_UTIMR_OFFSET, t);
+ HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_UTIMC_OFFSET, 0x02);
+ } else {
+ /* UCC1 = 1 */
+ HAL_WRITE_UINT16(port + CYG_HAL_FR30_MB91301_UTIMR_OFFSET, tt);
+ HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_UTIMC_OFFSET, 0x82);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// The minimal init, get and put functions. All by polling.
+
+void
+cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+ cyg_uint8 port;
+ cyg_uint8 value;
+
+ port = ((channel_data_t*)__ch_data)->base;
+
+ // set the port direction and function registers to serial
+ switch (port){
+ case CYG_HAL_FR30_MB91301_SER0_BASE:
+ HAL_READ_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+ value |= 0x6;
+ value &= ~0x1;
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+ HAL_READ_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value);
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value | 0x7);
+ if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT == 0){
+ cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD);
+ } else {
+ cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD);
+ }
+ break;
+
+ case CYG_HAL_FR30_MB91301_SER1_BASE:
+ HAL_READ_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+ value |= 0x30;
+ value &= ~0x8;
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, value);
+ HAL_READ_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value);
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, value | 0x38);
+ if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT == 1){
+ cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD);
+ } else {
+ cyg_hal_plf_serial_set_baudrate_internal(port, CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD);
+ }
+ break;
+/*
+ case CYG_HAL_FR30_MB91301_SER2_BASE:
+ HAL_READ_UINT8(CYG_HAL_FR30_MB91301_DDRG, value);
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRG, value | 0x40);
+ HAL_READ_UINT8(CYG_HAL_FR30_MB91301_PFRG, value);
+ HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRG, value | 0x60);
+ break;
+*/
+ }
+
+ // set up U-Timer
+/* HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_UTIMC_OFFSET, 0x02);
+ // 115200 bps
+ HAL_WRITE_UINT16(port + CYG_HAL_FR30_MB91301_UTIMR_OFFSET, 0x7);
+
+ cyg_hal_plf_serial_set_baudrate_internal(port, baudrate);
+*/
+ // setup UART
+ HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SCR_OFFSET, 0x13);
+ HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SMR_OFFSET, 0x30);
+}
+
+void
+cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch)
+{
+ cyg_uint8 ssr;
+ cyg_uint8 port;
+
+ port = ((channel_data_t*)__ch_data)->base;
+ // wait for tx rdy
+ do
+ {
+ HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, ssr);
+ } while (!(ssr & BIT3));
+ // Now, write it
+ HAL_WRITE_UINT8( port + CYG_HAL_FR30_MB91301_SODR_OFFSET, __ch );
+}
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+ cyg_uint8 ssr;
+ cyg_uint8 port;
+
+ port = ((channel_data_t*)__ch_data)->base;
+ HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, ssr);
+ if (!(ssr & BIT4))
+ return false;
+
+ HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SIDR_OFFSET, *ch);
+// hal_diag_led(port);
+ return true;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+ cyg_uint8 ch;
+
+ while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+ return ch;
+}
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ while(__len-- > 0)
+ cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+}
+
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+ int delay_count;
+ channel_data_t* chan;
+ cyg_bool res;
+
+ // Some of the diagnostic print code calls through here with no idea what the ch_data is.
+ // Go ahead and assume it is channels[0].
+ if (__ch_data == 0)
+ __ch_data = (void*)&channels[0];
+
+ chan = (channel_data_t*)__ch_data;
+
+ delay_count = chan->msec_timeout; // delay in 1000 us steps
+ for(;;) {
+ res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+ if (res || 0 == delay_count--)
+ break;
+ CYGACC_CALL_IF_DELAY_US(1000);
+ }
+ return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+ static int irq_state = 0;
+ channel_data_t* chan;
+ int ret = 0;
+ cyg_uint8 port;
+ cyg_uint8 value;
+
+ // Some of the diagnostic print code calls through here with no idea what the ch_data is.
+ // Go ahead and assume it is channels[0].
+ if (__ch_data == 0)
+ __ch_data = (void*)&channels[0];
+
+ chan = (channel_data_t*)__ch_data;
+
+ switch (__func) {
+ case __COMMCTL_IRQ_ENABLE:
+ irq_state = 1;
+ port = ((channel_data_t*)__ch_data)->base;
+ HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value);
+ HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value | BIT1);
+ break;
+ case __COMMCTL_IRQ_DISABLE:
+ ret = irq_state;
+ irq_state = 0;
+ port = ((channel_data_t*)__ch_data)->base;
+ HAL_READ_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value);
+ HAL_WRITE_UINT8(port + CYG_HAL_FR30_MB91301_SSR_OFFSET, value & ~BIT1);
+ break;
+ case __COMMCTL_DBG_ISR_VECTOR:
+ ret = chan->isr_vector;
+ break;
+ case __COMMCTL_SET_TIMEOUT:
+ {
+ va_list ap;
+
+ va_start(ap, __func);
+
+ ret = chan->msec_timeout;
+ chan->msec_timeout = va_arg(ap, cyg_uint32);
+
+ va_end(ap);
+ }
+ break;
+ case __COMMCTL_SETBAUD:
+ {
+ cyg_uint32 baud_rate;
+ cyg_uint16 n, nn;
+ va_list ap;
+
+ va_start(ap, __func);
+ baud_rate = va_arg(ap, cyg_uint32);
+ va_end(ap);
+ port = ((channel_data_t*)__ch_data)->base;
+ cyg_hal_plf_serial_set_baudrate_internal(port, baud_rate);
+ }
+ break;
+
+ case __COMMCTL_GETBAUD:
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+ *__ctrlc = 0;
+ return 0;
+}
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int i, cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+#define NUM_CHANNELS CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
+ for (i = 0; i < NUM_CHANNELS; i++) {
+
+ // Disable interrupts.
+ HAL_INTERRUPT_MASK(channels[i].isr_vector);
+
+ // Init channels
+ cyg_hal_plf_serial_init_channel((void*)&channels[i]);
+ // Setup procs in the vector table
+
+ // Set COMM callbacks for channel
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[i]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+ }
+ // Restore original console
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+
+ initialized = 1;
+ cyg_hal_plf_serial_init();
+
+}
+
+//-----------------------------------------------------------------------------
+// end of ser.c
+
--- /dev/null
+/*=================================================================
+//
+// cache.c
+//
+// SYNTH ftok test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Andrew Lunn
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): asl
+// Contributors: asl
+// Date: 05/11/2005
+//####DESCRIPTIONEND####
+*/
+
+#ifndef HOST
+#include <cyg/hal/hal_io.h>
+#include <cyg/infra/diag.h>
+
+#define printf diag_printf
+#define ftok cyg_hal_sys_ftok
+
+#else
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#endif
+
+int main(void)
+{
+ printf("ftok(\"/etc/passwd\",0x12)) = 0x%8x\n",
+ ftok("/etc/passwd",0x12));
+
+ printf("ftok(\"/etc/passwd\",0x72)) = 0x%8x\n",
+ ftok("/etc/passwd",0x72));
+
+ printf("ftok(\"/boot/vmlinuz\",0x72)) = 0x%8x\n",
+ ftok("/boot/vmlinuz",0x72));
+
+ printf("ftok(\"/boot/vmlinuz\",0x12)) = 0x%8x\n",
+ ftok("/boot/vmlinuz",0x12));
+
+ return 0;
+}
+
+#ifndef HOST
+
+externC void
+cyg_start( void )
+{
+ main();
+}
+#endif
--- /dev/null
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- can.sgml -->
+<!-- -->
+<!-- Generic CAN documentation. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN#### -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- -->
+<!-- ####COPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): Uwe Kindler -->
+<!-- Date: 2006/12/04 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART id="io-can"><title>CAN Support</title>
+
+<CHAPTER id="io-can-overview">
+<TITLE>Overview</TITLE>
+
+<SECTION id="io-can-overview-descr">
+<TITLE>Description</TITLE>
+
+<PARA>
+The Controller Area Network, CAN, is a multicast shared, differential
+serial bus standard especially suited for networking "intelligent"
+devices as well as sensors and actuators within a system or sub-system.
+The protocol was originally developed in the 1980s by Robert Bosch GmbH
+aiming at automotive applications. Nowadays CAN has gained widespread use
+and is used in industrial automation as well as in automotive, mobile
+machines and in many embedded control applications.
+</PARA>
+
+<PARA>
+The CAN protocol is defined by the ISO 11898-1 standard. The physical layer
+uses differential transmission on a twisted pair wire. CAN uses a
+non-destructive bit-wise arbitration to control access to the bus.
+</PARA>
+
+<PARA>
+There is no explicit address in the messages because in CAN networks there
+is no addressing of subscribers or stations, but instead, each message carries
+a prioritized identifier. A transmitter sends a message to all CAN nodes
+(broadcasting). The identifier may serve as an identification of the contents
+of the message and also determines the priority that the message enjoys in
+competition for bus access. A node decides on the basis of this identifier
+received whether it should process the message or not.
+</PARA>
+
+<PARA>
+The CAN messages are small (at most eight data bytes) and are protected
+by a checksum. Each CAN message consists of an 11 bit message ID, up to 8
+bytes of data and, a CRC checksum and a number of control bits. These
+short messages ensure a robust transfer of data in electromagnetically
+noisy environments. An extended version of the CAN frame supports 29 bit
+message identifiers.
+</PARA>
+
+<PARA>
+Basically there are two different operational modes for CAN receivers -
+FullCAN and BasicCAN. The difference between these two modes is the
+Object Storage function. The BasicCAN architecture is quite similar to a
+simple UART. A BasicCAN device has typically one transmit buffer and two
+receive buffers. The CAN chip handles only the transmitting and receiving
+of the data (and the error handling) and so most of the manipulation of the
+data has to be done by the CPU. The CPU has to request the transmitting or
+acknowledge the receiving of the data through the interrupt flags. This will
+burden the CPU and take up much of the CPU time.
+</PARA>
+
+<PARA>
+The FullCAN architecture is more suitable for high-speed performance. It
+has its own storage area on chip and works with a number of message buffers
+or message boxes. The CAN controller has its own Acceptance Filtering Mask
+on chip. It can thus determine which frames are to be received by examining
+the identifiers. The CPU in this case will only receive the valid (wanted)
+frames and hence improve the performance of the CPU.
+</PARA>
+
+<PARA>
+You can find more information at the
+<ulink url="http://www.can-cia.org/">CAN in Automation</ulink> website.
+</PARA>
+
+</SECTION> <!-- "io-can-description" -->
+
+<SECTION id="io-can-ecos-support">
+<TITLE>eCos Support for CAN</TITLE>
+
+<PARA>
+The eCos CAN subsystem supports the BasicCAN and FullCAN mode. The architecture
+and the interface of the eCos CAN driver is quite similar to the eCos serial
+driver and supports the same interface.
+</PARA>
+
+<PARA>
+The eCos CAN support for any given platform is spread over a number of different
+packages:
+</PARA>
+
+<itemizedlist>
+ <listitem>
+ <para>
+
+This package, <varname>CYGPKG_IO_CAN</varname>, exports a generic
+device independent CAN I/O API for accessing devices attached to a CAN
+network. This API handles issues such as locking between threads. The
+package does not contain any hardware-specific code. Instead it will
+call into a CAN device driver to handle the hardware device
+access. This package also defines the inderface that such hardware
+drivers should provide.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Each CAN device will have its own device driver, which is implemented
+as a separate package, for example
+<varname>CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN</varname>. For devices that may
+be attached to a variety of different boards the device driver will be
+generic and a second platform specific package will be used to customize
+it to each platform. For devices that are associated with a specific
+chipset, only a single package may be present.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<PARA>
+Typically all appropriate packages will be loaded automatically when
+you configure eCos for a given platform. If the application does not use
+any of the CAN I/O facilities, directly or indirectly, then linker garbage
+collection should eliminate all unnecessary code and data. All necessary
+initialization should happen automatically. However the exact details may
+depend on the platform, so the platform HAL documentation should be
+checked for further details.
+</PARA>
+
+<PARA>
+There is an important exception to this: if the CAN devices are attached
+to an expansion connector, such as PCI, then the platform HAL will not
+know about these devices. Instead the necessary packages will need to be
+added explicitly during configuration.
+</PARA>
+</SECTION>
+</CHAPTER>
+
+<CHAPTER id="io-can-api">
+<TITLE>User API</TITLE>
+
+<PARA>
+The CAN driver uses the standard eCos I/O API functions. All functions
+except <function>cyg_io_lookup()</function> require an I/O "handle".
+</PARA>
+
+<PARA>
+All functions return a value of the type <type>Cyg_ErrNo</type>.
+If an error condition is detected, this value will be negative and the
+absolute value indicates the actual error, as specified in
+<filename>cyg/error/codes.h</filename>. The only other legal return values
+will be <varname>ENOERR</varname>, <varname>-EINTR</varname> and
+<varname>-EAGAIN</varname>. All other function arguments are pointers
+(references). This allows the drivers to pass information efficiently,
+both into and out of the driver. The most striking example of this is the
+<parameter>len</parameter> value passed to the read and write functions.
+This parameter contains the desired length of data on input to the
+function and the actual transferred length on return.
+</PARA>
+
+<PROGRAMLISTING>
+// Lookup a CAN device and return its handle
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_lookup</function>(
+ const char <parameter>*name</parameter>,
+ cyg_io_handle_t <parameter>*handle</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function maps a CAN device name onto an appropriate handle. If the
+named device is not in the system, then the error
+<varname>-ENOENT</varname> is returned. If the device is found, then
+the handle for the device is returned by way of the handle pointer
+<parameter>*handle</parameter>.
+</PARA>
+
+<PROGRAMLISTING>
+// Send a CAN message
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_write</function>(
+ cyg_io_handle_t <parameter>handle</parameter>,
+ const void <parameter>*buf</parameter>,
+ cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function sends one single CAN message (not a buffer of CAN messages)
+to a device. The size of data to send is contained in
+<parameter>*len</parameter> and the actual size sent will be returned in
+the same place.
+</PARA>
+
+<PROGRAMLISTING>
+// Read one CAN event from device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_read</function>(
+ cyg_io_handle_t <parameter>handle</parameter>,
+ void <parameter>*buf</parameter>,
+ cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function receives one single CAN event from a device. The desired size
+of data to receive is contained in <parameter>*len</parameter> and the
+actual size obtained will be returned in the same place.
+</PARA>
+
+<PROGRAMLISTING>
+// Read configuration of a CAN device
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_get_config</FUNCTION>(
+ cyg_io_handle_t <parameter>handle</parameter>,
+ cyg_uint32 <parameter>key</parameter>,
+ void *<parameter>buf</parameter>,
+ cyg_uint32 *<parameter>len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a
+device. The type of information retrieved is specified by the
+<parameter>key</parameter>. The data will be returned in the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data requested, which must be at least as large as the size
+appropriate to the selected key. The actual size of data retrieved is
+placed in <parameter>*len</parameter>. The appropriate key values
+are all listed in the file <filename><cyg/io/config_keys.h></filename>.
+</PARA>
+
+<PROGRAMLISTING>
+// Change configuration of a CAN device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_set_config</function>(
+ cyg_io_handle_t <parameter>handle</parameter>,
+ cyg_uint32 <parameter>key</parameter>,
+ const void <parameter>*buf</parameter>,
+ cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time
+configuration of a device. The type of information is specified by the
+<parameter>key</parameter>. The data will be obtained from the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data provided, which must match the size appropriate to the
+selected key. The appropriate key values are all listed in the file
+<filename><cyg/io/config_keys.h></filename>.
+</PARA>
+</CHAPTER>
+
+<CHAPTER id="io-can-driver-details">
+<TITLE>CAN driver details</TITLE>
+
+<PARA>
+Allow applications and other packages to access CAN devices.
+</PARA>
+
+<SECTION id="io-can-driver-description">
+<TITLE>Description</TITLE>
+
+<PARA>
+A raw CAN driver is is provided as a standard part of the eCos system.
+</PARA>
+
+<PARA>
+Use the include file <filename><cyg/io/canio.h></filename> for this driver.
+</PARA>
+
+<PARA>
+The CAN driver is capable of sending single CAN messages to a device and
+receiving single CAN events from a CAN device. Controls are provided to
+configure the actual hardware, but there is no manipulation of the data by
+this driver.
+</PARA>
+
+<PARA>
+There may be many instances of this driver in a given system, one for each
+CAN channel. Each channel corresponds to a physical device and there will
+typically be a device module created for this purpose. The device modules
+themselves are configurable, allowing specification of the actual hardware
+details.
+</PARA>
+</SECTION>
+
+<SECTION id="io-can-api-details">
+<TITLE>API Details</TITLE>
+
+<SECTION>
+<TITLE>cyg_io_write</TITLE>
+
+<PROGRAMLISTING>
+cyg_io_write(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To transmit a message an application must fill a <type>cyg_can_message</type>
+buffer and call <function>cyg_io_write()</function>.
+This function sends one single CAN message (not a buffer of CAN messages)
+to a device. The size of data to send is contained in <parameter>*len</parameter>
+and the actual size sent will be returned in the same place. A pointer to a
+<type>cyg_can_message</type> is contained in <parameter>*buf</parameter>.
+The driver maintains a buffer to hold the data. The size of the intermediate
+buffer is configurable within the interface module. The data is not modified
+at all while it is being buffered. On return, <parameter>*len</parameter>
+contains the amount of characters actually consumed - that means
+<parameter>*len</parameter> always contains
+<function>sizeof(cyg_can_message)</function>.
+</PARA>
+
+<PARA>
+It is possible to configure the write call to be blocking (default) or
+non-blocking. Non-blocking mode requires both the configuration option
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, and
+the specific device to be set to non-blocking mode for writes
+(see <function>cyg_io_set_config()</function>). In blocking mode, the
+call will not return until there is space in the buffer and the content
+of the CAN message has been consumed. In non-blocking mode, if there is
+no space in buffer for the CAN message, <varname>-EAGAIN</varname> is
+returned and the caller must try again.
+</PARA>
+
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout.
+None-blocking mode with timeout requires the configuration option
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, requires
+the eCos kernel package to be included and the specific device to be set
+to non-blocking mode for writes (see <function>cyg_io_set_config()
+</function>).
+In non-blocking mode with timeouts, if there is no space in buffer for the
+CAN message, the driver waits a certain amount of time (the timeout time)
+for space in the buffer. If there is still no space in buffer after
+expiration of the timeout time, <varname>-EINTR</varname> is returned and
+the caller must try again.
+</PARA>
+
+<PARA>
+If a message was sucessfully sent, the function returns <varname>ENOERR</varname>.
+</PARA>
+</SECTION>
+
+<SECTION>
+<TITLE>CAN Messages</TITLE>
+
+<PARA>
+The CAN driver uses <structname>cyg_can_message</structname> structures to
+pass messages between the application and the CAN driver. The type
+cyg_can_message provides a device independent type of CAN message.
+Before calling the write function this message should be setup properly.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct can_message
+{
+ cyg_uint32 id;
+ cyg_uint8 data[8];
+ cyg_can_id_type ext;
+ cyg_can_frame_type rtr;
+ cyg_uint8 dlc;
+} cyg_can_message;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>id</varname></term>
+ <listitem><para>
+Message ID. This is the ID to be transmitted with the message, or the
+ID received. If the <structfield>ext</structfield> field is set, then
+this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>data</varname></term>
+ <listitem><para>
+Message data. Only the first <structfield>dlc</structfield> bytes of
+data are valid. If the <structfield>rtr</structfield> field is set,
+then the contents of this field are ignored.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_id_type</type> <varname>ext</varname></term>
+ <listitem><para>
+Extended ID. If this field is <varname>CYGNUM_CAN_ID_EXT</varname> then the
+<structname>id</structname> field contains a 29 bit extended ID. If it
+contains <varname>CYGNUM_CAN_ID_STD</varname> then the ID is 11 bits.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_frame_type</type> <varname>rtr</varname></term>
+ <listitem><para>
+Remote Transmission Request. If this field contains
+<varname>CYGNUM_CAN_FRAME_RTR</varname> then the RTR bit on the message
+will be set and the <structfield>data</structfield> field will be ignored.
+If the field contains <varname>CYGNUM_CAN_FRAME_DATA</varname> then a
+normal data frame will be send.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint8</type> <varname>dlc</varname></term>
+ <listitem><para>
+The length of the data carried in the message. This can range from
+zero to 8. In a message with the <structfield>rtr</structfield> field set,
+this indicates the size of data being requested.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for sending one single CAN message:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_message tx_msg;
+cyg_uint32 len;
+Cyg_ErrNo ret;
+
+tx_msg.id = 0x100;
+tx_msg.ext = CYGNUM_CAN_ID_EXT;
+tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+tx_msg.dlc = 1;
+tx_msg.data[0] = 0xF1;
+
+len = sizeof(tx_msg);
+ret = cyg_io_write(hDrvCAN, &tx_msg, &len);
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg_can_message -->
+
+<SECTION>
+<TITLE>cyg_io_read</TITLE>
+
+<PROGRAMLISTING>
+cyg_io_read(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To receive a message the application calls <function>cyg_can_recv()</function>.
+This function receives one single event from a device. The desired size
+of data to receive is contained in <parameter>*len</parameter> and the
+actual size obtained will be returned in the same place. A pointer to
+a <type>cyg_can_event</type> is contained in <parameter>*buf</parameter>.
+No manipulation of the data is performed before being transferred.
+Again, this buffering is completely configurable. On return,
+<parameter>*len</parameter> contains <function>sizeof(cyg_can_event)</function>.
+</PARA>
+
+<PARA>
+It is possible to configure the read call to be blocking (default) or
+non-blocking. Non-blocking mode requires both the configuration option
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled,
+and the specific device to be set to non-blocking mode for reads
+(see <function>cyg_io_set_config()</function>). In blocking mode,
+the call will not return until one single CAN event has been read.
+In non-blocking mode, if there is no CAN event in buffer, the call
+returns immediately with <varname>-EAGAIN</varname> and the caller must
+try again.
+</PARA>
+
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout.
+None-blocking mode with timeout requires the configuration option
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled,
+requires the eCos kernel package to be included and the specific device
+to be set to non-blocking mode for reads (see
+<function>cyg_io_set_config()</function>). In non-blocking mode with timeouts,
+if there is no CAN event in receive buffer, the driver waits a certain amount
+of time (the timeout time) for a CAN event to arrive. If there is still no
+CAN event in buffer after expiration of the timeout time, <varname>-EINTR</varname>
+is returned and the caller must try again.
+</PARA>
+
+<PARA>
+If a event was sucessfully received, the function returns <varname>ENOERR</varname>.
+</PARA>
+</SECTION><!-- cyg_io_read -->
+
+
+<SECTION>
+<TITLE>CAN Events</TITLE>
+
+<PARA>
+The CAN driver uses <structname>cyg_can_event</structname> structures to
+pass events from hardware device driver to the generic CAN driver.
+A <structname>cyg_can_event</structname> provides a generic device
+independent type for handling CAN events that may occur.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_event_st
+{
+ cyg_uint32 timestamp;
+ cyg_can_message msg;
+ cyg_uint16 flags;
+} cyg_can_event;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>timestamp</varname></term>
+ <listitem><para>
+If the hardware CAN device driver supports timestamps then this field may
+contain a timestamp value for an event that occured.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_message</type> <varname>msg</varname></term>
+ <listitem><para>
+CAN message. The msg field contains a CAN message if an RX or TX event
+occured. If another type of event occured,
+the <structfield>data</structfield> field of
+the <structfield>msg</structfield> may contain additional event
+specific data.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint16</type> <varname>flags</varname></term>
+ <listitem><para>
+Event flags. The <varname>flags</varname> field contains 16 bits that
+indicate which kind of events occured.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+The following events are supported and after receiving an event the
+application should check the flag field against these values:
+</PARA>
+
+<PROGRAMLISTING>
+typedef enum
+{
+ CYGNUM_CAN_EVENT_RX = 0x0001, // message received
+ CYGNUM_CAN_EVENT_TX = 0x0002, // message transmitted
+ CYGNUM_CAN_EVENT_WARNING_RX = 0x0004, // (TEC) reached warning level (>96)
+ CYGNUM_CAN_EVENT_WARNING_TX = 0x0008, // (REC) reached warning level (>96)
+ CYGNUM_CAN_EVENT_ERR_PASSIVE = 0x0010, // CAN "error passive" occured
+ CYGNUM_CAN_EVENT_BUS_OFF = 0x0020, // CAN "bus off" error occured
+ CYGNUM_CAN_EVENT_OVERRUN_RX = 0x0040, // overrun in RX queue or hardware
+ CYGNUM_CAN_EVENT_OVERRUN_TX = 0x0080, // overrun in TX queue occured
+ CYGNUM_CAN_EVENT_CAN_ERR = 0x0100, // a CAN bit or frame error occured
+ CYGNUM_CAN_EVENT_LEAVING_STANDBY = 0x0200, // CAN hardware leaves standby
+ CYGNUM_CAN_EVENT_ENTERING_STANDBY = 0x0400, // CAN hardware enters standby
+ CYGNUM_CAN_EVENT_ARBITRATION_LOST = 0x0800, // arbitration lost
+ CYGNUM_CAN_EVENT_FILTER_ERR = 0x1000, // CAN message filter / acceptance filter error
+ CYGNUM_CAN_EVENT_PHY_FAULT = 0x2000, // General failure of physical layer
+ CYGNUM_CAN_EVENT_PHY_H = 0x4000, // Fault on CAN-H (Low Speed CAN)
+ CYGNUM_CAN_EVENT_PHY_L = 0x8000, // Fault on CAN-L (Low Speed CAN)
+} cyg_can_event_flags;
+</PROGRAMLISTING>
+
+<PARA>
+Often the flags field will contain only one single set flag. But it is
+possible that a number of flags is set and so the flag field should always
+be checked by a receiver. I.e. if the <varname>CYGNUM_CAN_EVENT_RX</varname>
+is set then also the <varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname>
+may be set if the received message caused an RX overrun.
+</PARA>
+
+<PARA>
+The internal receive buffers of the CAN device driver are circular buffers.
+That means that even if the buffers are completely filled new messages
+will be received. In this case the newest message will always overwrite
+the oldest message in receive buffer. If this happens the
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set for this
+new message that caused overwriting of the old one. The
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set also if
+a overrun occures in hardware message buffers of the CAN device.
+</PARA>
+
+<PARA>
+Example code for receiving one single CAN event:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_event rx_event;
+cyg_uint32 len;
+Cyg_ErrNo ret;
+
+len = sizeof(rx_event);
+ret = cyg_io_read(hDrvCAN, &rx_event, &len);
+
+if (ENOERR == ret)
+{
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ // handle RX event
+ }
+
+ if (rx_event.flags & ~CYGNUM_CAN_EVENT_RX)
+ {
+ // handle other events
+ }
+}
+else if (-EINTR == ret)
+{
+ // handle timeout
+}
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg_can_event -->
+
+
+<SECTION>
+<TITLE>cyg_io_get_config</TITLE>
+
+<PROGRAMLISTING>
+cyg_io_get_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a device.
+The type of information retrieved is specified by the <parameter>key</parameter>.
+The data will be returned in the given buffer. The value of
+<parameter>*len</parameter> should contain the amount of data requested,
+which must be at least as large as the size appropriate to the selected
+<parameter>key</parameter>. The actual size of data retrieved is placed
+in <parameter>*len</parameter>. The appropriate key values are all listed
+in the file <filename><cyg/io/config_keys.h></filename>.
+</PARA>
+
+<PARA>
+The following config keys are currently supported:
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+CYG_IO_GET_CONFIG_CAN_INFO
+CYG_IO_GET_CONFIG_CAN_BUFFER_INFO
+CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO
+CYG_IO_GET_CONFIG_CAN_TIMEOUT
+CYG_IO_GET_CONFIG_CAN_HDI
+CYG_IO_GET_CONFIG_CAN_STATE
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-get-config -->
+
+<SECTION>
+<TITLE>cyg_io_set_config</TITLE>
+
+<PROGRAMLISTING>
+cyg_io_set_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time configuration
+of a device. The type of information is specified by the <parameter>key</parameter>.
+The data will be obtained from the given buffer. The value of
+<parameter>*len</parameter> should contain the amount of data provided,
+which must match the size appropriate to the selected <parameter>key</parameter>.
+The appropriate key values are all listed in the file
+<filename><cyg/io/config_keys.h></filename>.
+</PARA>
+
+<PARA>
+The following config keys are currently supported:
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+CYG_IO_SET_CONFIG_CAN_INFO
+CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN
+CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_TIMEOUT
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+CYG_IO_SET_CONFIG_CAN_MODE
+CYG_IO_SET_CONFIG_CAN_ABORT
+CYG_IO_SET_CONFIG_CAN_CALLBACK
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+</SECTION><!-- io-can-api-details -->
+
+<SECTION id="io-can-runtime-cfg">
+<TITLE>Runtime Configuration</TITLE>
+
+<PARA>
+Runtime configuration is achieved by exchanging data structures with the
+driver via the <function>cyg_io_set_config()</function> and
+<function>cyg_io_get_config()</function> functions.
+</PARA>
+
+<SECTION>
+<TITLE>Device configuration</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_info_st {
+ cyg_can_baud_rate_t baud;
+} cyg_can_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Device configuration is achieved by by exchanging
+<structname>cyg_can_info_t</structname> data structures with the driver
+via the <function>cyg_io_set_config()</function> and
+<function>cyg_io_get_config()</function> functions using the config keys
+<varname>CYG_IO_GET_CONFIG_CAN_INFO</varname> and
+<varname>CYG_IO_SET_CONFIG_CAN_INFO</varname>.
+The field <structfield>baud</structfield> contains a baud rate selection.
+This must be one of the following values:
+</PARA>
+
+<PROGRAMLISTING>
+CYGNUM_CAN_KBAUD_10
+CYGNUM_CAN_KBAUD_20
+CYGNUM_CAN_KBAUD_50
+CYGNUM_CAN_KBAUD_100
+CYGNUM_CAN_KBAUD_125
+CYGNUM_CAN_KBAUD_250
+CYGNUM_CAN_KBAUD_500
+CYGNUM_CAN_KBAUD_800
+CYGNUM_CAN_KBAUD_1000
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+
+<SECTION>
+<TITLE>Timeout configuration</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_timeout_info_st
+{
+ cyg_uint32 rx_timeout;
+ cyg_uint32 tx_timeout;
+} cyg_can_timeout_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Timeout configuration is achieved by by exchanging
+<structname>cyg_can_timeout_info_t</structname> data structures with the
+driver via the <function>cyg_io_set_config()</function> and
+<function>cyg_io_get_config()</function> functions using the config keys
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname> and
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname>.
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>rx_timeout</varname></term>
+ <listitem><para>
+Timeout for <function>cyg_io_read</function> calls.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>tx_timeout</varname></term>
+ <listitem><para>
+Timeout for <function>cyg_io_write</function> calls.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Timeout runtime configuration is supported if the configuration options
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname>
+and <varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> are enabled.
+</PARA>
+</SECTION><!-- can-timeout-config -->
+
+<SECTION>
+<TITLE>Reading buffer configuration</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_buf_info_st
+{
+ cyg_int32 rx_bufsize;
+ cyg_int32 rx_count;
+ cyg_int32 tx_bufsize;
+ cyg_int32 tx_count;
+} cyg_can_buf_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_BUFFER_INFO</varname> - This function
+retrieves the current state of the software buffers in the CAN drivers.
+For the transmit buffer it returns the the total number of
+<type>cyg_can_message</type> objects in buffer and the current number of
+<type>cyg_can_message</type> objects occupied in the buffer.
+For the receive buffer it returns the total number of
+<type>cyg_can_event</type> objects in receive buffer and the current
+number of <type>cyg_can_event</type> objects occupied in the buffer.
+It does not take into account any buffering such as FIFOs or holding
+registers that the CAN hardware device itself may have.
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>rx_bufsize</varname></term>
+ <listitem><para>
+Total number of <type>cyg_can_event</type> buffers in receive queue.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>rx_count</varname></term>
+ <listitem><para>
+Current number of <type>cyg_can_event</type> buffers occupied in receive queue.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>tx_bufsize</varname></term>
+ <listitem><para>
+Total number of <type>cyg_can_message</type> buffers in transmit queue.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint32</type> <varname>rtx_count</varname></term>
+ <listitem><para>
+Current number of <type>cyg_can_message</type> buffers occupied in transmit queue.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+</SECTION> <!-- can-read-buffer-config -->
+
+
+<SECTION>
+<TITLE>Reading hardware description information</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_hdi_st
+{
+ cyg_uint8 support_flags;
+ cyg_uint8 controller_type;
+} cyg_can_hdi;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_HDI</varname> - This function retrieves
+information about the used hardware. The Hardware Description Interface
+provides a method to gather information about the CAN hardware and the
+functionality of the driver. For this purpose the structure
+<structname>cyg_can_hdi</structname> is defined.
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_uint8</type> <varname>support_flags</varname></term>
+ <listitem><para>
+Contains information about the capabilities of the used CAN hardware.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint8</type> <varname>controller_type</varname></term>
+ <listitem><para>
+A number that identifies the CAN controller type.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+The following flags are available in the field <structfield>support_flags</structfield>:
+</PARA>
+
+<PROGRAMLISTING>
+| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
++-------+-------+-------+-------+-------+-------+-------+-------+
+| res | res | res |timest.|SW-Filt|FullCAN| Frametype |
+</PROGRAMLISTING>
+
+<variablelist>
+ <varlistentry>
+ <term><parameter>Frametype</parameter></term>
+ <listitem><para>
+Bit 0 and Bit 1 of the structure describe the possibilities of the CAN
+controller. The following values are defined:
+ <PROGRAMLISTING>
+CYGNUM_CAN_HDI_FRAMETYPE_STD // receives only standard frame
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE // can receive but not send extended frames
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE // can send and receive extended frames
+ </PROGRAMLISTING>
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>FullCAN</parameter></term>
+ <listitem><para>
+If the Bit 2 - <varname>CYGNUM_CAN_HDI_FULLCAN </varname> - is set to one,
+the CAN controller supports more than one message buffer.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>SW-Filter</parameter></term>
+ <listitem><para>
+If Bit 3 - <varname>CYGNUM_CAN_HDI_FILT_SW</varname> - is set to one then
+the CAN driver supports some kind of software message filtering.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>Timestamp</parameter></term>
+ <listitem><para>
+If Bit 4 - <varname>CYGNUM_CAN_HDI_TIMESTAMP</varname> - is set to one then
+the CAN hardware supports timestamps for CAN messages
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+</SECTION> <!-- can-read-buffer-config -->
+
+<SECTION>
+<TITLE>Reading hardware message buffer configuration</TITLE>
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbox_info_st
+{
+ cyg_uint8 count; // number of message buffers available for this device
+ cyg_uint8 free; // number of free message buffers
+} cyg_can_msgbuf_info;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO</varname> - If the CAN hardware supports
+more than one message buffer for reception of CAN messages (flag
+<varname>CYGNUM_CAN_HDI_FULLCAN</varname> is set while reading hardware description
+interface with <varname>CYG_IO_GET_CONFIG_CAN_HDI</varname>) then this function
+reads the number of message buffers the CAN hardware supports and the number of
+free message buffers.
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_uint8</type> <varname>count</varname></term>
+ <listitem><para>
+Counts the number of message buffers supported by the device.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint8</type> <varname>free</varname></term>
+ <listitem><para>
+Contains the number of free message buffers. The free message buffers are
+available for setting up remote buffers (<varname>CYG_IO_SET_CONFIG_CAN_REMOTE_BUF</varname>)
+and message filters (<varname>CYG_IO_SET_CONFIG_CAN_FILTER_MSG</varname>).
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+</SECTION> <!-- can-read-buffer-config -->
+
+<SECTION>
+<TITLE>Reading state of CAN hardware</TITLE>
+
+<PROGRAMLISTING>
+typedef enum
+{
+ CYGNUM_CAN_STATE_ACTIVE, // CAN controller active, no errors
+ CYGNUM_CAN_STATE_STOPPED, // CAN controller in stopped mode
+ CYGNUM_CAN_STATE_STANDBY, // CAN controller in Sleep mode
+ CYGNUM_CAN_STATE_BUS_WARN, // CAN controller active, warning level is reached
+ CYGNUM_CAN_STATE_ERR_PASSIVE, // CAN controller went into error passive mode
+ CYGNUM_CAN_STATE_BUS_OFF, // CAN controller went into bus off mode
+ CYGNUM_CAN_STATE_PHY_FAULT, // General failure of physical layer
+ CYGNUM_CAN_STATE_PHY_H, // Fault on CAN-H detected (Low Speed CAN)
+ CYGNUM_CAN_STATE_PHY_L, // Fault on CAN-L detected (Low Speed CAN)
+} cyg_can_state;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_STATE</varname> - This function retrieves the
+present state of the CAN controller. Possible values are defined in the
+<type>cyg_can_state</type> enumeration.
+</PARA>
+</SECTION> <!-- can-read-hw-state -->
+
+
+<SECTION>
+<TITLE>Changing mode of CAN hardware</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_MODE</varname> - This function changes
+the operating mode of the CAN controller. The identifiers for the different
+operating modes are defined in the <type>cyg_can_mode</type> enumeration.
+</PARA>
+
+<PROGRAMLISTING>
+typedef enum
+{
+ CYGNUM_CAN_MODE_STOP, // set controller into stop mode
+ CYGNUM_CAN_MODE_START, // set controller into operational mode
+ CYGNUM_CAN_MODE_STANDBY // set controller into standby / sleep mode
+} cyg_can_mode;
+</PROGRAMLISTING>
+
+<variablelist>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MODE_STOP</type></term>
+ <listitem><para>
+Set controller into stop mode
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MODE_START</type></term>
+ <listitem><para>
+Set controller into operational mode
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MODE_STANDBY</type></term>
+ <listitem><para>
+Set controller into standby / sleep mode.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Before the hardware configuration of the device is changed, that means
+if baud rate is changed or the message buffer and filter configuration
+is changed, the CAN hardware should be set into stop mode and if
+configuration is finished, then device should be set back into
+operational mode. Before the device is set into standby mode, the
+output buffers should be flushed or drained because transmission of a
+CAN message may wake up the CAN hardware. If a received message wakes
+up the CAN hardware from standby mode then
+a <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> event will be
+inserted into receive message buffer or
+the <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> flag will be
+set for the message that caused wake up of CAN hardware.
+</PARA>
+</SECTION> <!-- can-mode-cfg -->
+
+<SECTION>
+<TITLE>Flush or drain buffers</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN</varname> - This function
+waits for any buffered output to complete. This function only
+completes when there is no more data remaining to be sent to the
+device.
+</PARA>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH</varname> - This function
+discards any buffered output for the device.
+</PARA>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH</varname> - This function
+discards any buffered input for the device.
+</PARA>
+</SECTION>
+
+<SECTION>
+<TITLE>Configuring blocking/non-blocking calls</TITLE>
+<PARA>
+By default all calls to <function>cyg_io_read()</function>
+and <function>cyg_io_write()</function> are blocking calls. The config
+keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+
+<PARA>
+enable switching between blocking and nonblocking calls separatly for
+read and write calls. If blocking calls are configured then the
+read/write functions return only if a message was stored into TX
+buffer or a event was received from RX buffer. If non-blocking calls
+are enabled and there is no space in TX buffer or RX buffer is empty
+then the function returns immediately
+with <varname>-EAGAIN</varname>.
+</PARA>
+
+<PARA>
+If non-blocking calls are enabled and additionally timeouts are
+supported by driver, then the read/write functions wait until timeout
+value is expired and then return with <varname>-EINTR</varname>. If
+the read/write operation succeeds during the timed wait then the
+functions return succesfully with
+<varname>ENOERR</varname>.
+</PARA>
+
+<PARA>
+To query if <function>cyg_io_read()</function>
+and <function>cyg_io_write()</function> are blocking or non-blocking
+you can use the config keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+</SECTION> <!-- can-cfg-unblock -->
+
+<SECTION>
+<TITLE>Message buffer management</TITLE>
+
+<PARA>
+Full CAN controllers often support more the one message buffer. These
+message buffers are often configurable for transmission or reception
+of certain CAN messages or as a remote buffers. If a CAN hardware
+supports more than one message buffer then it is possible to configure
+the CAN hardware to receive only CAN messages with certain identifiers
+or to configure hardware support for remote buffers. If message
+filtering is done by hardware, the number of received CAN messages
+decreases and so also the time for processing received CAN messages
+and the memory required for buffering received messages
+decreases. This saves valuable memory and processing time.
+</PARA>
+
+<PARA>
+The eCos CAN driver supports a generic way of adding message filters
+or remote buffers. By default the CAN driver is configured for
+reception of any kind of CAN standard and extended
+frames. Configuration of message buffers is done by
+calling <function>cyg_io_set_config()</function> with the config key
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+</PROGRAMLISTING>
+
+<PARA>
+and by exchanging <type>cyg_can_msgbuf_cfg</type> data structures.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbox_cfg_st
+{
+ cyg_can_msgbuf_cfg_id cfg_id; // configuration id
+ cyg_can_msgbuf_handle handle; // handle to message buffer
+ cyg_can_message msg; // CAN message - for configuration of buffer
+} cyg_can_msgbuf_cfg;
+</PROGRAMLISTING>
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+ <listitem><para> The <varname>cfg_id</varname> field
+contains the configuration ID that tells the driver what to do with a
+message buffer.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+ <listitem><para>
+Contains a reference to a certain message buffer.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_message</type> <varname>msg</varname></term>
+ <listitem><para>
+Required for configuration of message buffer parameters.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+The following configuration identifiers are supported:
+</PARA>
+
+<PROGRAMLISTING>
+CYGNUM_CAN_MSGBUF_RESET_ALL // clears alle message buffers
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL // cfg driver for reception of all can messages
+CYGNUM_CAN_MSGBUF_RX_FILTER_ADD // add single message filter
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD // add new remote response buffer
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE // stores data into existing remote buffer
+</PROGRAMLISTING>
+
+<variablelist>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MSGBUF_RESET_ALL</type></term>
+ <listitem><para>
+Clears alle message buffers - no message will be received and all remote buffers are deleted.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL</type></term>
+ <listitem><para>
+Configure driver for reception of all can messages
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ADD</type></term>
+ <listitem><para>
+Add single message filter.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</type></term>
+ <listitem><para>
+Add new remote response buffer.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</type></term>
+ <listitem><para>
+Stores data into existing remote buffer (remote buffer handle required).
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for resetting all message buffers:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_msgbuf_cfg msgbox_cfg;
+
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+ CYG_IO_SET_CONFIG_CAN_MSGBUF,
+ &msgbox_cfg, &len))
+{
+ // handle configuration error
+}
+</PROGRAMLISTING>
+</SECTION> <!-- can-msgbuf-cfg -->
+
+
+<SECTION>
+<TITLE>Remote frame response buffer configuration</TITLE>
+
+<PARA>
+The remote frame is a message frame which is transmitted to request a
+data frame. Some CAN hardware generates receive interrupts when a
+remote transmission request arrives. Other CAN hardware, i.e. the
+Motorola FlexCAN module, does not generate any receive
+interrupt. These CAN hardware chips like the FlexCAN module can be
+configured to transmit a data frame automatically in response to a
+remote frame. In order to support any kind of CAN hardware the eCos CAN
+driver provides a generic handling of remote transmission requests.
+</PARA>
+
+<PARA>
+The transmission of the data frame in response to a remote frame is
+completely handled by the CAN driver. If the hardware driver, like
+the driver for the FlexCAN module, supports hardware message buffers,
+then the response frame is automatically transmitted if a remote
+transmission request with a matching ID arrives. If a CAN hardware
+does not provide hardware support for sending data frames in response
+to a remote frame, then this need to be implemented in software by the
+hardware device driver.
+</PARA>
+
+<PARA>
+It is always possible to add remote response buffers. It does not
+matter if the driver is configured for reception of all CAN messages
+or if message filtering is used. As long as there are free message
+buffers available, it is possible to add remote response buffers.
+</PARA>
+
+<PARA>
+In order to respond to a remote frame, a remote frame response buffer
+need to be initialized before a data frame can be sent in response to
+a remote frame. This is achieved by by
+exchanging <type>cyg_can_remote_buf</type> data structures with the
+driver via the <function>cyg_io_set_config()</function> function using
+the config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once
+the buffer is initialized, the CAN data can be changed at any time by
+the application.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbuf_cfg_st
+{
+ cyg_can_msgbuf_cfg_id cfg_id; // configuration id
+ cyg_can_msgbuf_handle handle; // handle to message buffer
+ cyg_can_message msg; // CAN message - for configuration of buffer
+} cyg_can_remote_buf;
+</PROGRAMLISTING>
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+ <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with
+a message buffer (<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</varname> or
+<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</varname>).
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+ <listitem><para>
+If there is no buffer initialized for this data, the value of the handle field need to be set to
+<varname>CYGNUM_CAN_MSGBUF_INIT</varname>. After the call to <function>cyg_io_set_config()</function>
+the handle field contains a valid remote buffer handle ( >= 0) or the value
+<varname>CYGNUM_CAN_MSGBUF_NA</varname> ( < 0) if no free buffer is available.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_message</type> <varname>msg</varname></term>
+ <listitem><para>
+The CAN frame that should be transmitted in response to a remote frame.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for setting up a remote response buffer:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_remote_buf rtr_buf;
+
+// prepare the remote response buffer
+rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+rtr_buf.handle = CYGNUM_CAN_MSGBUF_INIT;
+rtr_buf.msg.id = 0x7FF;
+rtr_buf.msg.ext = CYGNUM_CAN_ID_STD;
+rtr_buf.msg.rtr = CYGNUM_CAN_FRAME_DATA;
+rtr_buf.msg.dlc = 1;
+rtr_buf.msg.data[0] = 0xAB;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+ CYG_IO_SET_CONFIG_CAN_MSGBUF,
+ &rtr_buf, &len))
+{
+ // handle configuration error
+}
+
+if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
+{
+ // no free message buffer available - handle this problem here
+}
+
+
+// change CAN data for a buffer that is already initialized
+rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE;
+rtr_buf.msg.data[0] = 0x11;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+ CYG_IO_SET_CONFIG_CAN_MSGBUF,
+ &rtr_buf, &len))
+{
+ // handle configuration error
+}
+</PROGRAMLISTING>
+</SECTION> <!-- can-rtrbuf-cfg -->
+
+
+<SECTION>
+<TITLE>Message filter configuration</TITLE>
+
+<PARA>
+If message filtering is done by hardware the number of received CAN
+messages decreases and so also the time for processing received CAN
+messages and the memory required for buffering received messages
+decreases. This saves valuable memory and processing time. The eCos
+CAN driver supports a generic way of adding message filters. By
+default the CAN driver is configured for reception of any kind of CAN
+standard and extended frames. As soon as a message filter is added,
+the CAN driver will only receive the CAN frames with the identifier of
+the CAN filter. By adding a number of message filters it is possible
+for the CAN hardware to receive an number of different CAN messages.
+</PARA>
+
+<PARA>
+Adding message filters is only possible if driver is not configured
+for reception of all available CAN messages. If the driver is
+configured for reception of all CAN messages then message buffers need
+to be reset before adding single message filters.
+</PARA>
+
+<PARA>
+In order to add a message filter, a message buffer need to be
+initialized. This is achieved by
+exchanging <type>cyg_can_filter</type> data structures with the driver
+via the <function>cyg_io_set_config()</function> function using the
+config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once the
+buffer is initialized, the CAN hardware can receive messages with the
+identifier of the filter.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbox_cfg_st
+{
+ cyg_can_msgbuf_cfg_id cfg_id;
+ cyg_can_msgbuf_handle handle;
+ cyg_can_message msg;
+} cyg_can_filter;
+</PROGRAMLISTING>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+ <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with
+a message buffer.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+ <listitem><para>
+After the call to <function>cyg_io_set_config()</function> the handle field contains a valid value
+( >= 0) or the value <varname>CYGNUM_CAN_MSGBUF_NA</varname> ( < 0) if no free buffer is available.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_can_message</type> <varname>msg</varname></term>
+ <listitem><para>
+The fields <structfield>id</structfield> and <structfield>ext</structfield> of the <structfield>msg</structfield>
+configure the type of message to receive by a certain message filter.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Before adding message filters the device should be stopped and after
+configuration it should be set into operational mode again.
+</PARA>
+
+<PARA>
+Example code for setting up a message filter:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_msgbuf_cfg msgbox_cfg;
+cyg_can_filter rx_filter;
+
+// reset all message buffers
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+ CYG_IO_SET_CONFIG_CAN_MSGBUF,
+ &msgbox_cfg, &len))
+{
+ // handle configuration error
+}
+
+// prepare the message filter
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+rx_filter.msg.id = 0x800;
+rx_filter.msg.ext = CYGNUM_CAN_ID_EXT;
+
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+ CYG_IO_SET_CONFIG_CAN_MSGBUF,
+ &rx_filter, &len))
+{
+ // handle configuration error;
+}
+else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+{
+ // no free message buffer available - handle this problem here
+}
+</PROGRAMLISTING>
+</SECTION> <!-- can-msgfilt-cfg -->
+
+
+<SECTION id="can-msgfilt-deact">
+<TITLE>Message filter deactivation</TITLE>
+
+<PARA>
+After startup of your device the CAN driver is configured for
+reception of all available CAN messages. If you change this
+configuration by adding single message filters then you can reset this
+default state with the configuration ID:
+</PARA>
+
+<PROGRAMLISTING>
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL
+</PROGRAMLISTING>
+
+<PARA>
+This message buffer configuration id will clear all message filters
+and remote buffers and prepares the CAN hardware for reception of any
+kind of CAN standard and extended frames. It is not necessary to reset
+the message buffer configuration before this configuration step is
+executed because this should be done by device driver.
+</PARA>
+
+<PARA>
+Example code for deactivation of message filtering:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_filter rx_filter;
+
+// now setup a RX all configuration
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+ CYG_IO_SET_CONFIG_CAN_MSGBUF,
+ &rx_filter, &len))
+{
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+}
+</PROGRAMLISTING>
+</SECTION> <!-- can-msgfilt-deact -->
+
+<SECTION id="can-event-callback">
+<TITLE>Configuring a callback on events</TITLE>
+
+<PARA>
+By default application cannot get information about an event arriving
+in the RX buffer until it calls
+the <function>cyg_io_read()</function>. Usually this leads applications
+to use accessory threads to wait for new CAN events.
+</PARA>
+
+<PARA>
+The CDL option <varname>CYGOPT_IO_CAN_SUPPORT_CALLBACK</varname>
+allows application to use a callback on event arrival. It is
+configured by passing a <structname>cyg_can_callback_cfg</structname>
+data structure to the driver via
+the <function>cyg_io_set_config()</function> function using the config
+key
+<varname>CYG_IO_SET_CONFIG_CAN_CALLBACK</varname>.
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_CALLBACK
+</PROGRAMLISTING>
+
+<PROGRAMLISTING>
+typedef void (*cyg_can_event_cb_t)(cyg_uint16, CYG_ADDRWORD);
+
+typedef struct cyg_can_callback_cfg_st
+{
+ cyg_can_event_cb_t callback_func; // callback function
+ cyg_uint16 flag_mask; // flags mask
+ CYG_ADDRWORD data; // data passed to callback
+} cyg_can_callback_cfg;
+</PROGRAMLISTING>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cyg_can_event_cb_t</type> <varname>callback_func</varname></term>
+ <listitem><para>
+Pointer to the callback function. The function will be called from DSR context so
+you should be careful to only call API functions that are safe in DSR
+context. The First parameter is a combination of event flags for events that have
+occurred. Second parameter is a user defined data pointer or value.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>CYG_ADDRWORD</type> <varname>data</varname></term>
+ <listitem><para>
+Additional user data that will be passed to callback function as a second parameter.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cyg_uint16</type> <varname>flag_mask</varname></term>
+ <listitem><para>
+Should be set with a combination
+of <varname>CYGNUM_CAN_EVENT_*</varname> flags. If one of these
+events happens, the callback function will be called, with the
+actually event flags passed as a parameter. To disable the callback
+function from being called set <varname>flag_mask</varname> to 0.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+</SECTION> <!-- can-event-callback -->
+
+</SECTION>
+</CHAPTER>
+
+<CHAPTER id="io-can-configuration">
+<TITLE>Configuration</TITLE>
+
+<PARA>
+The CAN subsystem has a number of configuration options.
+</PARA>
+
+<variablelist>
+ <varlistentry>
+ <term><type>cdl_interface CYGINT_IO_CAN_TIMESTAMP</type></term>
+ <listitem><para>
+A hardware device driver that supports timestamps should implement this interface.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_TIMESTAMP</type></term>
+ <listitem><para>
+If the CAN hardware driver supports some kind of timestamps then this option enables
+propagation of timestamps to higher layers. This may add some extra code to hardware
+drivers.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT</type></term>
+ <listitem>
+<para> This option enables support for TX
+events. If a CAN message is transmitted successfully a TX event will
+be inserted into the receive event queue and propagated to higher
+layers. If this option is enabled the RX event queue will be filled
+faster.
+</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</type></term>
+ <listitem>
+<para>
+This option enables extra code in the generic CAN driver which allows
+clients to switch read() and write() call semantics from blocking to
+non-blocking.
+</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_CALLBACK</type></term>
+ <listitem>
+<para>
+This option enables extra code in the generic CAN driver which allows
+an application to register a callback for events. The callback function
+is called from DSR context so you should be careful to only call API
+functions that are safe in DSR context.
+</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_READ</type></term>
+ <listitem><para>
+The initial timeout value in clock ticks for <FUNCTION>cyg_io_read()</FUNCTION> calls.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_WRITE</type></term>
+ <listitem><para> The initial timeout value in clock ticks
+for <FUNCTION>cyg_io_write()</FUNCTION> calls.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+</CHAPTER>
+
+
+<CHAPTER id="io-can-device-drivers">
+<TITLE>Writing a CAN hardware device driver</TITLE>
+
+<PARA>
+A CAN driver is nothing more than a named entity that supports the
+basic I/O functions - read, write, get config, and set config. The
+device driver uses and manages interrupts from the device. While the
+interface is generic and device driver independent, the actual driver
+implementation is completely up to the device driver designer.
+</PARA>
+
+<PARA>
+That said, the reason for using a device driver is to provide access
+to a CAN device from application code in as general purpose a fashion
+as reasonable. Most driver writers are also concerned with making this
+access as simple as possible while being as efficient as possible.
+</PARA>
+
+<PARA>
+Like other device drivers the CAN device driver is concerned with the
+movement of information - the CAN messages. In order to make the most
+efficient use of system resources, interrupts are used. This will
+allow other application processing to take place while the data
+transfers are under way, with interrupts used to indicate when various
+events have occurred. For example, a CAN device typically generates an
+interrupt after a CAN message has been sent or a CAN message has been
+received by a CAN hardware message buffer. It makes sense to allow
+further application processing while the data is being sent since this
+can take quite a long time. The interrupt can be used to allow the
+driver to send a CAN message as soon as the current one is complete,
+without any active participation by the application code.
+</PARA>
+
+<PARA>
+The main building blocks for CAN device drivers are found in the
+include files
+<filename><cyg/io/devtab.h></filename> and <filename><cyg/io/can.h></filename>
+</PARA>
+
+<PARA>
+Like many other device drivers in eCos, CAN device drivers are described by a device
+table entry, using the <type>cyg_devtab_entry_t</type> type. The entry should be created using
+the <varname>DEVTAB_ENTRY()</varname> macro.
+</PARA>
+
+
+<SECTION id="io-can-how-to-write-interface-driver">
+<TITLE>How to Write a CAN Hardware Interface Driver</TITLE>
+
+<PARA>
+The standard CAN driver supplied with eCos is structured as a hardware
+independent portion and a hardware dependent interface module. To add
+support for a new CAN device, the user should be able to use the
+existing hardware independent portion and just add their own interface
+driver which handles the details of the actual device. The user should
+have no need to change the hardware independent portion.
+</PARA>
+
+<PARA>
+The interfaces used by the CAN driver and CAN implementation modules
+are contained in the file <filename><cyg/io/can.h></filename>.
+</PARA>
+
+<SECTION>
+<title>DevTab Entry</TITLE>
+
+<PARA>
+The interface module contains the devtab entry (or entries if a single
+module supports more than one interface). This entry should have the
+form:
+</PARA>
+
+<PROGRAMLISTING>
+DEVTAB_ENTRY(<<module_name>>,
+ <<device_name>>,
+ 0,
+ &can_devio,
+ <<module_init>>,
+ <<module_lookup>>,
+ &<<can_channel>>
+ );
+</PROGRAMLISTING>
+
+<variablelist>
+<title>Arguments</title>
+ <varlistentry>
+ <term><parameter>module_name</parameter></term>
+ <listitem><para>The "C" label for this devtab entry</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>device_name</parameter></term>
+ <listitem><para>The "C" string for the
+ device. E.g. <filename>/dev/can0</filename>.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>can_devio</parameter></term>
+ <listitem><para>The table of I/O functions. This set is defined in
+ the hardware independent CAN driver and should be used.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>module_init</parameter></term>
+ <listitem><para>The hardware module initialization function.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>module_lookup</parameter></term>
+ <listitem><para>The device lookup function. This function
+ typically sets up the CAN device for actual use, turning on
+ interrupts, configuring the message buffers, etc.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>can_channel</parameter></term>
+ <listitem><para>This table (defined below) contains the interface
+ between the interface module and the CAN driver proper.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Example devtab entry for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+DEVTAB_ENTRY(flexcan_devtab,
+ CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ flexcan_init,
+ flexcan_lookup, // CAN driver may need initializing
+ &flexcan_can0_chan
+ );
+</PROGRAMLISTING>
+</SECTION>
+
+
+<SECTION>
+<title>CAN Channel Structure</TITLE>
+
+<PARA>
+Each CAN device must have a “CAN channel”.
+This is a set of data which describes all operations on the device.
+It also contains buffers, etc. The CAN channel is created by the macro:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,
+ out_buf, out_buflen,
+ in_buf, in_buflen)
+</PROGRAMLISTING>
+
+<variablelist>
+ <title>Arguments</title>
+ <varlistentry>
+ <term><parameter>l</parameter></term>
+ <listitem><para>The "C" label for this structure.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>funs</parameter></term>
+ <listitem><para>The set of interface functions (see below).</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>dev_priv</structfield></term>
+ <listitem><para>A placeholder for any device specific data for
+ this channel.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>baud</structfield></term>
+ <listitem><para>The initial baud rate value
+ (<type>cyg_can_baud_rate_t</type>).</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>out_buf</structfield></term>
+ <listitem><para>Pointer to the output buffer</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>out_buflen</structfield></term>
+ <listitem><para>The length of the output buffer.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>in_buf</structfield></term>
+ <listitem><para>pointer to the input buffer.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>in_buflen</structfield></term>
+ <listitem><para>The length of the input buffer.</PARA></listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Example CAN channel implementation for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(
+ flexcan_can0_chan,
+ flexcan_lowlevel_funs,
+ flexcan_can0_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_KBAUD),
+ flexcan_can0_txbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_TX,
+ flexcan_can0_rxbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_RX
+);
+</PROGRAMLISTING>
+
+<PARA>
+The interface from the hardware independent driver into the hardware
+interface module is contained in the <structfield>funs</structfield>
+table. This is defined by the macro:
+</PARA>
+</SECTION>
+
+<SECTION>
+<TITLE>CAN Lowlevel Functions Structure</TITLE>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(l, putmsg, getevent, get_config, set_config, start_xmit, stop_xmit)
+</PROGRAMLISTING>
+
+<variablelist>
+ <title>Arguments</title>
+ <varlistentry>
+ <term><structfield>l</structfield></term>
+ <listitem><para>The "C" label for this structure.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>putmsg</structfield></term>
+ <listitem>
+ <para><literal>
+ bool (*putmsg)(can_channel *priv, cyg_can_message *pmsg, void *pdata)
+ </literal></para>
+ <para>
+ This function sends one CAN message to the interface. It should
+ return <literal>true</literal> if the message is actually
+ consumed. It should return <literal>false</literal> if there is
+ no space in the interface
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>getevent</structfield></term>
+ <listitem>
+ <para><literal>
+ bool (*getevent)(can_channel *priv, cyg_can_event *pevent, void *pdata)
+ </literal></para>
+ <para>
+ This function fetches one event from the interface.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>get_config</structfield></term>
+ <listitem>
+ <para><literal>
+ Cyg_ErrNo (*get_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+ </literal></para>
+ <para>
+ This function is used to query the configuration of a CAN channel.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>set_config</structfield></term>
+ <listitem>
+ <para><literal>
+ Cyg_ErrNo (*set_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+ </literal></para>
+ <para>
+ This function is used to change configuration of a CAN channel.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>start_xmit</parameter></term>
+ <listitem><para><literal>void (*start_xmit)(can_channel *priv)</literal></para>
+ <para>
+ Enable the transmit channel and turn on transmit interrupts.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>stop_xmit</parameter></term>
+ <listitem>
+ <para><literal>void (*stop_xmit)(can_channel *priv)</literal></para>
+ <para>Disable the transmit channel and turn transmit interrupts off.</PARA>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<PARA>
+Example implementation of low level function structure for Motorola FlexCAN
+device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(flexcan_lowlevel_funs,
+ flexcan_putmsg,
+ flexcan_getevent,
+ flexcan_get_config,
+ flexcan_set_config,
+ flexcan_start_xmit,
+ flexcan_stop_xmit
+ );
+</PROGRAMLISTING>
+</SECTION>
+
+<SECTION>
+<TITLE>Callbacks</TITLE>
+
+<PARA>
+The device interface module can execute functions in the
+hardware independent driver via <literal>chan->callbacks</literal>.
+These functions are available:
+</PARA>
+
+<PROGRAMLISTING>
+void (*can_init)(can_channel *chan)
+</PROGRAMLISTING>
+
+<PARA>This function is used to initialize the CAN channel.</PARA>
+
+<PROGRAMLISTING>
+void (*xmt_msg)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function would be called from an interrupt handler after a
+transmit interrupt indicating that additional messages may be
+sent. The upper driver will call the <function>putmsg</function>
+function as appropriate to send more data to the device.
+</PARA>
+
+<PROGRAMLISTING>
+void (*rcv_event)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to tell the driver that a message has arrived
+at the interface or that an event has occurred. This function is typically
+called from the interrupt handler.
+</PARA>
+</SECTION><!-- Callbacks -->
+
+</SECTION><!-- id="io-can-how-to-write-interface-driver" -->
+</CHAPTER>
+
+</PART>
--- /dev/null
+//==========================================================================
+//
+// can_filter.c
+//
+// CAN message filter test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-03-21
+// Description: CAN hardware filter test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined (CYGOPT_IO_CAN_STD_CAN_ID)
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+cyg_io_handle_t hCAN0;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_uint16 i;
+ cyg_can_hdi hdi;
+ cyg_can_msgbuf_info msgbox_info;
+ cyg_can_msgbuf_cfg msgbox_cfg;
+
+
+ len = sizeof(hdi);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // Normally the CAN modul should support message filters. So the
+ // FULLCAN flag should be set - if it is not, we treat this as an error
+ //
+ if (!(hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN))
+ {
+ CYG_TEST_FAIL_FINISH("/dev/can0 does not support message buffers");
+ }
+
+
+ //
+ // Now reset message buffer configuration - this is mandatory bevore starting
+ // message buffer runtime configuration
+ //
+ msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+ len = sizeof(msgbox_cfg);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0");
+ }
+
+ //
+ // Now query number of available and free message boxes
+ //
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // if there are no free message boxes available then this is a failure
+ //
+ if (!msgbox_info.free)
+ {
+ CYG_TEST_FAIL_FINISH("No free message boxes available for /dev/can0");
+ }
+
+ //
+ // We setup as many standard CAN message filters as there are free
+ // message buffers available.
+ //
+ for (i = 0; i < msgbox_info.free; ++i)
+ {
+ cyg_can_filter rx_filter;
+
+ rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
+ rx_filter.msg.id = i;
+ rx_filter.msg.ext = CYGNUM_CAN_ID_STD;
+
+ len = sizeof(rx_filter);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+ else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+ {
+ CYG_TEST_FAIL_FINISH("Error setting up message filter for /dev/can0");
+ }
+ }
+
+
+ diag_printf("\n\nNow try to send CAN messages. The device should only\n"
+ "receive messages identifiers in the range of 0x00 to 0x%X.\n"
+ "As soon as a standard message with ID 0x000 arrives, all\n"
+ "message filters will be cleared\n\n", (msgbox_info.free - 1));
+
+ //
+ // Now receive messages until a message arrives with largest ID of all
+ // available message filters
+ //
+ rx_event.msg.id = 1;
+ while(rx_event.msg.id != 0)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+ else if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ } // if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ rx_event.msg.id = 1;
+ }
+ } // while(1)
+
+
+ //
+ // Now enable reception of all available CAN messages
+ //
+ cyg_can_filter rx_filter;
+ rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
+ len = sizeof(rx_filter);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF , &rx_filter, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+
+ diag_printf("\n\nAll message filters have been cleared an now the device\n"
+ "will receive any available CAN message identifiers.\n"
+ "Send a CAN message with ID 0x100 to stop this test.\n\n");
+
+ //
+ // Now receive messages until a message arrives with largest ID of all
+ // available message filters
+ //
+ rx_event.msg.id = 1;
+ while(rx_event.msg.id != 0x100)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+ else if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ } // if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ } // while(1)
+
+ CYG_TEST_PASS_FINISH("can_filter test OK");
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+
+ //
+ // create the two threads which access the CAN device driver
+ // a reader thread with a higher priority and a writer thread
+ // with a lower priority
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_IO_CAN_STD_CAN_ID
+#define N_A_MSG "Needs support for standard CAN identifiers"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_filter.c
--- /dev/null
+//==========================================================================
+//
+// can_hdi.c
+//
+// CAN hardware description information test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-03-22
+// Description: CAN hardware desciption information test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+cyg_io_handle_t hCAN0;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_hdi hdi;
+ cyg_can_msgbuf_info msgbox_info;
+
+
+ //
+ // Query information about hardware of CAN controller
+ //
+ len = sizeof(hdi);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // Check type of CAN controller - type of supported CAN frames
+ //
+ diag_printf("\n\nSupported message formats:\n");
+ if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_STD)
+ {
+ diag_printf(" Standard CAN (2.0A): yes\n");
+ diag_printf(" Extended CAN (2.0B): no\n");
+ }
+ else if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE)
+ {
+ diag_printf(" Standard CAN (2.0A): yes\n");
+ diag_printf(" Extended CAN (2.0B): passive\n");
+ }
+ else if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE)
+ {
+ diag_printf(" Standard CAN (2.0A): yes\n");
+ diag_printf(" Extended CAN (2.0B): yes\n");
+ }
+
+ //
+ // Check if this is a FullCAN controller
+ //
+ diag_printf("\nController type: ");
+ if (hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN)
+ {
+ diag_printf("FullCAN\n");
+ //
+ // FullCAN means the controller supports a number of message buffers.
+ // Now query number of available and free message buffers
+ //
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ diag_printf(" Message buffers: %d\n", msgbox_info.count);
+ diag_printf(" Message buffers free: %d\n", msgbox_info.free);
+ }
+ else
+ {
+ diag_printf("BasicCAN\n");
+ }
+
+ //
+ // Check if automatic baudrate detection is supported
+ //
+ if (hdi.support_flags & CYGNUM_CAN_HDI_AUTBAUD)
+ {
+ diag_printf("\nAutomatic baudrate detection: supported\n");
+ }
+
+ //
+ // Check if driver supports timestamps
+ //
+ if (hdi.support_flags & CYGNUM_CAN_HDI_TIMESTAMP)
+ {
+ diag_printf("Timestamps: supported\n");
+ }
+
+ diag_printf("\n\n");
+ CYG_TEST_PASS_FINISH("can_hdi test OK");
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+
+ //
+ // create the two threads which access the CAN device driver
+ // a reader thread with a higher priority and a writer thread
+ // with a lower priority
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_hdi.c
--- /dev/null
+//==========================================================================
+//
+// can_load.c
+//
+// CAN load test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-14
+// Description: CAN load test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_STD_CAN_ID) && defined(CYGOPT_IO_CAN_EXT_CAN_ID)
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+cyg_thread_entry_t can1_thread;
+thread_data_t can1_thread_data;
+
+cyg_io_handle_t hCAN0;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_can_timeout_info_t timeouts;
+
+#if defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS)
+ //
+ // setup large timeout values because we do not need timeouts here
+ //
+ timeouts.rx_timeout = 100000;
+ timeouts.tx_timeout = 100000;
+
+ len = sizeof(timeouts);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_TIMEOUT ,&timeouts, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+#endif // defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS)
+
+ //
+ // This thread simply receives all CAN events and prints the event flags and the
+ // CAN message if it was a TX or RX event. You can use this test in order to check
+ // when a RX overrun occurs
+ //
+ while (1)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+
+ if ((rx_event.flags & CYGNUM_CAN_EVENT_RX) || (rx_event.flags & CYGNUM_CAN_EVENT_TX))
+ {
+ print_can_msg(&rx_event.msg, "");
+ }
+ }
+ }
+}
+
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can1_thread(cyg_addrword_t data)
+{
+ cyg_uint16 i = 0;
+ cyg_uint32 len;
+ cyg_can_message tx_msg =
+ {
+ 0x000, // CAN identifier
+ data :
+ {
+ {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 } // 8 data bytes
+ },
+ CYGNUM_CAN_ID_STD, // standard frame
+ CYGNUM_CAN_FRAME_DATA, // data frame
+ 8, // data length code
+ };
+
+ //
+ // This thread simply sends CAN messages. It increments the ID for each new CAN messsage
+ // and sends a remote frame after seven data frames. In the first byte of each data frame
+ // the number (0 - 7) of the data frame is stored and the length of the data frame grows
+ // from 1 - 8 data bytes.
+ //
+ // The received pattern should look like this way:
+ // ID Length Data
+ // ----------------------------------------------
+ // 000 1 00
+ // 001 2 01 F1
+ // 002 3 02 F1 F2
+ // 003 4 03 F1 F2 F3
+ // 004 5 04 F1 F2 F3 F4
+ // 005 6 05 F1 F2 F3 F4 F5
+ // 006 7 06 F1 F2 F3 F4 F5 F6
+ // 007 8 Remote Request
+ // 008 1 00
+ // 009 2 01 F1
+ // 00A 3 02 F1 F2
+ // ...
+ //
+ while (1)
+ {
+ tx_msg.id = i;
+ tx_msg.dlc = (i % 8) + 1;
+ tx_msg.data.bytes[0] = (i % 8);
+ i = (i + 1) % 0x7FF;
+
+ //
+ // the 6th frame is a remote frame
+ //
+ if ((i % 8) == 6)
+ {
+ tx_msg.rtr = CYGNUM_CAN_FRAME_RTR;
+ tx_msg.ext = CYGNUM_CAN_ID_STD;
+ }
+ //
+ // the 7th frame is a extended frame
+ //
+ else if ((i % 8) == 7)
+ {
+ tx_msg.ext = CYGNUM_CAN_ID_EXT;
+ tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ }
+ //
+ // the 8th frame is a extended remote frame
+ //
+ else if (!(i % 8))
+ {
+ tx_msg.ext = CYGNUM_CAN_ID_EXT;
+ tx_msg.rtr = CYGNUM_CAN_FRAME_RTR;
+ }
+ //
+ // all other frames are standard data frames
+ //
+ else
+ {
+ tx_msg.ext = CYGNUM_CAN_ID_STD;
+ tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ }
+
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+
+ cyg_thread_delay(50);
+ } // while (1)
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // create the two threads which access the CAN device driver
+ // a reader thread with a higher priority and a writer thread
+ // with a lower priority
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_create(5, can1_thread,
+ (cyg_addrword_t) can0_thread_data.hdl,
+ "can1_thread",
+ (void *) can1_thread_data.stack,
+ 1024 * sizeof(long),
+ &can1_thread_data.hdl,
+ &can1_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+ cyg_thread_resume(can1_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // defined(CYGOPT_IO_CAN_STD_CAN_ID) && defined(CYGOPT_IO_CAN_EXT_CAN_ID)
+#define N_A_MSG "Needs support for standard and extended CAN identifiers"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_load.c
--- /dev/null
+//==========================================================================
+//
+// can_remote.c
+//
+// CAN remote response buffer test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-14
+// Description: CAN load test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_RUNTIME_MBOX_CFG)
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_REMOTE_BUF)
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN0;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Main thread
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_can_remote_buf rtr_buf;
+ cyg_can_filter rx_filter;
+ cyg_can_msgbuf_info msgbox_info;
+ cyg_can_msgbuf_cfg msgbox_cfg;
+
+ //
+ // We would like to setup 2 remote buffers - check if we have enough
+ // free message buffers
+ //
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+ else
+ {
+ diag_printf("\n\n\nMessage boxes available: %d free: %d\n",
+ msgbox_info.count, msgbox_info.free);
+ }
+
+ //
+ // We have not enougth free message buffers, so we clear all message buffers now
+ // and try again
+ //
+ if (msgbox_info.free < 2)
+ {
+ msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+ len = sizeof(msgbox_cfg);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF, &msgbox_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error clearing message buffers of /dev/can0");
+ }
+
+ //
+ // Now query number of free message boxes again. We need 3 free message boxes.
+ // 2 message boxes for setup of remote response buffers and 1 message box for
+ // setup of receive message box for CAN identifier 0x100
+ //
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+ else
+ {
+ diag_printf("Message boxes available: %d free: %d\n",
+ msgbox_info.count, msgbox_info.free);
+ }
+
+ if (msgbox_info.free < 3)
+ {
+ CYG_TEST_FAIL_FINISH("Not enough free message buffers available for /dev/can0");
+ }
+ else
+ {
+ rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
+ CYG_CAN_MSG_SET_STD_ID(rx_filter.msg, 0x100);
+
+ len = sizeof(rx_filter);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error adding rx filter for CAN ID 0x100 for /dev/can0");
+ }
+ } // if (msgbox_info.free < 3)
+ } // if (msgbox_info.free < 2)
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ //
+ // Setup the first remote response buffer for resception of standard
+ // remote frames
+ //
+ rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+ CYG_CAN_MSG_SET_PARAM(rtr_buf.msg, 0x7FF, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA);
+ CYG_CAN_MSG_SET_DATA(rtr_buf.msg, 0, 0xAB);
+
+ len = sizeof(rtr_buf);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+#endif
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_can_remote_buf rtr_buf2;
+ //
+ // setup the second remote response buffer for reception of extended
+ // remote frames
+ //
+ rtr_buf2.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+ CYG_CAN_MSG_SET_PARAM(rtr_buf2.msg, 0x800, CYGNUM_CAN_ID_EXT, 4, CYGNUM_CAN_FRAME_DATA);
+ CYG_CAN_MSG_SET_DATA(rtr_buf2.msg, 0, 0xCD);
+
+ len = sizeof(rtr_buf2);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf2, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
+ {
+ CYG_TEST_FAIL_FINISH("No free message buffer available for /dev/can0");
+ }
+#endif
+
+ diag_printf("\nTest of CAN remote response buffer configuration\n"
+ "If a CAN node sends a remote request with ID 0x7FF (std. ID)\n"
+ "or 0x800 (ext. ID) then the CAN driver should respond with\n"
+ "data frames.\n\n");
+ diag_printf("!!! This test can be stopped by sending a data frame\n"
+ "with ID 0x100 !!!\n\n");
+
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+ else
+ {
+ diag_printf("Message boxes available: %d free: %d\n",
+ msgbox_info.count, msgbox_info.free);
+ }
+
+ while (1)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ if (0x100 == rx_event.msg.id)
+ {
+ CYG_TEST_PASS_FINISH("can_remote test OK");
+ }
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ }
+ }
+ }
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_IO_CAN_REMOTE_BUF
+#define N_A_MSG "Needs support for CAN remote response buffers"
+#endif
+
+#else // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+#define N_A_MSG "Needs support for CAN message buffer runtime configuration"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_remote.c
--- /dev/null
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
--- /dev/null
+//==========================================================================
+//
+// can_tx.c
+//
+// Simple CAN TX test
+//
+//==========================================================================
+//####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): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-01-08
+// Description: Simple write test of CAN driver
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN0;
+ cyg_uint32 i;
+ cyg_uint32 len;
+ CYG_CAN_MSG_INIT(tx_msg, 0x001, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA);
+
+ //
+ // Open device and check return value
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ //
+ // Now send 1000 messages with standard identifier.
+ // Each message contains the message number in its identifier
+ // and in the first data byte
+ //
+ for (i = 0; i < 1000; ++i)
+ {
+ CYG_CAN_MSG_SET_STD_ID(tx_msg, i);
+ CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+ len = sizeof(tx_msg);
+
+ //
+ // Each message with an odd identifier should be a remote request message
+ //
+ if (i % 2)
+ {
+ CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_RTR);
+ }
+ else
+ {
+ CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_DATA);
+ }
+
+ //
+ // Sending CAN messages is blocking so the thread waits until there is
+ // space in the tx queue
+ //
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+ }
+#endif
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ //
+ // Now send 1000 messages with extended identifier.
+ // Each message contains the message number in its identifier
+ // and in the first data byte
+ //
+ for (i = 0; i < 1000; ++i)
+ {
+ CYG_CAN_MSG_SET_EXT_ID(tx_msg, i + 0x800);
+ CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+ CYG_CAN_MSG_SET_DATA_LEN(tx_msg, 8);
+ len = sizeof(tx_msg);
+
+ //
+ // Each message with an odd identifier should be a remote request message
+ //
+ if (i % 2)
+ {
+ CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_RTR);
+ }
+ else
+ {
+ CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_DATA);
+ }
+
+ //
+ // Sending CAN messages is blocking so the thread waits until there is
+ // space in the tx queue
+ //
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+ }
+#endif
+
+
+ CYG_TEST_PASS_FINISH("CAN TX test OK");
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the threads that access the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_tx.c
--- /dev/null
+#ifndef CYGONCE_FILEIO_FNMATCH_H
+#define CYGONCE_FILEIO_FNMATCH_H
+
+//==========================================================================
+//
+// fnmatch.h
+//
+//==========================================================================
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from NetBSD, and are
+// covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+
+/* $NetBSD: fnmatch.h,v 1.12 2005/02/03 04:39:32 perry Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
+ */
+
+#include <cyg/infra/cyg_type.h> // common type definitions and support
+
+#define FNM_NOMATCH (1) /* Match failed. */
+#define FNM_NOSYS (2) /* Function not implemented. */
+
+#define FNM_NOESCAPE (0x01) /* Disable backslash escaping. */
+#define FNM_PATHNAME (0x02) /* Slash must be matched by slash. */
+#define FNM_PERIOD (0x04) /* Period must be matched by period. */
+#define FNM_CASEFOLD (0x08) /* Pattern is matched case-insensitive */
+#define FNM_LEADING_DIR (0x10) /* Ignore /<tail> after Imatch. */
+
+__externC int
+fnmatch(const char *, const char *, int);
+
+#endif /* !CYGONCE_FILEIO_FNMATCH_H */
--- /dev/null
+/* $NetBSD: fnmatch.c,v 1.21 2005/12/24 21:11:16 perry Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <ctype.h>
+#include <fnmatch.h>
+#include <string.h>
+
+#define EOS '\0'
+
+static const char *rangematch(const char *, int, int);
+
+static inline int
+foldcase(int ch, int flags)
+{
+
+ if ((flags & FNM_CASEFOLD) != 0 && isupper(ch))
+ return (tolower(ch));
+ return (ch);
+}
+
+#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags))
+
+int
+fnmatch(const char *pattern, const char *string, int flags)
+{
+ const char *stringstart;
+ char c, test;
+
+ CYG_ASSERT(pattern != NULL, "pattern NULL pointer!");
+ CYG_ASSERT(string != NULL, "string NULL pointer!");
+
+ for (stringstart = string;;)
+ switch (c = FOLDCASE(*pattern++, flags)) {
+ case EOS:
+ if ((flags & FNM_LEADING_DIR) && *string == '/')
+ return (0);
+ return (*string == EOS ? 0 : FNM_NOMATCH);
+ case '?':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && (flags & FNM_PATHNAME))
+ return (FNM_NOMATCH);
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '*':
+ c = FOLDCASE(*pattern, flags);
+ /* Collapse multiple stars. */
+ while (c == '*')
+ c = FOLDCASE(*++pattern, flags);
+
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+
+ /* Optimize for pattern with * at end or before /. */
+ if (c == EOS) {
+ if (flags & FNM_PATHNAME)
+ return ((flags & FNM_LEADING_DIR) ||
+ strchr(string, '/') == NULL ?
+ 0 : FNM_NOMATCH);
+ else
+ return (0);
+ } else if (c == '/' && flags & FNM_PATHNAME) {
+ if ((string = strchr(string, '/')) == NULL)
+ return (FNM_NOMATCH);
+ break;
+ }
+
+ /* General case, use recursion. */
+ while ((test = FOLDCASE(*string, flags)) != EOS) {
+ if (!fnmatch(pattern, string,
+ flags & ~FNM_PERIOD))
+ return (0);
+ if (test == '/' && flags & FNM_PATHNAME)
+ break;
+ ++string;
+ }
+ return (FNM_NOMATCH);
+ case '[':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && flags & FNM_PATHNAME)
+ return (FNM_NOMATCH);
+ if ((pattern =
+ rangematch(pattern, FOLDCASE(*string, flags),
+ flags)) == NULL)
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '\\':
+ if (!(flags & FNM_NOESCAPE)) {
+ if ((c = FOLDCASE(*pattern++, flags)) == EOS) {
+ c = '\\';
+ --pattern;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ if (c != FOLDCASE(*string++, flags))
+ return (FNM_NOMATCH);
+ break;
+ }
+ /* NOTREACHED */
+}
+
+static const char *
+rangematch(const char *pattern, int test, int flags)
+{
+ int negate, ok;
+ char c, c2;
+
+ CYG_ASSERT(pattern != NULL, "pattern NULL pointer!");
+
+ /*
+ * A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). This implementation treats it like '!', for
+ * consistency with the regular expression syntax.
+ * J.T. Conklin (conklin@ngai.kaleida.com)
+ */
+ if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
+ ++pattern;
+
+ for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) {
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = FOLDCASE(*pattern++, flags);
+ if (c == EOS)
+ return (NULL);
+ if (*pattern == '-'
+ && (c2 = FOLDCASE(*(pattern+1), flags)) != EOS &&
+ c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ c2 = FOLDCASE(*pattern++, flags);
+ if (c2 == EOS)
+ return (NULL);
+ if (c <= test && test <= c2)
+ ok = 1;
+ } else if (c == test)
+ ok = 1;
+ }
+ return (ok == negate ? NULL : pattern);
+}
--- /dev/null
+//==========================================================================
+//
+// fnmatch.c
+//
+// Test fnmatch function
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2007 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): asl
+// Contributors: asl
+// Date: 2007-01-27
+// Purpose: Test fnmatch function.
+// Description: //
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_fileio.h>
+
+#ifndef CYGPKG_FILEIO_FNMATCH
+# define NA_MSG "FNMATCH function not available"
+#endif
+
+#include <cyg/infra/testcase.h>
+
+#ifndef NA_MSG
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <fnmatch.h>
+
+//==========================================================================
+// main
+
+int main( int argc, char **argv )
+{
+ int i;
+ cyg_bool failed = false;
+
+ struct
+ {
+ const int result;
+ const int flags;
+ const char * string;
+ const char * pattern;
+ } test_case[] = {
+ { 0, 0, "abc", "abc" }, /* 0 */
+ { FNM_NOMATCH, 0, "cba", "abc" },
+ { 0, 0, "abc", "a*" },
+ { FNM_NOMATCH, 0, "abc", "b*" },
+ { 0, 0, "abc", "[abc]*" },
+ { FNM_NOMATCH, 0, "abc", "[def]*" },
+ { FNM_NOMATCH, 0, "abc", "*[def]*" },
+ { 0, 0, "a/b", "a/b" },
+ { FNM_NOMATCH, 0, "a/b", "a/a" },
+ { FNM_NOMATCH, 0, "a/b", "b/b" },
+
+ { 0, 0, "a b", "a\\ b"}, /* 10 */
+ { FNM_NOMATCH, FNM_NOESCAPE, "a b", "a\\ b"},
+
+ { 0, 0, "a/b", "a*b" },
+ { 0, 0, "a/b", "a?b" },
+ { 0, 0, "a/b", "a[/]b" },
+ { FNM_NOMATCH, FNM_PATHNAME, "a/b", "a*b"},
+ { FNM_NOMATCH, FNM_PATHNAME, "a/b", "a?b"},
+ { FNM_NOMATCH, FNM_PATHNAME, "a/b", "a[/]b"},
+ { 0, FNM_PATHNAME, "a/b", "a/b"},
+
+ { 0, 0, ".abc", "?abc" },
+ { 0, 0, ".abc", "*abc" }, /* 20 */
+ { 0, 0, ".abc", "[.]abc" },
+ { 0, 0, ".abc", ".abc" },
+ { FNM_NOMATCH, FNM_PERIOD, ".abc", "?abc" },
+ { FNM_NOMATCH, FNM_PERIOD, ".abc", "*abc" },
+ { 0, FNM_PERIOD, ".abc", "[.]abc" },
+ { 0, FNM_PERIOD, ".abc", ".abc" },
+
+ { 0, 0, "/.abc", "/?abc" },
+ { 0, 0, "/.abc", "/*abc" },
+ { 0, 0, "/.abc", "/[.]abc" },
+ { 0, 0, "/.abc", "/.abc" }, /* 30 */
+ { FNM_NOMATCH, FNM_PERIOD|FNM_PATHNAME, "/.abc", "/?abc" },
+ { FNM_NOMATCH, FNM_PERIOD|FNM_PATHNAME, "/.abc", "/*abc" },
+ { 0, FNM_PERIOD|FNM_PATHNAME, "/.abc", "/[.]abc" },
+ { 0, FNM_PERIOD|FNM_PATHNAME, "/.abc", "/.abc" }
+ };
+
+ for (i=0; i < CYG_NELEM(test_case); i++) {
+ if (test_case[i].result !=
+ fnmatch(test_case[i].pattern,
+ test_case[i].string,
+ test_case[i].flags)) {
+ diag_printf("<INFO>: test number %d failed\n", i);
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ CYG_TEST_FAIL_FINISH("fnmatch failed");
+ } else {
+ CYG_TEST_PASS_FINISH("fnmatch passed");
+ }
+}
+
+#else
+
+//==========================================================================
+// main
+
+int main( int argc, char **argv )
+{
+ CYG_TEST_INIT();
+
+ CYG_TEST_NA(NA_MSG);
+}
+
+#endif
+
+// -------------------------------------------------------------------------
+// EOF fnmatch.c
--- /dev/null
+2008-07-12 Frank Pagliughi <fpagliughi@mindspring.com>
+
+ * Generic USB Serial package created.
+ Some files were rearranged during the import and the Documentation
+ written Andrew Lunn.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 FSF
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# usbs_serial.cdl
+#
+# USB slave-side serial package.
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+##
+## 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.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+# Contributors:
+# Date: 2008-06-04
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_IO_USB_SLAVE_SERIAL {
+ display "USB slave serial support"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_IO_USB_SLAVE
+ requires { CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS >= 1 }
+ requires { CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS >= 1 }
+ compile usbs_serial.c
+ implements CYGINT_IO_USB_SLAVE_CLIENTS
+# doc ref/io-usb-slave-eth.html
+
+ description "
+ The USB slave serial package supports the development of USB
+ peripherals which mimic a serial connection to the host
+ machine. Such a device creates a relatively simple upgrade to
+ USB from a legacy serial connection, especially from the
+ perspective of the host software and device drivers."
+
+ cdl_option CYGDAT_IO_USB_SLAVE_CLASS_TYPE {
+ display "Serial USB Class"
+ flavor data
+ default_value { "ACM" }
+ legal_values { "ACM" "generic" }
+ description "
+ The USB serial module can enumerate as either a generic
+ (vendor-specific) usb device or a communications class ACM
+ device. The generic device requires a pair of Bulk
+ endpoints, while the ACM device also requires an Interrupt
+ IN endpoint. For a Windows host, the ACM configuration is
+ required to use the standard 'usbser.sys' device driver,
+ but for a Linux host, the generic configuration works, and
+ saves the additional endpoint."
+ }
+ cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_EP0 {
+ display "Name of EP0 structure"
+ flavor data
+ default_value { "usbs_at91_ep0" }
+ description "
+ The name of the variable that contains the endpoint 0
+ structure. This should be set to the EP0 structure for
+ the desired USB device driver such as usbs_at91_ep0,
+ usbs_sa11x0_ep0, etc"
+ }
+ cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_EP0_MAX_PACKET_SIZE {
+ display "The size of EP0"
+ flavor data
+ default_value 8
+ legal_values { 8 16 64 }
+ description "
+ The size of the EP0 hardware buffer on the specific USB
+ chip used."
+ }
+ cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM {
+ display "Tx (USB IN) endpoint number"
+ flavor data
+ default_value 1
+ description "
+ The endpoint that should be used for the device-side
+ transmitter, which is the USB IN direction."
+ }
+ cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP {
+ display "The Tx (USB IN) endpoint structure"
+ flavor data
+ default_value { "usbs_at91_ep1" }
+ description "
+ The endpoint structure that corresponds to the selected
+ Tx endpoint number. This is dependent on the USBS device
+ driver selected, and could be usbs_at91_ep1,
+ usbs_sa11x0_ep1, etc"
+
+ }
+ cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM {
+ display "Rx (USB OUT) endpoint number"
+ flavor data
+ default_value 2
+ description "
+ The endpoint that should be used for the device-side
+ receiver, which is the USB OUT direction."
+ }
+ cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP {
+ display "The Rx (USB OUT) endpoint structure"
+ flavor data
+ default_value { "usbs_at91_ep2" }
+ description "
+ The endpoint structure that corresponds to the selected
+ Rx endpoint number. This is dependent on the USBS device
+ driver selected, and could be usbs_at91_ep2,
+ usbs_sa11x0_ep2, etc"
+ }
+ cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM {
+ display "Interrupt IN endpoint number"
+ flavor data
+ default_value 3
+ active_if { CYGDAT_IO_USB_SLAVE_CLASS_TYPE == "ACM" }
+ description "
+ The endpoint that should be used for the ACM Interrupt IN"
+ }
+ cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_INTR_EP {
+ display "Interrupt IN endpoint structure"
+ flavor data
+ default_value { "usbs_at91_ep3" }
+ active_if { CYGDAT_IO_USB_SLAVE_CLASS_TYPE == "ACM" }
+ description "
+ The endpoint structure that corresponds to the selected ACM
+ Interrupt IN endpoint."
+ }
+ cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID {
+ display "USB Forum Vendor ID"
+ flavor data
+ default_value 0xFFFF
+ legal_values 1 to 0xFFFF
+ description "
+ Each USB vendor has an Vendor ID allocated to it by the
+ USB-IF organization. Any arbitrary value can be selected
+ for testing provided that it doesn't conflict with devices
+ on the development host, but a device should NEVER be
+ released publicly without a valid Vendor ID"
+
+ }
+ cdl_option CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID {
+ display "USB product ID"
+ flavor data
+ default_value 1
+ legal_values 1 to 0xFFFF
+ description "
+ You are free to select an arbitrary 16-bit Product ID for
+ a device. The combination of Vendor ID and Product ID
+ uniquely identified a USB device."
+ }
+ cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_MFG_STR {
+ display "The Device Vendor's Name (Manufacturer String)"
+ flavor data
+ default_value { "\"eCos\"" }
+ description "
+ The standard USB enumeration allows for a
+ manufacturer's name which is normally reported to the
+ user when the device is first plugged into the host."
+ }
+ cdl_option CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR {
+ display "The Device Product Name"
+ flavor data
+ default_value { "\"eCos USB Serial Device\"" }
+ description "
+ The standard USB enumeration allows for a product name
+ which is normally reported to the user when the device
+ is first plugged into the host."
+ }
+
+ cdl_option CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG {
+ display "Enable debug output from the driver"
+ default_value 0
+ flavor bool
+ description "
+ The driver may produce debug output which can be
+ useful to work out why it is not working as expected."
+ }
+
+ cdl_component CYGPKG_IO_USB_SLAVE_SERIAL_OPTIONS {
+ display "Build options"
+ flavor none
+
+ description "
+ Package-specific build options including control over compiler
+ flags used only in building this package."
+
+ cdl_option CYGPKG_IO_USB_SLAVE_SERIAL_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_USB_SLAVE_SERIAL_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are removed from
+ the set of global flags if present."
+ }
+
+
+ cdl_component CYGBLD_IO_USB_SLAVE_SERIAL_EXAMPLES {
+ display "Build example programs"
+ no_define
+ requires { CYGPKG_IO_FILEIO }
+ requires { CYGPKG_IO_SERIAL_DEVICES }
+ description "
+ Enabling this option will cause the example programs
+ to be built using the normal test case infrastructure.
+ They are however not test cases and should not be used
+ with any automatic test farm running all the
+ tests. Hence this option is disabled by default."
+
+ cdl_option CYGPKG_IO_USB_SLAVE_SERIAL_TESTS {
+ display "USBS serial example/test programs"
+ no_define
+ flavor data
+ calculated { "tests/usbserial_echo.c tests/usb2serial.c" }
+ description "
+ usbserial_echo will echo charactors received
+ over the usb serial port back to the sender.
+ usb2serial acts as a bridge between a USB serial
+ slave and a real serial port. It is hard coded to use
+ /dev/ser0."
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<!-- DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- usbs_serial.sgml -->
+<!-- -->
+<!-- USB slave-side serial port package. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN#### -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2008 FSF -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- -->
+<!-- ####COPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): Andrew Lunn, Frank Pagliughi -->
+<!-- Contact(s): asl -->
+<!-- Date: 2008/06/18 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="io-usb-slave-serial">
+ <!-- reference id="io-usb-slave-serial" -->
+ <title>eCos Support for USB Serial like Peripherals</title>
+
+ <!-- {{{ Intro -->
+
+ <refentry id="usbs-serial-intro">
+ <refmeta>
+ <refentrytitle>Introduction</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Introduction</refname>
+ <refpurpose>
+ eCos support for USB Serial like Peripherals
+ </refpurpose>
+ </refnamediv>
+
+ <refsect1><title>Introduction</title>
+ <para>
+ The eCos USB-Serial package provides additional support for
+ USB peripherals that look like a serial port to the
+ host. These can follow the ACM communication device
+ specification or simpler devices which just have two bulk
+ endpoints. Microsoft Windows requires ACM mode. Linux should
+ operate with both modes, however ACM may cause problems since
+ the eCos driver does not implement all the class descriptors,
+ so generic mode is recommended.
+ </para>
+ <para>
+ The USB-Serial package is not tied to any specific
+ hardware. It requires the presence of USB hardware on the
+ target and a suitable device driver to make endpoints
+ available for this code to use. The configuration system
+ cannot load the eCos package automatically for specific
+ targets, in the way that a USB device driver or an ethernet
+ driver can be loaded automatically. Instead, the package has
+ to be added explicitly. When using the command line tools this
+ will involve an operation like the following:
+ </para>
+ <screen width=72 format=linespecific>
+ $ ecosconfig add usbs_serial
+ </screen>
+ <para>
+ Typically, this will automatically cause the USB device driver
+ to become active.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <!-- }}} -->
+ <!-- {{{ Config -->
+
+ <refentry id="usbs-serial-config">
+ <refmeta>
+ <refentrytitle>Configuration</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Configuration</refname>
+ <refpurpose>Configuration USB Serial like Peripherals</refpurpose>
+ </refnamediv>
+
+ <refsect1><title>Configuration</title>
+ <para>
+ The package requires a few basic configurations plus
+ optionally some additional configuration options.
+ </para>
+ <para>
+ The driver needs two or three endpoints, depending if ACM
+ communications or a more generic model is used. This is
+ configured
+ with <literal>CYGDAT_IO_USB_SLAVE_CLASS_TYPE</literal> which
+ can take the value <literal>ACM</literal>
+ or <literal>generic</literal>.
+ </para>
+ <para>
+ The <literal>CYGDAT_IO_USB_SLAVE_SERIAL_EP0</literal> must be
+ configured with the control end point of the USB
+ device. <literal>CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP</literal>
+ must be configured with the endpoint to be used for
+ transmission and
+ <literal>CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP</literal> must be
+ configured with the end point used for reception. Associated
+ with these
+ are <literal>CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM</literal>
+ and <literal>CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM</literal>
+ which are the endpoint numbers and are used during enumeration
+ of the device. The TX and RX endpoints must operate in BULK
+ mode.
+ </para>
+ <para>
+ If operation mode ACM is selected a third endpoint is
+ needed. This must operate in interrupt mode and should be
+ configured
+ in <literal>CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP</literal>
+ and <literal>
+ CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM</literal>.
+ </para>
+ <para>
+ The USB serial device will make its vendor:product ID known to
+ the host. This should be configured
+ with <literal>CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID</literal>
+ and <literal>CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID</literal>. NOTE:
+ The default configurations are not valid for products, but
+ should work for testing.
+ </para>
+ <para>
+ The USB enumeration also contains text strings to describe the
+ device. This text string can be set
+ with <literal>CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR</literal>.
+ </para>
+ <para>
+ The last configuration option of interest
+ is <literal>CYGPKG_IO_USB_SLAVE_SERIAL_EXAMPLES</literal>. When
+ true example programs will be built when the eCos tests are
+ built. These are not pass/fail test like other eCos tests, but
+ examples of how the eCos USB serial class can be used.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <!-- }}} -->
+ <!-- {{{ Host Config -->
+
+ <refentry id="usbs-serial-host-config">
+ <refmeta>
+ <refentrytitle>Host Configuration</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Host Configuration</refname>
+ <refpurpose>Host Configuration for USB Serial like Peripherals
+ </refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>Host Configuration</title>
+ <para>
+ Configuration for two hosts are listed here, Microsoft Windows
+ and Linux. It should also be possible to use the eCos USB
+ serial like peripheral driver with other hosts.
+ </para>
+ <refsect2><title>Linux</title>
+ <para>
+ The eCos USB serial like peripheral driver can be used in
+ Linux in one of two ways.
+ <itemizedlist>
+ <listitem>
+ <para>
+ Using the generic usbserial kernel module passing the
+ vendor and product ID as module parameters. e.g.
+ </para>
+ <programlisting width=72>
+ modprobe usbserial vendor=0xabcd product=0x1234
+ </programlisting>
+ <para>
+ would load the kernel module so that it would use a
+ USB device abcd:1234 as a serial device.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Using the mini driver provided with eCos in the
+ <filename class=directory>host/linux</filename>
+ directory. This driver must be edited and the correct
+ vendor and product ID set to match the vendor and
+ product ID used by the device. Once compiled this
+ driver can be loaded with:
+ </para>
+ <programlisting width=72>
+ modprobe usbserial
+ modprobe ecos_usbserial
+ </programlisting>
+ <para>
+ This driver is known to compile with kernel versions
+ 2.6.18 and probably works fine with other
+ kernels. However it fails to compile with kernels
+ after 2.6.25.
+ </para>
+ </listitem>
+ </itemizedlist>
+ Both of these methods will result in the Linux Kernel making
+ a new serial device available. This is typically
+ named <filename>/dev/ttyUSB0</filename>.
+ </para>
+ </refsect2>
+ <refsect2><title>Microsoft Windows</title>
+ <para>
+ To install the device in a Microsoft Windows system make use
+ of the INF file
+ in <filename>host/windows/eCosUsbSerial.inf</filename>. Copy
+ this INF file and <filename>usbser.sys</filename> from your
+ version of Windows into an empty directory. Then plug in the
+ USB device. When prompted to load a driver navigate to the
+ INF file and select it.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ </refentry>
+
+ <!-- }}} -->
+ <!-- {{{ Using -->
+ <refentry id="usbs-serial-using">
+ <refmeta>
+ <refentrytitle>API Function</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>usbs_serial_start</refname>
+ <refname>usbs_serial_init</refname>
+ <refname>usbs_serial_start</refname>
+ <refname>usbs_serial_wait_until_configured</refname>
+ <refname>usbs_serial_is_configured</refname>
+ <refname>usbs_serial_start_tx</refname>
+ <refname>usbs_serial_wait_for_tx</refname>
+ <refname>usbs_serial_tx</refname>
+ <refname>usbs_serial_start_rx</refname>
+ <refname>usbs_serial_wait_for_rx</refname>
+ <refname>usbs_serial_rx</refname>
+ <refname>usbs_serial_state_change_handler</refname>
+ <refpurpose>
+ eCos USB Serial like Peripherals API
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include <cyg/io/usb/usbs_serial.h>
+ </funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>void
+ <function>usbs_serial_start</function>
+ </funcdef>
+ <paramdef>void</paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>void
+ <function>usbs_serial_init</function>
+ </funcdef>
+ <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+ <paramdef>usbs_tx_endpoint * <parameter>tx_ep</parameter></paramdef>
+ <paramdef>usbs_rx_endpoint * <parameter>rx_ep</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>void
+ <function>usbs_serial_wait_until_configured</function>
+ </funcdef>
+ <paramdef>void></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>cyg_bool
+ <function>usbs_serial_is_configured</function>
+ </funcdef>
+ <paramdef>void</paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>void
+ <function>usbs_serial_start_tx</function>
+ </funcdef>
+ <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+ <paramdef>const void *<parameter>buf</parameter></paramdef>
+ <paramdef>int * <parameter>n</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int
+ <function>usbs_serial_wait_for_tx</function>
+ </funcdef>
+ <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>void
+ <function>usbs_serial_start_rx</function>
+ </funcdef>
+ <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+ <paramdef>const void *<parameter>buf</parameter></paramdef>
+ <paramdef>int * <parameter>n</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int
+ <function>usbs_serial_wait_for_rx</function>
+ </funcdef>
+ <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int
+ <function>usbs_serial_rx</function>
+ </funcdef>
+ <paramdef>usbs_serial * <parameter>ser</parameter></paramdef>
+ <paramdef>const void *<parameter>buf</parameter></paramdef>
+ <paramdef>int * <parameter>n</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>void
+ <function>usbs_serial_state_change_handler</function>
+ </funcdef>
+ <paramdef>usbs_control_endpoint * <parameter>ep</parameter></paramdef>
+ <paramdef>void * <parameter>data</parameter></paramdef>
+ <paramdef>usbs_state_change <parameter>change</parameter></paramdef>
+ <paramdef>int <parameter>prev_state</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="usbs-serial-api-description">
+ <title>Description</title>
+ <para>
+ For examples of how to use this API see the
+ files <filename>.../tests/usbserial_echo.c</filename>
+ and <filename>.../tests/usb2serial.c</filename>
+ </para>
+
+ <para>
+ The first function that needs calling
+ is <function>usbs_serial_start()</function>. This will initialise
+ the eCos USB slave layer, creating all the enumeration data and
+ then let the host know that the device exists.
+ </para>
+ <para>
+ Once the USB subsystem has been started it is necessary to wait
+ for the host to configure the device using the
+ function <function>usbs_serial_wait_until_configured()</function>. The
+ host will assign the device an ID and then load the appropriate
+ device driver in the host in order to make use the device.
+ </para>
+ <para>
+ Once the device is configured it is then possible to make use of
+ it, i.e. send and receive data. This transfer of data can be
+ accomplished either asynchronously or synchronously. It is also
+ possible to mix asynchronously and synchronously between
+ receiving and sending data.
+ </para>
+ <para>
+ To perform asynchronous operations the
+ functions <function>usbs_serial_start_rx()</function>
+ and <function>usbs_serial_start_tx()</function> is used to
+ start the operation. These functions start the necessary
+ actions and then return immediately. At a later time the
+ functions <function>usbs_serial_wait_for_tx()</function>
+ or <function>usbs_serial_wait_for_rx()</function> should be
+ called. These will, if necessary, block and then return the
+ status and any data for the previously started asynchronous
+ call.
+ </para>
+ <para>
+ To perform synchronous operations the
+ functions <function>usbs_serial_rx()</function>
+ and <function>usbs_serial_tx()</function> are used. These
+ functions will block until the requested action is complete.
+ </para>
+ </refsect1>
+ </refentry>
+ <!-- }}} -->
+</part>
+<!-- /reference -->
--- /dev/null
+.ecos_usbserial.o.d
+.tmp_versions
+*.ko
\ No newline at end of file
--- /dev/null
+# Makefile for ecos_usbserial Linux kernel module
+
+ifneq ($(KERNELRELEASE),)
+ obj-m := ecos_usbserial.o
+else
+ KDIR ?= /lib/modules/$(shell uname -r)/build
+ PWD := $(shell pwd)
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+endif
+
--- /dev/null
+//==========================================================================
+//
+// ecos_usbserial.c
+//
+// Kernel driver for the eCos USB serial driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors:
+// Date: 2008-06-02
+// Description: Kernel driver for the eCos USB serial driver
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+#define VENDOR_ID 0xFFFF
+#define PRODUCT_ID 1
+
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver ecos_usbserial_driver = {
+ .name = "ecos_usbserial",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table
+};
+
+static struct usb_serial_driver ecos_usbserial_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ecos_usbserial",
+ },
+ .id_table = id_table,
+ .num_interrupt_in = NUM_DONT_CARE,
+ .num_bulk_in = NUM_DONT_CARE,
+ .num_bulk_out = NUM_DONT_CARE,
+ .num_ports = 1
+};
+
+static int __init ecos_usbserial_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&ecos_usbserial_device);
+ if (retval)
+ return retval;
+
+ retval = usb_register(&ecos_usbserial_driver);
+ if (retval) {
+ usb_serial_deregister(&ecos_usbserial_device);
+ return retval;
+ }
+
+ return 0;
+}
+
+static void __exit ecos_usbserial_exit(void)
+{
+ usb_deregister(&ecos_usbserial_driver);
+ usb_serial_deregister(&ecos_usbserial_device);
+}
+
+module_init(ecos_usbserial_init);
+module_exit(ecos_usbserial_exit);
+
+MODULE_LICENSE("GPL");
+
--- /dev/null
+; eCos USB Serial INF file for Windows
+; This can be used for any USB device that emulates a serial port connection.
+; Simply set the VID & PID numbers in this file to the proper values for the
+; device, copy this file and the 'usbser.sys' file from your version of Windows
+; into the same directory, and load these when prompted by the Windows device
+; manager.
+
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=eCosUsbSerial
+DriverVer=06/02/2008,0.0.0.1
+
+[DestinationDirs]
+DefaultDestDir=12 ; %windir$\System32\drivers
+
+[Manufacturer]
+eCosUsbSerial=eCosDevices
+
+[eCosDevices]
+"eCosUsbSerial"=InstalleCosUsbSerial,USB\VID_FFFF&PID_0001
+
+[InstalleCosUsbSerial]
+CopyFiles=CopyeCosUsbFiles
+AddReg=eCosUsbReg
+
+[CopyeCosUsbFiles]
+usbser.sys ; The standard Windows USB serial driver
+
+[eCosUsbReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[InstalleCosUsbSerial.Services]
+AddService = usbser,2,eCosUsbSerialService
+
+[eCosUsbSerialService]
+DisplayName = ECOS_USB_SERIAL_NAME
+ServiceType = 1 ; driver
+StartType = 3 ; on-demand or manual
+ErrorControl = 1 ; report errors
+ServiceBinary = %12%\usbser.sys ; Driver path: %windir%\System32\drivers
+LoadOrderGroup = Base
+
+[Strings]
+ECOS_USB_SERIAL_NAME = "eCos USB Serial Driver"
+
--- /dev/null
+#ifndef CYGONCE_USBS_SERIAL_H
+#define CYGONCE_USBS_SERIAL_H
+//==========================================================================
+//
+// include/usbs_serial.h
+//
+// Description of the USB slave-side serial device support
+//
+//==========================================================================
+//####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): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors:
+// Date: 2008-06-02
+// Purpose:
+// Description: USB slave-side serial support
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// The primary purpose of the USB slave-side serial code is to provide a
+// simple USB connection to the host, especially for embedded systems that
+// are upgrading from RS-232 serial connections. The host would see the
+// device as if through a serial port, and thus the host software would
+// remain unchanged. It would also eliminate the need for a new device
+// driver on the host.
+//
+// On this side (the eCos USB slave side), the application sees the host
+// through a normal USB slave connection with two Bulk endpoints - one in
+// the IN direction and one in the OUT direction. This module provides the
+// necessary USB descriptors to enumerate the device for a single serial
+// port, but then the application is free to communicate with the host
+// using any desired API:
+// - The standard eCos USB slave API
+// - The low-level File I/O layer (if USB devtab entries configured)
+// - The C stdio functions (again, if USB devtab entries configured)
+// - The USB serial API defined here.
+//
+// The USB serial API is a thin layer over the standard eCos USB functions
+// to provide common synchronous and asynchronous transfers over the assigned
+// Bulk endpoints.
+//
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/usb/usbs.h>
+
+// ----------------------------------------------------------------------------
+// The ACM class requests
+//
+
+#define USBS_SERIAL_SEND_ENCAPSULATED_COMMAND 0x00
+#define USBS_SERIAL_GET_ENCAPSULATED_RESPONSE 0x01
+#define USBS_SERIAL_SET_COMM_FEATURE 0x02
+#define USBS_SERIAL_GET_COMM_FEATURE 0x03
+#define USBS_SERIAL_CLEAR_COMM_FEATURE 0x04
+
+#define USBS_SERIAL_SET_LINE_CODING 0x20
+#define USBS_SERIAL_GET_LINE_CODING 0x21
+#define USBS_SERIAL_SET_CONTROL_LINE_STATE 0x22
+#define USBS_SERIAL_SEND_BREAK 0x23
+
+// ----------------------------------------------------------------------------
+// Data structure to manage the pair of USB endpoints that comprise a single
+// serial port connection. Each "port" requires one Bulk IN endpoint and one
+// Bulk OUT endpoint.
+
+typedef struct usbs_serial {
+ // The communication endpoints. For the first (default) channel, these
+ // are normally set by the configuration, but can be changed by the
+ // application, if desired.
+ usbs_tx_endpoint* tx_ep;
+ usbs_rx_endpoint* rx_ep;
+
+ // The signal that a transmit operation is complete, and it's result.
+ cyg_sem_t tx_ready;
+ int tx_result;
+
+ // The signal that a receive operation is complete, and it's result.
+ cyg_sem_t rx_ready;
+ int rx_result;
+
+} usbs_serial;
+
+// The package contains one USB serial device.
+extern usbs_serial usbs_ser0;
+
+// It's assumed that there's a single USB slave chip in the system, with a
+// single control endpoint 0. The actual variable is contained in the device
+// driver, but the USB serial code keeps a pointer to it for driver
+// independence. The application might find it useful for overriding low-level
+// code or callbacks.
+extern usbs_control_endpoint* usbs_serial_ep0;
+
+// ----------------------------------------------------------------------------
+// A C interface to the serial USB code.
+// The application can use this interface, the standard (low-level) USB slave
+// API, the standard Unix-like I/O API, or C stdio API.
+
+// Initialize support for a particular USB serial "port"
+// This associates a usbs_serial structure with specific endpoints and
+// initializes the structure for communications.
+void usbs_serial_init(usbs_serial*, usbs_tx_endpoint*, usbs_rx_endpoint*);
+
+// Block the calling thread until the host configures the USB device.
+void usbs_serial_wait_until_configured(void);
+
+// Determines if the USB subsystem is configured
+cyg_bool usbs_serial_is_configured(void);
+
+// Start an asynchronous transmit of a single buffer.
+void usbs_serial_start_tx(usbs_serial*, const void* buf, int n);
+
+// Block the calling thread until the transmit completes.
+// Returns the result code for the transfer
+int usbs_serial_wait_for_tx(usbs_serial*);
+
+// Blocking, synchronous transmit of a single buffer.
+int usbs_serial_tx(usbs_serial*, const void* buf, int n);
+
+// Start an asynchronous receive of a buffer.
+void usbs_serial_start_rx(usbs_serial*, void* buf, int n);
+
+// Block the calling thread until the receive completes.
+// Returns the result code for the transfer
+int usbs_serial_wait_for_rx(usbs_serial*);
+
+// Blocking, synchronous receive of a single buffer.
+int usbs_serial_rx(usbs_serial*, void* buf, int n);
+
+// The default USB-serial state change handler paces the functions
+// usbs_serial_wait_until_configured() and usbs_serial_is_configured().
+// The application can override the state chain handler, but chain to
+// this function to keep the full USB-serial system working.
+void usbs_serial_state_change_handler(usbs_control_endpoint*, void*,
+ usbs_state_change, int);
+
+// Starts the USB subsystem
+void usbs_serial_start(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // CYGONCE_USBS_SERIAL_H
+
--- /dev/null
+//==========================================================================
+//
+// usbs_serial.c
+//
+// Support for slave-side USB serial devices.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Date: 2008-06-02
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/kernel/kapi.h>
+
+#include <pkgconf/io_usb_slave_serial.h>
+#include <cyg/io/usb/usbs_serial.h>
+#include <string.h>
+
+#if defined(CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+#define EP0_MAX_PACKET_SIZE CYGNUM_IO_USB_SLAVE_SERIAL_EP0_MAX_PACKET_SIZE
+
+extern usbs_control_endpoint CYGDAT_IO_USB_SLAVE_SERIAL_EP0;
+extern usbs_tx_endpoint CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP;
+extern usbs_rx_endpoint CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP;
+
+#define TX_EP_NUM CYGNUM_IO_USB_SLAVE_SERIAL_TX_EP_NUM
+#define RX_EP_NUM CYGNUM_IO_USB_SLAVE_SERIAL_RX_EP_NUM
+#define INTR_EP_NUM CYGNUM_IO_USB_SLAVE_SERIAL_INTR_EP_NUM
+#define EP0 (&CYGDAT_IO_USB_SLAVE_SERIAL_EP0)
+#define TX_EP (&CYGDAT_IO_USB_SLAVE_SERIAL_TX_EP)
+#define RX_EP (&CYGDAT_IO_USB_SLAVE_SERIAL_RX_EP)
+#define INTR_EP (&CYGDAT_IO_USB_SLAVE_SERIAL_INTR_EP)
+
+
+#define VENDOR_ID CYGNUM_IO_USB_SLAVE_SERIAL_VENDOR_ID
+#define PRODUCT_ID CYGNUM_IO_USB_SLAVE_SERIAL_PRODUCT_ID
+
+#define USB_MAX_STR_LEN 256
+
+#define LO_BYTE_16(word16) ((cyg_uint8) ((word16) & 0xFF))
+#define HI_BYTE_16(word16) ((cyg_uint8) (((word16) >> 8) & 0xFF))
+
+#define BYTE0_32(word32) ((cyg_uint8) ((word32) & 0xFF))
+#define BYTE1_32(word32) ((cyg_uint8) (((word32) >> 8) & 0xFF))
+#define BYTE2_32(word32) ((cyg_uint8) (((word32) >> 16) & 0xFF))
+#define BYTE3_32(word32) ((cyg_uint8) (((word32) >> 24) & 0xFF))
+
+
+#define MFG_STR_INDEX '\x01'
+#define PRODUCT_STR_INDEX '\x02'
+
+#define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH(interfaces, endpoints) \
+ (USB_CONFIGURATION_DESCRIPTOR_LENGTH + \
+ ((interfaces) * USB_INTERFACE_DESCRIPTOR_LENGTH) + \
+ ((endpoints) * USB_ENDPOINT_DESCRIPTOR_LENGTH))
+
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+ #define USBS_SERIAL_DEVICE_CLASS 2
+ #define USBS_SERIAL_NUM_IFACE 2
+ #define USBS_SERIAL_NUM_ENDP 3
+ #define USBS_SERIAL_DATA_IFACE_CLASS 0x0A // Data
+#else
+ #define USBS_SERIAL_DEVICE_CLASS 0
+ #define USBS_SERIAL_NUM_IFACE 1
+ #define USBS_SERIAL_NUM_ENDP 2
+ #define USBS_SERIAL_DATA_IFACE_CLASS 0xFF // Vendor
+#endif
+
+// ----- Configuration Descriptor -----
+
+static const usb_configuration_descriptor usb_configuration = {
+ length: sizeof(usb_configuration_descriptor),
+ type: USB_CONFIGURATION_DESCRIPTOR_TYPE,
+ total_length_lo:
+ USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_LO(USBS_SERIAL_NUM_IFACE,
+ USBS_SERIAL_NUM_ENDP),
+ total_length_hi:
+ USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_HI(USBS_SERIAL_NUM_IFACE,
+ USBS_SERIAL_NUM_ENDP),
+ number_interfaces: USBS_SERIAL_NUM_IFACE,
+ configuration_id: 1,
+ configuration_str: 0,
+ attributes: (USB_CONFIGURATION_DESCRIPTOR_ATTR_REQUIRED |
+ USB_CONFIGURATION_DESCRIPTOR_ATTR_SELF_POWERED),
+ max_power: 50
+};
+
+// ----- Interface Descriptor -----
+
+static const usb_interface_descriptor usb_interface[] = {
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+ {
+ length: sizeof(usb_interface_descriptor),
+ type: USB_INTERFACE_DESCRIPTOR_TYPE,
+ interface_id: 0,
+ alternate_setting: 0,
+ number_endpoints: 1,
+ interface_class: 0x02, // Comm class
+ interface_subclass: 0x02,
+ interface_protocol: 0x01,
+ interface_str: 0x00
+ },
+ {
+ length: sizeof(usb_interface_descriptor),
+ type: USB_INTERFACE_DESCRIPTOR_TYPE,
+ interface_id: 1,
+ alternate_setting: 0,
+ number_endpoints: 2,
+ interface_class: USBS_SERIAL_DATA_IFACE_CLASS,
+ interface_subclass: 0x00,
+ interface_protocol: 0x00,
+ interface_str: 0x00
+ }
+#else
+ {
+ length: sizeof(usb_interface_descriptor),
+ type: USB_INTERFACE_DESCRIPTOR_TYPE,
+ interface_id: 0,
+ alternate_setting: 0,
+ number_endpoints: 2,
+ interface_class: USBS_SERIAL_DATA_IFACE_CLASS,
+ interface_subclass: 0x00,
+ interface_protocol: 0x00,
+ interface_str: 0x00
+ }
+#endif
+};
+
+// ----- Endpoint Descriptors -----
+
+static const usb_endpoint_descriptor usb_endpoints[] =
+{
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+ // Interrupt in endpoint
+ {
+ sizeof(usb_endpoint_descriptor),
+ USB_ENDPOINT_DESCRIPTOR_TYPE,
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | INTR_EP_NUM,
+ USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ 0x40,
+ 0,
+ 255
+ },
+#endif
+
+ // Tx (Bulk IN) Endpoint Descriptor
+ {
+ sizeof(usb_endpoint_descriptor),
+ USB_ENDPOINT_DESCRIPTOR_TYPE,
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | TX_EP_NUM,
+ USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ 0x40,
+ 0,
+ 0
+ },
+
+ // Rx (Bulk OUT) Endpoint Descriptor
+ {
+ sizeof(usb_endpoint_descriptor),
+ USB_ENDPOINT_DESCRIPTOR_TYPE,
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT | RX_EP_NUM,
+ USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ 0x40,
+ 0,
+ 0
+ }
+};
+
+// ----- String Descriptors -----
+
+static char mfg_str_descr[USB_MAX_STR_LEN],
+ product_str_descr[USB_MAX_STR_LEN];
+
+
+static const char* usb_strings[] = {
+ "\x04\x03\x09\x04",
+ mfg_str_descr,
+ product_str_descr
+};
+
+// ----- Enumeration Data w/ Device Descriptor -----
+
+static usbs_enumeration_data usb_enum_data = {
+ {
+ length: sizeof(usb_device_descriptor),
+ type: USB_DEVICE_DESCRIPTOR_TYPE,
+ usb_spec_lo: 0x00,
+ usb_spec_hi: 0x02,
+ device_class: USBS_SERIAL_DEVICE_CLASS,
+ device_subclass: 0,
+ device_protocol: 0,
+ max_packet_size: EP0_MAX_PACKET_SIZE,
+ vendor_lo: LO_BYTE_16(VENDOR_ID),
+ vendor_hi: HI_BYTE_16(VENDOR_ID),
+ product_lo: LO_BYTE_16(PRODUCT_ID),
+ product_hi: HI_BYTE_16(PRODUCT_ID),
+ device_lo: 0x00,
+ device_hi: 0x00,
+ manufacturer_str: MFG_STR_INDEX,
+ product_str: PRODUCT_STR_INDEX,
+ serial_number_str: 0,
+ number_configurations: 1
+ },
+
+ total_number_interfaces: USBS_SERIAL_NUM_IFACE,
+ total_number_endpoints: USBS_SERIAL_NUM_ENDP,
+ total_number_strings: 3,
+ configurations: &usb_configuration,
+ interfaces: usb_interface,
+ endpoints: usb_endpoints,
+ strings: (const unsigned char **) usb_strings
+};
+
+// --------------------------------------------------------------------------
+// USBS Serial Data
+// --------------------------------------------------------------------------
+
+usbs_control_endpoint* usbs_serial_ep0 = EP0;
+
+// Lock for the state.
+cyg_mutex_t usbs_serial_lock;
+
+// Condition variable for state changes
+cyg_cond_t usbs_serial_state_cond;
+
+int usbs_serial_state;
+
+usbs_serial usbs_ser0 = {
+ tx_ep: TX_EP,
+ rx_ep: RX_EP,
+ tx_result: 0,
+ rx_result: 0,
+};
+
+static void (*usbs_serial_app_state_change_fn)(struct usbs_control_endpoint*,
+ void*, usbs_state_change, int)
+= 0;
+
+// --------------------------------------------------------------------------
+// Create a USB String Descriptor from a C string.
+
+void
+usbs_serial_create_str_descriptor(char descr[], const char *str)
+{
+ int i, n = strlen(str);
+
+ if (n > (USB_MAX_STR_LEN/2 - 2))
+ n = USB_MAX_STR_LEN/2 - 2;
+
+ descr[0] = (cyg_uint8) (2*n + 2);
+ descr[1] = USB_DEVREQ_DESCRIPTOR_TYPE_STRING;
+
+ for (i=0; i<n; i++) {
+ descr[i*2+2] = str[i];
+ descr[i*2+3] = '\x00';
+ }
+}
+
+// --------------------------------------------------------------------------
+// ACM Class Handler
+//
+// For a Windows host, the device must, at least, respond to a SetLineCoding
+// request (0x20), otherwise Windows will report that it's unable to open the
+// port. This request normally sets the standard serial parameters:
+// baud rate, # stop bits, parity, and # data bits
+// If we're just making believe that we're a serial port to communicate with
+// the host via USB, then these values don't matter. So we ACK the request,
+// but ignore the parameters.
+// If we were actually creating a USB-serial converter, then we would need to
+// read these values and configure the serial port accordingly.
+//
+// Similarly, the host can request the current settings through a
+// GetLineCoding request (0x21). Since we're just faking it, we return some
+// arbitrary values: 38400,1,N,8
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+static usbs_control_return
+usbs_serial_acm_class_handler(usbs_control_endpoint* ep0, void* data)
+{
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+ usb_devreq *req = (usb_devreq *) ep0->control_buffer;
+ static cyg_uint8 rsp_buf[32];
+ cyg_uint32 baud = 38400; // Arbitrary, fake value to return to the host.
+
+ DBG("USB Serial ACM Class Handler: ");
+
+ switch (req->request) {
+
+ case USBS_SERIAL_SET_LINE_CODING :
+ DBG("ACM Request: Set Line Coding\n");
+ result = USBS_CONTROL_RETURN_HANDLED;
+ break;
+
+ case USBS_SERIAL_GET_LINE_CODING :
+ DBG("ACM Request: Get Line Coding\n");
+ rsp_buf[0] = BYTE0_32(baud);
+ rsp_buf[1] = BYTE1_32(baud);
+ rsp_buf[2] = BYTE2_32(baud);
+ rsp_buf[3] = BYTE3_32(baud);
+ rsp_buf[4] = 0; // One stop bit
+ rsp_buf[5] = 0; // No parity
+ rsp_buf[6] = 8; // 8 data bits
+ ep0->buffer = rsp_buf;
+ ep0->buffer_size = 7;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ break;
+
+ default :
+ DBG("*** Unhandled ACM Request: 0x%02X ***\n",
+ (unsigned) req->request);
+ }
+
+ return result;
+}
+#endif // CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+// --------------------------------------------------------------------------
+// Callback for a USB state change
+
+void
+usbs_serial_state_change_handler(usbs_control_endpoint* ep, void* data,
+ usbs_state_change change, int prev_state)
+{
+#if defined(CYGBLD_IO_USB_SLAVE_SERIAL_DEBUG)
+ const char *STATE_CHG_STR[] = { "Detached", "Attached", "Powered", "Reset",
+ "Addressed", "Configured", "Deconfigured",
+ "Suspended", "Resumed" };
+
+ if (change > 0) {
+ DBG("### %d:%s ###\n", change, STATE_CHG_STR[(int) change-1]);
+ }
+#endif
+
+ // Called from DSR, cond broadcast should be ok without mutex lock
+ usbs_serial_state = usbs_serial_ep0->state;
+ cyg_cond_broadcast(&usbs_serial_state_cond);
+
+ if (usbs_serial_app_state_change_fn)
+ (*usbs_serial_app_state_change_fn)(ep, data, change, prev_state);
+}
+
+// --------------------------------------------------------------------------
+// Block the calling thread until the USB is configured.
+
+void
+usbs_serial_wait_until_configured(void)
+{
+ cyg_mutex_lock(&usbs_serial_lock);
+ while (usbs_serial_state != USBS_STATE_CONFIGURED)
+ cyg_cond_wait(&usbs_serial_state_cond);
+ cyg_mutex_unlock(&usbs_serial_lock);
+}
+
+// --------------------------------------------------------------------------
+// Determine if the device is currently configured.
+
+cyg_bool
+usbs_serial_is_configured(void)
+{
+ return usbs_serial_state == USBS_STATE_CONFIGURED;
+}
+
+// --------------------------------------------------------------------------
+// Callback for when a transmit is complete
+
+static void
+usbs_serial_tx_complete(void *p, int result)
+{
+ usbs_serial* ser = (usbs_serial*) p;
+ ser->tx_result = result;
+ cyg_semaphore_post(&ser->tx_ready);
+}
+
+// --------------------------------------------------------------------------
+// Callback for when a receive is complete
+
+static void
+usbs_serial_rx_complete(void *p, int result)
+{
+ usbs_serial* ser = (usbs_serial*) p;
+ ser->rx_result = result;
+ cyg_semaphore_post(&ser->rx_ready);
+}
+
+// --------------------------------------------------------------------------
+// Start an asynchronous transmit of a buffer.
+//
+
+void
+usbs_serial_start_tx(usbs_serial* ser, const void* buf, int n)
+{
+ usbs_start_tx_buffer(ser->tx_ep, (unsigned char*) buf, n,
+ usbs_serial_tx_complete, ser);
+}
+
+// --------------------------------------------------------------------------
+// Block the caller until the transmit is complete
+
+int
+usbs_serial_wait_for_tx(usbs_serial* ser)
+{
+ cyg_semaphore_wait(&ser->tx_ready);
+ return ser->tx_result;
+}
+
+// --------------------------------------------------------------------------
+// Perform a synchronous transmit and wait for it to complete.
+
+int
+usbs_serial_tx(usbs_serial* ser, const void* buf, int n)
+{
+ usbs_serial_start_tx(ser, buf, n);
+ return usbs_serial_wait_for_tx(ser);
+}
+
+// --------------------------------------------------------------------------
+// Start an asynchronous receive of a buffer.
+
+void
+usbs_serial_start_rx(usbs_serial* ser, void* buf, int n)
+{
+ usbs_start_rx_buffer(ser->rx_ep, (unsigned char*) buf, n,
+ usbs_serial_rx_complete, ser);
+}
+
+// --------------------------------------------------------------------------
+// Block the caller until the receive is complete
+
+int
+usbs_serial_wait_for_rx(usbs_serial* ser)
+{
+ cyg_semaphore_wait(&ser->rx_ready);
+ return ser->rx_result;
+}
+
+// --------------------------------------------------------------------------
+// Perform a synchronous receive and wait for it to complete.
+
+int
+usbs_serial_rx(usbs_serial* ser, void* buf, int n)
+{
+ usbs_serial_start_rx(ser, buf, n);
+ return usbs_serial_wait_for_rx(ser);
+}
+
+// --------------------------------------------------------------------------
+// Initialize a serial port structure.
+
+void
+usbs_serial_init(usbs_serial* ser, usbs_tx_endpoint* tx_ep,
+ usbs_rx_endpoint* rx_ep)
+{
+ ser->tx_ep = tx_ep;
+ ser->rx_ep = rx_ep;
+
+ cyg_semaphore_init(&ser->tx_ready, 0);
+ cyg_semaphore_init(&ser->rx_ready, 0);
+}
+
+// --------------------------------------------------------------------------
+// Start the USB subsystem
+
+void
+usbs_serial_start(void)
+{
+ usbs_serial_init(&usbs_ser0, TX_EP, RX_EP);
+
+ cyg_mutex_init(&usbs_serial_lock);
+ cyg_cond_init(&usbs_serial_state_cond, &usbs_serial_lock);
+
+ // Make the mfg & product names into USB string descriptors
+
+ usbs_serial_create_str_descriptor(mfg_str_descr,
+ CYGDAT_IO_USB_SLAVE_SERIAL_MFG_STR);
+ usbs_serial_create_str_descriptor(product_str_descr,
+ CYGDAT_IO_USB_SLAVE_SERIAL_PRODUCT_STR);
+
+ // ----- Set up enumeration & USB callbacks -----
+
+ usbs_serial_state = usbs_serial_ep0->state;
+
+ usbs_serial_ep0->enumeration_data = &usb_enum_data;
+
+ if (usbs_serial_ep0->state_change_fn)
+ usbs_serial_app_state_change_fn = usbs_serial_ep0->state_change_fn;
+
+ usbs_serial_ep0->state_change_fn = usbs_serial_state_change_handler;
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+ if (!usbs_serial_ep0->class_control_fn)
+ usbs_serial_ep0->class_control_fn = usbs_serial_acm_class_handler;
+#endif
+
+ // ----- Start USB subsystem -----
+
+ usbs_start(usbs_serial_ep0);
+}
--- /dev/null
+//==========================================================================
+//
+// usb2serial.c
+//
+// Example application for the USB serial layer in eCos.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors:
+// Date: 2008-06-02
+// Description: USB serial example application.
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/kernel.h>
+#include <cyg/io/serialio.h>
+
+// Replace this with any other USB driver desired.
+#include <cyg/io/usb/usbs_at91.h>
+#include <cyg/io/usb/usbs_serial.h>
+#include <pkgconf/io_usb_slave_serial.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+// This application creates a USB-serial converter. To the host it will appear
+// as a single serial USB port, such as /dev/ttyUSB0 for a Linux host.
+// Any characters received from the USB host will be sent out the serial port
+// and visa-verse. It creates a separate, dedicated thread for each direction.
+//
+// It uses the eCos USB-serial layer to enumerate with the USB host and monitor
+// the connection, but then uses standard C I/O functions to perform the
+// communications.
+//
+// The USB serial module can be configured as a generic adapter or an an ACM
+// communications class device. For the latter, the application handles the
+// USB communications class requests which allows it to receive requests from
+// the host to set serial parameters, like the baud rate. This actually turns
+// this example into a more realistic USB-serial adapter that can be configured
+// dynamically by the host.
+//
+// The eCos library must be configured with the packages for USB slave, USB
+// serial, and File I/O. It also requires the proper serial port driver for the
+// target platform.
+//
+// This example was tested with the AT91SAM7S-EK board, but should work with any
+// board that has a USB slave and serial port, and the necessary drivers.
+
+
+// Comment this line out to remove debug output.
+#define DEBUG_OUTPUT
+
+#if defined(DEBUG_OUTPUT)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+// Set these to the USB devtab entries for the Tx and Rx Bulk endpoints
+// selected in the configuration of the USB serial subsystem.
+#define USB_TX_DEV "/dev/usbs1"
+#define USB_RX_DEV "/dev/usbs2"
+
+// Set this for any available serial port on the target.
+#define SER_DEV "/dev/ser0"
+
+// Buffer for incoming USB bulk data. The local USB driver can probably split
+// packets, but just in case, making this the page size of the host might be
+// helpful.
+#define BUF_SIZE 4096
+static char usb2ser_buf[BUF_SIZE];
+
+// The threads
+cyg_thread thread[2];
+
+// Space for two 4K stacks
+#define THREAD_STACK_SIZE 4096
+char stack[2][THREAD_STACK_SIZE];
+
+// The handles for the threads
+cyg_handle_t usb2ser_thread,
+ ser2usb_thread;
+
+// --------------------------------------------------------------------------
+// For an ACM serial device we can handle the USB class messages to deal with
+// requests from the host like setting the serial parameters (baud rate,
+// etc).
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+static cyg_uint8 acm_buf[32];
+static cyg_uint32 baud = 34800;
+
+// --------------------------------------------------------------------------
+// Handler for the completion of a SetLineCoding request from the host.
+// The 'acm_buf' should contain the 7-byte request OUT packet from the
+// host. This contains a request to change the serial parameters.
+// In this example function, we will accept a few different baud rates.
+// To keep the example relatively simple, though, we keep the other serial
+// parameters to 1 stop bit, no parity, 8 data bits.
+
+static usbs_control_return
+acm_set_line_coding(usbs_control_endpoint* ep0, int n)
+{
+ int err;
+ cyg_uint32 req_baud;
+ cyg_io_handle_t handle;
+
+ // Get the requested baud rate from the received ctrl OUT packet
+ req_baud = ((acm_buf[3] << 24) | (acm_buf[2] << 16) |
+ (acm_buf[1] << 8) | acm_buf[0]);
+
+ DBG("Set Baud: %u\n", (unsigned) baud);
+
+ // Look up the serial handle and attempt to set the baud rate.
+ if (cyg_io_lookup(SER_DEV, &handle) == 0) {
+ cyg_serial_info_t ser_info;
+ cyg_uint32 len = sizeof(ser_info);
+
+ switch (baud) {
+ case 9600 : ser_info.baud = CYGNUM_SERIAL_BAUD_9600; break;
+ case 38400 : ser_info.baud = CYGNUM_SERIAL_BAUD_38400; break;
+ case 115200 : ser_info.baud = CYGNUM_SERIAL_BAUD_115200; break;
+ default:
+ DBG("Unsupported baud rate\n");
+ return USBS_CONTROL_RETURN_HANDLED;
+ }
+ ser_info.stop = CYGNUM_SERIAL_STOP_1;
+ ser_info.parity = CYGNUM_SERIAL_PARITY_NONE;
+ ser_info.word_length = CYGNUM_SERIAL_WORD_LENGTH_8;
+ ser_info.flags = 0;
+
+ err = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
+ &ser_info, &len);
+ if (err == 0)
+ baud = req_baud;
+ else {
+ DBG("Error setting serial params\n");
+ }
+ }
+ else {
+ DBG("Error looking up serial device: %s\n", SER_DEV);
+ }
+ return USBS_CONTROL_RETURN_HANDLED;
+}
+
+// --------------------------------------------------------------------------
+// Handler for the ACM class messages.
+//
+static usbs_control_return
+acm_class_handler(usbs_control_endpoint* ep0, void* data)
+{
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+ usb_devreq *req = (usb_devreq *) ep0->control_buffer;
+
+ static cyg_uint8 rsp_buf[32];
+
+ DBG("ACM Class Handler\n");
+
+ switch (req->request) {
+
+ case USBS_SERIAL_SET_LINE_CODING :
+ DBG("Set Line Coding\n");
+ memset(acm_buf, 0, 32);
+ ep0->buffer = acm_buf;
+ ep0->buffer_size = 7;
+ ep0->complete_fn = acm_set_line_coding;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ break;
+
+ case USBS_SERIAL_GET_LINE_CODING :
+ DBG("Get Line Coding\n");
+ rsp_buf[0] = baud & 0xFF;
+ rsp_buf[1] = (baud >> 8) & 0xFF;
+ rsp_buf[2] = (baud >> 16) & 0xFF;
+ rsp_buf[3] = (baud >> 24) & 0xFF;
+ rsp_buf[4] = 0; // One stop bit
+ rsp_buf[5] = 0; // No parity
+ rsp_buf[6] = 8; // 8 data bits
+ ep0->buffer = rsp_buf;
+ ep0->buffer_size = 7;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ break;
+
+ default :
+ DBG("*** Unhandled ACM Request: 0x%02X ***\n",
+ (unsigned) req->request);
+ }
+
+ return result;
+}
+
+#endif // CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+
+// --------------------------------------------------------------------------
+// Thread receives packets from the USB and sends them out the serial port
+// It uses a buffered stdio input, an un-buffered low-level file output.
+// This isn't terribly efficient, but rather an example of both methods.
+
+void usb2ser_func(cyg_addrword_t data)
+{
+ int c;
+ FILE *rxf = fopen(USB_RX_DEV, "r");
+ int txh = open(SER_DEV, O_WRONLY, 0);
+
+ DBG("Usb2Ser: Thread starting\n");
+
+ if (!rxf) {
+ DBG("Error opening USB rx port\n");
+ return;
+ }
+
+ if (txh < 0) {
+ DBG("Error opening serial tx port\n");
+ return;
+ }
+
+ // Give the USB receiver an adequate buffer.
+ setvbuf(rxf, usb2ser_buf, _IOFBF, BUF_SIZE);
+
+ while (1) {
+
+ // ----- Wait for the host to configure -----
+
+ DBG("Usb2Ser: Waiting for USB configuration\n");
+ usbs_serial_wait_until_configured();
+ cyg_thread_delay((cyg_tick_count_t) 10);
+
+ // ----- While configured read data & send out serial port -----
+
+ DBG("Usb2Ser: USB configured\n");
+ while (usbs_serial_is_configured()) {
+ if ((c = getc(rxf)) < 0) {
+ DBG("*** USB Read Error: %d ***\n", c);
+ }
+ else {
+ char ch = (char) c;
+ write(txh, &ch, 1);
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------------
+// Thread receives packets from the serial port and sends them out the USB
+// It uses a buffered stdio input, an un-buffered low-level file output.
+// This isn't terribly efficient, but rather an example of both methods.
+
+void ser2usb_func(cyg_addrword_t data)
+{
+ int c;
+ FILE *rxf = fopen(SER_DEV, "r");
+ int txh = open(USB_TX_DEV, O_WRONLY, 0);
+
+ DBG("Ser2Usb: Thread starting\n");
+
+ if (!rxf) {
+ DBG("Error opening serial rx port\n");
+ return;
+ }
+
+ if (txh < 0) {
+ DBG("Error opening USB tx port\n");
+ return;
+ }
+
+ while (1) {
+
+ // ----- Wait for the host to configure -----
+
+ DBG("Ser2Usb: Waiting for USB configuration\n");
+ usbs_serial_wait_until_configured();
+ cyg_thread_delay((cyg_tick_count_t) 10);
+
+ // ----- While configured read data & send out serial port -----
+
+ DBG("Ser2Usb: USB configured\n");
+ while (usbs_serial_is_configured()) {
+ if ((c = getc(rxf)) < 0) {
+ DBG("*** Console Read Error: %d ***\n", c);
+ }
+ else {
+ char ch = (char) c;
+ write(txh, &ch, 1);
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------------
+// Application Startup
+// --------------------------------------------------------------------------
+
+void cyg_user_start(void)
+{
+ DBG("Entering cyg_user_start() function\n");
+
+#ifdef CYGDAT_IO_USB_SLAVE_CLASS_TYPE_ACM
+ // Override the class handler to use ours.
+ usbs_serial_ep0->class_control_fn = acm_class_handler;
+#endif
+
+ cyg_thread_create(4, usb2ser_func, (cyg_addrword_t) 0,
+ "Usb2Serial", (void *) stack[0], THREAD_STACK_SIZE,
+ &usb2ser_thread, &thread[0]);
+
+ cyg_thread_create(4, ser2usb_func, (cyg_addrword_t) 1,
+ "Serial2Usb", (void *) stack[1], THREAD_STACK_SIZE,
+ &ser2usb_thread, &thread[1]);
+
+ // Start USB subsystem
+ usbs_serial_start();
+
+ // Start the threads running.
+ cyg_thread_resume(usb2ser_thread);
+ cyg_thread_resume(ser2usb_thread);
+}
+
--- /dev/null
+//==========================================================================
+//
+// usb_serial_echo.c
+//
+// Example application for the USB serial layer in eCos.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+//
+// 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.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+// Contributors:
+// Date: 2008-06-02
+// Description: USB serial example application.
+//
+//####DESCRIPTIONEND####
+//===========================================================================
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/kernel.h>
+#include <cyg/io/usb/usbs_at91.h>
+#include <cyg/io/usb/usbs_serial.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEBUG_OUTPUT
+
+#if defined(DEBUG_OUTPUT)
+#define DBG diag_printf
+#else
+#define DBG (1) ? (void)0 : diag_printf
+#endif
+
+typedef unsigned char byte;
+
+// --------------------------------------------------------------------------
+// Data & Callback(s)
+// --------------------------------------------------------------------------
+
+#define BUF_SIZE 4096
+
+static byte rx_buf[2][BUF_SIZE+1], tx_buf[BUF_SIZE+1];
+
+// --------------------------------------------------------------------------
+// Main Routine
+// --------------------------------------------------------------------------
+
+int main(void)
+{
+ int n;
+ unsigned ibuf, next_buf;
+
+ // ----- Start USB subsystem -----
+
+ usbs_serial_start();
+
+ // ----- Get data from host and send it back -----
+
+ while (1) {
+ ibuf = 0;
+
+ // ----- Wait for the host to configure -----
+
+ usbs_serial_wait_until_configured();
+ cyg_thread_delay((cyg_tick_count_t) 10);
+
+ // ----- While configured read data & print to screen -----
+
+ usbs_serial_start_rx(&usbs_ser0, rx_buf[ibuf], BUF_SIZE);
+
+ while (usbs_serial_is_configured()) {
+
+ n = usbs_serial_wait_for_rx(&usbs_ser0);
+ next_buf = ibuf ^ 1;
+
+ usbs_serial_start_rx(&usbs_ser0, rx_buf[next_buf], BUF_SIZE);
+
+ if (n < 0) {
+ DBG("*** I/O Error: %d ***\n", n);
+ }
+ else {
+ memcpy(tx_buf, rx_buf[ibuf], n);
+ usbs_serial_tx(&usbs_ser0, tx_buf, n);
+ rx_buf[ibuf][n] = '\0';
+ DBG("%s", rx_buf[ibuf]);
+ }
+
+ ibuf = next_buf;
+ }
+ }
+
+ return 0;
+}
+
--- /dev/null
+#===============================================================================
+#
+# bulk-boundaries.tcl
+#
+# Support for USB testing
+#
+#===============================================================================
+#####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.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+#===============================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): asl
+# Date: 2006-04-21
+# Purpose: Test the bulk endpoints with different sizes of packets
+# at the important boundaries.
+#
+#####DESCRIPTIONEND####
+#===============================================================================
+
+set pktsizes { 1 2 3 4 5 7 8 9 15 16 17 31 32 33 63 64 65 127 128 129 \
+ 255 256 257 511 512 513 1023 1024 1025 2047 2048 2049 \
+ 4095 4096 4097 }
+
+ if { 0 != [llength $usbtest::bulk_in_endpoints] } {
+ puts "Bulk IN endpoints: $usbtest::bulk_in_endpoints"
+ foreach ep $usbtest::bulk_in_endpoints {
+ puts [format " %2d: packet sizes %d to %d, padding %d" $ep \
+ $usbtest::bulk_in($ep,min_size) \
+ $usbtest::bulk_in($ep,max_size) \
+ $usbtest::bulk_in($ep,max_in_padding)]
+ foreach pktsize $pktsizes {
+ if { $pktsize <= $usbtest::bulk_in($ep,max_size) } {
+ puts [format "Testing IN endpoint %d with packet size %4d" \
+ $ep $pktsize]
+ usbtest::reset
+ usbtest::bulktest $ep in 5 txsize1=$pktsize format=byteseq \
+ data1=42 data* $usbtest::MULTIPLIER \
+ data+ $usbtest::INCREMENT
+ if { [usbtest::start 10] } {
+ puts "Passed"
+ } else {
+ puts "Failed"
+ foreach result $usbtest::results {
+ puts $result
+ }
+ }
+ }
+ }
+ }
+ }
+
+if { 0 != [llength $usbtest::bulk_out_endpoints] } {
+ puts "Bulk OUT endpoints: $usbtest::bulk_out_endpoints"
+ foreach ep $usbtest::bulk_out_endpoints {
+ puts [format " %2d: packet sizes %d to %d" $ep \
+ $usbtest::bulk_out($ep,min_size) \
+ $usbtest::bulk_out($ep,max_size)]
+ foreach pktsize $pktsizes {
+ if { $pktsize <= $usbtest::bulk_out($ep,max_size) } {
+ puts [format "Testing OUT endpoint %d with packet size %4d" \
+ $ep $pktsize]
+ usbtest::reset
+ usbtest::bulktest $ep out 5 txsize1=$pktsize format=byteseq \
+ data1=42 data* $usbtest::MULTIPLIER \
+ data+ $usbtest::INCREMENT rxsize1=4096
+ if { [usbtest::start 10] } {
+ puts "Passed"
+ } else {
+ puts "Failed"
+ foreach result $usbtest::results {
+ puts $result
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+#ifndef CYGONCE_ISO_FNMATCH_H
+#define CYGONCE_ISO_FNMATCH_H
+/*========================================================================
+//
+// fnmatch.h
+//
+// fnmatch()
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2007 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Peter Korsgaard <peter.korsgaard@barco.com>
+// Contributors:
+// Date: 2007-01-24
+// Purpose: This file provides the fnmatch() function
+// required by POSIX 1003.2-1992, section B.6.
+// Description: The real contents of this file get set from the
+// configuration (set by the implementation)
+// Usage: #include <fnmatch.h>
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/isoinfra.h> /* Configuration header */
+
+/* INCLUDES */
+
+#ifdef CYGBLD_ISO_FNMATCH_HEADER
+# include CYGBLD_ISO_FNMATCH_HEADER
+#endif
+
+#endif /* CYGONCE_ISO_FNMATCH_H multiple inclusion protection */
+
+/* EOF fnmatch.h */
--- /dev/null
+#ifndef CYGONCE_ISO_SYS_TIME_H
+#define CYGONCE_ISO_SYS_TIME_H
+/*========================================================================
+//
+// sys/time.h
+//
+// struct timeval and gettimeofday()
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Limited
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Alexander Neundorf <neundorf@kde.org>
+// Contributors:
+// Date: 2005-10-04
+// Purpose: This file provides the time macros, types and functions
+// required by ISO C and POSIX 1003.1.
+// Description: The real contents of this file get set from the
+// configuration (set by the implementation)
+// Usage: #include <sys/time.h>
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/isoinfra.h> /* Configuration header */
+
+/* INCLUDES */
+
+/* This is the "standard" way to get NULL and size_t from stddef.h,
+ * which is the canonical location of the definitions.
+ */
+#define __need_NULL
+#define __need_size_t
+#include <stddef.h>
+
+#include <time.h>
+#ifdef CYGBLD_ISO_STRUCTTIMEVAL_HEADER
+# include CYGBLD_ISO_STRUCTTIMEVAL_HEADER
+#else
+
+/*
+ * Structure returned by gettimeofday(2),
+ * and used in other calls such as select(2).
+ */
+struct timeval {
+ time_t tv_sec; /* seconds */
+ time_t tv_usec; /* and microseconds */
+};
+
+#endif
+
+
+#endif /* CYGONCE_ISO_SYS_TIME_H multiple inclusion protection */
+
+/* EOF sys/time.h */
--- /dev/null
+//==========================================================================
+//
+// timeslice2.c
+//
+// Timeslice 2 test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Limited
+//
+// 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: 2001-06-18
+// Description: An additional timeslicing test.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/kernel/smp.hxx>
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+//==========================================================================
+
+#if defined(CYGSEM_KERNEL_SCHED_TIMESLICE) && \
+ defined(CYGFUN_KERNEL_API_C) && \
+ defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \
+ defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+//==========================================================================
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#define NTHREADS_MAX (CYGNUM_KERNEL_CPU_MAX*6)
+
+static int ncpus = CYGNUM_KERNEL_CPU_MAX;
+
+static char test_stack[STACK_SIZE];
+static cyg_thread test_thread;
+static cyg_handle_t main_thread;
+
+static char hipri_stack[STACK_SIZE];
+static cyg_thread hipri_thread_obj;
+static cyg_handle_t hipri_thread;
+
+static char stacks[NTHREADS_MAX][STACK_SIZE];
+static cyg_thread test_threads[NTHREADS_MAX];
+static cyg_handle_t threads[NTHREADS_MAX];
+
+static volatile int failed = false;
+
+static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX];
+
+//==========================================================================
+
+void
+test_thread_timeslice(CYG_ADDRESS id)
+{
+ for(;;)
+ slicerun[id][CYG_KERNEL_CPU_THIS()]++;
+}
+
+//==========================================================================
+
+void run_test_timeslice(int nthread)
+{
+ int i,j;
+ cyg_uint32 cpu_total[CYGNUM_KERNEL_CPU_MAX];
+ cyg_uint32 cpu_threads[CYGNUM_KERNEL_CPU_MAX];
+ cyg_uint32 thread_total[NTHREADS_MAX];
+
+ CYG_TEST_INFO( "Timeslice2 Test: Check timeslicing works under preemption");
+
+ // Init flags.
+ for (i = 0; i < nthread; i++)
+ for( j = 0; j < ncpus; j++ )
+ slicerun[i][j] = 0;
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test_thread_timeslice, // entry
+ i, // index
+ "test_thread", // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume( threads[i]);
+ }
+
+ // Just wait a while, until the threads have all run for a bit.
+ cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS*100 );
+
+ // Suspend all the threads
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_suspend(threads[i]);
+ }
+
+
+ // And check that a thread ran on each CPU, and that each thread
+ // ran.
+
+
+ diag_printf(" Thread ");
+ for( j = 0; j < ncpus; j++ )
+ {
+ cpu_total[j] = 0;
+ cpu_threads[j] = 0;
+ // " %11d" __123456789ab"
+ diag_printf(" CPU %2d",j);
+ }
+ // " %11d" __123456789ab"
+ diag_printf(" Total\n");
+ for (i = 0; i < nthread; i++)
+ {
+ thread_total[i] = 0;
+ diag_printf(" %2d ",i);
+ for( j = 0; j < ncpus; j++ )
+ {
+ thread_total[i] += slicerun[i][j];
+ cpu_total[j] += slicerun[i][j];
+ if( slicerun[i][j] > 0 )
+ cpu_threads[j]++;
+ diag_printf(" %11d",slicerun[i][j]);
+ }
+ diag_printf(" %11d\n",thread_total[i]);
+ if( thread_total[i] == 0 )
+ failed++;
+ }
+
+ diag_printf(" Total ");
+ for( j = 0; j < ncpus; j++ )
+ diag_printf(" %11d",cpu_total[j]);
+ diag_printf("\n");
+ diag_printf("Threads ");
+ for( j = 0; j < ncpus; j++ )
+ {
+ diag_printf(" %11d",cpu_threads[j]);
+ if( cpu_threads[j] < 2 )
+ failed++;
+ }
+ diag_printf("\n");
+
+ // Delete all the threads
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ CYG_TEST_INFO( "Timeslice2 Test: done");
+}
+
+
+//==========================================================================
+
+void
+hipri_test(CYG_ADDRESS id)
+{
+ while( 1 )
+ {
+ cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS/2 );
+ }
+}
+
+//==========================================================================
+
+void
+run_tests(CYG_ADDRESS id)
+{
+ int step;
+ int nthread;
+
+ // Try to run about 10 times in total, with varying numbers of threads
+ // from only one extra up to the full set:
+
+ step = (NTHREADS_MAX - (1 + CYG_KERNEL_CPU_COUNT()))/10;
+ if( step == 0 ) step = 1;
+
+ for( nthread = 1 + CYG_KERNEL_CPU_COUNT() ;
+ nthread <= NTHREADS_MAX ;
+ nthread += step )
+ run_test_timeslice(nthread);
+
+ if( failed )
+ CYG_TEST_FAIL_FINISH("Timeslice2 test failed\n");
+
+ CYG_TEST_PASS_FINISH("Timeslice2 test OK");
+}
+
+//==========================================================================
+
+void timeslice_main( void )
+{
+ CYG_TEST_INIT();
+
+ // Work out how many CPUs we actually have.
+ ncpus = CYG_KERNEL_CPU_COUNT();
+
+ cyg_thread_create(0, // Priority - just a number
+ run_tests, // entry
+ 0, // index
+ "run_tests", // Name
+ test_stack, // Stack
+ STACK_SIZE, // Size
+ &main_thread, // Handle
+ &test_thread // Thread data structure
+ );
+ cyg_thread_resume( main_thread);
+
+ cyg_thread_create(5, // Priority - just a number
+ hipri_test, // entry
+ 0, // index
+ "hipri_run", // Name
+ hipri_stack, // Stack
+ STACK_SIZE, // Size
+ &hipri_thread, // Handle
+ &hipri_thread_obj // Thread data structure
+ );
+ cyg_thread_resume( hipri_thread);
+
+ cyg_scheduler_start();
+}
+
+//==========================================================================
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ timeslice_main();
+}
+
+//==========================================================================
+
+#else // CYGSEM_KERNEL_SCHED_TIMESLICE etc
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("Timeslice test requires:\n"
+ "CYGSEM_KERNEL_SCHED_TIMESLICE &&\n"
+ "CYGFUN_KERNEL_API_C && \n"
+ "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+ CYG_TEST_NA("Timeslice test requirements");
+}
+
+#endif // CYGSEM_KERNEL_SCHED_TIMESLICE etc.
+
+//==========================================================================
+// EOF timeslice2.c
--- /dev/null
+redboot-guide-a4.aux
+redboot-guide-a4.log
+redboot-guide-a4.out
+redboot-guide-a4.pdf
+redboot-guide-a4.tex
+redboot-guide-letter.aux
+redboot-guide-letter.log
+redboot-guide-letter.out
+redboot-guide-letter.pdf
+redboot-guide-letter.tex
+*.html
\ No newline at end of file
--- /dev/null
+//==========================================================================
+//
+// flash_load.c
+//
+// RedBoot file/image loader into flash
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric LTD
+//
+// 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): Oliver Munz
+// Contributors: om, asl
+// Date: 2006-02-21
+// Purpose:
+// Description:
+//
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <redboot.h>
+#include <flash_load.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/infra/cyg_ass.h>
+
+static int flash_block_size;
+
+static cyg_uint8 * current_flash_page;
+
+/* Allocation of the flash-sector size RAM-buffer is done */
+static bool init_done = false;
+
+/* We have initialized the current page ready for writing */
+static bool flash_page_init = false;
+
+static cyg_uint8 *flash_buffer;
+
+// If the io flash code outputs when erasing/writing it will upset the
+// download over the communications channel. So we install a dummy
+// print function.
+static int dummy_printf(const char *fmt, ...){
+ return 0;
+}
+
+// Calculate the address of the first byte in a flash block
+static cyg_uint8 * flash_block_begin(cyg_uint32 addr)
+{
+ return (cyg_uint8 *)
+ ((addr / flash_block_size) * flash_block_size);
+}
+
+// Initialize the loading process
+void flash_load_start(void)
+{
+ flash_init(dummy_printf);
+
+ init_done = true;
+ flash_page_init = false;
+}
+
+// Write a byte into flash. We maintain a copy in RAM of the FLASH
+// page we are currently "writing" into. This copy is loaded with the
+// current contents of the FLASH page when the first byte is "written"
+// to the page. The "writes" are then made into the RAM copy. We only
+// write to FLASH when there is a "write" outside of the current page,
+// or the flash_load_finish function is called.
+void flash_load_write(cyg_uint8 *flash_addr, cyg_uint8 value)
+{
+
+ cyg_uint32 retcode = FLASH_ERR_OK;
+ void * err_addr;
+ cyg_uint32 addr = (cyg_uint32)flash_addr;
+ cyg_uint32 offset;
+
+ if (!flash_page_init) {
+ /* First Byte for the current flash block. Read the current contents */
+ current_flash_page = flash_block_begin(addr);
+ flash_read(flash_buffer, current_flash_page, flash_block_size, &err_addr);
+ flash_page_init = true;
+ }
+ if (flash_block_begin(addr) != current_flash_page) {
+ /* We have moved into the next flash page. Write the current
+ page so we can move on */
+ retcode = flash_erase(current_flash_page, flash_block_size, &err_addr);
+ if (retcode != FLASH_ERR_OK){ /* Flash ERROR */
+ diag_printf("Error erase at %p: %s\n", err_addr, flash_errmsg(retcode));
+ return;
+ }
+
+ retcode = flash_program(current_flash_page, flash_buffer,
+ flash_block_size, &err_addr);
+ if (retcode != FLASH_ERR_OK){
+ diag_printf("Error writing at %p: %s\n",
+ err_addr, flash_errmsg(retcode));
+ return;
+ }
+ current_flash_page = flash_block_begin(addr);
+ flash_read(flash_buffer, current_flash_page, flash_block_size, &err_addr);
+ }
+
+ offset = flash_addr - current_flash_page;
+ CYG_ASSERT(offset < flash_block_size, "offset not inside flash block");
+
+ flash_buffer[offset] = value;
+}
+
+// Program the current page into flash.
+void flash_load_finish(void)
+{
+ cyg_uint32 retcode = FLASH_ERR_OK;
+ void * err_addr;
+
+ if (init_done && flash_page_init) {
+ flash_page_init = false;
+
+ retcode = flash_erase(current_flash_page, flash_block_size, &err_addr);
+ if (retcode != FLASH_ERR_OK){
+ diag_printf("Error erase at %p: %s\n", err_addr, flash_errmsg(retcode));
+ } else {
+ retcode = flash_program(current_flash_page, flash_buffer,
+ flash_block_size, &err_addr);
+ if (retcode != FLASH_ERR_OK){
+ diag_printf("Error writing at %p: %s\n",
+ err_addr, flash_errmsg(retcode));
+ }
+ }
+ }
+ flash_init(diag_printf);
+}
+
+// This is called during redboot start up. We allocate a buffer the
+// size of the flash page.
+void
+flash_load_init(void)
+{
+ int flash_blocks;
+
+ flash_get_block_info(&flash_block_size, &flash_blocks);
+ workspace_end -= flash_block_size;
+
+ flash_buffer = workspace_end;
+}
+
+// Register this initialization function in the table
+RedBoot_init(flash_load_init, RedBoot_INIT_LAST);
+
+
+
--- /dev/null
+//==========================================================================
+//
+// flash_load.h
+//
+// Interfaces to byte writing into FLASH during load
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+// Copyright (C) 2006 Andrew Lunn <andrew.lunn@ascom.ch>
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: om, asl
+// Date: 2005-02-21
+// Purpose:
+// Description:
+//
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef FLASH_LOAD_H
+#define FLASH_LOAd_H
+
+// Prepare a write to flash.
+void flash_load_start(void);
+
+// Finish a write to flash
+void flash_load_finish(void);
+
+// Write a single byte. This will be buffered until either a full page
+// is available or flash_write_finish is called.
+void flash_load_write(cyg_uint8 *addr, cyg_uint8 value);
+
+#endif // FLASH_LOAD_H
+
--- /dev/null
+//==========================================================================
+//
+// gunzip.c
+//
+// RedBoot GZIP uncompress command
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Ltd
+//
+// 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.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Peter Korsgaard
+// Contributors: Peter Korsgaard
+// Date: 2005-04-04
+// Purpose:
+// Description:
+//
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <redboot.h>
+
+RedBoot_cmd("gunzip",
+ "Uncompress GZIP compressed data",
+ "-s <location> -d <location>",
+ do_gunzip
+ );
+
+void
+do_gunzip(int argc, char *argv[])
+{
+ struct option_info opts[2];
+ unsigned long src, dst;
+ bool src_set, dst_set;
+ _pipe_t pipe;
+ _pipe_t* p = &pipe;
+ int err;
+
+ init_opts(&opts[0], 's', true, OPTION_ARG_TYPE_NUM,
+ (void *)&src, (bool *)&src_set, "source address");
+ init_opts(&opts[1], 'd', true, OPTION_ARG_TYPE_NUM,
+ (void *)&dst, (bool *)&dst_set, "destination address");
+ if (!scan_opts(argc, argv, 1, opts, 2, 0, 0, "")) {
+ return;
+ }
+
+ // Must have src and dst
+ if (!src_set || !dst_set) {
+ // try to use load_address for src
+ if (dst_set
+ && load_address >= (CYG_ADDRESS)ram_start
+ && load_address < load_address_end) {
+ src = load_address;
+ diag_printf("Decompressing from %p to %p\n",
+ (void*)src, (void*)dst);
+ }
+ else
+ {
+ diag_printf("usage: gunzip -s <addr> -d <addr>\n");
+ return;
+ }
+ }
+
+ p->out_buf = (unsigned char*)dst;
+ p->out_max = p->out_size = -1;
+ p->in_buf = (unsigned char*)src;
+ p->in_avail = -1;
+
+ err = (*_dc_init)(p);
+
+ if (0 == err)
+ err = (*_dc_inflate)(p);
+
+ // Free used resources, do final translation of error value.
+ err = (*_dc_close)(p, err);
+
+ if (0 != err && p->msg) {
+ entry_address = (CYG_ADDRESS)NO_MEMORY;
+ diag_printf("Decompression error: %s\n", p->msg);
+ } else {
+ load_address = entry_address = (CYG_ADDRESS)dst;
+ load_address_end = (CYG_ADDRESS)p->out_buf;
+ diag_printf("Decompressed %lu bytes\n",
+ load_address_end - load_address);
+ }
+}