Engineer-to-Engineer Note EE-359
Technical notes on using Analog Devices products and development tools
Visit our Web resources http://www.analog.com/ee-notes and http://www.analog.com/processors or
e-mail processor.support@analog.com or processor.tools.support@analog.com for technical support.
ADSP-CM40x Boot Time Optimization and Device Initialization
Contributed by Andrew Caldwell and Kritika Shahu Rev 2 July 7, 2015
Copyright 2015, Analog Devices, Inc. All rights reserved. Analog Devices assumes no responsibility for customer product design or the use or application of customers’
products or for any infringements of patents or rights of others which may result from Analog Devices assistance. All trademarks and logos are property of their
respective holders. Information furnished by Analog Devices applications and development tools engineers is believed to be accurate and reliable, however no
responsibility is assumed by Analog Devices regarding technical accuracy and topicality of the content provided in Analog Devices Engineer-to-Engineer Notes.
Introduction
The ADSP-CM40x family of mixed-signal control processors provide on-chip programmable SPI flash
memory for code and data storage. The SPI peripheral and the implementation of an instruction cache on
ADSP-CM40x processors allow for code execution directly from the on-chip SPI flash device.
The processor, when originally released from reset, executes code from the on-chip boot ROM space. This
boot code is responsible for initial processor configuration and for handling each of the processors
supported boot modes
[1]
.
The boot process is capable of vectoring and executing code directly from the on-chip SPI flash memory,
or it may load a boot image in the form of a boot stream to the processors internal SRAM.
The purpose of this EE-Note is to introduce users to techniques that may be used to reduce the initial system
bring-up time when using the SPI master boot mode for code execution and show how to implement device
initialization software to optimize the system hardware as early as possible before executing the end
application.
Example code compatible with IAR Embedded Workbench for ARM®
[4]
development tools is provided in
the ADSP-CM40x Enablement Software Package
[3]
.
Optimizing Boot Time
In order to minimize processor bring-up time, it is important to optimize system clocks and configure core
features/peripherals as early as possible in the boot process. By default, the processor exits the reset state
with the PLL in bypass mode to ensure that the oscillator watchdog - a peripheral used to detect the most
probable oscillator failures, such as loss of input clock or harmonic oscillation - can be configured
appropriately before bringing the PLL out of bypass mode.
In order to optimize the bring-up time for SPI master boot mode, it is also required to configure the SPI
peripheral and cache controller for optimal performance. The SPI flash memory can be configured in
command skip mode, and the cache pre-fetch feature can be enabled in order to optimize execution of code
directly from internal flash.
There are a number of ways to configure the system with processor initialization routines for the Clock
Generation Unit (CGU), Dynamic Power Management block (DPM), Oscillator Watchdog (OSCWD), Serial
Peripheral Interface (SPI), and cache controller.
ADSP-CM40x Boot Time Optimization and Device Initialization (EE-359) Page 2 of 11
1. Initialize all required units from main() in the user application code.
2. Use an initialization block, if booting the processor using a compliant boot stream consisting of
block headers and payload.
3. Implement a multi-application approach, where device initialization is maintained in a separate piece
of firmware from the end application.
4. Utilize the __low_level_init() function of the IAR Embedded Workbench run-time startup.
This document will focus on the latter two options to configure the processor efficiently and early in the
boot process prior to the rest of the runtime initialization sequence. A brief introduction to the other two
methods is also provided.
The selected methods are two distinctly different approaches to the same problem, each having its own
benefits and limitations. By providing examples of how to implement these two approaches, users can adopt
a strategy that is best suited to their requirements.
Initializing the Units from main() in the Final Application
Initializing all units at the beginning of the application code is the least efficient way to configure the
processor and results in extended bring-up time.
The DPM and CGU blocks are just some of the components that may be required to be configured. It is
advisable to execute the initialization routine from internal SRAM, as the clock being supplied to the SPI
flash device will also be reconfigured during the process.
The run-time setup code for the user application will copy all code and data intended for internal SRAM
during the execution of the startup sequence before executing the main routine where the hardware is then
optimized. Since the PLL is bypassed during the copying operation, the bring-up time is extended.
For those applications that are not concerned about boot time requirements, this is certainly a viable option
and perhaps the simplest to implement. A single project is required, with the only requirement being that
code brings the PLL out of bypass and reconfigures the CGU block to be executed from SRAM (not from
SPI flash memory).
Initialization Codes from Boot Streams
The on-chip boot ROM provides a boot kernel that is fully capable of loading a user application in a
distributed manner to the on-chip SRAM, provided that the application image is in a compliant boot stream
format. This boot stream format supports a feature referred to as ‘init code’. During the booting process, a
block header instructs the boot kernel that init code has been loaded. The boot kernel will then execute this
code before continuing with the boot process. It is an effective means of optimizing the system early in the
boot process before the rest of the user application has been loaded. For further details, please refer to the
Boot ROM and Booting the Processor section of the Hardware Reference Manual
[2]
.
Using Multiple Applications for Initialization
The multiple application approach requires the user to create and load a small application solely for the
purposes of configuring the optimization features of the processor. As the application is small, a minimum
amount of user code and data are loaded from the SPI flash memory to the internal SRAM before being
executed. Once executed, the application vectors to the next application in the flash memory space, whether