CYGPKG_HAL_M68K_MCF5275 — eCos Support for Freescale MCF5275 Processors


The Freescale MCF5275 microcontroller family covers the MCF5274, MCF5274L, MCF5275 and MCF5275L ColdFire processors. These differ slightly in the set of peripherals available. The L parts are limited to a single ethernet controller and 2 UARTs, with the non-L parts having two ethernet controllers and 3 UARTs. The MCF5275L and MCF5275 parts have a hardware cryptography accelerator, which is not currently used by eCos.


The eCos MCF52xx ethernet driver currently only supports a single ethernet device (FEC0), so the second ethernet available on the MCF5274 and MCF5275 parts is not currently used by eCos.

The processor HAL package CYGPKG_HAL_M68K_MCF5275 provides support for all MCF5275 processors, although at the time of writing it has only been tested on an MCF5274. It complements the M68K architectural HAL package CYGPKG_HAL_M68K and the variant HAL package CYGPKG_HAL_M68K_MCFxxxx. An eCos configuration should also include a platform HAL package to support board-level details. e.g. how the on-chip peripherals are connected to the outside world.


The MCF5275 processor HAL package should be loaded automatically when eCos is configured for appropriate target hardware. It should never be necessary to load this package explicitly. Unloading the package should only happen as a side effect of switching target hardware.

The package's CDL script provides default interrupt priorities for some of the mcf5275's on-chip devices. This makes it easier for the various device driver packages to install unique interrupt priorities, as required by the hardware.

Most of the package's configuration options relate to hardware. The settings are generally determined by the platform HAL and there is little need for application developers to change them. The first hardware option is CYGHWR_HAL_M68K_MCF5275_CPU, identifying the specific MCF5275 processor being used. Legal values are MCF5274L, MCF5275L, MCF5274 and MCF5275. Typically the platform HAL will set this option via a CDL constraint.

Component CYGHWR_HAL_M68K_MCF5275_GPIO contains various options related to pin-connectivity. This gives full control over the PAR pin assignment registers, and for those pins configured as GPIO it is also possible to control the pin direction and data settings. These options are used to initialize the processor's GPIO module early on during system initialization, but applications may change settings later on as necessary. The platform HAL can define CYGHWR_HAL_M68K_MCF5275_BOARD_PINS to specify the default I/O pin mapping to be used.

The GPIO settings are used to determine default settings for on-chip peripherals, including the three UARTs, the I²C bus and the QSPI bus. For example if none of the relevant GPIO pins are assigned to UART2 then component CYGHWR_HAL_M68K_MCFxxxx_UART2 will be disabled by default, and that UART cannot be used for HAL diagnostics nor accessed via the serial device driver. It is possible to override these settings if desired, for example if a UART is connected but will be manipulated directly by application code instead of via a device driver.

  1. For each of the three on-chip UARTs there will be a component, e.g. CYGHWR_HAL_M68K_MCFxxxx_UART0, determining whether or not the UART is usable on the target hardware. There are additional options CYGHWR_HAL_M68K_MCFxxxx_UART0_RTS and CYGHWR_HAL_M68K_MCFxxxx_UART0_CTS indicating whether or not the hardware handshake lines are connected, and CYGHWR_HAL_M68K_MCFxxxx_UART0_RS485_RTS to indicate that the RTS line controls an RS485 transceiver.
  2. Component CYGHWR_HAL_M68K_MCF5275_I2C determines whether or not the processor HAL will instantiate an I²C bus device hal_mcfxxxx_i2c_bus. There are also options to control the interrupt priority and to set the FDR register which controls the bus speed. The default bus speed will be the standard I²C bus speed of 100KHz, or as close as can be achieved given hardware limitations.
  3. Component CYGHWR_HAL_M68K_MCF5275_SPI determines whether or not the processor HAL will instantiate an SPI bus device hal_mcfxxxx_qspi_bus. It contains an additional configuration option for the interrupt priority.

For configurations which include the eCos kernel, CYGIMP_HAL_M68K_MCF5275_IDLE determines what happens when the idle thread runs.

The option CYGPKG_HAL_M68K_MCF5275_ISR_PRIORITIES provides support for configuring the interrupt priorities as detailed in the interrupt priorities section.

