This document contains information on a new product. Specifications and information herein are subject to change
without notice.
Freescale reserves the right to make changes without further notice to any products herein. Freescale makes no warranty,
representation or guarantee regarding the suitability of its products for any particular purpose, nor does Freescale assume any
liability arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without
limitation consequential or incidental damages. "Typical" parameters which may be provided in Freescale data sheets and/or
specifications can and do vary in different applications and actual performance may vary over time. All opening parameters,
including "Typicals" must be validated for each customer application by customer's technical experts. Freescale does not convey
any license under its patent rights nor the rights of others. Freescale products are not designed, intended, or authorized for use as
components in systems intended for surgical implant into the body, or other applications intended to support or sustain life, or for any
other application in which the failure of the Freescale product could create a situation where personal injury or death may occur.
Should Buyer purchase or use Freescale products for any such unintended or unauthorized application, Buyer shall indemnify and
hold Freescale and its officers, employees, subsidiaries, affiliates, and distributors harmless against all claims, costs, damages, and
expenses, and reasonable attorney fees arising out of, directly or indirectly, any claim of personal injury or death associated with
such unintended or unauthorized use, even if such claim alleges that Freescale was negligent regarding the design or manufacture
of the part. Freescale is registered trademarks of Freescale Semiconductor, Inc. Freescale Semiconductor, Inc. is an Equal
Opportunity/Affirmative Action Employer. All other tradenames, trademarks, and registered trademarks are the property of their
respective owners.
How to reach us:
North and South America +1 800 521 6274 6AM-5PM Mountain Standard Time
Europe: 9AM-5PM Central European Time
English +44 1296 380 456 or +46 8 52200080
German +49 89 92103 559
French +33 1 69 35 48 48
Asia:
Asia Pacific Region excl.India +800 2666 8080 8AM-6PM Hong Kong
This user’s manual is targeted for Freescale 56F8xxx application developers. Its purpose is to
describe the development environment, the software modules and the tools for the 56F8xxx and
the Application Programming Interface (API). Simply, this manual describes how to use the
Freescale DSP56800E_Quick_Start tool to develop software for the Freescale 56F8xxx Digital
Signal Controllers (DSC).
1.1 Overview
The DSP56800E_Quick_Start development environment provides fully debugged peripheral
drivers, examples and interfaces, that allow programmers to create their own C application code,
independent of the core architecture. This environment has been developed to complement the
existing development environment for Freescale 56F8xxx embedded processors. It provides a
software infrastructure that allows development of efficient, ready to use high level software
applications, that are fully portable and reusable between different core architectures. The
maximum portability is achieved for devices with comparable on-chip peripheral modules.
This manual contains information specific only to DSP56800E_Quick_Start tool as it applies to
the Freescale 56F8xxx software development. Therefore it is required that users of the
DSP56800E_Quick_Start tool should be familiar with the 56800E family in general, as described
in the DSP56800E 16-Bit DSP Core Reference Manual (DSP56800ERM/D), MC56F8300Peripheral User Manual (MC56F8300UM/D) and the 56F8000 Peripheral Reference Manual
(MC56F8000RM), before continuing. The 56F8xxx devices are supported by a complete set of
hardware development boards - evaluation modules (EVMs) and development system cards for
fast system development (e.g. Legacy Motor Interface Daughter Card).
Comprehensive information about available tools and documentation can be found on Freescale
web pages:
http://www.freescale.com/
Freescale DSP56800E_Quick_Start tool is designed for and can be fully integrated with Freescale
CodeWarrior development tools. Before starting to explore the full feature set of the
DSP56800E_Quick_Start, one should install and become familiar with the CodeWarrior
development environment.
All together, the DSP56800E_Quick_Start, the CodeWarrior, and the EVMs create a complete
and scalable tool solution for easy, fast and efficient development.
The DSP56800E_Quick_Start environment is composed of the following major components:
core-system infrastructure, on-chip drivers with defined API, sample example applications,
Graphical Configuration Tool and FreeMASTER software support. This section brings very
illustrative information about these components, while the comprehensive description can be
found in specially targeted chapters.
1.1.1.1 Core-system Infrastructure
The core-system infrastructure creates the fundamental infrastructure for the 56F8xxx device
operation and enables further integration with other components, e.g. on-chip drivers. The basic
development support provided includes: setting of the required operation mode, commonly used
macro definitions, portable architecture-dependent register declaration, mechanism for static
configuration of on-chip peripherals as well as interrupt vectors, and the project templates.
1.1.1.2 On-chip Drivers
The on-chip drivers isolate the hardware-specific functionality into a set of driver commands with
defined API. The API standardizes the interface between the software and the hardware, see
Figure 1-1. This isolation enables a high degree of portability or architectural and hardware
independence for application code. This is mainly valid for devices with similar peripheral
modules. The driver code reuses lead for greater efficiency and performance.
Figure 1-1. Software Structure
1.1.1.3 Sample Applications
The DSP56800E_Quick_Start tool contains many sample applications that demonstrate how to
use on-chip drivers and how to implement some user-specific tasks. These sample examples are
kept simple and illustrative and their intention is to minimize the learning curve.
The Graphical Configuration Tool (GCT) is a graphical user interface (GUI), designed to provide
static chip and on-chip peripheral module setting/initialization, including association of the
interrupt vectors with user interrupt service routines.
The Graphical Configuration Tool is not required in order to use the DSP56800E_Quick_Start
environment, i.e. it is optional. Nevertheless, this tool simplifies the configuration of on-chip
peripheral modules and the device itself. It also guides the user by supplying a lot of useful
information and hints. It is therefore recommended to use the Graphical Configuration Tool.
1.1.1.5 FreeMASTER Software
The FreeMASTER application is a software tool initially created for developers of Motor Control
applications, but it may be extended to any other application development. This tool allows
remote control of an application using a user-friendly graphical environment running on a PC. It
also provides the ability to view some real-time application variables in both textual and graphical
form.
Main features:
•Graphical environment
•Visual Basic Script or Java Script can be used for control of target board
•Easy to understand navigation
•Connection to target board possible over a network, including Internet
•Demo mode with password protection support
•Visualization of real-time data in Scope window
•Acquisition of fast data changes using integrated Recorder
•Value interpretation using custom defined text messages
•Built-in support for standard variable types (integer, floating point, bit fields)
•Several built-in transformations for real type variables
•Automatic variable extraction from CodeWarrior linker output files (MAP, ELF)
•Remote control of application execution
The FreeMASTER tool is not required in order to use the DSP56800E_Quick_Start environment,
i.e. it is optional. Nevertheless, FreeMASTER is a versatile tool to be used for multipurpose
algorithms and applications. It provides a lot of excellent features, including:
•Real-Time debugging
•Diagnostic tool
•Demonstration tool
•Education tool
The full description can be found in the FreeMASTER User Manual attached to the
FreeMASTER tool.
This chapter provides the information required to get the DSP56800E_Quick_Start tool installed
and running.
1.2.1 Install CodeWarrior Development Tools
CodeWarrior Development Studio 56800/E Hybrid Controllers provides a complete software
development environment for Freescale hybrid controllers. CodeWarrior is a windows based
Integrated Development Environment (IDE) with highly efficient C compilers.
As previously mentioned, Freescale DSP56800E_Quick_Start tool is designed for and can be
integrated with CodeWarrior development tools. With CodeWarrior tools, users can build
applications and integrate other software included as part of the DSP56800E_Quick_Start release.
Once the software is built, CodeWarrior tools allows users to download executable images into
the target platform and run or debug the downloaded code.
The rest of this section describes the general installation process of the CodeWarrior tools.
However, it is recommended to use the installation guide attached to the actual version of
CodeWarrior, if available.
To start the installation process, perform the following steps:
1. Insert the CodeWarrior CD-ROM into your computer's CD-ROM drive.
If Auto Install is disabled on your computer, click the Start button, select Run, and type the
CD-ROM's drive letter and \Setup.exe in the Open: text box. (e.g. D:\Setup.exe)
2. Follow the CodeWarrior software installation instructions on your screen.
Note: After installing CodeWarrior, remember to restart the computer. This restart ensures that
newly installed drivers will be available for use.
3. Register CodeWarrior
•Click the St art button, then select CodeWarrior Registration from the CodeWarrior group. This
runs the MWRegister.exe program.
•Enter your registration number and contact information. If you do not have a registration number,
leave the Registration Number text box blank. • Click OK and send the resulting text file (e.g.
MWRegistration.txt) to license@metrowerks.com. A license key will be sent to you via E-mail.
4. Install the license key.
•Locate the license.dat file in the CodeWarrior installation directory and open this file with any
standard text editor, for example, Notepad.
•Copy or type the key starting on a new line at the bottom of the license.dat file. For more detailed
instructions see the License_Install.txt file in the Licensing directory.
In order for the DSP56800E_Quick_Start to integrate itself with the development tools, the
CodeWarrior tools should be installed prior to the installation of DSP56800E_Quick_Start
installation (see previous section). If the DSP56800E_Quick_Start tool is installed while
CodeWarrior is not present, users can only browse the installed software package, but will not be
able to build, download and run the released code. However, the installation can be simply
completed once CodeWarrior is installed, see Section 1.2.2.1.
The installation itself consists of copying the required files to the destination hard drive, checking
the presence of CodeWarrior and creating the shortcut under the Start->Programs menu.
Note: Each DSP56800E_Quick_Start release is installed in its own new directory named
DSP56800E_Quick_Start rX.Y (where X.Y denotes the release number). Thus, it enables to
maintain the older releases and projects. It gives free choice to select the active release.
To start the installation process, perform the following steps:
1. Execute DSP56800E_Quick_Start_rXY.exe
2. Follow the DSP56800E_Quick_Start software installation instructions on your screen.
To integrate DSP56800E_Quick_Start with CodeWarrior, perform the following steps:
3. Set path to the DSP56800E_Quick_Start source within IDE
a) Launch CodeWarrior IDE from the Start->Programs->Freescale CodeWarrior menu
b) Open IDE Preferences dialog window using Edit->Preferences...
c) Select Source Trees panel from IDE Preferences Panels-General
d) Type DSP56800E_Quick_Start Source to the Name box
e) Choose Absolute Path as a path type
f)Click Choose and locate the DSP56800E_Quick_Start installation directory, e.g.
Setting Up a Remote Connection. A remote connection is a type of connection to use for
debugging along with any preferences that connection may need. To create a new remote
connection for the DSP56800E_Quick_Start:
a) Launch CodeWarrior IDE from the Start->Programs->Freescale CodeWarrior menu
b) On the main menu, select Edit -> Preferences
c) Click Remote Connections in the left column
d) Click the Add button - the New Connection window appears
e) In the Name edit box, type in HW as the connection name
f)In the Debugger combo box, select CCS 56800E Protocol Plug-in
g) In the Connection Type combo box, select CCS Remote Connection
h) Leave the check boxes unchecked (this is the default state)
This section describes the additional installation steps required if CodeWarrior is installed after
the DSP56800E_Quick_Start installation. Note: if this condition does not apply to you, skip this
section completely.
Suppose that CodeWarrior and DSP56800E_Quick_Start are now successfully installed. The next
step is to copy the content (i.e. the subdirectory) of the DSP56800E_Quick_Start Stationery
folder (e.g. ...Freescale\DSP56800E_Quick_Start r2.4\stationery) into the CodeWarrior root
folder (e.g. ...\CodeWarrior). This operation “registers” the DSP56800E_Quick_Start project
templates for the newly created projects. It is necessary to integrate DSP56800E_Quick_Start
with CodeWarrior as the last step. To do this, perform the following steps:
a) Launch CodeWarrior IDE from the Start->Programs->Freescale CodeWarrior menu
b) Open the IDE Preferences dialog window using Edit->Preferences...
c) Select the Source Trees panel from IDE Preferences Panels-General
d) Type DSP56800E_Quick_Start Source to the Name box
e) Choose Absolute Path as a path type
f)Click Choose and locate the DSP56800E_Quick_Start installation directory, e.g.
The Graphical Configuration Tool is installed together with the whole DSP56800E_Quick_Start
environment as a part of the Typical installation. The graphical configuration tool can also be
installed as a selectable component within the Custom installation.
The Graphical Configuration Tool is able to work as stand-alone, but integration with the
CodeWarrior IDE increases markedly the efficiency of this tool. This integration is based on the
IDE user-configurable menus and its interface for external plug-ins.
To integrate the Graphical Configuration Tool with CodeWarrior IDE, perform the following
steps:
a) Launch CodeWarrior IDE from the Start->Programs->Freescale CodeWarrior menu
b) Open the Commands and Key Bindings dialog window using Edit->Commands and
c) Unroll the desired menu command group (e.g. Project) from the command tree on the
left side of the dialog box.
d) Click on any item of unrolled tree
e) Click on button New Command
f)Type Co&nfiguration Tool to the Name box (char ‘&’ in front of char ‘n’ enables
selecting assigned menu item using Alt-n)
g) Click on check box Appears in Menus and tick it.
h) Click on button on the right side of the Execute edit box and browse for gct56F800.exe
i)Click on button on the right side of the Arguments edit box and select item Project File
directory from popup menu
j)If you want to assign key binding, click on button New Binding and press chosen key
combination, e.g. Ctrl+F12
k) Press button Save and close the dialog box
Now you should be able to execute the Graphical Configuration Tool from the CodeWarrior IDE
menu or by pressing the chosen key shortcut. Note that the DSP56800E_Quick_Start project
should be open in the IDE to quickly execute the Graphical Configuration Tool.
The FreeMASTER application can run on any computer with Microsoft Windows 98 or later
operating system. Before installing, the Internet Explorer 4.0 or higher (5.5 is recommended)
should be installed.
The following requirements result from those for the Internet Explorer 4.0 application:
Computer: 486DX/66 MHz or higher processor
Operating system: Microsoft Windows XP, Windows 2000, Windows NT4 with SP6, Windows
98
Required software: Internet Explorer 4.0 or higher installed. For selected features (e.g. regular
expression-based parsing), Internet Explorer 5.5 or higher is required.
Hard drive space: 8 MB
Other hardware requirements: Mouse, serial RS-232 port for local control, network access for
remote control
1.2.2.3.2 Target Development Board Requirements
To enable the FreeMASTER connection to the target board application, follow the instructions
provided with the embedded-side development tool. The recommended and fastest way to start
using FreeMASTER is by trying the sample application. Note that the sample application name
may still refer the “PC Master” software, which is the previous name of the FreeMASTER tool.
FreeMASTER is fully backward compatible with PC Master.
FreeMASTER software relies on the following items to be provided by the target development
board:
Interface: Serial communication port or the JTAG port (available on all Freescale EVM boards).
Data RAM Memory: Approximately 160 words of data memory plus the size of the recorder
buffer is needed for the full configuration. Optionally, some features can be disabled to reduce
required data memory size.
Program Flash Memory: Required size is approximately 2K words for the full configuration.
Optionally, some features can be removed to reduce required program memory size
1.2.2.3.3 Enabling FreeMASTER on Target Application
To enable the FreeMASTER operation on the target board application, see description and an
example in Chapter 6, “FreeMASTER Driver.” .
1.2.2.3.4 How to Install
The FreeMASTER application is an optional part of the DSP56800E_Quick_Start environment
and must be installed separately, e.g. running the fmaster13-1.exe.
1.2.3 Install MC56F8xxxEVM Hardware
The DSP56800E_Quick_Start for 56F8xxx has been designed and tested with the
MC56F83xxEVM or MC56F8xxxDEMO target hardware. If the user wants to quickly exercise
software applications included with DSP56800E_Quick_Start, MC56F8xxxEVM/DEMO
hardware must be installed.
The MC56F8xxxEVM/DEMO installation information is provided with CodeWarrior installation
and can be found in the following document (located in the CodeWarrior installationdirectory):
Once the DSP56800E_Quick_Start tool is installed, the user can build and run any of the released
demo applications for the MC56F83xxEVM / MC56F8xxxDEMO by opening and building the
project, using the CodeWarrior development environment. We will use pwm_demo.mcp as an
example:
Step 1: Launch CodeWarrior IDE from the Start->Programs->Freescale CodeWarrior menu.
Step 2: Using File->Open command, open the pwm_demo.mcp project by selecting, e.g.
Note: Select the corresponding directory according to your EVM board, for the
MC56F8346EVM, open the ..\DSP56800E_Quick_Start r2.4\sample_applications\
MC56F8346EVM\pwm_demo directory.
Step 3: Execute the application in the Debug mode by pressing the F5 key or choose the Debug
command from the Project menu.
Step 4: Run the application by pressing the green arrow (Run) in the debug window or choose the
Run command from the Project menu.
At this point, the application is running - the LEDs associated to the PWM outputs are flashing
now and the green LED is blinking periodically.
The subsequent chapters describe how to create a new application, how to use interrupts, how to
use on-chip drivers and other information required to successfully create a new application.
The Core System Infrastructure is one of the three main blocks that compose the
DSP56800E_Quick_Start tool (see Section 1.1.1 where the partitioning is described). Its purpose
is to provide the fundamental infrastructure for the 56800E device operation (e.g. sets the
operation mode, the interrupt handling, the initialization of the global variables, CodeWarrior
Compiler options). It also provides some additional support (commonly used macros, data types)
and enables further integration with On-chip Drivers.
2.1 Boot Sequence
The Core System Infrastructure provides the fundamental code which is executed before the
user’s main function. This code provides basic settings needed to initialize the chip, settings
required by the CodeWarrior Compiler, initialization of global variables. Finally it passes control
to the user’s application code (the main function).
Note: This chapter describes the boot process of the MC56F83xx family of microcontrollers
which contain the Boot Flash memory. The boot process of the devices without the dedicated
Boot Flash memory (MC56F80xx) is relatively simpler as the vector table need not to be
relocated. Except this difference, the other startup steps are common for all 56800E devices.
For the MC56F83xx devices, the post-reset execution flow may be briefly described as follows
(also see Figure 2-1):
1. After processor reset, the execution starts at the Hardware Reset vector in program memory,
where the DSP56800E_Quick_Start tool places its jump to the Start() assembly routine
— For the EXTBOOT=1 and EMI_MODE=0 processor configuration (processor external pins are
sampled during reset), the reset vector is located at address 0x0000 and the jump is supplied
directly from the first entry of vector table located in the interrupt_vectors section in vectors.c
file.
— For another configuration, the reset vector is located at address 0x20000. A jump to the Start()
routine is compiled on this address (in the boot_jump section in vectors.c file) while keeping
the full vector table on address 0x0000.
2. If the chip reset is generated by the watchdog module (COP), the same rules as in the
previous point apply, except that the second entry of the vector table is used. Again the COP
Reset vector is supplied from either the full vector table at address 0x0000
(interrupt_vectors section) or the reset jumps table at address 0x20000 (boot_jump
section). The default value of COP Reset vector is Start(), so the standard power-up code
is processed. The user is able to redefine the COP Reset service routine same way the other
interrupt vectors are installed (see Section 2.5.2 on page 2-27 for more details).
5. user’s main() function (in default project it is located in main.c)
6. userPostMain() function (in appconfig.c file)
The following subsections provide a detailed description of all initialization performed before
user’s main() function is called.
2.1.1 Power-up/Reset
The 56800E core specifies two reset vectors: Hardware Reset and COP Watchdog Reset. These
reset vectors are located at first two locations of interrupt vector table at address 0x0000 or
0x20000 depending on the configuration of the EXTBOOT and EMI_MODE pins. These vectors
identify the address of the program code where the program control is passed to on reset. In
applications developed with the DSP56800E_Quick_Start tool, the default entry point is the
Start() assembly routine in the startup.c file.
In the DSP56800E_Quick_Start tool, the vector table (vectors.c) is always linked at address
0x0000 for any processor configuration. To assure the startup code gets called after reset even for
the configurations where 0x20000 is the default vectors base, two jumps to the Start() are linked
at these addresses from the boot_jump section of the vectors.c file for both reset vectors. The
startup code then configures the interrupt controller to use the address 0x0000 as the vector table
base address.
2.1.2
The entry point of all projects developed with the DSP56800E_Quick_Start tool is the Start()
assembly routine located in the startup.c file in {project}\SystemConfig directory. This routine
performs the following initialization:
Start()
•configures the interrupt controller to use the address 0x0000 as the vector base address
•sets the OMR register according to the settings in global application configuration file (appconfig.h)
•initializes the On-chip Clock Synthesis (OCCS) module, sets the PLL (by values from appconfig.h)
and waits while the generated clock is stable
•sets the External Memory Interface unit (SEMI) to generate the proper chip select signals and the
wait states for the external memories according to the appconfig.h file
•[optionally] runs the internal memory tests with halting the processor if memory module is not
usable
•initializes the stack pointer (SP) to the address after any data segments
•clears the .bss segment which holds the uninitialized global and static C variables
•copies the initial values from Flash memory to initialized global C variables (.data segment). Either
xFlash or pFlash memory can be chosen to hold the initialization data.
•clears and initializes variables in the fardata.bss and fardata.data segments
•clears and initializes variables in the .bss.pmem and .bss.data segment (program RAM-based
variables)
- entry point
•initializes the program RAM-based code of the pramcode section.
When all the initialization is done, the functions userPreMain(), main(), userPostMain() are
called.
2.1.3 userPreMain()
The userPreMain() function is called before the main application code in the main() function. The
user can add any additional initialization code here. The function is located in the appconfig.c file.
2.1.4
The main() function is called after all the code described above is executed (i.e. the processor is
initialized and the user’s pre-main code is executed). It is the place where the user writes the
application code. By default the function is located in the main.c file, but the file can be renamed
by the user.
The userPostMain() function is called after the main application code is finished. The user can
add any additional code he/she wishes. By default the processor is halted by debughlt instruction
here. The function is located in the appconfig.c file.
The DSP56800E_Quick_Start tool defines some basic data types to support code portability
between different hardware architectures and tools. These basic data types, which are defined in
the C header file types.h, support International Telecommunication Union (ITU) generic word
types, integer, fractional, and complex data types. This is used throughout the interface definitions
for the On-Chip Drivers. Note that in some development environments these data type definitions
are located in the prototype.h file.
1. Generic word types
•Word8 - to represent 8-bit signed character variable/value
•UWord8 - to represent 16-bit unsigned character variable/value
•Word16 - to represent 16-bit signed variable/value
•UWord16 - to represent 16-bit unsigned variable/value
•Word32 - to represent 32-bit signed variable/value
•UWord32 - to represent 32-bit unsigned variable/value
2. Integer types
•Int8 - to represent 8-bit signed character variable/value
•UInt8 - to represent 8-bit unsigned character variable/value
•Int16 - to represent 16-bit signed variable/value
•UInt16 - to represent 16-bit unsigned variable/value
•Int32 - to represent 32-bit signed variable/value
•UInt32 - to represent 32-bit unsigned variable/value
3. Fractional types
•Frac16 - to represent 16-bit signed variable/value
•Frac32 - to represent 32-bit signed variable/value
•CFrac16 - to represent 16-bit complex numbers
•CFrac32 - to represent 32-bit complex numbers
4. Miscellaneous types
•bool - to represent boolean variable (true/false)
The global symbol ArchIO provides a C interface (structure type) to all peripheral and core
registers mapped in data memory. All registers are accessed via this structure so there is no need
to know and specify the concrete addresses of the registers to write or read. This mechanism
increases code readability and portability and simplifies access to registers. The ArchIO is
declared in the C header file arch.h.
The ArchIO is of type arch_sIO, which is the structure type composed from another structures,
one for each peripheral module.
There are two possible approaches how to define and use the ArchIO structure:
•define ArchIO as the direct (numeric) address of memory-mapped peripheral registers casted to the
proper structure type.
•define ArchIO as the extern variable while defining its address by a directive in linker command
file.
The second approach is used in the DSP56800E_Quick_Start tool implementation by default.
This section describes routines, macros and intrinsic function redefinition provided by the Core
System Infrastructure.
2.4.1 Architecture dependent routines
This section describes architecture dependent routines and macros which provide interface to the
56800E core architecture. It encapsulates the unique features of the 56800E architecture into the
abstract APIs. All routines are defined in the arch.h header file.
2.4.1.1 archEnableInt - enable interrupts
Call(s):
void archEnableInt(void);
Arguments: None.
Description: The archEnableInt macro enables all interrupts by clearing bits I1 (Bit 9) and I0
(Bit 8) in the Status Register (SR).
Example 2-3. archEnableInt macro usage
archEnableInt();
2.4.1.2 archEnableIntLvl123 - enable interrupt levels 1, 2 and 3
Call(s):
void archEnableIntLvl123(void);
Arguments: None.
Description: The archEnableIntLvl123 macro enables interrupts at levels 1, 2 and 3 while
masking the interrupts at level 0. It is accomplished by clearing bit I1 (Bit 9) and setting bit I0 (Bit
Description: The archGetSetSaturationMode inline function sets the saturation mode to a user
specified value. The function manipulates with the saturation (SA) bit - Bit 4 in the Operating
Mode Register (OMR).
Returns: Saturation mode prior to the new state (the return value is masked SA-bit from the
previous OMR value).
Example 2-16. archGetSetSaturationMode function usage
This section describes macros for peripheral memory access. The macros are used to read, write,
set, clear, change the memory mapped on-chip peripherals. Using these macros offers a greater
portability than simply referencing on-chip peripherals with direct memory accesses. All macros
are defined in the periph.h header file.
Required Header File(s):
#include “types.h“
#include “periph.h“
2.4.2.1 periphMemRead - memory read
Call(s):
UWord16 periphMemRead(UWord16 *pAddr);
Arguments:
Table 2-3.
pAddrinThe memory address from which to read a 16-bit word.
periphMemRead
arguments
Description: The periphMemRead macro reads a 16-bit word from the memory location
addressed by parameter pAddr.
Description: The periphMemInvBitSet macro reads the memory content, inverts its value and sets
the selected bits in a memory location addressed by parameter pAddr.
Note, that this macro can be used in some special purposes, e.g. for clearing the pending flags.
Example 2-21. periphMemInvBitSet macro usage
periphMemInvBitSet(0x0004, &ArchIO.Sim.rststs);
This code clears the Power On Reset flag in the RSTSTS register.
Description: The periphBitGrpSR macro sets the bit group to a given value in a memory location
addressed by parameter pAddr. All bits specified by GroupMask are affected. These bits are
either set if the corresponding bits in Mask value are also set or they are cleared if the
corresponding bits in Mask value are cleared.
The “SR” variant uses two non-interruptible instructions bfset and bfclr to accomplish the
requested operation. The bfset first sets the “one” bits in the destination location, and bfclr then
clears the “zero” bits there.
Caution: This macro is the optimal way how to set the specified group of bits to given value.
However, it must be kept in mind that during the short time between these two bit operations, the
target memory location goes through the third state where the bit group might contain invalid
value (“ones” already set but “zeroes” not yet cleared).
Example 2-23. periphBitGrpSR macro usage
periphBitGrpSR(0x007f, 10, &ArchIO.Pll.plldb);
This code sets the lower 7 bits of PLL Divide-By register to the value 10. Other bits in the register
are not affected.
2.4.2.7 periphBitGrpRS - set bit group to given value
Description: The periphBitGrpRS macro sets the bit group to a given value in a memory location
addressed by parameter pAddr. All bits specified by GroupMask are affected. The bits are either
set if the corresponding bits in Mask value are also set or they are cleared if the corresponding bits
in Mask value are cleared.
The “RS” variant uses two non-interruptible instructions bfclr and bfset to accomplish the
requested operation. The bfclr first clears the “zero” bits in the destination location, and bfset then
sets the “one” bits there.
Caution: This macro is the optimal way how to set the specified group of bits to given value.
However, it must be kept in mind that during the short time between these two bit operations, the
target memory location goes through the third state where the bit group might contain invalid
value (“zeroes” already cleared but “ones” not yet set).
Example 2-24. periphBitGrpRS macro usage
periphBitGrpRS(0x007f, 10, &ArchIO.Pll.plldb);
This code sets the lower 7 bits of PLL Divide-By register to the value 10. Other bits in the register
are not affected.
2.4.2.8 periphBitGrpZS - set bit group to given value
Description: The periphBitGrpZS macro sets the bit group to a given value in a memory location
addressed by parameter pAddr. All bits specified by GroupMask are affected. The bits are either
set if the corresponding bits in Mask value are also set or they are cleared if the corresponding bits
in Mask value are cleared.
periphBitSet
arguments
The “ZS” variant uses two non-interruptible instructions bfclr and bfset to accomplish the
requested operation. The bfclr first clears all bits in GroupMask and bfset then sets the “one” bits
there.
Caution: This macro is the optimal way how to set the specified group of bits to given value.
However, it must be kept in mind that during the short time between these two bit operations, the
target memory location goes through the third state where the bit group contains zeroes.
Example 2-25. periphBitGrpZS macro usage
periphBitGrpZS(0x007f, 10, &ArchIO.Pll.plldb);
This code sets the lower 7 bits of PLL Divide-By register to the value 10. Other bits in the register
are not affected.
2.4.2.9 periphBitGrpSet - set bit group to given value
Description: The periphBitGrpSet macro sets the bit group to a given value in a memory location
addressed by parameter pAddr. All bits specified by GroupMask are affected. The bits are either
set if the corresponding bits in Mask value are also set or they are cleared if the corresponding bits
in Mask value are cleared.
This variant uses the accumulator and read-modify-write instructions to accomplish the requested
operation. The memory location is first read to accumulator, the bfclr and bfset instructions are
performed on accumulator and the result value is then written back to memory location.
Caution: It might seem this macro is the “proper” way how to set the group of bits to certain
value as there are no intermediate invalid values written in the target memory location. However,
it is quite dangerous to use this macro when interrupts may occur between the read and write
operations. If the interrupt service routine would write the other portion of the target memory
location, the written value could be overwritten back with its previous state by the write
accumulator operation of periphBitGrpSet.
Example 2-26. periphBitGrpSet macro usage
periphBitGrpSet(0x007f, 10, &ArchIO.Pll.plldb);
This code sets the lower 7 bits of PLL Divide-By register to the value 10. Other bits in the register
are not affected (but see “Caution” above).
Description: The periphSafeAckByOne macro clears (acknowledges) bit flags which are
active-high and are cleared by write-one in a peripheral memory location addressed by parameter
pAddr. The GroupMask specifies all flags which might be affected by clearing procedure. The
Mask value specifies flag/flags to be cleared.
This section describes some additional routines provided by the DSP56800E_Quick_Start tool.
2.4.3.1 impyuu - integer multiply unsigned 16b x unsigned 16b
Call(s):
UWord32 impyuu(UWord16 unsigA, UWord16 unsigB);
Arguments:
Table 2-15. impyuu arguments
unsigAinfirst argument
unsigBinsecond argument
Description: The impyuu inline function multiplies a 16-bit unsigned integer with a 16-bit
unsigned integer and returns the 32-bit unsigned integer result.
result = impysu(var1, var2); /* returns -2147450880 */
This code multiplies variables var1 and var2 and returns the result in result variable.
2.4.3.3 shl2 - optimized version of
shl
intrinsic function
Call(s):
Word16 shl2(Word16 num, UWord16 shifts);
Arguments:
Table 2-17. shl2 arguments
numinparameter to be shifted
shiftsinnumber of shifts
Description: The shl2 function performs a multi-bit arithmetic shift of the first parameter to the
left by the amount specified in the second parameter. The result is returned as a 16-bit integer.
This function is the optimized version of the shl intrinsic function (see CodeWarrior Help for
more information on shl).
Returns:num parameter shifted shifts times to the left
Description: The shr2 function performs a multi-bit arithmetic shift of the first parameter to the
right by the amount specified in the second parameter. The result is returned as a 16-bit integer.
This function is the optimized version of the shr intrinsic function (see CodeWarrior Help for
more information on shr).
Returns:num parameter shifted shifts times to the right
Example 2-33. shr2 function usage
Word16 var1 = 16;
Word16 result;
result = shr2(var1, 3); /* returns 0x0002 */
This code shifts var1 variable three times to the right and returns the result in the result variable.
2.4.4 Intrinsic Functions
The DSP56800E_Quick_Start tool exploits the system intrinsic functions defined in
intrinsics_56800E.h header file distributed with the CodeWarrior Development Studio 56800/E
Hybrid Controllers.
To preserve compatibility with the DSP56800_Quick_Start tool, the intrinsics_56800E.h is
included in types.h header file.
This section describes interrupt processing and interrupt configuration using the
DSP56800E_Quick_Start tool. For detailed information on interrupts and interrupt processing for
the 56F800E, please see the 56800E 16-Bit Core Reference Manual and the target processor’s
User’s Manual.
2.5.1 Processing Interrupts
An interrupt is an event that is generated by a condition inside the microcontroller or from
external sources. When such event occurs, the interrupt processing transfers control from the
currently executing program to an interrupt service routine (ISR), with the ability to later return to
the current program upon completion of the ISR. Among the main uses of interrupts we can have
data transfers between microcontroller memory and a peripheral device, or begin of execution of
an algorithm upon reception of a new sample. An interrupt can also be used, for example, to exit
the microcontroller’s low-power wait processing state.
2.5.1.1 Interrupt Vector Table
The interrupt system on 56F800E can be defined as vectored. Each interrupt source has its own
program memory location at a fixed address, to which program control is passed when an
interrupt occurs. This program memory location must contain a JSR instruction with the address
of the interrupt service routine (ISR). When this interrupt occurs, the JSR instruction is executed
and the program control is passed to the ISR. The program memory containing the JSR
instructions with the addresses of the ISR is called interrupt vector table.
Depending on processor configuration (the state of the EXTBOOT and EMI_MODE pins during
reset), the interrupt vector table might be located at base address 0x0000 or 0x20000. During the
code execution, the interrupt vector table base address can be changed by modifying the VBA
register of interrupt controller unit (INTC).
In the DSP56800E_Quick_Start tool, the full interrupt vector table is always located at address
0x0000 regardless of the configuration of the EXTBOOT and EMI_MODE pins. The VBA
register is set to zero during the startup code. For the case the processor configuration directs reset
vector to 0x20000, the jump to startup code is also linked to this address. See Section 2.1.1 on
page 2-2 for closer description of the booting process.
In the DSP56800E_Quick_Start tool, the interrupt vector table is implemented in C code which
enables to effectively use the C preprocessor. The special macros defined in the global application
configuration file (appconfig.h) can be used to setup the interrupt vector and to assign the
interrupt priorities.
The interrupt controller and its configuration are described in more details later in Section 2.5.2.1.
2.5.1.2 Interrupt Processing Flow
Figure 2-2 shows an interrupt processing flow. The DSP56800E_Quick_Start tool does not
provide any intermediate step when calling the ISR. When an interrupt occurs, the currently
executed program is interrupted and the JSR instruction from the interrupt vector table is fetched.
Executing the JSR instruction results in the program changing its flow directly to an ISR. Also the
status register and the program counter are pushed onto the stack. When the user ISR finishes, it
executes a Return from Interrupt (RTI) instruction, which pops the program counter and the status
register from the hardware stack. It puts the User Code back into the same state as it was in before
execution, assuming that the User ISR saved and restored all the registers it had used.
Figure 2-2. Interrupt Processing Flow
2.5.1.3 ISRs
An ISR is a program code that is executed when an interrupt is detected. An ISR is responsible for
servicing the cause of the interrupt, such as reading a sample from a port when it is full or
transmitting a sample to a port when it is empty. When an interrupt occurs, all other interrupts of
the same or of a lower priority are disabled from executing, until the current ISR finishes
executing. For this reason, an ISR should be as fast as possible to prevent any overflow or under
run condition.
Inside the ISR it is necessary to save, and upon servicing the interrupt, to restore all used registers,
including registers from the register bank used by the compiler. The DSP56800E_Quick_Start
tool does not provide any automatic saving/restoring of used registers.
The last instruction of an ISR must be “Return from Interrupt” (RTI) instruction. This instruction
restores the SR and the PC from the stack.
Both saving/restoring registers and using RTI instead of RTS are provided by the compiler
directive #pragma interrupt. #pragma interrupt is used when declaring a C function and it
instructs the compiler to save all registers used within a C function and to restore those register
values upon exiting. Also it places an RTI instruction instead of an RTS at the end of the function.
See Section 2.5.3.
On 56F800E hybrid microcontroller family, each interrupt can be assigned the interrupt priority
level (IPL). It is the number from 0 (lowest priority) to 3 (highest priority). When servicing the
interrupt, until the RTI instruction is executed, the other interrupts of the same and lower priority
levels are masked (temporarily disabled). If there is an interrupt request of the masked priority
level, its processing is postponed until the level is unmasked again.
This model assures that the interrupts of the same level can not “nest” one to each other. On the
other hand, the higher priority interrupts do nest to the lower priority interrupts.
2.5.1.5 Fast Interrupts
Up to 2 interrupt sources can be declared as Fast Interrupts. The Fast Interrupts jump directly to a
service routine based on values in the Fast Interrupt Vector Address registers without having to go
to a jump table first.
IRQs used as fast interrupts MUST be set to priority level 2. Unexpected results can occur if a fast
interrupt vector is set to any other priority.
Caution: A special Fast Interrupt Return instruction (frtid) must be used in order to return from
the Fast Interrupt service routine. There are also several limitations in the way how the Fast
Interrupt service routine can be coded. See the 56800E Processor Core Reference Manual for
more details.
2.5.1.6 Clearing Interrupt Flags
Each on-chip peripheral interrupt source has its own interrupt flag, which must be cleared after
the interrupt is serviced. For each peripheral module, the method of clearing the interrupt flag is
different. As the DSP56800E_Quick_Start tool does not add any infrastructure code to the
interrupt service routines, it also does not clear the interrupt flag inside the ISR. See Code
Example 2-34.
This example shows the PWMA Reload Interrupt Service Routine. Note that the PWM_CLEAR_
RELOAD_FLAGioctl() command is used to clear the Reload Interrupt Flag (Bit 5) in the PWM
Control Register and that this is the user’s responsibility.
This section describes the configuration of interrupts using the DSP56800E_Quick_Start tool.
Interrupt configuration consists of installing the interrupt service routine (ISR) at the specified
interrupt vector, enabling the interrupt and setting the interrupt priority level.
2.5.2.1 Installing ISRs
The DSP56800E_Quick_Start tool supports static (compile-time) installation of the ISRs,
dynamic installation (run-time) is not supported. In general, static installation of ISRs requires
less program memory and has a lower (or even no) time overhead.
The static installation of ISRs consists of writing the address of the ISR to the interrupt vector
table for given interrupt source at compilation time. The interrupt vector table is located in the
vectors.c file. By default all interrupt vectors are initialized with the address of the
unhandled_interrupt() function in the vectors.c file, which contains the debughlt instruction and
provides an alarm to the user, that this interrupt was not installed but has occurred, which is very
useful when debugging. One exception to this is the Hardware Reset vector, which contains the
address of the startup code - Start() routine in the startup.c file.
To install a user’s ISR at the xxth interrupt vector add the following #define in appconfig.h:
#defineINT_VECTOR_ADDR_xxuserISRname
The conditional compilation then forces the compiler to use the userISRname() ISR instead of the
default unhandled_interrupt() at the position of the xxth interrupt vector in the interrupt vector
table. The userISRname is the placeholder for the name of interrupt service routine with prototype
of
void userISRroutine (void)
In your source code, you then put the following code:
#pragma interrupt
void userISRname(void)
{
/* ISR code */
}
The range of interrupt vectors which can be installed (xx) is 1 to 80. Vector 0 is the Hardware
Reset vector and always refers to the Start() code.
2.5.2.2 Assigning Interrupt Priority Levels
As described in Section 2.5.1.4 on page 2-26, each enabled interrupt can be assigned to one
interrupt priority level in range from 0 to 3.
There are some exceptions from this rule for the particular interrupt sources which has assigned a
fixed priority levels. Also, as there are only two bits (four combinations) to encode five different
states of the interrupt source (disabled, level 0,..., level 3) there is always one priority level, which
cannot be set for any interrupt.
The DSP56800E_Quick_Start tool hides these difficulties and implementation details described
above and simplifies the configuration of the interrupt priority levels to the maximal extent (while
keeping the generated code optimal).
To enable the interrupt servicing and to assign a certain priority level, the user defines the macro:
INT_PRIORITY_LEVEL_xx INTC_LEVELn
To explicitly disable the interrupt, the user can define the macro as
INT_PRIORITY_LEVEL_xx INTC_DISABLED
where xx is the interrupt number (from 1 to 80) and n is the interrupt level (from 0 to 3). The
interrupt sources configurations are then applied to a processor core by issuing the INTC_INIT
ioctl command, for example in the main function.
The C preprocessor and compiler check the validity of the selected priority level early during the
compilation and issues compilation errors if invalid combination of interrupt source number and
interrupt priority level is requested (or if priority level is requested to be set for the source with
fixed priority level).
2.5.2.3 Installing Fast Interrupts
As described in Section 2.5.1.5 on page 2-26, two interrupt sources can be selected as “Fast
Interrupts”. For the fast interrupts, the interrupt controller does not fetch the jsr instruction from
the vector table and directly loads the program counter (PC) with address specified in dedicated
Fast Interrupt Vector Address (FIVA) registers.
In the DSP56800E_Quick_Start tool, the fast interrupts are automatically configured by the
INTC_INIT code if the user defines the macros:
INTC_FIM0_INIT xx
or
INTC_FIM1_INIT xx
where xx specifies what interrupt source is to be selected as fast interrupt (0 or 1).
By default, the address of interrupt service routine defined by INT_VECTOR_ADDR_xx is then
automatically loaded into the FIVA registers during the INTC_INIT command. The
preprocessor also verifies the interrupt identified for a fast interrupt is configured to priority level
2 (which is required for the proper operation).
Caution: A special Fast Interrupt Return instruction (frtid) must be used in order to return from
the Fast Interrupt service routine.
If there is another vector address to be used for the fast interrupt processing, instead of the default
INT_VECTOR_ADDR_xx, the following macros can be defined in appconfig.h
INTC_FIVA0_INIT fastint0ISR
or
INTC_FIVA1_INIT fastint1ISR
where fastint0ISR and fastint1ISR are the placeholders for the fast interrupt service
routine names.
In addition to the interrupt controller peripheral described above, the 56800E core has its own
method how to enable and disable the interrupts of certain priority levels. So, regardless the
interrupt setting defined by macros in appconfig.h and initialization done by the INTC_INIT
command, there is another step to do to enable interrupt servicing in the application.
At the core level, the interrupts can be in four states:
•All interrupts disabled (default state) - use archDisableInt() macro
•All interrupts enabled - use archEnableInt() macro
•Priority levels 1, 2 and 3 enabled, level 0 disabled - use archEnableIntLvl123() macro
•Priority levels 2 and 3 enabled, levels 0 and 1 disabled - use archEnableIntLvl23() macro
2.5.3 Code Example
The following example shows the installation of the ISR into the interrupt vector table and shows
how to enable interrupts using the DSP56800E_Quick_Start tool.
The following example shows the installation of the external interrupt IRQA, the timer/counter
D2 interrupt and the PWM A reload interrupt. The example shows a part of the code, which must
be included in appconfig.h, all three ISRs and the initialization code. ISRs are declared as
#pragma interrupt to instruct the compiler to save/restore all used registers and to terminate the
ISRs with an RTI instruction. Inside the appconfig.h file, INT_VECTOR_ADDR_xx and
ITCN_INT_PRIORITY_xx define statements are used to install the ISR at the specified interrupt
vector and to define the interrupt priority level. The achEnableInt() macro and the ITCN driver
commands ITCN_INIT_GPRS and ITCN_INIT_IPR are used to enable interrupts.
Example 2-35. Installing ISRs and enabling interrupts
1) appconfig.h file
/*****************************************************************************
**
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
**
*
* File Name: appconfig.h
*
* Description: file for static configuration of the application
* (initial values, interrupt vectors)
*
*****************************************************************************/
/*****************************************************************************
**
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
******************************************************************************
**
*
* FILE NAME: main.c
*
* DESCRIPTION: Sample application demonstrating the use of external interrupt
* IRQA. Use IRQA button to toggle RED LED. GREEN LED is
flashing.
*
* TARGET: MC56F8346 device
*
******************************************************************************
*/
/* toggle RED on port C */
ioctl(GPIO_C, GPIO_TOGGLE_PIN, LED_RED);
main
int i;
/* Setup LEDs GPIO on port C (could be done also via appconfig.h) */
ioctl(GPIO_C, GPIO_SETAS_GPIO, LEDS);
ioctl(GPIO_C, GPIO_SETAS_OUTPUT, LEDS);
ioctl(GPIO_C, GPIO_WRITE_DATA, 0);
This section describes the implementation details and the system code of each project created
from the DSP56800E_Quick_Start tool stationery for the MC56F83xx hybrid controllers.
2.6.1 Project Targets
Each created project contains several targets for different hardware configurations of the
microcontroller system. All targets are briefly described in the following tables:
There is a different linker command file (LCF) for each target, which defines the destination
memory ranges used by the linker. Although the syntax of the LCF and C header files are
completely different. The LCF for each target is also used as prefix1 header file in its target
configuration. The macros defined in the LCF identify the target for further conditional
compilation of the project source files.
The trick which enables using a file with the LCF syntax as a header file is shown on Code
Example 2-36. It successfully exploits the fact that the ‘#’ sign is treated as a start of comment
line in LCF syntax, so the C-like #define statements do not cause the LCF syntax errors. On the
other side, the #if 0 ... #endif block excludes the LCF part of the file from C compilation.
1. Prefix file is unconditionaly included at the begining of every compiled C file.
#define TARGET_LDM/* Large Data Model */
#define TARGET_CODE_EXTRAM/* Code located in external pRAM */
#define TARGET_CONSTDATA_EXTRAM /* Constants and const s located in external xRAM */
#define TARGET_INITDATA_EXTRAM/* Initialized global vars located in external RAM */
#define TARGET_DATA_EXTRAM/* Variables located in external RAM */
#if 0 /* everything below is excluded from C compilation */
MEMORY
{
...
}
SECTIONS
{
...
}
...
#endif /* end of code excluded by C-preprocessor */
2.6.2 Inside Startup Code
This section goes step-by-step through the processor initialization code described briefly in
Section 2.1.2 on page 2-3. The startup code described here can be found in the startup.c file,
located in the SystemConfig subdirectory of any project created using the
DSP56800E_Quick_Start tool stationery.
2.6.2.1 Symbols Used in Startup Code
2.6.2.1.1 Included Header Files
The master Quick_Start header file qs.h is included in the startup code. This file further includes
other critical system files to define common C types, peripheral module base addresses and other
types and macros required by the startup code. The application configuration header file
appconfig.h is also included so the startup code is able to configure system modules like OCCS
(PLL) and SEMI.
#include “qs.h”
2.6.2.1.2 Initial Value of Operation Mode Register (OMR)
Although it is not very common, the initial value of the Operation Mode Register (OMR) can be
specified in appconfig.h using the OMR_INIT macro.
The following startup.c statements define the default initial OMR value for the cases when the
user had not defined the OMR_INIT in appconfig.h:
The default initialization value of the OMR is based on the TARGET_OMR_INIT value, which
might be defined in the prefix file (LCF) within the active compilation target. Currently, the
TARGET_OMR_INIT is not defined in the prefix file of any target, leaving the initial OMR value
on 0x0000.
The following OMR bits are important for the proper operation of the C application:
•CM = 0 - optional for C application
•XP = 0 - enabling separate program and data buses (Harvard Architecture)
•R = 0 - rounding off, required for C applications
•SA = 0 - saturation off, required for C applications
•EX = 0 - complete X memory space as external, required by CodeWarrior debugger
The critical OMR bits are checked by the C preprocessor directive, issuing the compile-time
warning when found in the OMR_INIT value:
#if (OMR_INIT & (OMR_CM|OMR_XP|OMR_R|OMR_SA))
#warning Initial OMR value might be invalid for the C project
#endif
#if (OMR_INIT) & OMR_EX
#warning CodeWarrior cannot debug projects with OMR.EX bit set
#endif
2.6.2.1.3 Other appconfig.h Symbols
Using the OCCS_REQUIRED_LOCK_MODE macro, the user specifies in which lock state of the
PLL the setup code continues to the rest of the startup code:
•0x20 (default) - continue when “coarse” lock mode is reached (bit LCK0 in PLLSR)
•0x40 - continue when “fine” lock mode is reached (bit LCK1 in PLLSR)
#ifndef OCCS_REQUIRED_LOCK_MODE
#define OCCS_REQUIRED_LOCK_MODE 0x20 /* coarse (LCK0) by default */
#endif
#if (OCCS_REQUIRED_LOCK_MODE != 0x40) && (OCCS_REQUIRED_LOCK_MODE != 0x20)
#error OCCS_REQUIRED_LOCK_MODE must be one of 0x20 (coarse) or 0x40 (fine)
#endif
One of the startup code optional features is to perform the internal data RAM checking. The
checking algorithm, fully described later in Section 2.6.2.2.7, uses two values which writes, reads
and verifies to check each memory location. By default the two values are 0xAAAA and 0x5555.
If there is any reason to change the values, the user can define the macros
CONFIG_INTRAM_CHECKVALUE1 and CONFIG_INTRAM_CHECKVALUE2 in the
appconfig.h file.
While linking, the linker replaces any zeros generated by compiler for external symbols with
proper values calculated during linking process when the physical addresses of the symbols are
known. Some values of external symbols can be also specified directly by the directives in the
linker command file.
The following symbols are specified by the LCF and provide physical address of memory
segments used in the startup code:
The following subsections describe the source code of the Start assembly function.
asm void Start(void)
{
2.6.2.2.1 Initialize Interrupt Vectors Base Address
Depending on the state of the EXTBOOT and EMI_MODE pins during the system reset, the vector
table is located at the beginning of the Boot Program Flash or (if Boot Flash is not available) at
the beginning of the Program RAM. The startup code always updates the Vector Table Base
Address (VBA) to beginning of “.interrupt_vectors” section where the Quick_Start vector table is
located. By default this table is always put to the beginning of the Program RAM anyway.
By defining the ARCH_VECTBL_ADDR macro in the appconfig.h configuration file, the VBA
may be forced to a custom value.
2.6.2.2.2 Clear COP Counter and Keep Clearing Values in Registers
On the newer 56F800E-based devices, the COP Watchdog counter is enabled after reset, so it is
necessary to clear this counter periodically during any lengthy operation in the startup code. Early
in the startup, the COP counter is initially cleared and the clearing values are preserved in
registers. The R5, C1 and D1 registers are not changed anywhere in the rest of the startup code
and are used to clear the COP without loading the constant values again.
The “one” bits in the OMR_INIT value are set in the Operating Mode Register.
/* setup the OMR */
bfset OMR_INIT,omr
nop
nop
2.6.2.2.4 Other Initialization
The M01 register is initialized to -1 to activate linear addressing mode with R0 and R1 registers.
/* setup the m01 register for linear addressing */
move.w #-1,x0
moveu.w x0,m01
The values on the Hardware Stack are cleared (for proper debugger behavior).
/* clear (read-out) the hardware stack */
moveu.w hws,la
moveu.w hws,la
nop
nop
2.6.2.2.5 Core Clock Setup (OCCS)
The PLL Oscillator Control Register and the Divide-By Register are initialized with the
appconfig.h values if defined. The value in the Divide-By Register controls the prescaler and
postscaler frequency divisors and also multiplication factor of the PLL. Note that before the
PLLCR register is written, the PLL remains turned off and the system clock is still taken from a
default clock source (now divided by prescaler value). The default clock source is an external
oscillator or an internal relaxation oscillator on some devices.
/* configure external oscillator and clock mode */
#ifdef OCCS_OSCTL_INIT
#define OSCTL_TEMP (OCCS_OSCTL_INIT & 0x3fff) /* keep internal osc. enabled */
move.w #OSCTL_TEMP,ArchIO.Pll.osctl /* OSCTL,even if PLL not used */
nop
nop
#endif
/* setup the PLL according to appconfig.h values */
#ifdef OCCS_PLLDB_INIT
move.w OCCS_PLLDB_INIT,ArchIO.Pll.plldb /* PLLDB, even if PLL not used */
nop
nop
#endif
On the devices equipped with an internal relaxation oscillator, a user may want to initialize the
trimming value in the Oscillator Control Register by the factory-measured value which is saved in
the read-only Flash area (FMOPT1 Register).
/* load factory trimming value of the internal relaxation oscillator? */
Then, if the PLL Control Register initial value is defined in appconfig.h, the PLL setup code is
executed:
#ifdef OCCS_PLLCR_INIT
On the new devices (e.g. 56F802x/3x), all pins are in the GPIO mode after reset, including the
pins which may be needed as an external clock or crystal source. The startup code automatically
re-configures these pins to the required clock-related mode before switching to an external clock.
The new devices are identified by OCCS version 3 and SIM version 4 in the new code.
NOTE:
The peripheral module version identifiers are defined in the arch.h file for
each device purely for an internal use in the DSP56800E_Quick_Start
code. The version numbers do not rely to chip or silicon version.
/* on new devices, some external pins may be needed if PLLCR.PRESC=1 */
/* crystal on EXTAL and XTAL pins (GPIO_D4 and GPIO_D5)*/
#else
bfclr 0x1000, ArchIO.Sim.sim_gpscd
bfset 0x0030, ArchIO.PortD.per
/* give it some time until crystal/resonator stabilizes */
/* we now run from internal relaxation oscillator / 2 (i.e. 4MHz) */
move.w #5000,x0 /* wait 50ms */
do x0,waitosc
rep 36; nop; /* sigle loop pass takes 40 cycles */
move.w C1,X:(R5) /* and also clears the watchdog */
move.w D1,X:(R5)
waitosc:
When the PLL is to be turned on, it is first decided whether the code is running on real chip or in
software simulator. The simulator mode is identified by looking at the “clock source” bit-field
value in the PLLCR register. In the simulator mode, the PLL setup is skipped because the loop
waiting for the PLL lock would never finish.
brclr 1,ArchIO.Pll.pllcr,skip_pll_lock /* skip PLL in simulator mode */
While still running from an external oscillator, the PLL lock detector is activated and it is waiting
until the PLL lock is detected. According to appcofing.h setting, the required lock state is either
“coarse” or “fine” - which corresponds to the PLLSR bits LCK1 and LCK0. Note that the COP
counter is periodically cleared while waiting in the loop.
move.w #PLLCR_TEMP,ArchIO.Pll.pllcr /* PLL lock detector ON, core
pll_lock:
move.w C1,X:(R5) /* clear COP watchdog counter while waiting in the loop */
move.w D1,X:(R5)
brclr OCCS_REQUIRED_LOCK_MODE,ArchIO.Pll.pllsr,pll_lock /* test lock */
still on prescaler */
When the PLL is locked, the system clock is switched to PLL and the PLLCR is finally initialized
with the user defined value. As the last, the pending PLL interrupts are cleared.
Before the data memory is initialized (the bss segment is cleared and the global variables segment
is copied from non-volatile memory), the external memory interface (SEMI) has to be first set up.
The initialization is done by copying the initial values defined in appconfig.h to the SEMI
peripheral registers.
The memory chip selects signals CS2 to CS7 are shared with GPIO port D pins. So, when any
external memory is to be configured on these banks using the values from the appconfig.h file, the
appropriate GPIO circuitry is turned off here by setting the Peripheral Enable Register of the
GPIO port D.
As the last, the SEMI Bus Control Register is initialized.
/* global wait states not covered by CS registers */
#ifdef SEMI_BCR_INIT
move.w SEMI_BCR_INIT, ArchIO.Semi.bcr
#endif
#endif /* SEMI_BASE */
2.6.2.2.7 Internal Memory Checking
Checking the internal data RAM is an optional feature of the startup code. When the
INTXRAM_CHECK_ENABLED macro is defined in appconfig.h, this feature is activated.
The memory checking process consists of tree parts:
•Complete memory fill (value 0xAAAA) & read + compare
•Single write, read & compare for each memory location
cmp.w x:(r1),y0/* read written value & compare (should be test2) */
beq <t2passed/* TEST2: OK ? */
nop
debughlt /* !! MEMORY TEST FAILED !! */
stop
t2passed:
t3passed:
end_intramcheck1:
move.w lc,b/* skip TEST3 for the last memory cell (when LC==1) */
cmp.w #1,b
ble <t3passed
cmp.w y1,x0/* TEST3: value from incremented addr. should be ==test1 */
beq <t3passed/* TEST3: OK ? */
nop
debughlt /* !! MEMORY TEST FAILED !! */
stop
move.w b0,x:(r1)+/* clear checked memory location */
nop
nop/* without nops, the branch to t3passed above */
nop/* could confuse the hardware loop unit */
#endif
2.6.2.2.8 Stack Pointer Initialization
The stack pointer (SP) register is initialized to the first odd value after _Lstack_addr symbol
generated by linker command file. The first stack location is then initialized to NULL.
2.6.2.2.9 Clearing .bss, .bss.pmem and fardata.bss Segments
The .bss is the memory segment containing the global or static C variables to which are not
assigned initial values (or the initial value is 0). This segment is cleared by the startup code so the
global and static C variables are initialized to 0.
Note that the COP counter is periodically cleared in all loops below.
/* clear BSS segment (can't use 'do' and its 16 bit loop counter) */
move.l #>>_Lbss_size,r2 /* bss size */
tsta.l r2
beq <end_clearbss;/* skip if size is 0 */
move.l #>>_Lbss_start,r1 /* dest address */