The HAL Port

This section describes how the MCF5275 processor HAL package implements parts of the eCos HAL specification. It should be read in conjunction with similar sections from the architectural and variant HAL documentation.


The header file cyg/hal/proc_io.h provides definitions of MCF5275-specific on-chip peripherals. Many of the on-chip peripherals are compatible with those on the MCF5282 or other ColdFire processors, and for those peripherals it is the var_io.h header provided by the MCFxxxx variant HAL which provides the appropriate definitions. Both headers are automatically included by the architectural header cyg/hal/hal_io.h, so typically application code and other packages will just include the latter.

The MCF5275 reserves a 1GB area of memory for the internal peripheral space. Usually this is mapped between 0x40000000 and 0x7FFFFFFF. Most of this space is not used, but accessing it can cause problems including apparently locking up the processor such that either a hard reset or a watchdog timeout is needed. The target-side gdb stubs code can trap most accesses initiated by host-side gdb, but cannot protect against errant accesses by application code.

Interrupt Handling

The header file cyg/hal/proc_intr.h provides VSR and ISR vector numbers for all interrupt sources. The VSR vector number, for example CYGNUM_HAL_VECTOR_TMR0, should be used for calls like cyg_interrupt_get_vsr. It corresponds directly to the M68K exception number. The ISR vector number, for example CYGNUM_HAL_ISR_TMR0, should be used for calls like cyg_interrupt_create. This header file is automatically included by the architectural header cyg/hal/hal_intr.h, and other packages and application code will normally just include the latter.

The eCos HAL macros HAL_INTERRUPT_MASK, HAL_INTERRUPT_UNMASK, HAL_INTERRUPT_ACKNOWLEDGE, and HAL_INTERRUPT_CONFIGURE are implemented by the processor HAL. The mask and unmask operations are straightforward, simply manipulating the IMR registers in the on-chip interrupt controllers. The acknowledge macro is only relevant for external interrupts coming in via the edge port module and will clear the interrupt by writing to the EPIER register. There is no simple way to clear interrupts generated by other sources. Instead each such interrupt has to be cleared in a device-specific way, and that is the responsibility of the appropriate device driver. The configure macro is only relevant for external interrupts and involves manipulating the edge port module.

The HAL_INTERRUPT_SET_LEVEL macro, used implicitly by higher level code such as cyg_interrupt_create, is also implemented by the processor HAL. In the MCF5275 processor interrupt priorities have to be managed very carefully. Interrupts are managed via two interrupt controllers, INTC0 and INTC1. Each controller contains ICRxx control registers for each interrupt to manage that interrupt's priority. The HAL_INTERRUPT_SET_LEVEL macro simply fills in the ICRxx register.

An ICRxx value is a six-bit number. The top three bits correspond to the standard M68K IPL interrupt level. The bottom three bits give a finer-grained priority within that IPL level. For example, if the priority argument to cyg_interrupt_create is 42 then that corresponds to an IPL level of 5 and a finer-grained priority of 2. If the system has been configured to support nested interrupts and a level 42 interrupt goes off, the processor's IPL level will be set to 5 so all interrupts with priorities < 48 will remain blocked. The finer-grained priority controls what happens when two interrupts with the same IPL level go off at the same time.

Interrupt priorities between 0 and 7 would correspond to an IPL level of 0. The interrupt controller can only raise an interrupt if the IPL level is at least 1, so the smallest valid interrupt priority is 8. Interrupt priorities between 56 and 63 correspond to IPL level 7, and such interrupts are non-maskable and must be used with care. These interrupts cannot be managed safely by the usual eCos ISR and DSR mechanisms, instead application code will have to install a custom VSR and manage the entire interrupt. This means that interrupt priorities should normally be in the range 8 to 55.

As a special case, external interrupts coming in via the edge port module have hard-wired priorities which do not clash with the programmable ones. For these the priority argument to HAL_INTERRUPT_SET_LEVEL and higher-level code is ignored.

The MCF5275 interrupt controllers have a major restriction: all interrupt priorities within each controller must be unique. If two interrupts go off at the same time and have exactly the same priority then the controllers' behaviour is undefined. In a typical application some of the interrupts will be handled by eCos device drivers while others will be handled directly by application code. Since eCos cannot know which interrupts may get used, it cannot allocate unique priorities. Instead this has to be left to the application developer. eCos does provide configuration options such as CYGNUM_KERNEL_COUNTERS_CLOCK_ISR_PRIORITY and CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_ISR_PRIORITY to provide control over the eCos-managed interrupts, and provides default values for these which are unique.

To ensure that the configured interrupt priorities are unique the processor HAL comes with a test case intrpri. The source code for this can be found in the package's tests subdirectory. The test examines the ICRxx registers in both interrupt controllers. It will report all priorities that are in use, and report a failure if a non-unique priority is detected. This code may prove useful for application developers trying to allocate interrupt priorities.


Non-unique interrupt priorities can lead to very confusing system behaviour. For example if the PIT3 system clock (interrupt 0x27) and UART2 (interrupt 0x0F) are accidentally given the same priority and go off at the same time, the interrupt controller may actually issue an interrupt 0x2F, the bitwise-or of the two interrupt numbers. That interrupt belongs to the on-chip USB module. There may not be an installed handler for that interrupt at all, and even if there is a handler it will only manipulate the USB hardware and not clear the system clock and UART interrupts. Hence the system is likely to go into a spin, continually trying to service the wrong interrupt. To track down such problems during debugging it may prove useful to install a breakpoint on the hal_arch_default_isr function.

Clock Support

The processor HAL provides support for the eCos system clock. This always uses hardware timer PIT3, which should not be manipulated directly by application code. If gprof-based profiling is enabled then that will use hardware timer PIT2. PIT timers 0 and 1 are never used by eCos so application code is free to manipulate these as required.

Some of the configuration options related to the system clock, for example CYGNUM_HAL_RTC_PERIOD, are actually contained in the platform HAL rather than the processor HAL. These options need to take into account the processor clock speed, a characteristic of the platform rather than the processor.

Cache Handling

The MCF5275 has 16K of cache. Usually this will be set up as a split cache, 8K for instructions and 8K for data, which should give the best performance for typical applications. The standard HAL cache macros are supported.

On some platforms it may be better to organize the cache differently. For example if the platform involves running code only out of internal SRAM which may access external data, it may be possible to improve performance by using a 16K data cache instead of a split cache. This is controlled by CYGIMP_HAL_M68K_MCF5275_CACHE_MODE, which may be either a fixed #define or a configuration option depending on the platform. For more details see the header file proc_cache.h.

The HAL also defines a macro HAL_MEMORY_BARRIER() which acts to synchronize the pipeline, delaying execution until all previous operations including all pending writes are complete. This will usually be necessary when interacting with devices that access memory directly.

Other Issues

The MCF5275 processor HAL does not affect the implementation of data types, stack size definitions, SMP support, system startup, or debug support. The MCFxxxx variant HAL versions of HAL_LSBIT_INDEX and HAL_MSBIT_INDEX are used since the processor supports the ff1.l and bitrev.l instructions. HAL_DELAY_US is implemented as a simple counting loop. HAL_IDLE_THREAD_ACTION may be defined depending on configuration option CYGIMP_HAL_M68K_MCF5275_IDLE.

Other Functionality

The processor HAL will instantiate a cyg_i2c_bus structure hal_mcfxxxx_i2c_bus when the configuration option CYGHWR_HAL_M68K_MCFxxxx_I2C is enabled. That option is enabled by default if various GPIO pins are configured appropriately. The implementation is provided by the CYGPKG_DEVS_I2C_MCFxxxx device driver. The processor HAL does not know what I²C devices may be attached to the bus so that is left to the platform HAL.

The processor HAL will instantiate a cyg_spi_bus structure hal_mcfxxxx_qspi_bus when the configuration option CYGHWR_HAL_M68K_MCFxxxx_SPI is enabled. That option is enabled by default if various GPIO pins are configured appropriately. The implementation is provided by the CYGPKG_DEVS_SPI_MCFxxxx_QSPI device driver. The processor HAL does not know what SPI devices may be attached to the bus so that is left to the platform HAL. All SPI device structures should be placed in the table mcfxxxx_qspi.