0% found this document useful (0 votes)
22 views400 pages

TMS320C28x™ MCU Workshop

Uploaded by

zain.yasin141
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views400 pages

TMS320C28x™ MCU Workshop

Uploaded by

zain.yasin141
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 400

TI

TMS320C28x™ MCU Workshop


Workshop Guide and Lab Manual

C28xmdw
Revision 7.2
February 2009
Technical Training
Organization
Important Notice

Important Notice
Texas Instruments and its subsidiaries (TI) reserve the right to make changes to their products or to
discontinue any product or service without notice, and advise customers to obtain the latest version of
relevant information to verify, before placing orders, that information being relied on is current and
complete. All products are sold subject to the terms and conditions of sale supplied at the time of order
acknowledgment, including those pertaining to warranty, patent infringement, and limitation of liability.

TI warrants performance of its semiconductor products to the specifications applicable at the time of sale in
accordance with TI’s standard warranty. Testing and other quality control techniques are utilized to the
extent TI deems necessary to support this warranty. Specific testing of all parameters of each device is not
necessarily performed, except those mandated by government requirements.

Customers are responsible for their applications using TI components.

In order to minimize risks associated with the customer’s applications, adequate design and operating
safeguards must be provided by the customer to minimize inherent or procedural hazards.

TI assumes no liability for applications assistance or customer product design. TI does not warrant or
represent that any license, either express or implied, is granted under any patent right, copyright, mask
work right, or other intellectual property right of TI covering or relating to any combination, machine, or
process in which such semiconductor products or services might be or are used. TI’s publication of
information regarding any third party’s products or services does not constitute TI’s approval, warranty or
endorsement thereof.

Copyright © 2001 – 2009 Texas Instruments Incorporated

Revision History
October 2001 – Revision 1.0 January 2005 – Revision 5.2
January 2002 – Revision 2.0 June 2005 – Revision 6.0
May 2002 – Revision 3.0 September 2005 – Revision 6.1
June 2002 – Revision 3.1 October 2005 – Revision 6.2
October 2002 – Revision 4.0 May 2006 – Revision 6.21
December 2002 – Revision 4.1 February 2007 – Revision 6.22
July 2003 – Revision 4.2 July 2008 – Revision 7.0
August 2003 – Revision 4.21 October 2008 – Revision 7.1
February 2004 – Revision 5.0 February 2009 – Revision 7.2
May 2004 – Revision 5.1

Mailing Address
Texas Instruments
Training Technical Organization
7839 Churchill Way
M/S 3984
Dallas, Texas 75251-1903

ii TMS320C28x MCU Workshop - Introduction


TMS320C28x™ MCU Workshop

TMS320C28x™ MCU Workshop


TMS320C28x™ MCU Workshop

eZdsp™ F28335 Starter Kit

Texas Instruments
Technical Training
T TO C28x is a trademark of Texas Instruments.
Technical Training
Organization eZdsp is a trademark of Spectrum Digital, Inc. Copyright © 2009 Texas Instruments. All rights reserved.

Introductions
Introductions

‹ Name
‹ Company
‹ Project Responsibilities
‹ DSP / Microcontroller Experience
‹ TMS320 DSP Experience
‹ Hardware / Software - Assembly / C
‹ Interests

TMS320C28x MCU Workshop - Introduction iii


TMS320C28x™ MCU Workshop

TMS320C28x™ MCU Workshop Outline


TMS320C28x™ MCU Workshop Outline
1. Architecture Overview
2. Programming Development Environment
Lab: Linker command file
3. Peripheral Register Header Files
4. Reset and Interrupts
5. System Initialization
Lab: Watchdog and interrupts
6. Analog-to-Digital Converter
Lab: Build a data acquisition system
7. Control Peripherals
Lab: Generate and graph a PWM waveform
8. Numerical Concepts and IQ Math
Lab: Low-pass filter the PWM waveform
9. Direct Memory Access (DMA)
Lab: Use DMA to buffer ADC results
10. System Design
Lab: Run the code from flash memory
11. Communications
12. DSP/BIOS
Lab: DSP/BIOS configuration tool
Lab: Change the code to use DSP/BIOS
Lab: Run DSP/BIOS code from flash memory
13. Support Resources

eZdsp™ F28335 Hardware


eZdsp™ F28335 Hardware
LED
JTAG Interface (P1) Expansion TMS320F28335 (DS2) SCI-B
(P2/P10) 150 MIPS GPIO32 (J12)
USB JTAG
Controller
Interface
(J201) SCI-A
(P12)
30 MHz
Clock
LED eCAN-A
(DS1) (P11)
+5V

Power
Connector
(P6) +5V

On-Chip:
34Kw RAM Analog eCAN-B
Bootloader I/O Interface Interface (J11)
GPIO Pins (P4/P8/P7) 256Kw Flash
1Kw OTP (P5/P9)

iv TMS320C28x MCU Workshop - Introduction


Architecture Overview

Introduction
This architecture overview introduces the basic architecture of the TMS320C28x (C28x) series of
microcontrollers from Texas Instruments. The C28x series adds a new level of general purpose
processing ability unseen in any previous DSP chips. The C28x is ideal for applications
combining digital signal processing, microcontroller processing, efficient C code execution, and
operating system tasks.

Unless otherwise noted, the terms C28x and C2833x refer to TMS320F2833x (with FPU) and
TMS320F2823x (without FPU) devices throughout the remainder of these notes. For specific
details and differences please refer to the device data sheet and user’s guide.

Learning Objectives
When this module is complete, you should have a basic understanding of the C28x architecture
and how all of its components work together to create a high-end, uniprocessor control system.

Learning Objectives

‹ Review the C28x block diagram


and device features
‹ Describe the C28x bus structure
and memory map
‹ Identify the various memory
blocks on the C28x
‹ Identify the peripherals available
on the C28x

TMS320C28x MCU Workshop - Architecture Overview 1-1


Module Topics

Module Topics
Architecture Overview.............................................................................................................................. 1-1

Module Topics......................................................................................................................................... 1-2


What is the TMS320C28x?...................................................................................................................... 1-3
TMS320C28x Internal Bussing .......................................................................................................... 1-4
C28x CPU ............................................................................................................................................... 1-5
Special Instructions............................................................................................................................. 1-6
Pipeline Advantage............................................................................................................................. 1-7
FPU Pipeline....................................................................................................................................... 1-8
Memory ................................................................................................................................................... 1-9
Memory Map ...................................................................................................................................... 1-9
Code Security Module (CSM) ...........................................................................................................1-10
Peripherals .........................................................................................................................................1-10
Fast Interrupt Response .........................................................................................................................1-11
C28x Mode.............................................................................................................................................1-12
Reset.......................................................................................................................................................1-13
Summary ................................................................................................................................................1-14

1-2 TMS320C28x MCU Workshop - Architecture Overview


What is the TMS320C28x?

What is the TMS320C28x?


The TMS320C28x is a 32-bit fixed point microcontroller that specializes in high performance
control applications such as, robotics, industrial automation, mass storage devices, lighting,
optical networking, power supplies, and other control applications needing a single processor to
solve a high performance application.

C28x Block Diagram


Program Bus
ePWM

Boot DMA eCAP


Sectored RAM
ROM 6 Ch.
Flash eQEP
XINTF

A(19-0) DMA Bus


12-bit ADC
D(31-0)
Watchdog

PIE
32-bit R-M-W Interrupt CAN 2.0B
32x32 bit Manager
Auxiliary Atomic FPU
Multiplier I2C
Registers ALU
3
Real-Time SCI
32-bit
JTAG Register Bus Timers SPI
Emulation CPU
McBSP
Data Bus
GPIO

The C28x architecture can be divided into 3 functional blocks:

• CPU and busing

• Memory

• Peripherals

TMS320C28x MCU Workshop - Architecture Overview 1-3


What is the TMS320C28x?

TMS320C28x Internal Bussing


As with many DSP-type devices, multiple busses are used to move data between the memories
and peripherals and the CPU. The C28x memory bus architecture contains:

• A program read bus (22-bit address line and 32-bit data line)

• A data read bus (32-bit address line and 32-bit data line)

• A data write bus (32-bit address line and 32-bit data line)

C28x CPU Internal Bus Structure


Program Program Address Bus (22)
PC
Program-read Data Bus (32) Program
Decoder
Memory
Data-read Address Bus (32)

Data-read Data Bus (32)

Data
Registers Execution Debug Memory
ARAU MPY32x32 FPU
SP Real-Time
ALU R-M-W
DP @X R0H JTAG
XT Atomic
XAR0 ALU to Emulation
P Peripherals
to R7H
XAR7 ACC

Register Bus / Result Bus


External
Data/Program-write Data Bus (32) Interface

Data-write Address Bus (32)

The 32-bit-wide data busses enable single cycle 32-bit operations. This multiple bus architecture,
known as a Harvard Bus Architecture enables the C28x to fetch an instruction, read a data value
and write a data value in a single cycle. All peripherals and memories are attached to the memory
bus and will prioritize memory accesses.

1-4 TMS320C28x MCU Workshop - Architecture Overview


C28x CPU

C28x CPU
The C28x is a highly integrated, high performance solution for demanding control applications.
The C28x is a cross between a general purpose microcontroller and a digital signal processor,
balancing the code density of a RISC processor and the execution speed of a DSP with the
architecture, firmware, and development tools of a microcontroller.

The DSP features include a modified Harvard architecture and circular addressing. The RISC
features are single-cycle instruction execution, register-to-register operations, and a modified
Harvard architecture. The microcontroller features include ease of use through an intuitive
instruction set, byte packing and unpacking, and bit manipulation.

C28x + FPU
‹ MCU/DSP balancing code
Program Bus
density & execution time
Š 16-bit instructions for
improved code density
Š 32-bit instructions for
improved execution time
PIE ‹ 32-bit fixed-point CPU + FPU
Interrupt
32-bit R-M-W
32x32 bit Manager ‹ 32x32 fixed-point MAC,
Auxiliary
Multiplier
Atomic FPU doubles as dual 16x16 MAC
Registers ALU
3 ‹ IEEE Single-precision floating
32-bit
point hardware and MAC
Register Bus Timers
‹ Floating-point simplifies
software development and
CPU boosts performance
‹ Fast interrupt service time
Data Bus
‹ Single cycle read-modify-write
instructions
‹ Unique real-time debugging
capabilities

The C28x design supports an efficient C engine with hardware that allows the C compiler to
generate compact code. Multiple busses and an internal register bus allow an efficient and
flexible way to operate on the data. The architecture is also supported by powerful addressing
modes, which allow the compiler as well as the assembly programmer to generate compact code
that is almost one to one corresponded to the C code.

The C28x is as efficient in DSP math tasks as it is in system control tasks. This efficiency
removes the need for a second processor in many systems. The 32 x 32-bit MAC capabilities of
the C28x and its 64-bit processing capabilities, enable the C28x to efficiently handle higher
numerical resolution problems that would otherwise demand a more expensive solution. Along
with this is the capability to perform two 16 x 16-bit multiply accumulate instructions
simultaneously or Dual MACs (DMAC). Also, some devices feature a floating-point unit.

The, C28x is source code compatible with the 24x/240x devices and previously written code can
be reassembled to run on a C28x device, allowing for migration of existing code onto the C28x.

TMS320C28x MCU Workshop - Architecture Overview 1-5


C28x CPU

Special Instructions
C28x Atomic Read/Modify/Write
‹ Atomic Instructions Benefits:
LOAD ‹ Simpler programming
READ

‹ Smaller, faster code


Registers CPU ALU / MPY Mem
‹ Uninterruptible (Atomic)
WRITE

STORE ‹ More efficient compiler

Standard Load/Store Atomic Read/Modify/Write


DINT
MOV AL,*XAR2 AND *XAR2,#1234h
AND AL,#1234h 2 words / 1 cycles
MOV *XAR2,AL
EINT
6 words / 6 cycles

Atomics are small common instructions that are non-interuptable. The atomic ALU capability
supports instructions and code that manages tasks and processes. These instructions usually
execute several cycles faster than traditional coding.

1-6 TMS320C28x MCU Workshop - Architecture Overview


C28x CPU

Pipeline Advantage
C28x Pipeline
A F1 F2 D 1 D2 R1 R 2 E W 8-stage pipeline
B F 1 F 2 D1 D 2 R1 R2 E W
C F1 F2 D 1 D2 R1 R 2 E W

D F 1 F 2 D1 D 2 R1 R2 E W
E & G Access
E F1 F2 D1 D2 R1 R 2 E W same address
F F1 F 2 D1 D2 R1 R2 E W

G F1 F2 D1 D2 R
R1 R 2 RE2 W
E W

H F1 F 2 D1 D2 R1 R
R21 RE2 W
E W
F1: Instruction Address
F2: Instruction Content Protected Pipeline
D1: Decode Instruction
D2: Resolve Operand Addr ‹ Order of results are as written in
R1: Operand Address source code
R2: Get Operand
E: CPU doing “real” work
‹ Programmer need not worry about
W: store content to memory the pipeline

The C28x uses a special 8-stage protected pipeline to maximize the throughput. This protected
pipeline prevents a write to and a read from the same location from occurring out of order.

This pipelining also enables the C28x to execute at high speeds without resorting to expensive
high-speed memories. Special branch-look-ahead hardware minimizes the latency for conditional
discontinuities. Special store conditional operations further improve performance.

TMS320C28x MCU Workshop - Architecture Overview 1-7


C28x CPU

FPU Pipeline
C28x + FPU Pipeline
Fetch Decode Read Exe Write
C28x Pipeline F1 F2 D1 D2 R1 R 2 E W

FPU Instruction D R E1 E2/W


Load
Store
0 delay slot instruction
1 delay slot instruction

Floating-point math operations and conversions between integer


and floating-point formats require 1 delay slot – everything else
does not require a delay slot (load, store, max, min, absolute, negative, etc.)
‹ Floating Point Unit has an unprotected pipeline
Š i.e. FPU can issue an instruction before previous instruction
has written results
‹ Compiler prevents pipeline conflicts
‹ Assembler detects pipeline conflicts
‹ Performance improvement by placing non-conflicting
instructions in floating-point pipeline delay slots

Floating-point operations are not pipeline protected. Some instructions require delay slots for the
operation to complete. This can be accomplished by insert NOPs or other non-conflicting
instructions between operations.

In the user’s guide, instructions requiring delay slots have a ‘p’ after their cycle count. The 2p
stands for 2 pipelined cycles. A new instruction can be started on each cycle. The result is valid
only 2 instructions later.

Three general guideslines for the FPU pipeline are:

Math MPYF32, ADDF32, 2p cycles


SUBF32, MACF32 One delay slot

Conversion I16TOF32, F32TOI16, 2p cycles


F32TOI16R, etc… One delay slot

Everything else* Load, Store, Compare, Single cycle


Min, Max, Absolute and No delay slot
Negative value

* Note: MOV32 between FPU and CPU registers is a special case.

1-8 TMS320C28x MCU Workshop - Architecture Overview


Memory

Memory
The memory space on the C28x is divided into program memory and data memory. There are
several different types of memory available that can be used as both program memory and data
memory. They include the flash memory, single access RAM (SARAM), OTP, off-chip memory,
and Boot ROM which is factory programmed with boot software routines or standard tables used
in math related algorithms.

Memory Map
The C28x CPU contains no memory, but can access memory both on and off the chip. The C28x
uses 32-bit data addresses and 22-bit program addresses. This allows for a total address reach of
4G words (1 word = 16-bits) in data memory and 4M words in program memory. Memory blocks
on all C28x designs are uniformly mapped to both program and data space.

This memory map shows the different blocks of memory available to the program and data space.

TMS320F28335 Memory Map


Data Program
0x000000 0x010000
M0 SARAM (1Kw)
0x000400 reserved
M1 SARAM (1Kw)
0x100000
0x000800 XINTF Zone 6 (1Mw)
0x000D00 0x200000
PIE Vectors XINTF Zone 7 (1Mw)
(256 w) 0x300000
0x000E00 reserved
PF 0 (6Kw) FLASH (256Kw)
0x002000
0x004000 0x33FFF8
PASSWORDS (8w)
XINTF Zone 0 (4Kw) 0x340000
0x005000 reserved
PF 3 (4Kw) 0x380080
0x006000 ADC calibration data
PF 1 (4Kw) reserved 0x380090
0x007000 reserved
PF 2 (4Kw) 0x380400
0x008000 User OTP (1Kw)
L0 SARAM (4Kw) 0x380800
0x009000 reserved Dual Mapped:
L1 SARAM (4Kw) 0x3F8000 L0, L1, L2, L3
0x00A000 L0 SARAM (4Kw)
L2 SARAM (4Kw) 0x3F9000
0x00B000 L1 SARAM (4Kw)
CSM Protected:
L3 SARAM (4Kw) 0x3FA000
0x00C000 L2 SARAM (4Kw) L0, L1, L2, L3, OTP
L4 SARAM (4Kw) 0x3FB000 FLASH, ADC CAL,
0x00D000 L3 SARAM (4Kw)
L5 SARAM (4Kw) 0x3FC000 Flash Regs in PF0
0x00E000 reserved
L6 SARAM (4Kw) 0x3FE000
0x00F000 Boot ROM (8Kw) DMA Accessible:
L7 SARAM (4Kw)
0x010000 0x3FFFC0 L4, L5, L6, L7,
BROM Vectors (64w) XINTF Zone 0, 6, 7
0x3FFFFF
Data Program

TMS320C28x MCU Workshop - Architecture Overview 1-9


Memory

Code Security Module (CSM)


Code Security Module
‹ Prevents reverse engineering and
protects valuable intellectual property
0x008000 L0 SARAM (4Kw)
0x009000 L1 SARAM (4Kw)
0x00A000 L2 SARAM (4Kw)
0x00B000 L3 SARAM (4Kw)
0x00C000
0x010000 reserved
0x300000 FLASH (256Kw) Dual
0x33FFF8 128-Bit Password Mapped
0x340000 reserved
0x380400 OTP (1Kw)
0x3F8000 L0 SARAM (4Kw)
0x3F9000 L1 SARAM (4Kw)
0x3FA000 L2 SARAM (4Kw)
0x3FB000 L3 SARAM (4Kw)

‹ 128-bit user defined password is stored in Flash


‹ 128-bits = 2128 = 3.4 x 1038 possible passwords
‹ To try 1 password every 8 cycles at 150 MHz, it
would take at least 5.8 x 1023 years to try all
possible combinations!

Peripherals
The C28x comes with many built in peripherals optimized to support control applications. These
peripherals vary depending on which C28x device you choose.

• ePWM • SPI

• eCAP • SCI

• eQEP • I2C

• Analog-to-Digital Converter • CAN

• Watchdog Timer • GPIO

• McBSP • DMA

1 - 10 TMS320C28x MCU Workshop - Architecture Overview


Fast Interrupt Response

Fast Interrupt Response


The fast interrupt response, with automatic context save of critical registers, resulting in a device
that is capable of servicing many asynchronous events with minimal latency. C28x implements a
zero cycle penalty to do 14 registers context saved and restored during an interrupt. This feature
helps reduces the interrupt service routine overheads.

C28x Fast Interrupt Response Manager


‹ 96 dedicated PIE
vectors
PIE module
‹ No software decision

Peripheral Interrupts 12x8 = 96


For 96 28x CPU Interrupt logic
interrupts
making required
INT1 to
‹ Direct access to RAM INT12
vectors 96 12 interrupts IFR IER
28x
PIE INTM CPU
‹ Auto flags update Register
‹ Concurrent auto Map

context save
Auto Context Save
T ST0
AH AL
PH PL
AR1 (L) AR0 (L)
DP ST1
DBSTAT IER
PC(msw) PC(lsw)

TMS320C28x MCU Workshop - Architecture Overview 1 - 11


C28x Mode

C28x Mode
The C28x is one of several members of the TMS320 digital signal controller/processors family.
The C28x is source code compatable with the 24x/240x devices and previously written code can
be reassembled to run on a C28x device. This allows for migration of existing code onto the
C28x.

C28x Operating Modes

Mode Type Mode Bits Compiler Option


OBJMODE AMODE

C28x Native Mode 1 0 -v28


C24x Compatible Mode 1 1 -v28 –m20
Test Mode (default) 0 0
Reserved 0 1

‹ Almost all uses will run in C28x Native Mode


‹ The bootloader will automatically select C28x Native Mode after reset
‹ C24x compatible mode is mostly for backwards compatibility with an
older processor family

1 - 12 TMS320C28x MCU Workshop - Architecture Overview


Reset

Reset
Reset – Bootloader

Reset
OBJMODE = 0 AMODE = 0
ENPIE = 0 INTM = 1

Bootloader sets
OBJMODE = 1
AMODE = 0
Reset vector fetched
from boot ROM Boot determined by
state of GPIO pins
0x3F FFC0

Execution
Entry Point
Note: M0 SARAM
Details of the various boot options will be
discussed in the Reset and Interrupts module

TMS320C28x MCU Workshop - Architecture Overview 1 - 13


Summary

Summary
Summary
‹ High performance 32-bit DSP
‹ 32x32 bit or dual 16x16 bit MAC
‹ IEEE single-precision floating point unit
‹ Atomic read-modify-write instructions
‹ Fast interrupt response manager
‹ 256Kw on-chip flash memory
‹ Code security module (CSM)
‹ Control peripherals
‹ 12-bit ADC module
‹ Up to 88 shared GPIO pins
‹ Watchdog timer
‹ DMA and external memory interface
‹ Communications peripherals

1 - 14 TMS320C28x MCU Workshop - Architecture Overview


Programming Development Environment

Introduction
This module will explain how to use Code Composer Studio (CCS) integrated development
environment (IDE) tools to develop a program. Creating projects and setting building options
will be covered. Use and the purpose of the linker command file will be described.

Learning Objectives
Learning Objectives

‹ Use Code Composer Studio to:


Š Create a Project
Š Set Build Options
‹ Create a user linker command file which:
Š Describes a system’s available memory
Š Indicates where sections will be placed
in memory

TMS320C28x MCU Workshop - Programming Development Environment 2-1


Module Topics

Module Topics
Programming Development Environment .............................................................................................. 2-1

Module Topics......................................................................................................................................... 2-2


Code Composer Studio ........................................................................................................................... 2-3
Software Development and COFF Concepts...................................................................................... 2-3
Projects ............................................................................................................................................... 2-5
Build Options...................................................................................................................................... 2-6
Creating a Linker Command File ........................................................................................................... 2-9
Sections .............................................................................................................................................. 2-9
Linker Command Files (.cmd) .........................................................................................................2-12
Memory-Map Description .................................................................................................................2-12
Section Placement..............................................................................................................................2-14
Exercise 2...............................................................................................................................................2-15
Summary: Linker Command File ......................................................................................................2-16
Lab 2: Linker Command File.................................................................................................................2-17
Solutions.................................................................................................................................................2-22

2-2 TMS320C28x MCU Workshop - Programming Development Environment


Code Composer Studio

Code Composer Studio


Software Development and COFF Concepts
In an effort to standardize the software development process, TI uses the Common Object File
Format (COFF). COFF has several features which make it a powerful software development
system. It is most useful when the development task is split between several programmers.

Each file of code, called a module, may be written independently, including the specification of
all resources necessary for the proper operation of the module. Modules can be written using
Code Composer Studio (CCS) or any text editor capable of providing a simple ASCII file output.
The expected extension of a source file is .ASM for assembly and .C for C programs.

Code Composer Studio

Build Code
lnk.cmd Simulator
Compile

eZdsp™
Asm Link Debug

External
Editor Libraries Graphs, Emulator
Profiling
MCU
Board

‹ Code Composer Studio includes:


Š Integrated Edit/Debug GUI
Š Code Generation Tools
Š DSP/BIOS

Code Composer Studio includes a built-in editor, compiler, assembler, linker, and an automatic
build process. Additionally, tools to connect file input and output, as well as built-in graph
displays for output are available. Other features can be added using the plug-ins capability

Numerous modules are joined to form a complete program by using the linker. The linker
efficiently allocates the resources available on the device to each module in the system. The
linker uses a command (.CMD) file to identify the memory resources and placement of where the
various sections within each module are to go. Outputs of the linking process includes the linked
object file (.OUT), which runs on the device, and can include a .MAP file which identifies where
each linked section is located.

The high level of modularity and portability resulting from this system simplifies the processes of
verification, debug and maintenance. The process of COFF development is presented in greater
detail in the following paragraphs.

TMS320C28x MCU Workshop - Programming Development Environment 2-3


Code Composer Studio

The concept of COFF tools is to allow modular development of software independent of


hardware concerns. An individual assembly language file is written to perform a single task and
may be linked with several other tasks to achieve a more complex total system.

Writing code in modular form permits code to be developed by several people working in parallel
so the development cycle is shortened. Debugging and upgrading code is faster, since
components of the system, rather than the entire system, is being operated upon. Also, new
systems may be developed more rapidly if previously developed modules can be used in them.

Code developed independently of hardware concerns increases the benefits of modularity by


allowing the programmer to focus on the code and not waste time managing memory and moving
code as other code components grow or shrink. A linker is invoked to allocate systems hardware
to the modules desired to build a system. Changes in any or all modules, when re-linked, create a
new hardware allocation, avoiding the possibility of memory resource conflicts.

Code Composer Studio: IDE

‹ Integrates: edit, code generation,


and debug

‹ Single-click access using buttons

‹ Powerful graphing/profiling tools


‹ Automated tasks using GEL scripts
and CCS scripting

‹ Built-in access to BIOS functions

‹ Supports TI and 3 rd party plug-ins

2-4 TMS320C28x MCU Workshop - Programming Development Environment


Code Composer Studio

Projects
Code Composer works with a project paradigm. Essentially, within CCS you create a project for
each executable program you wish to create. Projects store all the information required to build
the executable. For example, it lists things like: the source files, the header files, the target
system’s memory-map, and program build options.

The CCS Project

Project (.pjt) files contain:

‹ List of files:
Š Source (C, assembly)
Š Libraries
Š DSP/BIOS configuration file
Š Linker command files
‹ Project settings:
Š Build options (compiler,
Linker, assembler, and
DSP/BIOS)
Š Build configurations

The project information is stored in a .PJT file, which is created and maintained by CCS. To
create a new project, you need to select the Project:New… menu item.

Along with the main Project menu, you can also manage open projects using the right-click
popup menu. Either of these menus allows you to Add Files… to a project. Of course, you can
also drag-n-drop files onto the project from Windows Explorer.

TMS320C28x MCU Workshop - Programming Development Environment 2-5


Code Composer Studio

Build Options
Project options direct the code generation tools (i.e. compiler, assembler, linker) to create code
according to your system’s needs. When you create a new project, CCS creates two sets of build
options – called Configurations: one called Debug, the other Release (you might think of as
Optimize).

To make it easier to choose build options, CCS provides a graphical user interface (GUI) for the
various compiler options. Here’s a sample of the Debug configuration options.

Build Options GUI - Compiler

‹ GUI has 8 pages of categories for code


generation tools
‹ Controls many aspects of the build process,
such as:
Š Optimization level
Š Target device
Š Compiler/assembly/link options

There is a one-to-one relationship between the items in the text box and the GUI check and drop-
down box selections. Once you have mastered the various options, you can probably find
yourself just typing in the options.

2-6 TMS320C28x MCU Workshop - Programming Development Environment


Code Composer Studio

Build Options GUI - Linker

‹ GUI has 3 categories


for linking
Š Specify various link
options
‹ .\Debug
means the directory
called Debug one
level below the .pjt
file directory
‹ $(Proj_dir)\Debug
is an equivalent
expression

There are many linker options but these four handle all of the basic needs.
• -o <filename> specifies the output (executable) filename.
• -m <filename> creates a map file. This file reports the linker’s results.
• -c tells the compiler to autoinitialize your global and static variables.

• -x tells the compiler to exhaustively read the libraries. Without this option libraries are
searched only once, and therefore backwards references may not be resolved.

TMS320C28x MCU Workshop - Programming Development Environment 2-7


Code Composer Studio

Default Build Configurations

‹ For new projects, CCS automatically


creates two build configurations:
Š Debug (unoptimized)
Š Release (optimized)
‹ Use the drop-down menu to quickly
select the build configuration

‹ Add/Remove your own custom


build configurations using
Project Configurations
‹ Edit a configuration:
1. Set it active
2. Modify build options
3. Save project

To help make sense of the many compiler options, TI provides two default sets of options
(configurations) in each new project you create. The Release (optimized) configuration invokes
the optimizer with –o3 and disables source-level, symbolic debugging by omitting –g (which
disables some optimizations to enable debug).

2-8 TMS320C28x MCU Workshop - Programming Development Environment


Creating a Linker Command File

Creating a Linker Command File


Sections
Looking at a C program, you'll notice it contains both code and different kinds of data (global,
local, etc.).

Sections
Global vars (.ebss) Init values (.cinit)

‹ All code consists of


int x = 2; different parts called
int y = 7; sections
‹ All default section
names begin with “.”
void main(void) ‹ The compiler has
{ default section
names for initialized
long z; and uninitialized
z = x + y; sections

Local vars (.stack) Code (.text)

In the TI code-generation tools (as with any toolset based on the COFF – Common Object File
Format), these various parts of a program are called Sections. Breaking the program code and
data into various sections provides flexibility since it allows you to place code sections in ROM
and variables in RAM. The preceding diagram illustrated four sections:
• Global Variables
• Initial Values for global variables
• Local Variables (i.e. the stack)
• Code (the actual instructions)

TMS320C28x MCU Workshop - Programming Development Environment 2-9


Creating a Linker Command File

Following is a list of the sections that are created by the compiler. Along with their description,
we provide the Section Name defined by the compiler.

Compiler Section Names


Initialized Sections
Name Description Link Location
.text code FLASH
.cinit initialization values for FLASH
global and static variables
.econst constants (e.g. const int k = 3;) FLASH
.switch tables for switch statements FLASH
.pinit tables for global constructors (C++) FLASH

Uninitialized Sections
Name Description Link Location
.ebss global and static variables RAM
.stack stack space low 64Kw RAM
.esysmem memory for far malloc functions RAM

Note: During development initialized sections could be linked to RAM since


the emulator can be used to load the RAM

Sections of a C program must be located in different memories in your target system. This is the
big advantage of creating the separate sections for code, constants, and variables. In this way,
they can all be linked (located) into their proper memory locations in your target embedded
system. Generally, they’re located as follows:

Program Code (.text)


Program code consists of the sequence of instructions used to manipulate data, initialize system
settings, etc. Program code must be defined upon system reset (power turn-on). Due to this basic
system constraint it is usually necessary to place program code into non-volatile memory, such as
FLASH or EPROM.

Constants (.cinit – initialized data)


Initialized data are those data memory locations defined at reset.It contains constants or initial
values for variables. Similar to program code, constant data is expected to be valid upon reset of
the system. It is often found in FLASH or EPROM (non-volatile memory).

Variables (.ebss – uninitialized data)


Uninitialized data memory locations can be changed and manipulated by the program code during
runtime execution. Unlike program code or constants, uninitialized data or variables must reside
in volatile memory, such as RAM. These memories can be modified and updated, supporting the
way variables are used in math formulas, high-level languages, etc. Each variable must be
declared with a directive to reserve memory to contain its value. By their nature, no value is
assigned, instead they are loaded at runtime by the program

2 - 10 TMS320C28x MCU Workshop - Programming Development Environment


Creating a Linker Command File

Placing Sections in Memory

Memory
Sections
0x00 0000 M0SARAM
(0x400)
.ebss
0x00 0400 M1SARAM
(0x400)
.stack

0x30 0000 FLASH .cinit


(0x40000)

.text

Linking code is a three step process:


1. Defining the various regions of memory (on-chip SARAM vs. FLASH vs. External Memory).
2. Describing what sections go into which memory regions
3. Running the linker with “build” or “rebuild”

TMS320C28x MCU Workshop - Programming Development Environment 2 - 11


Creating a Linker Command File

Linker Command Files (.cmd)


The linker concatenates each section from all input files, allocating memory to each section based
on its length and location as specified by the MEMORY and SECTIONS commands in the linker
command file.

Linking

z Memory description
z How to place s/w into h/w

Link.cmd

.obj Linker .out

.map

Memory-Map Description
The MEMORY section describes the memory configuration of the target system to the linker.

The format is: Name: origin = 0x????, length = 0x????

For example, if you placed a 64Kw FLASH starting at memory location 0x3E8000, it would read:

MEMORY
{
FLASH: origin = 0x300000 , length = 0x040000
}

Each memory segment is defined using the above format. If you added M0SARAM and
M1SARAM, it would look like:

MEMORY
{
M0SARAM: origin = 0x000000 , length = 0x0400
M1SARAM: origin = 0x000400 , length = 0x0400
}

2 - 12 TMS320C28x MCU Workshop - Programming Development Environment


Creating a Linker Command File

Remember that the DSP has two memory maps: Program, and Data. Therefore, the MEMORY
description must describe each of these separately. The loader uses the following syntax to
delineate each of these:

Linker Page TI Definition


Page 0 Program
Page 1 Data

Linker Command File


MEMORY
{
PAGE 0: /* Program Memory */
FLASH: origin = 0x300000, length = 0x40000

PAGE 1: /* Data Memory */


M0SARAM: origin = 0x000000, length = 0x400
M1SARAM: origin = 0x000400, length = 0x400
}

TMS320C28x MCU Workshop - Programming Development Environment 2 - 13


Creating a Linker Command File

Section Placement
The SECTIONS section will specify how you want the sections to be distributed through
memory. The following code is used to link the sections into the memory specified in the
previous example:

SECTIONS
{
.text:> FLASH PAGE 0
.ebss:> M0SARAM PAGE 1
.cinit:> FLASH PAGE 0
.stack:> M1SARAM PAGE 1
}

The linker will gather all the code sections from all the files being linked together. Similarly, it
will combine all ‘like’ sections.

Beginning with the first section listed, the linker will place it into the specified memory segment.

Linker Command File


MEMORY
{
PAGE 0: /* Program Memory */
FLASH: origin = 0x300000, length = 0x40000

PAGE 1: /* Data Memory */


M0SARAM: origin = 0x000000, length = 0x400
M1SARAM: origin = 0x000400, length = 0x400
}
SECTIONS
{
.text:> FLASH PAGE = 0
.ebss:> M0SARAM PAGE = 1
.cinit:> FLASH PAGE = 0
.stack:> M1SARAM PAGE = 1
}

2 - 14 TMS320C28x MCU Workshop - Programming Development Environment


Exercise 2

Exercise 2
Looking at the following block diagram, and create a linker command file.

Exercise 2

0x00 0000 0x00 0400


M0SARAM M1SARAM
(0x400) (0x400)

0x00 8000 0x00 9000


L0SARAM L1SARAM
(0x1000) (0x1000)

0x30 0000
FLASH
(0x40000)

Generic F28x device

Create the linker command file for the given memory


map by filling in the blanks on the following slide

Fill in the blanks:

Exercise 2 - Command File


MEMORY
{
PAGE__: /* Program Memory */
_____: origin = ____ ___, length = ___ ___
______: /* Data Memory */
_______: origin = __ ____, length = _____
_______: origin = ____ ___, length = _____
_______: origin = ___ ____, length = __ ___
_______: origin = ___ ____, length = _ ____
}
SECTIONS
{
.text: > FLASH PAGE = 0
.ebss: > M0SARAM PAGE = 1
.cinit: > FLASH PAGE = 0
.stack: > M1SARAM PAGE = 1
}

TMS320C28x MCU Workshop - Programming Development Environment 2 - 15


Exercise 2

Summary: Linker Command File


The linker command file (.cmd) contains the inputs — commands — for the linker. This
information is summarized below:

Linker Command File Summary

‹ Memory Map Description


Š Name
Š Location
Š Size
‹ Sections Description
Š Directs software sections into named
memory regions
Š Allows per-file discrimination
Š Allows separate load/run locations

2 - 16 TMS320C28x MCU Workshop - Programming Development Environment


Lab 2: Linker Command File

Lab 2: Linker Command File


¾ Objective

Create a linker command file and link the C program file (Lab2.c) into the system described
below.

Lab 2: Linker Command File


0x00 0000 M0SARAM 0x00 B000 L3SARAM
Memory
(0x400) (0x1000)
0x00 0400 M1SARAM 0x00 C000 L4SARAM
on-chip
memory (0x400) (0x1000)
0x00 8000 L0SARAM 0x00 D000 L5SARAM

F28335 (0x1000) (0x1000)


0x00 9000 L1SARAM 0x00 E000 L6SARAM
(0x1000) (0x1000)
System Description:
0x00 A000 L2SARAM 0x00 F000 L7SARAM
• TMS320F28335
(0x1000) (0x1000)
• All internal RAM
blocks allocated

Placement of Sections:
• .text into RAM Block L0123SARAM on PAGE 0 (program memory)
• .cinit into RAM Block L0123SARAM on PAGE 0 (program memory)
• .ebss into RAM Block L4SARAM on PAGE 1 (data memory)
• .stack into RAM Block M1SARAM on PAGE 1 (data memory)

System Description
• TMS320F28335
• All internal RAM blocks allocated

Placement of Sections:
• .text into RAM Block L0123SARAM on PAGE 0 (program memory)
• .cinit into RAM Block L0123SARAM on PAGE 0 (program memory)
• .ebss into RAM Block L4SARAM on PAGE 1 (data memory)
• .stack into RAM Block M1SARAM on PAGE 1 (data memory)

¾ Procedure

Create a New Project


1. Double click on the Code Composer Studio icon on the desktop. Maximize Code
Composer Studio to fill your screen. Code Composer Studio has a Connect/Disconnect
feature which allows the target to be dynamically connected and disconnected. This will
reset the JTAG link and also enable “hot swapping” a target board. Connect to the target.

TMS320C28x MCU Workshop - Programming Development Environment 2 - 17


Lab 2: Linker Command File

Click: Debug Æ Connect

The menu bar (at the top) lists File ... Help. Note the horizontal tool bar below the menu
bar and the vertical tool bar on the left-hand side. The window on the left is the project
window and the large right-hand window is your workspace.

2. A project is all the files you will need to develop an executable output file (.out) which
can be run on the DSP hardware. Let’s create a new project for this lab. On the menu bar
click:
Project Æ New
type Lab2 in the project name field and make sure the save in location is:
C:\C28x\Labs\Lab2, then click Finish. This will create a .pjt file which will
invoke all the necessary tools (compiler, assembler, linker) to build your project. It will
also create a debug folder that will hold immediate output files.

3. Add the C file to the new project. Click:


Project Æ Add Files to Project…
and make sure you’re looking in C:\C28x\Labs\Lab2. Change the “files of type” to
view C source files (*.c) and select Lab2.c and click OPEN. This will add the file
Lab2.c to your newly created project.
4. Add Lab2.cmd to the project using the same procedure. This file will be edited during
the lab exercise.

5. In the project window on the left, click the plus sign (+) to the left of Project. Now,
click on the plus sign next to Lab2.pjt. Notice that the Lab2.cmd file is listed.
Click on Source to see the current source file list (i.e. Lab2.c).

Project Build Options


6. There are numerous build options in the project. The default option settings are sufficient
for getting started. We will inspect a couple of the default linker options at this time.

Click: Project Æ Build Options…

7. Select the Linker tab. Notice that .out and .map files are being created. The .out file is
the executable code that will be loaded into the DSP. The .map file will contain a linker
report showing memory usage and section addresses in memory.
8. Set the Stack Size to 0x200.
9. Next, setup the compiler run-time support library. In the Libraries Category, find the
Include Libraries (-l) box and enter: rts2800_ml.lib. Select OK and the
Build Options window will close.

Edit the Linker Command File - Lab2a.cmd


10. To open and edit Lab2.cmd, double click on the filename in the project window.

2 - 18 TMS320C28x MCU Workshop - Programming Development Environment


Lab 2: Linker Command File

11. Edit the Memory{} declaration by describing the system memory shown on the “Lab2:
Linker Command File” slide in the objective section of this lab exercise. Combine the
memory blocks L0SARAM, L1SARAM, L2SARM, and L3SARAM into a single
memory block called L0123SARAM. Place this combined memory block into program
memory on page 0. Place the other memory blocks into data memory on page 1.

12. In the Sections{} area, notice that a section called .reset has already been allocated.
The .reset section is part of the rts2800_ml.lib, and is not needed. By putting the TYPE =
DSECT modifier after its allocation, the linker will ignore this section and not allocate it.
13. Place the sections defined on the slide into the appropriate memories via the
Sections{} area. Save your work and close the file.

Build and Load the Project


14. The top four buttons on the horizontal toolbar control code generation. Hover your
mouse over each button as you read the following descriptions:
Button Name Description
1 Compile File Compile, assemble the current open file
2 Incremental Build Compile, assemble only changed files, then link
3 Rebuild All Compile, assemble all files, then link
4 Stop Build Stop code generation

15. Code Composer Studio can automatically load the output file after a successful build. On
the menu bar click: Option Æ Customize… and select the
“Program/Project/CIO” tab, check “Load Program After Build”.
Also, Code Composer Studio can automatically connect to the target when started. Select
the “Debug Properties” tab, check “Connect to the target at
startup”, then click OK.
16. Click the “Build” button and watch the tools run in the build window. Check for
errors (we have deliberately put an error in Lab2.c). When you get an error, scroll the
build window at the bottom of the Code Composer Studio screen until you see the error
message (in red), and simply double-click the error message. The editor will
automatically open the source file containing the error, and position the mouse cursor at
the correct code line.
17. Fix the error by adding a semicolon at the end of the "z = x + y" statement. For
future knowlege, realize that a single code error can sometimes generate multiple error
messages at build time. This was not the case here.
18. Rebuild the project (there should be no errors this time). The output file should
automatically load. The Program Counter should be pointing to _c_int00 in the
Disassembly Window.

19. Under Debug on the menu bar click “Go Main”. This will run through the C-
environment initialization routine in the rts2800_ml.lib and stop at main() in
Lab2.c.

TMS320C28x MCU Workshop - Programming Development Environment 2 - 19


Lab 2: Linker Command File

Debug Enviroment Windows


It is standard debug practice to watch local and global variables while debugging code. There
are various methods for doing this in Code Composer Studio. We will examine two of them
here: memory windows, and watch windows.

20. Open a memory window to view the global variable “z”.

Click: View Æ Memory on the menu bar.

Type “&z” into the address field and then enter. Note that you must use the ampersand
(meaning "address of") when using a symbol in a memory window address box. Also
note that Code Composer Studio is case sensitive.

Set the properties format to “Hex 16 Bit – TI style” at the bottom of the window. This
will give you more viewable data in the window. You can change the contents of any
address in the memory window by double-clicking on its value. This is useful during
debug.

21. Open the watch window to view the local variables x and y.

Click: View Æ Watch Window on the menu bar.

Click the “Watch Locals” tab and notice that the local variables x and y are already
present. The watch window will always contain the local variables for the code function
currently being executed.

(Note that local variables actually live on the stack. You can also view local variables in
a memory window by setting the address to “SP” after the code function has been
entered).

22. We can also add global variables to the watch window if desired. Let's add the global
variable “z”.

Click the “Watch 1” tab at the bottom of the watch window. In the empty box in the
“Name” column, type “z” and then enter. Note that you do not use an ampersand here.
The watch window knows you are specifying a symbol.

Check that the watch window and memory window both report the same value for “z”.
Trying changing the value in one window, and notice that the value also changes in the
other window.

Single-stepping the Code


23. Click the “Watch Locals” tab at the bottom of the watch window. Single-step through
main() by using the <F11> key (or you can use the Single Step button on the
vertical toolbar). Check to see if the program is working as expected. What is the value
for “z” when you get to the end of the program?

End of Exercise

2 - 20 TMS320C28x MCU Workshop - Programming Development Environment


Lab 2: Linker Command File

TMS320C28x MCU Workshop - Programming Development Environment 2 - 21


Solutions

Solutions
Exercise 2 - Solution
MEMORY
{
PAGE 0: /* Program Memory */
FLASH: origin = 0x300000, length = 0x40000
PAGE 1: /* Data Memory */
M0SARAM: origin = 0x000000, length = 0x400
M1SARAM: origin = 0x000400, length = 0x400
L0SARAM: origin = 0x008000, length = 0x1000
L1SARAM: origin = 0x009000, length = 0x1000
}
SECTIONS
{
.text: > FLASH PAGE = 0
.ebss: > M0SARAM PAGE = 1
.cinit: > FLASH PAGE = 0
.stack: > M1SARAM PAGE = 1
}

Lab 2: Solution - lab2.cmd


MEMORY
{
PAGE 0: /* Program Memory */
L0123SARAM: origin = 0x008000, length = 0x4000
PAGE 1: /* Data Memory */
M0SARAM: origin = 0x000000, length = 0x0400
M1SARAM: origin = 0x000400, length = 0x0400
L4SARAM: origin = 0x00C000, length = 0x1000
L5SARAM: origin = 0x00D000, length = 0x1000
L6SARAM: origin = 0x00E000, length = 0x1000
L7SARAM: origin = 0x00F000, length = 0x1000
}

SECTIONS
{
.text: > L0123SARAM PAGE = 0
.ebss: > L4SARAM PAGE = 1
.cinit: > L0123SARAM PAGE = 0
.stack: > M1SARAM PAGE = 1
.reset: > L0123SARAM PAGE = 0, TYPE = DSECT
}

2 - 22 TMS320C28x MCU Workshop - Programming Development Environment


Peripherial Registers Header Files

Introduction
The purpose of the DSP2833x C-code header files is to simplify the programming of the many
peripherals on the C28x device. Typically, to program a peripheral the programmer needs to
write the appropriate values to the different fields within a control register. In its simplest form,
the process consists of writing a hex value (or masking a bit field) to the correct address in
memory. But, since this can be a burdensome and repetitive task, the C-code header files were
created to make this a less complicated task.

The DSP2833x C-code header files are part of a library consisting of C functions, macros,
peripheral structures, and variable definitions. Together, this set of files is known as the ‘header
files.’

Registers and the bit-fields are represented by structures. C functions and macros are used to
initialize or modify the structures (registers).

In this module, you will learn how to use the header files and C programs to facilitate
programming the peripherals.

Learning Objectives
Learning Objectives

‹ Understand the usage of the F2833x


C-Code Header Files
‹ Be able to program peripheral
registers
‹ Understand how the structures are
mapped with the linker command file

TMS320C28x MCU Workshop - Peripheral Registers Header Files 3-1


Module Topics

Module Topics
Peripherial Registers Header Files .......................................................................................................... 3-1

Module Topics......................................................................................................................................... 3-2


Traditional and Structure Approach to C Coding .................................................................................. 3-3
Naming Conventions............................................................................................................................... 3-6
F2833x C-Code Header Files ................................................................................................................. 3-7
Peripheral Structure .h File ................................................................................................................. 3-7
Global Variable Definitions File ........................................................................................................ 3-9
Mapping Structures to Memory.........................................................................................................3-10
Linker Command File........................................................................................................................3-10
Peripheral Specific Routines..............................................................................................................3-11
Summary ................................................................................................................................................3-12

3-2 TMS320C28x MCU Workshop - Peripheral Registers Header Files


Traditional and Structure Approach to C Coding

Traditional and Structure Approach to C Coding


Traditional Approach to C Coding
#define ADCTRL1 (volatile unsigned int *)0x00007100
#define ADCTRL2 (volatile unsigned int *)0x00007101
...
void main(void)
{
*ADCTRL1 = 0x1234; //write entire register
*ADCTRL2 |= 0x4000; //reset sequencer #1
}

Advantages - Simple, fast and easy to type


- Variable names exactly match register names (easy
to remember)
Disadvantages - Requires individual masks to be generated to
manipulate individual bits
- Cannot easily display bit fields in Watch window
- Will generate less efficient code in many cases

Structure Approach to C Coding


void main(void)
{
AdcRegs.ADCTRL1.all = 0x1234; //write entire register
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //reset sequencer #1
}

Advantages - Easy to manipulate individual bits.


- Watch window is amazing! (next slide)
- Generates most efficient code (on C28x)

Disadvantages - Can be difficult to remember the structure names


(Editor Auto Complete feature to the rescue!)
- More to type (again, Editor Auto Complete feature
to the rescue)

TMS320C28x MCU Workshop - Peripheral Registers Header Files 3-3


Traditional and Structure Approach to C Coding

The CCS Watch Window using #define

The CCS Watch Window using Structures

3-4 TMS320C28x MCU Workshop - Peripheral Registers Header Files


Traditional and Structure Approach to C Coding

Is the Structure Approach Efficient?


The structure approach enables efficient compiler use of
DP addressing mode and C28x atomic operations

C Source Code Generated Assembly Code


// Stop CPU Timer0 MOVW DP, #0030
CpuTimer0Regs.TCR.bit.TSS = 1; OR @4, #0x0010

// Load new 32-bit period value MOVL XAR4, #0x010000


CpuTimer0Regs.PRD.all = 0x00010000; MOVL @2, XAR4

// Start CPU Timer0 AND @4, #0xFFEF


CpuTimer0Regs.TCR.bit.TSS = 0;

- Easy to read the code w/o comments


5 words, 5 cycles
- Bit mask built-in to structure

You could not have coded this example any more efficiently with hand assembly!

* C28x Compiler v5.0.1 with -g and either -o1, -o2, or -o3 optimization level

Compare with the #define Approach


The #define approach relies heavily on less-efficient pointers for
random memory access, and often does not take advantage of
C28x atomic operations

C Source Code Generated Assembly Code*


// Stop CPU Timer0 MOV @AL,*(0:0x0C04)
*TIMER0TCR |= 0x0010; ORB AL, #0x10
MOV *(0:0x0C04), @AL

// Load new 32-bit period value MOVL XAR5, #0x010000


*TIMER0TPRD32 = 0x00010000; MOVL XAR4, #0x000C0A
MOVL *+XAR4[0], XAR5
// Start CPU Timer0
*TIMER0TCR &= 0xFFEF; MOV @AL, *(0:0x0C04)
AND @AL, #0xFFEF
MOV *(0:0x0C04), @AL

- Hard to read the code w/o comments 9 words, 9 cycles


- User had to determine the bit mask

* C28x Compiler v5.0.1 with -g and either -o1, -o2, or -o3 optimization level

TMS320C28x MCU Workshop - Peripheral Registers Header Files 3-5


Naming Conventions

Naming Conventions
The header files use a familiar set of naming conventions. They are consistent with the Code
Composer Studio configuration tool, and generated file naming conventions

Structure Naming Conventions


‹ The DSP2833x header files define:
Š All of the peripheral structures
Š All of the register names
Š All of the bit field names
Š All of the register addresses
PeripheralName.RegisterName.all // Access full 16 or 32-bit register
PeripheralName.RegisterName.half.LSW // Access low 16-bits of 32-bit register
PeripheralName.RegisterName.half.MSW // Access high 16-bits of 32-bit register
PeripheralName.RegisterName.bit.FieldName // Access specified bit fields of register
Notes: [1] “PeripheralName” are assigned by TI and found in the DSP2833x header files.
They are a combination of capital and small letters (i.e. CpuTimer0Regs).
[2] “RegisterName” are the same names as used in the data sheet.
They are always in capital letters (i.e. TCR, TIM, TPR,..).
[3] “FieldName” are the same names as used in the data sheet.
They are always in capital letters (i.e. POL, TOG, TSS,..).

Editor Auto Complete to the Rescue!

3-6 TMS320C28x MCU Workshop - Peripheral Registers Header Files


F2833x C-Code Header Files

F2833x C-Code Header Files


The C-code header files consists of .h, c source files, linker command files, and other useful
example programs, documentations and add-ins for Code Composer Studio.

DSP2833x Header File Package


(http://www.ti.com, literature # SPRC530)

‹ Contains everything needed to use the


structure approach
‹ Defines all peripheral register bits and
register addresses
‹ Header file package includes:
Š \DSP2833x_headers\include Æ .h files
Š \DSP2833x_headers\cmd Æ linker .cmd files
Š \DSP2833x_headers\gel Æ .gel files for CCS
Š \DSP2833x_examples Æ ‘2833x examples
Š \DSP2823x_examples Æ ‘2823x examples
Š \doc Æ documentation

A peripheral is programmed by writing values to a set of registers. Sometimes, individual fields


are written to as bits, or as bytes, or as entire words. Unions are used to overlap memory
(register) so the contents can be accessed in different ways. The header files group all the
registers belonging to a specific peripheral.

A DSP2833x_Peripheral.gel GEL file can provide a pull down menu to load peripheral data
structures into a watch window. Code Composer Studio can load a GEL file automatically. To
include fuctions to the standard F28335.gel that is part of Code Composer Studio, add:

GEL_LoadGel(“base_path/gel/DSP2833x_Peripheral.gel”)

The GEL file can also be loaded during a Code Composer Studio session by clicking:

File Æ Load GEL…

Peripheral Structure .h File


The DSP2833x_Device.h header file is the main include file. By including this file in the .c
source code, all of the peripheral specific .h header files are automatically included. Of course,
each specific .h header file can included individually in an application that do not use all the
header files, or you can comment out the ones you do not need. (Also includes typedef
statements).

TMS320C28x MCU Workshop - Peripheral Registers Header Files 3-7


F2833x C-Code Header Files

Peripheral Structure .h files (1 of 2)


‹ Contain bits field structure definitions for each peripheral register
DSP2833x_Adc.h
/* ADC Individual Register Bit Definitions */
struct ADCTRL1_BITS { // bits description
Uint16 rsvd1:4; // 3:0 reserved
Uint16 SEQ_CASC:1; // 4 Cascaded sequencer mode
Your C-source file (e.g., Adc.c) Uint16 SEQ_OVRD:1 // 5 Sequencer override
#include “DSP2833x_Device.h” Uint16 CONT_RUN:1; // 6 Continuous run
Uint16 CPS:1; // 7 ADC core clock prescaler
Void InitAdc(void) Uint16 ACQ_PS:4; // 11:8 Acquisition w indow size
{ Uint16 SUSMOD:2; // 13:12 Emulation suspend mode
/* Reset the ADC m odule */ Uint16 RESET:1; // 14 ADC reset
AdcRegs.ADCTRL1.bit.RESET = 1; Uint16 rsvd2:1; // 15 reserved
};
/* configure the ADC register */
AdcRegs.ADCTRL1.all = 0x0710; /* Allow access to the bit fields or entire register */
}; union ADCTRL1_REG {
Uint16 all;
struct ADCTRL1_BITS bit;
};

// ADC External References & Function Declarations:


extern volatile struct ADC_REGS AdcRegs;

Peripheral Structure .h files (2 of 2)


‹ The header file package contains a .h file
for each peripheral in the device
DSP2833x_Device.h DSP2833x_DevEmu.h DSP2833x_SysCtrl.h
DSP2833x_PieCtrl.h DSP2833x_Adc.h DSP2833x_CpuTimers.h
DSP2833x_ECan.h DSP2833x_ECap.h DSP2833x_EPwm.h
DSP2833x_EQep.h DSP2833x_Gpio.h DSP2833x_I2c.h
DSP2833x_Sci.h DSP2833x_Spi.h DSP2833x_XIntrupt.h
DSP2833x_PieVect.h DSP2833x_DefaultIsr.h DSP2833x_DMA.h
DSP2833x_Mcbsp.h DSP2833x_Xintf.h

‹ DSP2833x_Device.h
Š Main include file (for ‘2833x and ‘2823x devices)
Š Will include all other .h files
Š Include this file in each source file:
#include “DSP2833x_Device.h”

3-8 TMS320C28x MCU Workshop - Peripheral Registers Header Files


F2833x C-Code Header Files

Global Variable Definitions File


With DSP2833x_GlobalVariableDefs.c included in the project all the needed variable definitions
are globally defined.

Global Variable Definitions File


DSP2833x_GlobalVariableDefs.c

‹ Declares a global instantiation of the structure


for each peripheral
‹ Each structure put in its own section using a
DATA_SECTION pragma to allow linking to
correct memory (see next slide)
DSP2833x_GlobalVariableDefs.c
#include "DSP2833x_Device.h“

#pragma DATA_SECTION(AdcRegs,"AdcRegsFile");
volatile struct ADC_REGS AdcRegs;

‹ Add this file to your CCS project:


DSP2833x_GlobalVariableDefs.c

TMS320C28x MCU Workshop - Peripheral Registers Header Files 3-9


F2833x C-Code Header Files

Mapping Structures to Memory


The data structures describe the register set in detail. And, each instance of the data type (i.e.,
register set) is unique. Each structure is associated with an address in memory. This is done by
(1) creating a new section name via a DATA_SECTION pragma, and (2) linking the new section
name to a specific memory in the linker command file.

Linker Command Files for the Structures


DSP2833x_nonBIOS.cmd and DSP2833x_BIOS.cmd

DSP2833x_GlobalVariableDefs.c
#include "DSP2833x_Device.h“ ‹ Links each structure to

the address of the
peripheral using the
#pragma DATA_SECTION(AdcRegs,"AdcRegsFile");
structures named
volatile struct ADC_REGS AdcRegs; section

DSP2833x_Headers_nonBIOS.cmd
‹ non-BIOS and BIOS
versions of the .cmd file
MEMORY
{
PAGE1:
... ‹ Add one of these files to
ADC: origin=0x007100, length=0x000020 your CCS project:
...
} DSP2833x_nonBIOS.cmd
SECTIONS or
{
... DSP2833x_BIOS.cmd
AdcRegsFile: > ADC PAGE = 1
...
}

Linker Command File


When using the header files, the user adds the MEMORY regions that correspond to the
CODE_SECTION and DATA_SECTION pragmas found in the .h and global-definitons.c file.

The user can modify their own linker command file, or use the pre-configured linker command
files such as EzDSP_RAM_lnk.cmd or F28335.cmd. These files have the peripheral memory
regions defined and tied to the individual peripheral.

3 - 10 TMS320C28x MCU Workshop - Peripheral Registers Header Files


F2833x C-Code Header Files

Peripheral Specific Routines


Peripheral Specific C functions are used to initialize the peripherals. They are used by adding the
appropriate .c file to the project.

Peripheral Specific Examples


‹ Example(s) projects for each peripheral
‹ Helpful to get you started
‹ Seperate projects for ‘2833x and ‘2823x
Š ‘2823x projects configured for no FPU

TMS320C28x MCU Workshop - Peripheral Registers Header Files 3 - 11


Summary

Summary
Peripheral Register Header Files
Summary
‹ Easier code development
‹ Easy to use
‹ Generates most efficient code
‹ Increases effectiveness of CCS watch window
‹ TI has already done all the work!
Š Use the correct header file package for your device:

Š F2833x and F2823x # SPRC530


Š F280x and F2801x # SPRC191
Š F2804x # SPRC324
Š F281x # SPRC097

Go to http://www.ti.com and enter the literature number in the keyword search box

3 - 12 TMS320C28x MCU Workshop - Peripheral Registers Header Files


Reset and Interrupts

Introduction
This module describes the interrupt process and explains how the Peripheral Interrupt Expansion
(PIE) works.

Learning Objectives
Learning Objectives

‹ Describe the C28x reset process


and post-reset device state
‹ List the event sequence during an
interrupt
‹ Describe the C28x interrupt
structure

TMS320C28x MCU Workshop - Reset and Interrupts 4-1


Module Topics

Module Topics
Reset and Interrupts ................................................................................................................................. 4-1

Module Topics......................................................................................................................................... 4-2


Reset........................................................................................................................................................ 4-3
Reset - Bootloader .............................................................................................................................. 4-3
Interrupts ................................................................................................................................................ 4-5
Interrupt Processing............................................................................................................................ 4-5
Peripheral Interrupt Expansion (PIE) ................................................................................................. 4-7
PIE Interrupt Vector Table ................................................................................................................. 4-8
Interrupt Response and Latency ........................................................................................................4-10

4-2 TMS320C28x MCU Workshop - Reset and Interrupts


Reset

Reset
Reset Sources

C28x Core
Watchdog Timer
XRS
XRS pin active

To XRS pin

Reset - Bootloader
Reset – Bootloader

Reset
OBJMODE = 0 AMODE = 0
ENPIE = 0 INTM = 1

Bootloader sets
OBJMODE = 1
AMODE = 0
Reset vector fetched
from boot ROM Boot determined by
state of GPIO pins
0x3F FFC0

Execution Bootloading
Entry Point Routines
FLASH SCI-A / SPI-A
M0 SARAM I2C
OTP eCAN-A
XINTF McBSP-A
GPIO / XINTF

TMS320C28x MCU Workshop - Reset and Interrupts 4-3


Reset

Bootloader Options
GPIO pins
87 / 86 / 85 / 84 /
XA15 XA14 XA13 XA12
1 1 1 1 jump to FLASH address 0x33 FFF6
1 1 1 0 bootload code to on-chip memory via SCI-A
1 1 0 1 bootload external EEPROM to on-chip memory via SPI-A
1 1 0 0 bootload external EEPROM to on-chip memory via I2C
1 0 1 1 Call CAN_Boot to load from eCAN-A mailbox 1
1 0 1 0 bootload code to on-chip memory via McBSP-A
1 0 0 1 jump to XINTF Zone 6 address 0x10 0000 for 16-bit data
1 0 0 0 jump to XINTF Zone 6 address 0x10 0000 for 32-bit data
0 1 1 1 jump to OTP address 0x38 0400
0 1 1 0 bootload code to on-chip memory via GPIO port A (parallel)
0 1 0 1 bootload code to on-chip memory via XINTF (parallel)
0 1 0 0 jump to M0 SARAM address 0x00 0000
0 0 1 1 branch to check boot mode
0 0 1 0 branch to Flash without ADC calibration (TI debug only)
0 0 0 1 branch to M0 SARAM without ADC calibration (TI debug only)
0 0 0 0 branch to SCI-A without ADC calibration (TI debug only)

Reset Code Flow - Summary


0x00 0000 0x00 0000
M0 SARAM (1Kw)

0x38 0400 XINTF Zone 6


OTP (1Kw) (x16 / x32)
0x10 0000
0x30 0000
FLASH (256Kw)
0x33 FFF6

Execution Entry
0x3F E000 Boot ROM (8Kw) Point Determined
Boot Code By GPIO Pins
0x3F F9A9
• •
• •

BROM vector (64w)


RESET 0x3F FFC0 0x3F F9A9 Bootloading
Routines
(SCI-A, SPI-A, I2C,
eCAN-A, McBSP-A
GPIO, XINTF)

4-4 TMS320C28x MCU Workshop - Reset and Interrupts


Interrupts

Interrupts
Interrupt Sources
Internal Sources
TINT2
TINT1 C28x CORE
TINT0 XRS

ePWM, eCAP, NMI


PIE INT1
eQEP, ADC, SCI,
(Peripheral
SPI, I2C, eCAN, INT2
Interrupt
McBSP, DMA, WD
Expansion) INT3



External Sources
INT12
INT13
XINT1 – XINT7
INT14
TZx
XRS
XNMI_XINT13

Interrupt Processing

Maskable Interrupt Processing


Conceptual Core Overview

Core (IFR) (IER) (INTM)


Interrupt “Latch” “Switch” “Global Switch”

INT1 1

INT2 0 C28x
Core

INT14 1

‹ A valid signal on a specific interrupt line causes the latch


to display a “1” in the appropriate bit

‹ If the individual and global switches are turned “on” the


interrupt reaches the core

TMS320C28x MCU Workshop - Reset and Interrupts 4-5


Interrupts

Interrupt Flag Register (IFR)


15 14 13 12 11 10 9 8
RTOSINT DLOGINT INT14 INT13 INT12 INT11 INT10 INT9

7 6 5 4 3 2 1 0
INT8 INT7 INT6 INT5 INT4 INT3 INT2 INT1

Pending : IFR Bit = 1


Absent : IFR Bit = 0

/*** Manual setting/clearing IFR ***/


extern cregister volatile unsigned int IFR;
IFR |= 0x0008; //set INT4 in IFR
IFR &= 0xFFF7; //clear INT4 in IFR

‹ Compiler generates atomic instructions (non-interruptible) for setting/clearing IFR


‹ Ifinterrupt occurs when writing IFR, interrupt has priority
‹ IFR(bit) cleared when interrupt is acknowledged by CPU
‹ Register cleared on reset

Interrupt Enable Register (IER)


15 14 13 12 11 10 9 8
RTOSINT DLOGINT INT14 INT13 INT12 INT11 INT10 INT9

7 6 5 4 3 2 1 0
INT8 INT7 INT6 INT5 INT4 INT3 INT2 INT1

Enable: Set IER Bit = 1


Disable: Clear IER Bit = 0

/*** Interrupt Enable Register ***/


extern cregister volatile unsigned int IER;
IER |= 0x0008; //enable INT4 in IER
IER &= 0xFFF7; //disable INT4 in IER

‹ Compiler generates atomic instructions (non-interruptible)


for setting/clearing IER
‹ Register cleared on reset

4-6 TMS320C28x MCU Workshop - Reset and Interrupts


Interrupts

Interrupt Global Mask Bit


Bit 0
ST1 INTM

‹ INTM used to globally enable/disable interrupts:


Š Enable: INTM = 0
Š Disable: INTM = 1 (reset value)
‹ INTM modified from assembly code only:

/*** Global Interrupts ***/


asm(“ CLRC INTM”); //enable global interrupts
asm(“ SETC INTM”); //disable global interrupts

Peripheral Interrupt Expansion (PIE)


Peripheral Interrupt Expansion - PIE
Interrupt Group 1
PIE module for 96 Interrupts
PIEIFR1 PIEIER1
Peripheral Interrupts 12x8 = 96

INT1.x interrupt group INT1.1 1


INT2.x interrupt group
INT1.2 0
INT3.x interrupt group INT1
• •
INT4.x interrupt group • •
INT5.x interrupt group
• •
INT1.8 1
INT6.x interrupt group
96
INT7.x interrupt group
28x Core Interrupt logic
INT8.x interrupt group
INT9.x interrupt group INT1 – INT12
INTM

INT10.x interrupt group 28x


IER
IFR

12 Interrupts
INT11.x interrupt group Core

INT12.x interrupt group

INT13 (TINT1 / XINT13)


INT14 (TINT2)
NMI

TMS320C28x MCU Workshop - Reset and Interrupts 4-7


Interrupts

PIE Registers
PIEIFRx register (x = 1 to 12)
15 - 8 7 6 5 4 3 2 1 0
reserved INTx.8 INTx.7 INTx.6 INTx.5 INTx.4 INTx.3 INTx.2 INTx.1

PIEIERx register (x = 1 to 12)


15 - 8 7 6 5 4 3 2 1 0
reserved INTx.8 INTx.7 INTx.6 INTx.5 INTx.4 INTx.3 INTx.2 INTx.1

PIE Interrupt Acknowledge Register (PIEACK)


15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
reserved PIEACKx

PIECTRL register 15 - 1 0
PIEVECT ENPIE

#include “DSP2833x_Device.h”
PieCtrlRegs.PIEIFR1.bit.INTx4 = 1; //manually set IFR for XINT1 in PIE group 1
PieCtrlRegs.PIEIER3.bit.INTx5 = 1; //enable EPWM5_INT in PIE group 3
PieCtrlRegs.PIEACK.all = 0x0004; //acknowledge the PIE group 3
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //enable the PIE

PIE Interrupt Vector Table


Default Interrupt Vector Table at Reset
Vector Offset
RESET 00 Default Vector Table
INT1 02 Re-mapped when
INT2 04 ENPIE = 1
INT3 06 Memory
INT4 08 0
INT5 0A
INT6 0C
INT7 0E
INT8 10
INT9 0x00 0D00
12
INT10 14
PIE Vectors
256w
INT11 16
INT12 18
INT13 1A
INT14 1C BROM Vectors 0x3F FFC0
DATALOG 1E 64w
20 ENPIE = 0
RTOSINT 0x3F FFFF
EMUINT 22
NMI 24
PieVectTableInit{ }
ILLEGAL 26
Used to initialize PIE vectors
USER 1-12 28-3E

4-8 TMS320C28x MCU Workshop - Reset and Interrupts


Interrupts

PIE Vector Mapping (ENPIE = 1)


Vector name PIE vector address PIE vector Description
not used 0x00 0D00 Reset vector (never fetched here)
INT1 0x00 0D02 INT1 re-mapped to PIE group below
…… …… …… re-mapped to PIE group below
INT12 0x00 0D18 INT12 re-mapped to PIE group below
INT13 0x00 0D1A XINT13 Interrupt or CPU Timer 1 (RTOS)
INT14 0x00 0D1C CPU Timer 2 (RTOS)
DATALOG 0x00 0D1D CPU Data logging Interrupt
…… …… ……
USER12 0x00 0D3E User-defined Trap
INT1.1 0x00 0D40 PIEINT1.1 Interrupt Vector
…… …… ……
INT1.8 0x00 0D4E PIEINT1.8 Interrupt Vector
…… …… ……
INT12.1 0x00 0DF0 PIEINT12.1 Interrupt Vector
…… …… ……
INT12.8 0x00 0DFE PIEINT12.8 Interrupt Vector
‹ PIE vector location – 0x00 0D00 – 256 words in data memory
‹ RESET and INT1-INT12 vector locations are re-mapped
‹ CPU vectors are re-mapped to 0x00 0D00 in data memory

F2833x PIE Interrupt Assignment Table


INTx.8 INTx.7 INTx.6 INTx.5 INTx.4 INTx.3 INTx.2 INTx.1

INT1 WAKEINT TINT0 ADCINT XINT2 XINT1 SEQ2INT SEQ1INT


EPWM6 EPWM5 EPWM4 EPWM3 EPWM2 EPWM1
INT2 _TZINT _TZINT _TZINT _TZINT _TZINT _TZINT
EPWM6 EPWM5 EPWM4 EPWM3 EPWM2 EPWM1
INT3 _INT _INT _INT _INT _INT _INT
ECAP6 ECAP5 ECAP4 ECAP3 ECAP2 ECAP1
INT4 _INT _INT _INT _INT _INT _INT
EQEP2 EQEP1
INT5 _INT _INT

INT6 MXINTA MRINTA MXINTB MRINTB SPITXINTA SPIRXINTA

INT7 DINTCH6 DINTCH5 DINTCH4 DINTCH3 DINTCH2 DINTCH1

INT8 SCITXINTC SCIRXINTC I2CINT2A I2CINT1A


ECAN1 ECAN0 ECAN1 ECAN0
INT9 _INTB _INTB _INTA _INTA
SCITXINTB SCIRXINTB SCITXINTA SCIRXINTA

INT10

INT11

INT12 LUF LVF XINT7 XINT6 XINT5 XINT4 XINT3

TMS320C28x MCU Workshop - Reset and Interrupts 4-9


Interrupts

Device Vector Mapping - Summary


RESET
<0x3F FFC0>

Reset Vector <0x3F F9A9> = Boot Code


Flash Entry Point <0x33 FFF6 > = LB _c_int00
User Code Start < _c_int00 >

_c_int00:
. . .
CALL main()
Initialization()
{
Load PIE Vectors PIE Vector Table
main() Enable the PIE
{ initialization(); Enable PIEIER 256 Word RAM
. . . Enable Core IER 0x00 0D00 – 0DFF
} Enable INTM
}

Interrupt Response and Latency


Interrupt Response - Hardware Sequence
CPU Action Description
Registers → stack 14 Register words auto saved
0 → IFR (bit) Clear corresponding IFR bit
0 → IER (bit) Clear corresponding IER bit
1 → INTM/DBGM Disable global ints/debug events
Vector → PC Loads PC with int vector address
Clear other status bits Clear LOOP, EALLOW, IDLESTAT

Note: some actions occur simultaneously, none are interruptible


T ST0
AH AL
PH PL
AR1 AR0
DP ST1
DBSTAT IER
PC(msw) PC(lsw)

4 - 10 TMS320C28x MCU Workshop - Reset and Interrupts


Interrupts

Interrupt Latency
Latency
ext. Internal
interrupt interrupt Assumes ISR in
occurs occurs internal RAM
here here

cycles
2 4 3 3 1 3
Sync ext. Recognition Get vector ISR
F1/F2/D1 of Save D2/R1/R2 of instruction
signal delay (3), SP and place ISR return ISR
alignment (1), in PC executed
instruction address instruction on next
(ext. interrupt (3 reg. (3 reg. pairs
interrupt placed in pairs cycle
saved)
only) pipeline saved)

‹ Minimum latency (to when real work occurs in the ISR):


¾ Internal interrupts: 14 cycles
¾ External interrupts: 16 cycles
‹ Maximum latency: Depends on wait states, INTM, etc.

TMS320C28x MCU Workshop - Reset and Interrupts 4 - 11


Interrupts

4 - 12 TMS320C28x MCU Workshop - Reset and Interrupts


System Initialization

Introduction
This module discusses the operation of the OSC/PLL-based clock module and watchdog timer.
Also, the general-purpose digital I/O ports, external interrups, various low power modes and the
EALLOW protected registers will be covered.

Learning Objectives
Learning Objectives

‹ OSC/PLL Clock Module

‹ Watchdog Timer

‹ General Purpose Digital I/O

‹ External Interrupts

‹ Low Power Modes

‹ Register Protection

TMS320C28x MCU Workshop - System Initialization 5-1


Module Topics

Module Topics
System Initialization.................................................................................................................................. 5-1

Module Topics......................................................................................................................................... 5-2


Oscillator/PLL Clock Module................................................................................................................. 5-3
Watchdog Timer...................................................................................................................................... 5-5
General-Purpose Digital I/O .................................................................................................................. 5-9
External Interrupts.................................................................................................................................5-12
Low Power Modes..................................................................................................................................5-13
Register Protection ................................................................................................................................5-15
Lab 5: System Initialization ...................................................................................................................5-17

5-2 TMS320C28x MCU Workshop - System Initialization


Oscillator/PLL Clock Module

Oscillator/PLL Clock Module


F2833x Oscillator / PLL Clock Module
(lab file: SysCtrl.c)
Watchdog
Module CLKIN C28x
XCLKIN
Core
OSCCLK
• • (PLL bypass)
X1 SYSCLKOUT

MUX
XTAL OSC
1/n • •
crystal VCOCLK
PLL HISPCP LOSPCP
X2
HSPCLK LSPCLK
SysCtrlRegs.PLLCR.bit.DIV ADC SCI, SPI, I2C,
SysCtrlRegs.PLLSTS.bit.DIVSEL McBSP
DIV CLKIN All other peripherals
DIVSEL n clocked by SYSCLKOUT
0x /4 * 00 0 0 OSCCLK / n * (PLL bypass)
10 /2 00 0 1 OSCCLK x 1 / n
00 1 0 OSCCLK x 2 / n Input Clock Fail Detect Circuitry
11 /1
00 1 1 OSCCLK x 3 / n
* default 01 0 0 OSCCLK x 4 / n PLL will issue a “limp mode”
Note: /1 mode can 01 0 1 OSCCLK x 5 / n clock (1-4 MHz) if input clock is
only be used when
01 1 0 OSCCLK x 6 / n
removed after PLL has locked.
PLL is bypassed
01 1 1 OSCCLK x 7 / n An internal device reset will also
10 0 0 OSCCLK x 8 / n be issued (XRSn pin not driven).
10 0 1 OSCCLK x 9 / n
10 1 0 OSCCLK x 10 / n

The OSC/PLL clock module provides all the necessary clocking signals for C28x devices. The
PLL has a 4-bit ratio control to select different CPU clock rates. Two modes of operation are
supported – crystal operation, and external clock source operation. Crystal operation allows the
use of an external crystal/resonator to provide the time base to the device. External clock source
operation allows the internal oscillator to be bypassed, and the device clocks are generated from
an external clock source input on the XCLKIN pin. The watchdog receives a clock signal from
OSCCLK. The C28x core provides a SYSCLKOUT clock signal. This signal is prescaled to
provide a clock source for some of the on-chip peripherals through the high-speed and low-speed
peripheral clock prescalers. Other peripherals are clocked by SYSCLKOUT and use their own
clock prescalers for operation.

TMS320C28x MCU Workshop - System Initialization 5-3


Oscillator/PLL Clock Module

High / Low – Speed Peripheral Clock


Prescaler Registers (lab file: SysCtrl.c)
SysCtrlRegs.HISPCP
15 - 3 2-0
reserved HSPCLK

ADC
SysCtrlRegs.LOSPCP
15 - 3 2- 0
reserved LSPCLK

SCI / SPI /
H/LSPCLK Peripheral Clock Frequency I2C / McBSP
000 SYSCLKOUT / 1
001 SYSCLKOUT / 2 (default HISPCP)
NOTE:
010 SYSCLKOUT / 4 (default LOSPCP)
011 SYSCLKOUT / 6 All Other
100 SYSCLKOUT / 8 Peripherals
101 SYSCLKOUT / 10 Clocked By
110 SYSCLKOUT / 12 SYSCLKOUT
111 SYSCLKOUT / 14

The peripheral clock control register allows individual peripheral clock signals to be enabled or
disabled. If a peripheral is not being used, its clock signal could be disabled, thus reducing power
consumption.

Peripheral Clock Control Registers


(lab file: SysCtrl.c)
SysCtrlRegs.PCLKCR0
15 14 13 12 11 10 9 8
ECANB ECANA MA MB SCIB SCIA reserved SPIA
ENCLK ENCLK ENCLK ENCLK ENCLK ENCLK ENCLK
7 6 5 4 3 2 1 0
SCIC I2CA ADC TBCLK reserved
reserved reserved ENCLK ENCLK ENCLK SYNC reserved

SysCtrlRegs.PCLKCR1
15 14 13 12 11 10 9 8
EQEP2 EQEP1 ECAP6 ECAP5 ECAP4 ECAP3 ECAP2 ECAP1
ENCLK ENCLK ENCLK ENCLK ENCLK ENCLK ENCLK ENCLK
7 6 5 4 3 2 1 0

reserved EPWM6 EPWM5 EPWM4 EPWM3 EPWM2 EPWM1


reserved ENCLK ENCLK ENCLK
ENCLK ENCLK ENCLK

SysCtrlRegs.PCLKCR3
15 - 14 13 12 11 10 9 8 7-0

reserved GPIOIN XINTF DMA CPUTIMER2 CPUTIMER1 CPUTIMER0 reserved


ENCLK ENCLK ENCLK ENCLK ENCLK ENCLK

Module Enable Clock Bit


0 = disable (default) 1 = enable

5-4 TMS320C28x MCU Workshop - System Initialization


Watchdog Timer

Watchdog Timer
Watchdog Timer

‹ Resets the C28x if the CPU crashes


Š Watchdog counter runs independent of CPU
Š If counter overflows, a reset or interrupt is
triggered (user selectable)
Š CPU must write correct data key sequence to
reset the counter before overflow
‹ Watchdog must be serviced or disabled
within 131,072 instructions after reset
‹ This translates to 4.37 ms with a 30 MHz
OSCCLK

The watchdog timer provides a safeguard against CPU crashes by automatically initiating a reset
if it is not serviced by the CPU at regular intervals. In motor control applications, this helps
protect the motor and drive electronics when control is lost due to a CPU lockup. Any CPU reset
will revert the PWM outputs to a high-impedance state, which should turn off the power
converters in a properly designed system.

The watchdog timer is running immediately after system power-up/reset, and must be dealt with
by software soon after. Specifically, you have 4.37ms (for a 150 MHz device) after any reset
before a watchdog initiated reset will occur. This translates into 131,072 instruction cycles,
which is a seemingly tremendous amount! Indeed, this is plenty of time to get the watchdog
configured as desired and serviced. A failure of your software to properly handle the watchdog
after reset could cause an endless cycle of watchdog initiated resets to occur.

TMS320C28x MCU Workshop - System Initialization 5-5


Watchdog Timer

Watchdog Timer Module (lab file: Watchdog.c)


SCSR . 0
OSCCLK
/64 111
6 - Bit /32 110 WDOVERRIDE
WDPS
Free - /16 101
/8 100 WDCR . 2 - 0
/512 • Running
Counter /4 011 • • •
/2 010 WDCR . 6
CLR 001
WDDIS
000


WDCNTR . 7 - 0
System
Reset • 8 - Bit Watchdog
WDFLAG
One-Cycle WDCR . 7
Counter
Delay
CLR
WDRST
Output •
Pulse
WDCR . 5 - 3 WDCHK 2-0
WDINT
SCSR .1
55 + AA
Detector Good Key 3 WDENINT
•• /
•• 3
/ Bad WDCR Key
Watchdog 1 0 1
Reset Key WDKEY . 7 - 0
Register

Watchdog Period Selection

WDPS FRC WD timeout period


Bits rollover @ 30 MHz OSCCLK
00x: 1 4.37 ms *
010: 2 8.74 ms
011: 4 17.48 ms
100: 8 34.96 ms
101: 16 69.92 ms
110: 32 139.84 ms
111: 64 279.68 ms
* reset default

‹ Remember: Watchdog starts counting immediately


after reset is released!
‹ Reset Default with OSCCLK = 30 MHz computed as
(1/30 MHz) * 512 * 256 = 4.37 ms

5-6 TMS320C28x MCU Workshop - System Initialization


Watchdog Timer

Watchdog Timer Control Register


SysCtrlRegs.WDCR (lab file: Watchdog.c)

WD Flag Bit
Gets set when the WD causes a reset
• Writing a 1 clears this bit
• Writing a 0 has no effect

15 - 8 7 6 5-3 2-0

reserved WDFLAG WDDIS WDCHK WDPS

Logic Check Bits WD Prescale


Write as 101 or reset Selection Bits
Watchdog Disable Bit immediately triggered
Write 1 to disable
(Functions only if WD OVERRIDE
bit in SCSR is equal to 1)

Resetting the Watchdog


SysCtrlRegs.WDKEY (lab file: Watchdog.c)

15 - 8 7-0

reserved WDKEY

‹ WDKEY write values:


55h - counter enabled for reset on next AAh write
AAh - counter set to zero if reset enabled
‹ Writing any other value has no effect
‹ Watchdog should not be serviced solely in
an ISR
Š If main code crashes, but interrupt continues to
execute, the watchdog will not catch the crash
Š Could put the 55h WDKEY in the main code, and
the AAh WDKEY in an ISR; this catches main
code crashes and also ISR crashes

TMS320C28x MCU Workshop - System Initialization 5-7


Watchdog Timer

WDKEY Write Results


Sequential Value Written
Step to WDKEY Result

1 AAh No action
2 AAh No action
3 55h WD counter enabled for reset on next AAh write
4 55h WD counter enabled for reset on next AAh write
5 55h WD counter enabled for reset on next AAh write
6 AAh WD counter is reset
7 AAh No action
8 55h WD counter enabled for reset on next AAh write
9 AAh WD counter is reset
10 55h WD counter enabled for reset on next AAh write
11 23h No effect; WD counter not reset on next AAh write
12 AAh No action due to previous invalid value
13 55h WD counter enabled for reset on next AAh write
14 AAh WD counter is reset

System Control and Status Register


SysCtrlRegs.SCSR (lab file: Watchdog.c)

WD Override (protect bit)


Protects WD from being disabled
0 = WDDIS bit in WDCR has no effect (WD cannot be disabled)
1 = WDDIS bit in WDCR can disable the watchdog
• This bit is a clear-only bit (write 1 to clear)
• The reset default of this bit is a 1

15 - 3 2 1 0

reserved WDINTS WDENINT WDOVERRIDE

WD Interrupt Status WD Enable Interrupt


(read only)
0 = WD generates a DSP reset
0 = active 1 = WD generates a WDINT interrupt
1 = not active

5-8 TMS320C28x MCU Workshop - System Initialization


General-Purpose Digital I/O

General-Purpose Digital I/O


F2833x GPIO Grouping Overview
GPIO Port A Mux1
Input

GPIO Port A
Register (GPAMUX1)
[GPIO 0 to 15] GPIO Port A
Direction Register Qual
(GPADIR)
GPIO Port A Mux2 [GPIO 0 to 31]
Register (GPAMUX2)
[GPIO 16 to 31]

GPIO Port B Mux1


Input
Internal Bus

GPIO Port B
Register (GPBMUX1)
[GPIO 32 to 47] GPIO Port B
Direction Register Qual
(GPBDIR)
GPIO Port B Mux2 [GPIO 32 to 63]
Register (GPBMUX2)
[GPIO 48 to 63]

GPIO Port C Mux1

GPIO Port C
Register (GPCMUX1)
[GPIO 64 to 79] GPIO Port C
Direction Register
(GPCDIR)
GPIO Port C Mux2 [GPIO 64 to 87]
Register (GPCMUX2)
[GPIO 80 to 87]

F2833x GPIO Pin Block Diagram


Peripheral Peripheral Peripheral
I/O DIR Bit 1 2 3
GPxSET 0 = Input
GPxCLEAR 1 = Output
GPxTOGGLE
GPxDIR
GPxDAT
Out
01• • 10 GPxMUX1
00• •11 GPxMUX2
I/O DAT
Bit (R/W) In MUX Control Bits *
00 = GPIO
01 = Peripheral 1
10 = Peripheral 2
11 = Peripheral 3
Input
Qualification
GPxPUD
• (GPIO 0-63 only)
GPxQSEL1
GPxQSEL2
Internal Pull-Up GPxCTRL
0 = enable (default GPIO 12-31)
1 = disable (default GPIO 0-11)
Pin

* See device datasheet for pin function selection matrices

TMS320C28x MCU Workshop - System Initialization 5-9


General-Purpose Digital I/O

F2833x GPIO Input Qualification

Input to GPIO and


pin peripheral
Qualification modules

SYSCLKOUT

‹ Qualification available on ports A & B (GPIO 0 - 63) only


‹ Individually selectable per pin samples taken
Š no qualification (peripherals only)
Š sync to SYCLKOUT only
Š qualify 3 samples
Š qualify 6 samples
‹ Port C pins are fixed as T T T
‘sync to SYSCLKOUT’ T = qual period

F2833x GPIO Input Qual Registers


GpioCtrlRegs.register (lab file: Gpio.c)

GPAQSEL1 / GPAQSEL2 / GPBQSEL1 / GPBQSEL2


31 0
16 pins configured per register

00 = sync to SYSCLKOUT only *


01 = qual to 3 samples
10 = qual to 6 samples
11 = no sync or qual (for peripheral only; GPIO same as 00)

GPACTRL / GPBCTRL
31 24 16 8 0
QUALPRD3 QUALPRD2 QUALPRD1 QUALPRD0
B: GPIO63-56 GPIO55-48 GPIO47-40 GPIO39-32
A: GPIO31-24 GPIO23-16 GPIO15-8 GPIO7-0

00h no qualification (SYNC to SYSCLKOUT) *


01h QUALPRD = SYSCLKOUT/2
02h QUALPRD = SYSCLKOUT/4
… … …
FFh QUALPRD = SYSCLKOUT/510 * reset default

5 - 10 TMS320C28x MCU Workshop - System Initialization


General-Purpose Digital I/O

C2833x GPIO Control Registers


GpioCtrlRegs.register (lab file: Gpio.c)
Register Description
GPACTRL GPIO A Control Register [GPIO 0 – 31]
GPAQSEL1 GPIO A Qualifier Select 1 Register [GPIO 0 – 15]
GPAQSEL2 GPIO A Qualifier Select 2 Register [GPIO 16 – 31]
GPAMUX1 GPIO A Mux1 Register [GPIO 0 – 15]
GPAMUX2 GPIO A Mux2 Register [GPIO 16 – 31]
GPADIR GPIO A Direction Register [GPIO 0 – 31]
GPAPUD GPIO A Pull-Up Disable Register [GPIO 0 – 31]
GPBCTRL GPIO B Control Register [GPIO 32 – 63]
GPBQSEL1 GPIO B Qualifier Select 1 Register [GPIO 32 – 47]
GPBQSEL2 GPIO B Qualifier Select 2 Register [GPIO 48 – 63]
GPBMUX1 GPIO B Mux1 Register [GPIO 32 – 47]
GPBMUX2 GPIO B Mux2 Register [GPIO 48 – 63]
GPBDIR GPIO B Direction Register [GPIO 32 – 63]
GPBPUD GPIO B Pull-Up Disable Register [GPIO 32 – 63]
GPCMUX1 GPIO C Mux1 Register [GPIO 64 – 79]
GPCMUX2 GPIO C Mux2 Register [GPIO 80 – 87]
GPCDIR GPIO C Direction Register [GPIO 64 – 87]
GPCPUD GPIO C Pull-Up Disable Register [GPIO 64 – 87]

C2833x GPIO Data Registers


GpioDataRegs.register (lab file: Gpio.c)
Register Description
GPADAT GPIO A Data Register [GPIO 0 – 31]
GPASET GPIO A Data Set Register [GPIO 0 – 31]
GPACLEAR GPIO A Data Clear Register [GPIO 0 – 31]
GPATOGGLE GPIO A Data Toggle [GPIO 0 – 31]
GPBDAT GPIO B Data Register [GPIO 32 – 63]
GPBSET GPIO B Data Set Register [GPIO 32 – 63]
GPBCLEAR GPIO B Data Clear Register [GPIO 32 – 63]
GPBTOGGLE GPIO B Data Toggle [GPIO 32 – 63]
GPCDAT GPIO C Data Register [GPIO 64 – 87]
GPCSET GPIO C Data Set Register [GPIO 64 – 87]
GPCCLEAR GPIO C Data Clear Register [GPIO 64 – 87]
GPCTOGGLE GPIO C Data Toggle [GPIO 64 – 87]

TMS320C28x MCU Workshop - System Initialization 5 - 11


External Interrupts

External Interrupts
External Interrupts
‹ 8 external interrupt signals: XNMI, XINT1-7

‹ The signals can be mapped to a variety of pins


Š XNMI, XINT1-2 can be mapped to any of GPIO0-31
Š XINT3-7 can be mapped to any of GPIO32-63

‹ The eCAP pins and their interrupts can be used


as additional external interrupts if needed

‹ XNMI, XINT1, and XINT2 also each have a free-


running 16-bit counter that measures the
elapsed time between interrupts
Š The counter resets to zero each time the interrupt
occurs

External Interrupt Registers


Interrupt Pin Selection Register Configuration Register Counter Register
(GpioIntRegs.register) (XIntruptRegs.register) (XIntruptRegs.register)
XNMI GPIOXNMISEL XNMICR XNMICTR
XINT1 GPIOXINT1SEL XINT1CR XINT1CTR
XINT2 GPIOXINT2SEL XINT2CR XINT2CTR
XINT3 GPIOXINT3SEL XINT3CR -
XINT4 GPIOXINT4SEL XINT4CR -
XINT5 GPIOXINT5SEL XINT5CR -
XINT6 GPIOXINT6SEL XINT6CR -
XINT7 GPIOXINT7SEL XINT7CR -

‹ Pin Selection Register chooses which pin(s) the signal comes out on
‹ Configuration Register controls the enable/disable and polarity
‹ Counter Register holds the interrupt counter

5 - 12 TMS320C28x MCU Workshop - System Initialization


Low Power Modes

Low Power Modes


Low Power Modes

Low Power CPU Logic Peripheral Watchdog PLL /


Mode Clock Logic Clock Clock OSC
Normal Run on on on on

IDLE off on on on

STANDBY off off on on

HALT off off off off

See device datasheet for power consumption in each mode

Low Power Mode Control Register 0


SysCtrlRegs.LPMCR0 (lab file: SysCtrl.c)

Watchdog Interrupt 000000 = 2 OSCCLKs


wake device from 000001 = 3 OSCCLKs
STANDBY Wake from STANDBY
GPIO signal qualification * .. .. ..
0 = disable (default) . . .
1 = enable 111111 = 65 OSCCLKS (default)

15 14 - 8 7-2 1-0
WDINTE reserved QUALSTDBY LPM0

Low Power Mode Selection


Low Power Mode Entering 00 = Idle (default)
1. Set LPM bits 01 = Standby
2. Enable desired exit interrupt(s) 1x = Halt
3. Execute IDLE instruction
4. The power down sequence of the hardware
depends on LP mode

* QUALSTDBY will qualify the GPIO wakeup signal in series with the GPIO port qualification.
This is useful when GPIO port qualification is not available or insufficient for wake-up purposes.

TMS320C28x MCU Workshop - System Initialization 5 - 13


Low Power Modes

Low Power Mode Exit

Exit
Interrupt RESET GPIO Watchdog Any
or Port A Interrupt Enabled
Low Power XNMI Signal Interrupt
Mode

IDLE yes yes yes yes

STANDBY yes yes yes no

HALT yes yes no no

GPIO Low Power Wakeup Select


SysCtrlRegs.GPIOLPMSEL

31 30 29 28 27 26 25 24

GPIO31 GPIO30 GPIO29 GPIO28 GPIO27 GPIO26 GPIO25 GPIO24

23 22 21 20 19 18 17 16
GPIO23 GPIO22 GPIO21 GPIO20 GPIO19 GPIO18 GPIO17 GPIO16

15 14 13 12 11 10 9 8

GPIO15 GPIO14 GPIO13 GPIO12 GPIO11 GPIO10 GPIO9 GPIO8

7 6 5 4 3 2 1 0
GPIO7 GPIO6 GPIO5 GPIO4 GPIO3 GPIO2 GPIO1 GPIO0

Wake device from


HALT and STANDBY mode
(GPIO Port A)
0 = disable (default)
1 = enable

5 - 14 TMS320C28x MCU Workshop - System Initialization


Register Protection

Register Protection
Write-Read Protection
DevEmuRegs.PROTSTART & DevEmuRegs.PROTRANGE
Suppose you need to write to a peripheral register and
then read a different register for the same peripheral
(e.g., write to control, read from status register)?

‹ CPU pipeline protects W-R order for the same address


‹ Write-Read protection mechanism protects W-R order
for different addresses
0x00 0000
M0SARAM 0x00 0400
Š Configured by PROTSTART M1SARAM
0x00 0800
and PROTRANGE registers PIE Vectors 0x00 0D00
0x00 0E00
Š Default values for these PF 0
registers protect the address 0x00 2000
reserved
range 0x4000 to 0x7FFF 0x00 4000
XINTF Zone 0
0x00 5000
Š Default values typically PF 3
sufficient 0x00 6000
PF 1
0x00 7000
PF 2
0x00 8000
Note: PF0 is not protected by default because the flexibility of PROTSTART and PROTRANGE are such that
M0 and M1 SARAM blocks would also need to be protected, thereby reducing the performance of this RAM.
See TMS320x2833x, 2823x System Control and Interrupts Reference Guide, #SPRUFB0

EALLOW Protection (1 of 2)

‹ EALLOW stands for Emulation Allow


‹ Code access to protected registers allowed
only when EALLOW = 1 in the ST1 register
‹ The emulator can always access protected
registers
‹ EALLOW bit controlled by assembly level
instructions
Š ‘EALLOW’ sets the bit (register access enabled)
Š ‘EDIS’ clears the bit (register access disabled)
‹ EALLOW bit cleared upon ISR entry, restored
upon exit

TMS320C28x MCU Workshop - System Initialization 5 - 15


Register Protection

EALLOW Protection (2 of 2)
The following registers are protected:
Device Emulation
Flash
Code Security Module
PIE Vector Table
DMA (most registers)
eCANA/B (control registers only; mailbox RAM not protected)
ePWM1 - 6 (some registers)
GPIO (control registers only)
System Control
See device datasheet and peripheral users guides for detailed listings

EALLOW register access C-code example:


asm(" EALLOW"); // enable protected register access
SysCtrlRegs.WDKEY=0x55; // write to the register
asm(" EDIS"); // disable protected register access

5 - 16 TMS320C28x MCU Workshop - System Initialization


Lab 5: System Initialization

Lab 5: System Initialization


¾ Objective
The objective of this lab is to perform the processor system initialization by applying the
information discussed in module 5. Additionally, the peripheral interrupt expansion (PIE) vectors
will be initialized and tested using the information discussed in the previous module. This
initialization process will be used again in all of the lab exercises throughout this workshop. The
system initialization for this lab will consist of the following:

• Setup the clock module – PLL, HISPCP = /1, LOSPCP = /4, low-power modes to default
values, enable all module clocks
• Disable the watchdog – clear WD flag, disable watchdog, WD prescale = 1
• Setup watchdog system and control register – DO NOT clear WD OVERRIDE bit, WD
generate a DSP reset
• Setup shared I/O pins – set all GPIO pins to GPIO function (e.g. a "00" setting for GPIO
function, and a “01”, “10”, or “11” setting for a peripheral function.)

The first part of the lab exercise will setup the system initialization and test the watchdog
operation by having the watchdog cause a reset. In the second part of the lab exercise the PIE
vectors will be added and tested by using the watchdog to generate an interrupt. This lab will
make use of the DSP2833x C-code header files to simplify the programming of the device, as
well as take care of the register definitions and addresses. Please review these files, and make use
of them in the future, as needed.

¾ Procedure

Create Project File


1. Create a new project called Lab5.pjt in C:\C28x\Labs\Lab5 and add the
following files to it:

CodeStartBranch.asm Lab_5_6_7.cmd
DelayUs.asm Main_5.c
DSP2833x_GlobalVariableDefs.c SysCtrl.c
DSP2833x_Headers_nonBIOS.cmd Watchdog.c
Gpio.c

Note that include files, such as DSP2833x_Device.h and Lab.h, are automatically
added at project build time. (Also, DSP2833x_DefaultIsr.h is automatically
added and will be used with the interrupts in the second part of this lab exercise).

TMS320C28x MCU Workshop - System Initialization 5 - 17


Lab 5: System Initialization

Project Build Options


2. We need to setup the search path to include the peripheral register header files. Click:

Project Æ Build Options…

Select the Compiler tab. In the Preprocessor Category, find the Include Search
Path (-i) box and enter:

..\DSP2833x_headers\include

This is the path for the header files.

3. Select the Linker tab and set the Stack Size to 0x200.

4. Setup the compiler run-time support library. In the Libraries Category, find the
Include Libraries (-l) box and enter: rts2800_ml.lib. Select OK and the
Build Options window will close.

Modify Memory Configuration


5. Open and inspect the linker command file Lab_5_6_7.cmd. Notice that the user
defined section “codestart” is being linked to a memory block named BEGIN_M0.
The codestart section contains code that branches to the code entry point of the project.
The bootloader must branch to the codestart section at the end of the boot process. Recall
that the "Jump to M0 SARAM" bootloader mode branches to address 0x000000 upon
bootloader completion.

Modify the linker command file Lab_5_6_7.cmd to create a new memory block
named BEGIN_M0: origin = 0x000000, length = 0x0002, in program memory. You will
also need to modify the existing memory block M0SARAM in data memory to avoid any
overlaps with this new memory block.

Setup System Initialization


6. Modify SysCtrl.c and Watchdog.c to implement the system initialization as
described in the objective for this lab.

7. Open and inspect Gpio.c. Notice that the shared I/O pins have been set to the GPIO
function. Save your work and close the modified files.

Build and Load


8. Click the “Build” button and watch the tools run in the build window. The output
file should automatically load.

9. Under Debug on the menu bar click “Reset CPU”.

10. Under Debug on the menu bar click “Go Main”. You should now be at the start of
Main().

5 - 18 TMS320C28x MCU Workshop - System Initialization


Lab 5: System Initialization

Run the Code – Watchdog Reset


11. Place the cursor on the first line of code in main() and set a breakpoint by right
clicking the mouse key and select Toggle Software Breakpoint. Notice that
line is highlighted with a red dot indicating that the breakpoint has been set. Alternately,
you can double-click in the gray field to the left of the code line to set the breakpoint.
The breakpoint is set to prove that the watchdog is disabled. If the watchdog causes a
reset, code execution will stop at this breakpoint.

12. Place the cursor in the “main loop” section (on the asm(“ NOP”); instruction
line) and right click the mouse key and select Run To Cursor. This is the same as
setting a breakpoint on the selected line, running to that breakpoint, and then removing
the breakpoint.

13. Run your code for a few seconds by using the <F5> key, or using the Run button on the
vertical toolbar, or using Debug Æ Run on the menu bar. After a few seconds halt
your code by using Shift <F5>, or the Halt button on the vertical toolbar. Where did your
code stop? Are the results as expected? If things went as expected, your code should be
in the “main loop”.

14. Modify the InitWatchdog() function to enable the watchdog (WDCR). This will
enable the watchdog to function and cause a reset. Save the file and click the “Build”
button. Then reset the CPU by clicking on Debug Æ Reset CPU. Under Debug on
the menu bar click “Go Main”.

15. Single-step your code off of the breakpoint.

16. Run your code. Where did your code stop? Are the results as expected? If things went
as expected, your code should stop at the breakpoint.

Setup PIE Vector for Watchdog Interrupt


The first part of this lab exercise used the watchdog to generate a CPU reset. This was tested
using a breakpoint set at the beginning of main(). Next, we are going to use the watchdog
to generate an interrupt. This part will demonstrate the interrupt concepts learned in the
previous module.

17. Add the following files to the project:

DefaultIsr_5.c
PieCtrl_5_6_7_8_9_10.c
PieVect_5_6_7_8_9_10.c

Check your files list to make sure the files are there.

18. In Main_5.c, add code to call the InitPieCtrl() function. There are no passed
parameters or return values, so the call code is simply:

InitPieCtrl();

TMS320C28x MCU Workshop - System Initialization 5 - 19


Lab 5: System Initialization

19. Using the “PIE Interrupt Assignment Table” shown in the previous module find the
location for the watchdog interrupt, “WAKEINT”. This will be used in the next step.

PIE group #: # within group:

20. Modify main() to do the following:


- Enable global interrupts (INTM bit)

Then modify InitWatchdog() to do the following:


- Enable the "WAKEINT" interrupt in the PIE (Hint: use the PieCtrlRegs structure)
- Enable the appropriate core interrupt in the IER register

21. In Watchdog.c modify the system control and status register (SCSR) to cause the
watchdog to generate a WAKEINT rather than a reset.

22. Open and inspect DefaultIsr_5.c. This file contains interrupt service routines. The
ISR for WAKEINT has been trapped by an emulation breakpoint contained in an inline
assembly statement using “ESTOP0”. This gives the same results as placing a breakpoint
in the ISR. We will run the lab exercise as before, except this time the watchdog will
generate an interrupt. If the registers have been configured properly, the code will be
trapped in the ISR.

23. Open and inspect PieCtrl_5_6_7_8_9_10.c. This file is used to initialize the PIE
RAM and enable the PIE. The interrupt vector table located in
PieVect_5_6_7_8_9_10.c is copied to the PIE RAM to setup the vectors for the
interrupts. Close the inspected files.

Build and Load


24. Save all changes to the files and click the “Build” button. Then reset the CPU, and
then “Go Main”.

Run the Code – Watchdog Interrupt


25. Place the cursor in the “main loop” section, right click the mouse key and select
Run To Cursor.

26. Run your code. Where did your code stop? Are the results as expected? If things went
as expected, your code should stop at the “ESTOP0” instruction in the WAKEINT ISR.

End of Exercise

Note: By default, the watchdog timer is enabled out of reset. Code in the file
CodeStartBranch.asm has been configured to disable the watchdog. This can be
important for large C code projects (ask your instructor if this has not already been
explained). During this lab exercise, the watchdog was actually re-enabled (or disabled
again) in the file Watchdog.c.

5 - 20 TMS320C28x MCU Workshop - System Initialization


Analog-to-Digital Converter

Introduction
This module explains the operation of the analog-to-digital converter. The system consists of a
12-bit analog-to-digital converter with 16 analog input channels. The analog input channels have
a range from 0 to 3 volts. Two input analog multiplexers are used, each supporting 8 analog input
channels. Each multiplexer has its own dedicated sample and hold circuit. Therefore, sequential,
as well as simultaneous sampling is supported. Also, the ADC system features programmable
auto sequence conversions with 16 results registers. Start of conversion (SOC) can be performed
by an external trigger, software, or an ePWM event.

Learning Objectives
Learning Objectives

‹ Understand the operation of the


Analog-to-Digital converter (ADC)
‹ Use the ADC to perform data acquisition

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6-1


Module Topics

Module Topics
Analog-to-Digital Converter..................................................................................................................... 6-1

Module Topics......................................................................................................................................... 6-2


Analog-to-Digital Converter................................................................................................................... 6-3
Analog-to-Digital Converter Registers............................................................................................... 6-5
Example – Sequencer “Start/Stop” Operation ...................................................................................6-10
ADC Conversion Result Buffer Register...........................................................................................6-11
Signed Input Voltages .......................................................................................................................6-11
ADC Calibration................................................................................................................................6-12
Lab 6: Analog-to-Digital Converter ......................................................................................................6-14

6-2 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Analog-to-Digital Converter

Analog-to-Digital Converter
ADC Module Block Diagram (Cascaded Mode)
ADCINA0
ADCINA1 MUX S/H RESULT0
A A
RESULT1
ADCINA7 12-bit A/D Result

MUX
RESULT2
Converter MUX
ADCINB0
ADCINB1 MUX S/H SOC EOC RESULT15
B B
ADCINB7 SEQ1
ADC full-scale Autosequencer
input range is
0 to 3V MAX_CONV1
Ch Sel (CONV00)
Ch Sel (CONV01)
Software Ch Sel (CONV02)
Ch Sel (CONV03)
ePWM_SOC_A
ePWM_SOC_B
External Pin Ch Sel (CONV15)
(GPIO/XINT2_ADCSOC)
Start Sequence
Trigger

ADC Module Block Diagram (Dual-Sequencer mode)


ADCINA0
RESULT0
ADCINA1 MUX S/H RESULT1
A A Result
ADCINA7
12-bit A/D MUX
MUX

MUX

ADCINB0
Converter
ADCINB1 MUX S/H RESULT7
B B Sequencer
Arbiter RESULT8
ADCINB7
SOC1/ SOC2/ RESULT9
ADC full-scale EOC1 EOC2 Result
input range is SEQ1 SEQ2
0 to 3V MUX MUX
Autosequencer Autosequencer
MAX_CONV1 MAX_CONV2 RESULT15

Ch Sel (CONV00) Ch Sel (CONV08)


Ch Sel (CONV01) Ch Sel (CONV09)

Ch Sel (CONV07) Ch Sel (CONV15)


Software
Start Sequence Start Sequence Software
ePWM_SOC_A Trigger Trigger ePWM_SOC_B
External Pin
(GPIO/XINT2_ADCSOC)

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6-3


Analog-to-Digital Converter

ADC Operating Mode Choices

‹ The user can make one choice from


each category below
‹ Choices are completely independent *

Sequencer Mode Sampling Mode Run Mode


Cascaded Sequential Start/Stop
Dual Simultaneous Continuous

* Note that using Continuous Run mode with Dual Sequencer generally doesn’t make sense
since sequencer #2 will not get to do any conversions!

ADC Clocking Flow


CLKIN PLLCR PLLSTS SYSCLKOUT HISPCP HSPCLK
(30 MHz) DIV DIVSEL (150 MHz) HSPCLK (150 MHz)
bits bits To CPU
bits
1010b (x10) 10b (/2) 000b (/1)
PCLKCR0.ADCENCLK = 1

ADCTRL3 FCLK ADCTRL1 ADCCLK


ADCCLKPS (12.5 MHz) (12.5 MHz) To ADC
CPS bit pipeline
bits
0110b ADCTRL1
0b sampling
ACQ_PS window
FCLK = HSPCLK/(2*ADCCLKPS) ADCCLK =
FCLK/(CPS+1) bits
0111b
sampling window = (ACQ_PS + 1)*(1/ADCCLK)

Note: Maximum F2833x ADCCLK is 25 MHz, but INL (integral nonlinearity error) is greater
above 12.5 MHz. See the device datasheet for more information.

6-4 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Analog-to-Digital Converter

Analog-to-Digital Converter Registers


Analog-to-Digital Converter Registers
AdcRegs.register (lab file: Adc.c)
Register Description
ADCTRL1 ADC Control Register 1
ADCTRL2 ADC Control Register 2
ADCTRL3 ADC Control Register 3
ADCMAXCONV ADC Maximum Conversion Channels Register
ADCCHSELSEQ1 ADC Channel Select Sequencing Control Register 1
ADCCHSELSEQ2 ADC Channel Select Sequencing Control Register 2
ADCCHSELSEQ3 ADC Channel Select Sequencing Control Register 3
ADCCHSELSEQ4 ADC Channel Select Sequencing Control Register 4
ADCASEQSR ADC Autosequence Status Register
ADCRESULT0 ADC Conversion Result Buffer Register 0
ADCRESULT1 ADC Conversion Result Buffer Register 1
ADCRESULT2 ADC Conversion Result Buffer Register 2

ADCRESULT14 ADC Conversion Result Buffer Register 14


ADCRESULT15 ADC Conversion Result Buffer Register 15
ADCREFSEL ADC Reference Select Register
ADCOFFTRIM ADC Offset Trim Register
ADCST ADC Status and Flag Register

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6-5


Analog-to-Digital Converter

ADC Control Register 1


AdcRegs.ADCTRL1

Upper Register:

ADC Module Reset


0 = no effect Acquisition Time Prescale (S/H)
1 = reset (set back to 0 ACQ Window = (ACQ_PS + 1)*(1/ADCCLK)
by ADC logic)

15 14 13 - 12 11 - 8 7
reserved RESET SUSMOD ACQ_PS CPS

Emulation Suspend Mode Conversion Prescale


00 = free run (do not stop) 0: ADCCLK = FCLK / 1
01 = stop after current sequence 1: ADCCLK = FCLK / 2
10 = stop after current conversion
11 = stop immediately

ADC Control Register 1


AdcRegs.ADCTRL1

Lower Register:
Continuous Run Sequencer Mode
0 = stops after reaching 0 = dual mode
end of sequence 1 = cascaded mode
1 = continuous (starts all over
again from “initial state”)

6 5 4 3-0
CONT_RUN SEQ_OVRD SEQ_CASC reserved

Sequencer Override
(functions only if CONT_RUN = 1)
0 = sequencer pointer resets to “initial state” at end of MAX_CONVn
1 = sequencer pointer resets to “initial state” after “end state”

6-6 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Analog-to-Digital Converter

ADC Control Register 2


AdcRegs.ADCTRL2

Upper Register:
ePWM SOC A
ePWM SOC B SEQ1 Mask Bit
Start Conversion (SEQ1) 0 = cannot be started
(cascaded mode only) 0 = clear pending SOC trigger
0 = no action by ePWM trigger
1 = software trigger-start SEQ1 1 = can be started
1 = start by ePWM
signal by ePWM trigger

15 14 13 12 11 10 9 8
ePWM_SOCB RST_SEQ1 SOC_SEQ1 reserved INT_ENA INT_MOD reserved ePWM_SOCA
_SEQ _SEQ1 _SEQ1 _SEQ1

Reset SEQ1 Interrupt Enable (SEQ1) Interrupt Mode (SEQ1)


0 = no action 0 = interrupt disable 0 = interrupt every EOS
1 = immediate reset 1 = interrupt enable 1 = interrupt every other EOS
SEQ1 to “initial state”

ADC Control Register 2


AdcRegs.ADCTRL2

Lower Register:
ePWM SOC B
SEQ2 Mask Bit
Start Conversion (SEQ2) 0 = cannot be started
External SOC (SEQ1) (dual-sequencer mode only)
0 = no action by ePWM trigger
0 = clear pending SOC trigger
1 = start by signal from 1 = can be started
1 = software trigger-start SEQ2 by ePWM trigger
ADCSOC pin

7 6 5 4 3 2 1 0
EXT_SOC RST_SEQ2 SOC_SEQ2 reserved INT_ENA INT_MOD reserved ePWM_SOCB
_SEQ1 _SEQ2 _SEQ2 _SEQ2

Reset SEQ2 Interrupt Enable (SEQ2) Interrupt Mode (SEQ2)


0 = no action 0 = interrupt disable 0 = interrupt every EOS
1 = immediate reset 1 = interrupt enable 1 = interrupt every other EOS
SEQ2 to “initial state”

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6-7


Analog-to-Digital Converter

ADC Control Register 3


AdcRegs.ADCTRL3

ADC Bandgap and ADC Power Down


Reference Power Down (except Bandgap & Ref.)
00 = powered down 0 = powered down
11 = powered up 1 = powered up

15 - 8 7-6 5 4- 1 0
reserved ADCBGRFDN ADCPWDN ADCCLKPS SMODE_SEL

ADC Clock Prescale Sampling Mode Select


0 : FCLK = HSPCLK 0 = sequential sampling mode
1 to F : FCLK = HSPCLK / (2*ADCCLKPS) 1 = simultaneous sampling mode

Maximum Conversion Channels Register


AdcRegs.ADCMAXCONV

♦ Bit fields define the number of conversions per trigger (binary+1)


Cascaded Mode

15-7 6 5 4 3 2 1 0
MAX_ MAX_ MAX_ MAX_ MAX_ MAX_ MAX_
reserved
CONV 2_2 CONV 2_1 CONV 2_0 CONV 1_3 CONV 1_2 CONV 1_1 CONV 1_0

SEQ2 SEQ1
Dual Mode

♦ Each sequencer starts at the “initial state” and advances sequentially


♦ Each will wrap at the “end state” unless software resets it sooner

SEQ1 SEQ2 Cascaded


Initial state CONV00 CONV08 CONV00
End state CONV07 CONV15 CONV15

6-8 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Analog-to-Digital Converter

ADC Input Channel Select


Sequencing Control Registers
AdcRegs.ADCCHSELSEQx

15 - 12 11 - 8 7-4 3-0
ADCCHSELSEQ1 CONV03 CONV02 CONV01 CONV00

ADCCHSELSEQ2 CONV07 CONV06 CONV05 CONV04

ADCCHSELSEQ3 CONV11 CONV10 CONV09 CONV08

ADCCHSELSEQ4 CONV15 CONV14 CONV13 CONV12

For purposes of these registers, channel numbers are:


0 = ADCINA0 8 = ADCINB0

7 = ADCINA7 15 = ADCINB7

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6-9


Analog-to-Digital Converter

Example – Sequencer “Start/Stop” Operation


Example - Sequencer Configuration (1 of 2)

ePWM
Time Base
Counter

ePWM
Output

V1 , V2 , V3 I1, I 2, I3 V1, V2, V3 I1, I 2, I3

Configuration Requirements:
‹ ePWM triggers the ADC
Š Three autoconversions (V1, V2, V3) off trigger 1 (CTR = 0)
Š Three autoconversions (I1, I2, I3) off trigger 2 (CTR = PRD)
‹ ADC in cascaded sequencer and sequential sampling modes

Example - Sequencer Configuration (2 of 2)


Š MAX_CONV1 is set to 2 and Channel Select Sequencing Control Registers are set to:
Bits → 15-12 11-8 7-4 3-0
I1 V3 V2 V1 ADCCHSELSEQ1
x x I3 I2 ADCCHSELSEQ2

Š Once reset and initialized, SEQ1 waits for a trigger


Š First trigger, three conversions performed: CONV00 (V1), CONV01 (V2), CONV02 (V3)
Š MAX_CONV1 value is reset to 2 (unless changed by software)
Š SEQ1 waits for second trigger
Š Second trigger, three conversions performed: CONV03 (I1), CONV04 (I2), CONV05 (I3)
Š End of second sequence, ADC Results registers have the following values:

RESULT0 V1
RESULT1 V2
RESULT2 V3
RESULT3 I1
RESULT4 I2
RESULT5 I3

Š SEQ1 waits at current state for another trigger


Š User can reset SEQ1 by software to state CONV00 and repeat same trigger 1,2 session

6 - 10 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Analog-to-Digital Converter

ADC Conversion Result Buffer Register

ADC Conversion Result Registers


AdcRegs.ADCRESULTx, x = 0 - 15 (2 wait-state read)
MSB LSB
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

AdcMirror.ADCRESULTx, x = 0 - 15 (1 wait-state read)


MSB LSB
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Input Digital AdcRegs. AdcMirror.


Voltage Result ADCRESULTx ADCRESULTx
3.0 FFFh 1111|1111|1111|0000 0000|1111|1111|1111
1.5 7FFh 0111|1111|1111|0000 0000|0111|1111|1111
0.00073 1h 0000|0000|0001|0000 0000|0000|0000|0001
0 0h 0000|0000|0000|0000 0000|0000|0000|0000

Signed Input Voltages

How Can We Handle Signed Input Voltages?


Example: -1.5 V ≤ Vin ≤ +1.5 V
R
R
R
C28x
Vin
1) Add 1.5 volts to the - R
-
analog input 1.5V + + ADCINx
R

ADCLO

GND
2) Subtract “1.5” from the digital result
#include “DSP2833x_Device.h”
#define offset 0x07FF
void main(void)
{
int16 value; // signed

value = AdcMirror.ADCRESULT0 – offset;


}

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6 - 11


Analog-to-Digital Converter

ADC Calibration
Built-In ADC Calibration
‹ TI reserved OTP contains device specific ADC
calibration data (2 words)
‹ The Boot ROM contains an ADC_cal() routine (6 words)
that copies the calibration data to the ADCREFSEL and
ADCOFFTRIM registers
‹ ADC_cal() must be run to meet the ADC specs in the
datasheet
Š The Bootloader automatically calls ADC_cal() such that no
action is normally required by the user
Š If the bootloader is bypassed (e.g., during development)
ADC_cal() should be called by the application:

#define ADC_cal_func_ptr (void (*)(void))0x380080


void main(void)
{
(*ADC_cal_func_ptr)(); // call ADC_cal()
}

Manual ADC Calibration


‹ If the offset and gain errors in the datasheet * are unacceptable for
your application, or you want to also compensate for board level
errors (e.g., sensor or amplifier offset), you can manually calibrate
‹ Offset error
Š Compensated in analog with ADCOFFTRIM
the ADCOFFTRIM register
Š No reduction in full-scale range CH
12-bit A/D
MUX

Š Ground an input pin, set


ADCOFFTRIM to maximum Converter
offset error, and take a reading
Š Re-adjust ADCOFFTRIM to CH
make result zero
‹ Gain error
Š Compensated in software
Š Some loss in full-scale range
Š Requires use of a second ADC input pin and an upper-range reference
voltage on that pin; see “TMS320280x and TMS320F2801x ADC
Calibration” appnote #SPRAAD8 for more information
‹ Tip: To minimize mux-to-mux variation effects, put your most critical
signals on a single mux and use that mux for calibration inputs
* +/-15 LSB offset, +/-30 LSB gain. See device datasheet for exact specifications

6 - 12 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Analog-to-Digital Converter

ADC Reference Selection


AdcRegs.ADCREFSEL
‹ The F28335 ADC has an internal reference with
temperature stability of ~50 PPM/°C *
‹ If this is not sufficient for your application, there is the
option to use an external reference *
Š External reference choices: 2.048 V, 1.5 V, 1.024 V
Š The reference value DOES NOT change the 0 - 3 V full-scale
range of the ADC
‹ The ADCREFSEL register controls the reference choice
15 - 14 13 - 0
REF_SEL reserved

ADC Reference Selection


00 = internal (default)
01 = external 2.048 V
10 = external 1.5 V
11 = external 1.024 V

* See device datasheet for exact specifications and ADC reference hardware connections

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6 - 13


Lab 6: Analog-to-Digital Converter

Lab 6: Analog-to-Digital Converter


¾ Objective

The objective of this lab is to become familiar with the programming and operation of the on-chip
analog-to-digital converter. The DSP will be setup to sample a single ADC input channel at a
prescribed sampling rate and store the conversion result in a memory buffer. This buffer will
operate in a circular fashion, such that new conversion data continuously overwrites older results
in the buffer.

Lab 6: ADC Sampling


+3.3 V Toggle
GND (GPIO20) (GPIO21)
data
ADC memory
CPU copies result
connector
to buffer during
wire RESULT0

pointer rewind
ADC ISR

ADCINA0

...
ePWM2 triggering
ADC on period match
using SOC A trigger every
20.833 µs (48 kHz) View ADC
buffer PWM
Samples

Code Composer
Studio

ePWM2

Recall that there are three basic ways to initiate an ADC start of conversion (SOC):
1. Using software
a. SOC_SEQ1/SOC_SEQ2 bit in ADCTRL2 causes an SOC upon completion of the current
conversion (if the ADC is currently idle, an SOC occurs immediately)
2. Automatically triggered on user selectable ePWM conditions
a. ePWM underflow (CTR = 0)
b. ePWM period match (CTR = PRD)
c. ePWM compare match (CTRU/D = CMPA/B)
3. Externally triggered using a pin
a. ADCSOC pin

One or more of these methods may be applicable to a particular application. In this lab, we will
be using the ADC for data acquisition. Therefore, one of the ePWMs (ePWM2) will be
configured to automatically trigger the SOC A signal at the desired sampling rate (SOC method
2b above). The ADC end-of-conversion interrupt will be used to prompt the CPU to copy the
results of the ADC conversion into a results buffer in memory. This buffer pointer will be
managed in a circular fashion, such that new conversion results will continuously overwrite older
conversion results in the buffer. In order to generate an interesting input signal, the code also
alternately toggles a GPIO pin (GPIO21) high and low in the ADC interrupt service routine. The

6 - 14 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Lab 6: Analog-to-Digital Converter

ADC ISR will also toggle LED DS2 on the eZdsp™ as a visual indication that the ISR is running.
This pin will be connected to the ADC input pin, and sampled. After taking some data, Code
Composer Studio will be used to plot the results. A flow chart of the code is shown in the
following slide.

Lab 6: Code Flow Diagram

Start General Initialization ADC interrupt


• PLL and clocks
• watchdog configure
• GPIO setup
• PIE initialization
Main Loop ADC ISR
while(1) • read the ADC result
ADC Initialization • write to result buffer
• convert channel A0 on { • adjust the buffer pointer
ePWM2 period match • toggle the GPIO pin
• send interrupt on }
• return from interrupt
every conversion
• setup a results buffer
in memory
return
ePWM2 Initialization
• clear counter
• set period register
• set to trigger ADC on
period match
• set the clock prescaler
• enable the timer

Notes
• Program performs conversion on ADC channel A0 (ADCINA0 pin)
• ADC conversion is set at a 48 kHz sampling rate
• ePWM2 is triggering the ADC on period match using SOC A trigger
• Data is continuously stored in a circular buffer
• GPIO21 pin is also toggled in the ADC ISR
• ADC ISR will also toggle the eZdsp™ LED DS2 as a visual indication that it is running

¾ Procedure

Project File
1. A project named Lab6.pjt has been created for this lab. Open the project by clicking
on Project Æ Open… and look in C:\C28x\Labs\Lab6. All Build Options
have been configured the same as the previous lab. The files used in this lab are:

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6 - 15


Lab 6: Analog-to-Digital Converter

Adc_6_7_8.c Gpio.c
CodeStartBranch.asm Lab_5_6_7.cmd
DefaultIsr_6.c Main_6.c
DelayUs.asm PieCtrl_5_6_7_8_9_10.c
DSP2833x_GlobalVariableDefs.c PieVect_5_6_7_8_9_10.c
DSP2833x_Headers_nonBIOS.cmd SysCtrl.c
EPwm_6.c Watchdog.c

Setup ADC Initialization and Enable Core/PIE Interrupts


2. In Main_6.c add code to call InitAdc() and InitEPwm() functions. The
InitEPwm() function is used to configure ePWM2 to trigger the ADC at a 48 kHz rate.
Details about the ePWM and control peripherals will be discussed in the next module.
3. Edit Adc.c to implement the ADC initialization as described above in the objective for
the lab by configuring the following registers: ADCTRL1, ADCTRL2, ADCMAXCONV
and ADCCHSELSEQ1. (Set ADC for cascaded sequencer mode, CPS = CLK/1, and
acquisition time prescale = 8 * (1/ADCCLK), ePWM2 triggering the ADC on period
match using SOC A trigger).

4. Using the “PIE Interrupt Assignment Table” find the location for the
ADC interrupt “ADCINT” and fill in the following information:

PIE group #: # within group:


This information will be used in the next step.

5. Modify the end of Adc.c to do the following:


- Enable the "ADCINT" interrupt in the PIE (Hint: use the PieCtrlRegs structure)
- Enable the appropriate core interrupt in the IER register
6. Open and inspect DefaultIsr_6.c. This file contains the ADC interrupt service
routine.

Build and Load


7. Save all changes to the files and click the “Build” button.

8. Reset the CPU, and then “Go Main”.

Run the Code


9. In Main_6.c place the cursor in the “main loop” section, right click on the mouse
key and select Run To Cursor.

10. Open a memory window to view some of the contents of the ADC results buffer. The
address label for the ADC results buffer is AdcBuf.

6 - 16 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Lab 6: Analog-to-Digital Converter

Note: Exercise care when connecting any wires, as the power to the eZdsp™ is on, and we
do not want to damage the eZdsp™! Details of pin assignments can be found in
Appendix A.

11. Using a connector wire provided, connect the ADCINA0 (pin # P9-2) to “GND” (pin #
P9-1) on the eZdsp™. Then run the code again, and halt it after a few seconds. Verify
that the ADC results buffer contains the expected value of 0x0000.

12. Adjust the connector wire to connect the ADCINA0 (pin # P9-2) to “+3.3V” (pin # P4-7)
on the eZdsp™. (Note: pin # P4-7 / GPIO20 has been set to “1” in Gpio.c). Then run the
code again, and halt it after a few seconds. Verify that the ADC results buffer contains
the expected value of 0x0FFF.

13. Adjust the connector wire to connect the ADCINA0 (pin # P9-2) to GPIO21 (pin # P4-8)
on the eZdsp™. Then run the code again, and halt it after a few seconds. Examine the
contents of the ADC results buffer (the contents should be alternating 0x0000 and
0x0FFF values). Are the contents what you expected?

14. Open and setup a graph to plot a 48-point window of the ADC results buffer.
Click: View Æ Graph Æ Time/Frequency… and set the following values:

Start Address AdcBuf

Acquisition Buffer Size 48

Display Data Size 48

DSP Data Type 16-bit unsigned integer

Sampling Rate (Hz) 48000

Time Display Unit μs

Select OK to save the graph options.

15. Recall that the code toggled the GPIO21 pin alternately high and low. (Also, the ADC
ISR is toggling the LED DS2 on the eZdsp™ as a visual indication that the ISR is
running). If you had an oscilloscope available to display GPIO21, you would expect to
see a square-wave. Why does Code Composer Studio plot resemble a triangle wave?
What is the signal processing term for what is happening here?

16. Recall that the program toggled the GPIO21 pin at a 48 kHz rate. Therefore, a complete
cycle (toggle high, then toggle low) occurs at half this rate, or 24 kHz. We therefore
expect the period of the waveform to be 41.667 μs. Confirm this by measuring the period
of the triangle wave using the graph (you may want to enlarge the graph window using
the mouse). The measurement is best done with the mouse. The lower left-hand corner
of the graph window will display the X and Y axis values. Subtract the X-axis values
taken over a complete waveform period.

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6 - 17


Lab 6: Analog-to-Digital Converter

Using Real-time Emulation


Real-time emulation is a special emulation feature that offers two valuable capabilities:

A. Windows within Code Composer Studio can be updated at up to a 10 Hz rate while the
DSP is running. This not only allows graphs and watch windows to update, but also
allows the user to change values in watch or memory windows, and have those
changes affect the DSP behavior. This is very useful when tuning control law
parameters on-the-fly, for example.

B. It allows the user to halt the DSP and step through foreground tasks, while specified
interrupts continue to get serviced in the background. This is useful when debugging
portions of a realtime system (e.g., serial port receive code) while keeping critical
parts of your system operating (e.g., commutation and current loops in motor control).

We will only be utilizing capability #1 above during the workshop. Capability #2 is a


particularly advanced feature, and will not be covered in the workshop.

17. Reset the CPU, and then enable real-time mode by selecting:

Debug Æ Real-time Mode

18. A message box may appear. Select YES to enable debug events. This will set bit 1
(DBGM bit) of status register 1 (ST1) to a “0”. The DBGM is the debug enable mask bit.
When the DBGM bit is set to “0”, memory and register values can be passed to the host
processor for updating the debugger windows.

19. The memory and graph windows displaying AdcBuf should still be open. The connector
wire between ADCINA0 (pin # P9-2) and GPIO21 (pin # P4-8) should still be connected.
In real-time mode, we would like to have our window continuously refresh. Click:

View Æ Real-time Refresh Options…

and check “Global Continuous Refresh”. Use the default refresh rate of 100
ms and select OK. Alternately, we could have right clicked on each window individually
and selected “Continuous Refresh”.

Note: “Global Continuous Refresh” causes all open windows to refresh at the
refresh rate. This can be problematic when a large number of windows are open, as
bandwidth over the emulation link is limited. Updating too many windows can cause the
refresh frequency to bog down. In that case, either close some windows, or disable
global refresh and selectively enable “Continuous Refresh” for individual
windows of interest instead.

20. Run the code and watch the windows update in real-time mode. Are the values updating
as expected?

21. Fully halting the DSP when in real-time mode is a two-step process. First, halt the
processor with Debug Æ Halt. Then uncheck the “Real-time mode” to take
the DSP out of real-time mode (Debug Æ Real-time Mode).

6 - 18 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Lab 6: Analog-to-Digital Converter

22. So far, we have seen data flowing from the DSP to the debugger in realtime. In this step,
we will flow data from the debugger to the DSP.
• Open and inspect DefaultIsr_6.c. Notice that the global variable
DEBUG_TOGGLE is used to control the toggling of the GPIO21 pin. This is the pin
being read with the ADC.
• Highlight DEBUG_TOGGLE with the mouse, right click and select “Add to
Watch Window”. The global variable DEBUG_TOGGLE should now be in the
watch window with a value of “1”.
• Run the code in real-time mode and change the value to “0”. Are the results shown
in the memory and graph window as expected? Change the value back to “1”. As
you can see, we are modifying data memory contents while the processor is running
in real-time (i.e., we are not halting the DSP nor interfering with its operation in any
way)! When done, fully halt the DSP.
23. Code Composer Studio includes GEL (General Extension Language) functions which
automate entering and exiting real-time mode. Four functions are available:
• Run_Realtime_with_Reset (reset DSP, enter real-time mode, run DSP)
• Run_Realtime_with_Restart (restart DSP, enter real-time mode, run DSP)
• Full_Halt (exit real-time mode, halt DSP)
• Full_Halt_with_Reset (exit real-time mode, halt DSP, reset DSP)
These GEL functions can be executed by clicking:
GEL Æ Realtime Emulation Control Æ GEL Function
In the remaining lab exercises we will be using the above GEL functions to run and halt
the code in real-time mode. If you would like, try repeating the previous step using the
following GEL functions:
GEL Æ Realtime Emulation Control Æ Run_Realtime_with_Reset
GEL Æ Realtime Emulation Control Æ Full_Halt

End of Exercise

TMS320C28x MCU Workshop - Analog-to-Digital Converter 6 - 19


Lab 6: Analog-to-Digital Converter

6 - 20 TMS320C28x MCU Workshop - Analog-to-Digital Converter


Control Peripherals

Introduction
This module explains how to generate PWM waveforms using the ePWM unit. Also, the eCAP
unit, and eQEP unit will be discussed.

Learning Objectives
Learning Objectives

‹ Pulse Width Modulation (PWM) review


‹ Generate a PWM waveform with the
Pulse Width Modulator Module (ePWM)
‹ Use the Capture Module (eCAP) to
measure the width of a waveform
‹ Explain the function of Quadrature
Encoder Pulse Module (eQEP)

Note: Different numbers of ePWM, eCAP, and eQEP modules are available on F2833x and
F2823x devices. See the device datasheet for more information.

TMS320C28x MCU Workshop - Control Peripherals 7-1


Module Topics

Module Topics

Control Peripherals................................................................................................................................... 7-1

Module Topics......................................................................................................................................... 7-2


PWM Review........................................................................................................................................... 7-3
ePWM...................................................................................................................................................... 7-5
ePWM Time-Base Module ................................................................................................................. 7-5
ePWM Compare Module.................................................................................................................... 7-9
ePWM Action Qualifier Module .......................................................................................................7-11
Asymmetric and Symmetric Waveform Generation using the ePWM..............................................7-16
PWM Computation Example.............................................................................................................7-17
ePWM Dead-Band Module ...............................................................................................................7-18
ePWM PWM Chopper Module .........................................................................................................7-21
ePWM Trip-Zone Module .................................................................................................................7-24
ePWM Event-Trigger Module...........................................................................................................7-27
Hi-Resolution PWM (HRPWM) .......................................................................................................7-29
eCAP ......................................................................................................................................................7-30
eQEP......................................................................................................................................................7-36
Lab 7: Control Peripherals....................................................................................................................7-38

7-2 TMS320C28x MCU Workshop - Control Peripherals


PWM Review

PWM Review
What is Pulse Width Modulation?

‹ PWM is a scheme to represent a


signal as a sequence of pulses
Š fixed carrier frequency
Š fixed pulse amplitude
Š pulse width proportional to
instantaneous signal amplitude
Š PWM energy ≈ original signal energy

t t
T
Original Signal PWM representation

Pulse width modulation (PWM) is a method for representing an analog signal with a digital
approximation. The PWM signal consists of a sequence of variable width, constant amplitude
pulses which contain the same total energy as the original analog signal. This property is
valuable in digital motor control as sinusoidal current (energy) can be delivered to the motor
using PWM signals applied to the power converter. Although energy is input to the motor in
discrete packets, the mechanical inertia of the rotor acts as a smoothing filter. Dynamic motor
motion is therefore similar to having applied the sinusoidal currents directly.

TMS320C28x MCU Workshop - Control Peripherals 7-3


PWM Review

Why use PWM with Power


Switching Devices?
‹ Desired output currents or voltages are known
‹ Power switching devices are transistors
Š Difficult to control in proportional region
Š Easy to control in saturated region
‹ PWM is a digital signal ⇒ easy for DSP to output

DC Supply DC Supply

? PWM
Desired PWM approx.
signal to of desired
system signal
Unknown Gate Signal Gate Signal Known with PWM

7-4 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM
ePWM Block Diagram

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

ePWM Time-Base Module


ePWM Time-Base Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

TMS320C28x MCU Workshop - Control Peripherals 7-5


ePWM

ePWM Time-Base Count Modes


TBCTR

TBPRD
Asymmetrical
Waveform

Count Up Mode
TBCTR

TBPRD
Asymmetrical
Waveform

Count Down Mode


TBCTR

TBPRD
Symmetrical
Waveform

Count Up and Down Mode

ePWM Phase Synchronization


Ext. SyncIn
(optional)

Phase
φ=0°
En
o o .o
SyncIn
EPWM1A
CTR=zero o
CTR=CMPB o o EPWM1B
X o
SyncOut
To eCAP1
SyncIn
Phase
φ=120°
En
o o .o
SyncIn
EPWM2A φ=120°

CTR=zero o
CTR=CMPB o o EPWM2B
X o
SyncOut

Phase
φ=240°
En
o o .
SyncIn
EPWM3A
φ=120°

o
CTR=zero o
CTR=CMPB o o EPWM3B
X o
SyncOut φ=240°

7-6 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Time-Base Module Registers


(lab file: EPwm.c)

Name Description Structure


TBCTL Time-Base Control EPwmxRegs.TBCTL.all =
TBSTS Time-Base Status EPwmxRegs.TBSTS.all =
TBPHS Time-Base Phase EPwmxRegs.TBPHS =
TBCTR Time-Base Counter EPwmxRegs.TBCTR =
TBPRD Time-Base Period EPwmxRegs.TBPRD =

ePWM Time-Base Control Register


EPwmxRegs.TBCTL

Upper Register:

Phase Direction
0 = count down after sync
1 = count up after sync TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)

15 - 14 13 12 - 10 9- 7
FREE_SOFT PHSDIR CLKDIV HSPCLKDIV

Emulation Halt Behavior TB Clock Prescale High Speed TB


00 = stop after next CTR inc/dec 000 = /1 (default) Clock Prescale
01 = stop when: 001 = /2 000 = /1
Up Mode; CTR = PRD 010 = /4 001 = /2 (default)
Down Mode; CTR = 0 011 = /8 010 = /4
Up/Down Mode; CTR = 0 100 = /16 011 = /6
1x = free run (do not stop) 101 = /32 100 = /8
110 = /64 101 = /10
111 = /128 110 = /12
111 = /14
(HSPCLKDIV is for legacy compatibility)

TMS320C28x MCU Workshop - Control Peripherals 7-7


ePWM

ePWM Time-Base Control Register


EPwmxRegs.TBCTL

Lower Register:
Counter Mode
00 = count up
Software Force Sync Pulse 01 = count down
0 = no action 10 = count up and down
1 = force one-time sync 11 = stop – freeze (default)

6 5-4 3 2 1- 0
SWFSYNC SYNCOSEL PRDLD PHSEN CTRMODE

Sync Output Select Period Shadow Load Phase Reg. Enable


(source of EPWMxSYNC0 signal) 0 = load on CTR = 0 0 = disable
00 = EPWMxSYNCI 1 = load immediately 1 = CTR = TBPHS on
01 = CTR = 0 EPWMxSYNCI signal
10 = CTR = CMPB
11 = disable SyncOut

ePWM Time-Base Status Register


EPwmxRegs.TBSTS

Counter Max Latched Counter Direction


0 = max value not reached 0 = CTR counting down
1 = CTR = 0xFFFF (write 1 to clear) 1 = CTR counting up

15 - 3 2 1 0
reserved CTRMAX SYNCI CTRDIR

External Input Sync Latched


0 = no sync event occurred
1 = sync has occurred (write 1 to clear)

7-8 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Compare Module


ePWM Compare Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCI
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

ePWM Compare Event Waveforms


TBCTR . = compare events are fed to the Action Qualifier Module

.. .. ..
TBPRD
CMPA Asymmetrical
CMPB Waveform

Count Up Mode
TBCTR

TBPRD
CMPA
CMPB
.. .. .. Asymmetrical
Waveform

Count Down Mode


TBCTR

.. .. .. ..
TBPRD
CMPA Symmetrical
CMPB Waveform

Count Up and Down Mode

TMS320C28x MCU Workshop - Control Peripherals 7-9


ePWM

ePWM Compare Module Registers


(lab file: EPwm.c)

Name Description Structure


CMPCTL Compare Control EPwmxRegs.CMPCTL.all =
CMPA Compare A EPwmxRegs.CMPA =
CMPB Compare B EPwmxRegs.CMPB =

ePWM Compare Control Register


EPwmxRegs.CMPCTL

CMPA and CMPB Shadow Full Flag


(bit automatically clears on load)
0 = shadow not full
1 = shadow full

15 - 10 9 8 7
reserved SHDWBFULL SHDWAFULL reserved

6 5 4 3- 2 1-0
SHDWBMODE reserved SHDWAMODE LOADBMODE LOADAMODE

CMPA and CMPB Operating Mode CMPA and CMPB Shadow Load Mode
0 = shadow mode; 00 = load on CTR = 0
double buffer w/ shadow register 01 = load on CTR = PRD
1 = immediate mode; 10 = load on CTR = 0 or PRD
shadow register not used 11 = freeze (no load possible)

7 - 10 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Action Qualifier Module


ePWM Action Qualifier Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

ePWM Action Qualifier Actions


for EPWMA and EPWMB

Time-Base Counter equals: EPWM


S/W Output
Force Actions
Zero CMPA CMPB TBPRD

SW Z CA CB P Do Nothing
X X X X X

SW Z CA CB P Clear Low
↓ ↓ ↓ ↓ ↓

SW Z CA CB P Set High
↑ ↑ ↑ ↑ ↑

SW Z CA CB P Toggle
T T T T T

TMS320C28x MCU Workshop - Control Peripherals 7 - 11


ePWM

ePWM Count Up Asymmetric Waveform


with Independent Modulation on EPWMA / B

TBCTR

TBPRD
. .
. .
Z P CB CA Z P CB CA Z P
↑ X X ↓ ↑ X X ↓ ↑ X

EPWMA

Z P CB CA Z P CB CA Z P
↑ X ↓ X ↑ X ↓ X ↑ X

EPWMB

ePWM Count Up Asymmetric Waveform


with Independent Modulation on EPWMA

TBCTR

TBPRD
. .
. .
CA CB CA CB
↑ ↓ ↑ ↓

EPWMA

Z Z Z
T T T

EPWMB

7 - 12 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Count Up-Down Symmetric


Waveform
with Independent Modulation on EPWMA / B
TBCTR

TBPRD

. . . . . . . .
CA CA CA CA
↑ ↓ ↑ ↓

EPWMA

CB CB CB CB
↑ ↓ ↑ ↓

EPWMB

ePWM Count Up-Down Symmetric


Waveform
with Independent Modulation on EPWMA
TBCTR

TBPRD

. . . .
CA CB CA CB
↑ ↓ ↑ ↓

EPWMA

Z P Z P
↓ ↑ ↓ ↑

EPWMB

TMS320C28x MCU Workshop - Control Peripherals 7 - 13


ePWM

ePWM Action Qualifier Module Registers


(lab file: EPwm.c)

Name Description Structure


AQCTLA AQ Control Output A EPwmxRegs.AQCTLA.all =
AQCTLB AQ Control Output B EPwmxRegs.AQCTLB.all =
AQSFRC AQ S/W Force EPwmxRegs.AQSFRC.all =
AQCSFRC AQ Cont. S/W Force EPwmxRegs.AQCSFRC.all =

ePWM Action Qualifier Control Register


EPwmxRegs.AQCTLy (y = A or B)

Action when Action when


CTR = CMPB CTR = CMPA Action when
on UP Count on UP Count CTR = 0

15 - 12 11 - 10 9-8 7-6 5-4 3- 2 1-0


reserved CBD CBU CAD CAU PRD ZRO

Action when Action when Action when


CTR = CMPB CTR = CMPA CTR = PRD
on DOWN Count on DOWN Count

00 = do nothing (action disabled)


01 = clear (low)
10 = set (high)
11 = toggle (low → high; high → low)

7 - 14 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Action Qualifier


S/W Force Register
EPwmxRegs.AQSFRC

One-Time S/W Force on Output B / A


0 = no action
1 = single s/w force event

15 - 8 7-6 5 4-3 2 1-0


reserved RLDCSF OTSFB ACTSFB OTSFA ACTSFA

AQSFRC Shadow Reload Options Action on One-Time S/W Force B / A


00 = load on event CTR = 0 00 = do nothing (action disabled)
01 = load on event CTR = PRD 01 = clear (low)
10 = load on event CTR = 0 or CTR = PRD 10 = set (high)
11 = load immediately (from active reg.) 11 = toggle (low → high; high → low)

ePWM Action Qualifier Continuous


S/W Force Register
EPwmxRegs.AQCSFRC

15 - 4 3-2 1-0
reserved CSFB CSFA

Continuous S/W Force on Output B / A


00 = forcing disabled
01 = force continuous low on output
10 = force continuous high on output
11 = forcing disabled

TMS320C28x MCU Workshop - Control Peripherals 7 - 15


ePWM

Asymmetric and Symmetric Waveform Generation using


the ePWM
PWM switching frequency:
The PWM carrier frequency is determined by the value contained in the time-base period register,
and the frequency of the clocking signal. The value needed in the period register is:

⎛ switching period ⎞
Asymmetric PWM: period register = ⎜⎜ ⎟⎟ − 1
⎝ timer period ⎠

switching period
Symmetric PWM: period register =
2(timer period)

Notice that in the symmetric case, the period value is half that of the asymmetric case. This is
because for up/down counting, the actual timer period is twice that specified in the period register
(i.e. the timer counts up to the period register value, and then counts back down).

PWM resolution:
The PWM compare function resolution can be computed once the period register value is
determined. The largest power of 2 is determined that is less than (or close to) the period value.
As an example, if asymmetric was 1000, and symmetric was 500, then:

Asymmetric PWM: approx. 10 bit resolution since 210 = 1024 ≈ 1000

Symmetric PWM: approx. 9 bit resolution since 29 = 512 ≈ 500

PWM duty cycle:


Duty cycle calculations are simple provided one remembers that the PWM signal is initially
inactive during any particular timer period, and becomes active after the (first) compare match
occurs. The timer compare register should be loaded with the value as follows:

Asymmetric PWM: TxCMPR = (100% - duty cycle) ∗ TxPR

Symmetric PWM: TxCMPR = (100% - duty cycle) ∗ TxPR

Note that for symmetric PWM, the desired duty cycle is only achieved if the compare registers
contain the computed value for both the up-count compare and down-count compare portions of
the time-base period.

7 - 16 TMS320C28x MCU Workshop - Control Peripherals


ePWM

PWM Computation Example


Symmetric PWM Computation Example
‹ Determine TBPRD and CMPA for 150 kHz, 25% duty
symmetric PWM from a 150 MHz time base clock

fP WM = 150 kHz

. .
Period
Compare
CA CA
Counter ↑ ↓

f TBCLK = 150 MHz


PWM Pin

1 . fTBCLK 1 150 MHz


TBPRD = = . = 500
2 fPWM 2 150 kHz
CMPA = (100% - duty cycle)*TBPRD = 0.75*500 = 375

Asymmetric PWM Computation Example


‹ Determine TBPRD and CMPA for 150 kHz, 25% duty
asymmetric PWM from a 150 MHz time base clock

.
fP WM = 150 kHz

Period
Compare .
CA P
Counter ↑ ↓

fTBCLK = 150 MHz


PWM Pin

fTBCLK 150 MHz


TBPRD = -1= - 1 = 999
fPWM 150 kHz
CMPA = (100% - duty cycle)*(TBPRD+1) - 1 = 0.75*(999+1) - 1 = 749

TMS320C28x MCU Workshop - Control Peripherals 7 - 17


ePWM

ePWM Dead-Band Module


ePWM Dead-Band Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

Motivation for Dead-Band

supply rail

gate signals are to power


complementary PWM switching
device

♦ Transistor gates turn on faster than they shut off


♦ Short circuit if both gates are on at same time!

7 - 18 TMS320C28x MCU Workshop - Control Peripherals


ePWM

Dead-band control provides a convenient means of combating current shoot-through problems in


a power converter. Shoot-through occurs when both the upper and lower gates in the same phase
of a power converter are open simultaneously. This condition shorts the power supply and results
in a large current draw. Shoot-through problems occur because transistors open faster than they
close, and because high-side and low-side power converter gates are typically switched in a
complimentary fashion. Although the duration of the shoot-through current path is finite during
PWM cycling, (i.e. the closing gate will eventually shut), even brief periods of a short circuit
condition can produce excessive heating and over stress in the power converter and power supply.

ePWM Dead-Band Module Block Diagram


PWMxA

Rising

.
0

.
Edge S1
0
° ° PWMxA
0
° ° S4
Delay ° ° S2 RED
°1
°1
In Out
(10-bit
° °1
counter)

Falling

.
Edge 0

. ° S3°
0 Delay 1
FED
° ° S5
° S0° PWMxB

°1
In Out
(10-bit
° °1
°0
counter)
IN-MODE POLSEL OUT-MODE

PWMxB

Two basic approaches exist for controlling shoot-through: modify the transistors, or modify the
PWM gate signals controlling the transistors. In the first case, the opening time of the transistor
gate must be increased so that it (slightly) exceeds the closing time. One way to accomplish this
is by adding a cluster of passive components such as resistors and diodes in series with the
transistor gate, as shown in the next figure.

by-pass diode

PWM
signal
R

Shoot-through control via power circuit modification

The resistor acts to limit the current rise rate towards the gate during transistor opening, thus
increasing the opening time. When closing the transistor however, current flows unimpeded from
the gate via the by-pass diode and closing time is therefore not affected. While this passive
approach offers an inexpensive solution that is independent of the control microprocessor, it is

TMS320C28x MCU Workshop - Control Peripherals 7 - 19


ePWM

imprecise, the component parameters must be individually tailored to the power converter, and it
cannot adapt to changing system conditions.

The second approach to shoot-through control separates transitions on complimentary PWM


signals with a fixed period of time. This is called dead-band. While it is possible to perform
software implementation of dead-band, the C28x offers on-chip hardware for this purpose that
requires no additional CPU overhead. Compared to the passive approach, dead-band offers more
precise control of gate timing requirements. In addition, the dead time is typically specified with
a single program variable that is easily changed for different power converters or adapted on-line.

ePWM Dead-Band Module Registers


(lab file: EPwm.c)

Name Description Structure


DBCTL Dead-Band Control EPwmxRegs.DBCTL.all =
DBRED 10-bit Rising Edge Delay EPwmxRegs.DBRED =
DBFED 10-bit Falling Edge Delay EPwmxRegs.DBFED =

Rising Edge Delay = T TBCLK x DBRED


Falling Edge Delay = TTBCLK x DBFED

7 - 20 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Dead Band Control Register


EPwmxRegs.DBCTL

Polarity Select
00 = active high
01 = active low complementary (RED)
10 = active high complementary (FED)
11 = active low

15 - 6 5-4 3-2 1-0


reserved IN_MODE POLSEL OUT_MODE

In-Mode Control Out-Mode Control


00 = PWMxA is source for RED and FED 00 = disabled (DBM bypass)
01 = PWMxA is source for FED 01 = PWMxA = no delay
PWMxB is source for RED PWMxB = FED
10 = PWMxA is source for RED 10 = PWMxA = RED
PWMxB is source for FED PWMxB = no delay
11 = PWMxB is source for RED and FED 11 = RED & FED (DBM fully enabled)

ePWM PWM Chopper Module


ePWM PWM Chopper Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

TMS320C28x MCU Workshop - Control Peripherals 7 - 21


ePWM

Purpose of the PWM Chopper Module

‹ Allows a high frequency carrier


signal to modulate the PWM
waveform generated by the Action
Qualifier and Dead-Band modules
‹ Used with pulse transformer-based
gate drivers to control power
switching elements

ePWM Chopper Waveform


EPWMxA

EPWMxB

CHPFREQ

EPWMxA

EPWMxB

Programmable
Pulse Width
OSHT (OSHTWTH)

Sustaining
EPWMxA Pulses

With One-Shot Pulse on EPWMxA and/or EPWMxB

7 - 22 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Chopper Module Registers


(lab file: EPwm.c)

Name Description Structure


PCCTL PWM-Chopper Control EPwmxRegs.PCCTL.all =

ePWM Chopper Control Register


EPwmxRegs.PCCTL

Chopper Clk Duty Cycle Chopper Clk Freq.


000 = 1/8 (12.5%) 000 = SYSCLKOUT/8 ÷ 1
001 = 2/8 (25.0%) 001 = SYSCLKOUT/8 ÷ 2
010 = 3/8 (37.5%) 010 = SYSCLKOUT/8 ÷ 3
011 = 4/8 (50.0%) 011 = SYSCLKOUT/8 ÷ 4
100 = 5/8 (62.5%) 100 = SYSCLKOUT/8 ÷ 5 Chopper Enable
101 = 6/8 (75.0%) 101 = SYSCLKOUT/8 ÷ 6 0 = disable (bypass)
110 = 7/8 (87.5%) 110 = SYSCLKOUT/8 ÷ 7 1 = enable
111 = reserved 111 = SYSCLKOUT/8 ÷ 8

15 - 11 10 - 8 7- 5 4- 1 0
reserved CHPDUTY CHPFREQ OSHTWTH CHPEN

One-Shot Pulse Width


0000 =1x SYSCLKOUT/8 1000 = 9 x SYSCLKOUT/8
0001 =2x SYSCLKOUT/8 1001 = 10 x SYSCLKOUT/8
0010 =3x SYSCLKOUT/8 1010 = 11 x SYSCLKOUT/8
0011 =4x SYSCLKOUT/8 1011 = 12 x SYSCLKOUT/8
0100 =5x SYSCLKOUT/8 1100 = 13 x SYSCLKOUT/8
0101 =6x SYSCLKOUT/8 1101 = 14 x SYSCLKOUT/8
0110 =7x SYSCLKOUT/8 1110 = 15 x SYSCLKOUT/8
0111 =8x SYSCLKOUT/8 1111 = 16 x SYSCLKOUT/8

TMS320C28x MCU Workshop - Control Peripherals 7 - 23


ePWM

ePWM Trip-Zone Module


ePWM Trip-Zone Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

Trip-Zone Module Features


♦ Trip-Zone has a fast, clock independent logic path to high-impedance
the EPWMxA/B output pins
♦ Interrupt latency may not protect hardware when responding to over
current conditions or short-circuits through ISR software
♦ Supports: #1) one-shot trip for major short circuits or over
current conditions
#2) cycle-by-cycle trip for current limiting operation
EPWM1A
Over
Current DSP EPWM1B
EPWM2A
P
Sensors core W
EPWM2B M
EPWM3A
TZ1 EPWMxTZINT EPWM3B O
TZ2 Cycle-by-Cycle EPWM4A U
TZ3 Mode EPWM4B
T
P
TZ4 EPWM5A U
TZ5 One-Shot EPWM5B T
TZ6 Mode EPWM6A S
EPWM6B

The power drive protection is a safety feature that is provided for the safe operation of systems
such as power converters and motor drives. It can be used to inform the monitoring program of

7 - 24 TMS320C28x MCU Workshop - Control Peripherals


ePWM

motor drive abnormalities such as over-voltage, over-current, and excessive temperature rise. If
the power drive protection interrupt is unmasked, the PWM output pins will be put in the high-
impedance state immediately after the pin is driven low. An interrupt will also be generated.

ePWM Trip-Zone Module Registers


(lab file: EPwm.c)

Name Description Structure


TZCTL Trip-Zone Control EPwmxRegs.TZCTL.all =
TZSEL Trip-Zone Select EPwmxRegs.TZSEL.all =
TZEINT Enable Interrupt EPwmxRegs.TZEINT.all =
TZFLG Trip-Zone Flag EPwmxRegs.TZFLG.all =
TZCLR Trip-Zone Clear EPwmxRegs.TZCLR.all =
TZFRC Trip-Zone Force EPwmxRegs.TZFRC.all =

ePWM Trip-Zone Control Register


EPwmxRegs.TZCTL

15 - 4 3-2 1-0
reserved TZB TZA

TZ1 to TZ6 Action on EPWMxB / EPWMxA


00 = high impedance
01 = force high
10 = force low
11 = do nothing (disable)

TMS320C28x MCU Workshop - Control Peripherals 7 - 25


ePWM

ePWM Trip-Zone Select Register


EPwmxRegs.TZSEL

One-Shot Trip Zone


(event only cleared under S/W
control; remains latched)
0 = disable as trip source
1 = enable as trip source

15 - 14 13 12 11 10 9 8
reserved OSHT6 OSHT5 OSHT4 OSHT3 OSHT2 OSHT1

7-6 5 4 3 2 1 0
reserved CBC6 CBC5 CBC4 CBC3 CBC2 CBC1

Cycle-by-Cycle Trip Zone


(event cleared when CTR = 0;
i.e. cleared every PWM cycle)
0 = disable as trip source
1 = enable as trip source

ePWM Trip-Zone Enable Interrupt


Register
EPwmxRegs.TZEINT

15 - 3 2 1 0
reserved OST CBC reserved

One-Shot Cycle-by-Cycle
Interrupt Enable Interrupt Enable
0 = disable 0 = disable
1 = enable 1 = enable

7 - 26 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Event-Trigger Module


ePWM Event-Trigger Module

CMPA . 15 - 0 CMPB . 15 - 0
TBCTL . 12 - 7
Shadowed Shadowed
Clock Compare Compare
Prescaler Register Register
AQCTLA . 11 - 0
TBCTR . 15 - 0
AQCTLB . 11 - 0 DBCTL . 4 - 0
16-Bit
Compare Action Dead
Time-Base
TBCLK Logic Qualifier Band
Counter

EPWMxSYNCI EPWMxSYNCO
Period
Register EPWMxA
PWM Trip
Shadowed
Chopper Zone
SYSCLKOUT TBPRD . 15 - 0 EPWMxB
PCCTL . 10 - 0
TZy
TZSEL . 15 - 0

ePWM Event-Trigger Interrupts and SOC


TBCTR

. . . . . . . .
TBPRD
CMPB
CMPA

EPWMA

EPWMB

CTR = 0

CTR = PRD
CTRU = CMPA

CTRD = CMPA

CTRU = CMPB

CTRD = CMPB

TMS320C28x MCU Workshop - Control Peripherals 7 - 27


ePWM

ePWM Event-Trigger Module Registers


(lab file: EPwm.c)

Name Description Structure


ETSEL Event-Trigger Selection EPwmxRegs.ETSEL.all =
ETPS Event-Trigger Pre-Scale EPwmxRegs.ETPS.all =
ETFLG Event-Trigger Flag EPwmxRegs.ETFLG.all =
ETCLR Event-Trigger Clear EPwmxRegs.ETCLR.all =
ETFRC Event-Trigger Force EPwmxRegs.ETFRC.all =

ePWM Event-Trigger Selection Register


EPwmxRegs.ETSEL

Enable SOCB / A Enable EPWMxINT


0 = disable 0 = disable
1 = enable 1 = enable

15 14 - 12 11 10 - 8 7-4 3 2-0
SOCBEN SOCBSEL SOCAEN SOCASEL reserved INTEN INTSEL

EPWMxSOCB / A Select EPWMxINT Select


000 = reserved 000 = reserved
001 = CTR = 0 001 = CTR = 0
010 = CTR = PRD 010 = CTR = PRD
011 = reserved 011 = reserved
100 = CTRU = CMPA 100 = CTRU = CMPA
101 = CTRD = CMPA 101 = CTRD = CMPA
110 = CTRU = CMPB 110 = CTRU = CMPB
111 = CTRD = CMPB 111 = CTRD = CMPB

7 - 28 TMS320C28x MCU Workshop - Control Peripherals


ePWM

ePWM Event-Trigger Prescale Register


EPwmxRegs.ETPS

EPWMxSOCB / A Counter EPWMxINT Counter


(number of events have occurred) (number of events have occurred)
00 = no events 00 = no events
01 = 1 event 01 = 1 event
10 = 2 events 10 = 2 events
11 = 3 events 11 = 3 events

15 - 14 13 - 12 11 - 10 9- 8 7-4 2-3 1-0


SOCBCNT SOCBPRD SOCACNT SOCAPRD reserved INTCNT INTPRD

EPWMxSOCB / A Period EPWMxINT Period


(number of events before SOC) (number of events before INT)
00 = disabled 00 = disabled
01 = SOC on first event 01 = INT on first event
10 = SOC on second event 10 = INT on second event
11 = SOC on third event 11 = INT on third event

Hi-Resolution PWM (HRPWM)


Hi-Resolution PWM (HRPWM)
PWM Period

Regular
Device Clock PWM Step
(i.e. 150 MHz) (i.e. 6.67 ns)

HRPWM divides a clock Calibration Logic tracks the


cycle into smaller steps number of Micro Steps per
ms ms ms ms ms ms
called Micro Steps clock to account for
(Step Size ~= 150 ps) Calibration Logic variations caused by
Temp/Volt/Process

HRPWM
Micro Step (~150 ps)

‹ Significantly increases the resolution of conventionally derived digital PWM


‹ Uses 8-bit extensions to Compare registers (CMPxHR) and Phase register
(TBPHSHR) for edge positioning control
‹ Typically used when PWM resolution falls below ~9-10 bits which occurs at
frequencies greater than ~300 kHz (with system clock of 150 MHz)
‹ Not all ePWM outputs support HRPWM feature (see device datasheet)

TMS320C28x MCU Workshop - Control Peripherals 7 - 29


eCAP

eCAP
Capture Units (eCAP)

Timer
Trigger
pin
Timestamp
Values

‹ The eCAP module timestamps transitions on a


capture input pin

The capture units allow time-based logging of external TTL signal transitions on the capture input
pins. The C28x has up to six capture units.

Capture units can be configured to trigger an A/D conversion that is synchronized with an
external event. There are several potential advantages to using the capture for this function over
the ADCSOC pin associated with the ADC module. First, the ADCSOC pin is level triggered,
and therefore only low to high external signal transitions can start a conversion. The capture unit
does not suffer from this limitation since it is edge triggered and can be configured to start a
conversion on either rising edges or falling edges. Second, if the ADCSOC pin is held high
longer than one conversion period, a second conversion will be immediately initiated upon
completion of the first. This unwanted second conversion could still be in progress when a
desired conversion is needed. In addition, if the end-of-conversion ADC interrupt is enabled, this
second conversion will trigger an unwanted interrupt upon its completion. These two problems
are not a concern with the capture unit. Finally, the capture unit can send an interrupt request to
the CPU while it simultaneously initiates the A/D conversion. This can yield a time savings
when computations are driven by an external event since the interrupt allows preliminary
calculations to begin at the start-of-conversion, rather than at the end-of-conversion using the
ADC end-of-conversion interrupt. The ADCSOC pin does not offer a start-of-conversion
interrupt. Rather, polling of the ADCSOC bit in the control register would need to be performed
to trap the externally initiated start of conversion.

7 - 30 TMS320C28x MCU Workshop - Control Peripherals


eCAP

Some Uses for the Capture Units

‹ Measure the time width of a pulse


‹ Low speed velocity estimation from incr. encoder:
Problem: At low speeds, calculation of speed
x -x
based on a measured position change at vk ≈ k k-1
fixed time intervals produces large estimate Δt
errors

Alternative: Estimate the speed using a measured time interval


at fixed position intervals
Signal from one
Δx
vk ≈ quadrature
tk - tk-1 encoder channel
Δx

‹ Auxiliary PWM generation

eCAP Block Diagram – Capture Mode


CAP1POL
CAP1 . 31 - 0 ECCTL . 0

Capture 1 Polarity
Register Select 1
CAP2POL
CAP2 . 31 - 0 ECCTL . 2

TSCTR . 31 - 0 Capture 2 Polarity PRESCALE


Event Logic

Register Select 2 ECCTL . 13 - 9


32-Bit CAP3POL Event
Time-Stamp CAP3 . 31 - 0 ECCTL . 4 Prescale
Counter ECAPx
Capture 3 Polarity pin
Register Select 3
SYSCLKOUT CAP4POL
CAP4 . 31 - 0 ECCTL . 6

Capture 4 Polarity
Register Select 4

TMS320C28x MCU Workshop - Control Peripherals 7 - 31


eCAP

eCAP Block Diagram – APWM Mode

Shadowed
Period CAP3 . 31 - 0
CAP1 . 31 - 0 Period Register shadow
immediate Register (CAP3) mode
mode (CAP1)

TSCTR . 31 - 0

32-Bit PWM
Time-Stamp Compare
Counter Logic ECAP
pin
SYSCLKOUT
CAP2 . 31 - 0 Compare
immediate Register Compare CAP4 . 31 - 0
mode (CAP2) Register shadow
Shadowed (CAP4) mode

eCAP Module Registers


(lab file: ECap.c)

Name Description Structure


ECCTL1 Capture Control 1 ECapxRegs.ECCTL1.all =
ECCTL2 Capture Control 2 ECapxRegs.ECCTL2.all =
TSCTR Time-Stamp Counter ECapxRegs.TSCTR =
CTRPHS Counter Phase Offset ECapxRegs.CTRPHS =
CAP1 Capture 1 ECapxRegs.CAP1 =
CAP2 Capture 2 ECapxRegs.CAP2 =
CAP3 Capture 3 ECapxRegs.CAP3 =
CAP4 Capture 4 ECapxRegs.CAP4 =
ECEINT Enable Interrupt ECapxRegs.ECEINT.all =
ECFLG Interrupt Flag ECapxRegs.ECFLG.all =
ECCLR Interrupt Clear ECapxRegs.ECCLR.all =
ECFRC Interrupt Force ECapxRegs.ECFRC.all =

7 - 32 TMS320C28x MCU Workshop - Control Peripherals


eCAP

eCAP Control Register 1


ECapxRegs.ECCTL1

Upper Register:
CAP1 – 4 Load
on Capture Event
0 = disable
1 = enable

15 - 14 13 - 9 8
FREE_SOFT PRESCALE CAPLDEN

Emulation Control Event Filter Prescale Counter


00 = TSCTR stops immediately 00000 = divide by 1 (bypass)
01 = TSCTR runs until equals 0 00001 = divide by 2
1X = free run (do not stop) 00010 = divide by 4
00011 = divide by 6
00100 = divide by 8

11110 = divide by 60
11111 = divide by 62

eCAP Control Register 1


ECapxRegs.ECCTL1

Lower Register:
Counter Reset on Capture Event
0 = no reset (absolute time stamp mode)
1 = reset after capture (difference mode)

7 6 5 4 3 2 1 0
CTRRST4 CAP4POL CTRRST3 CAP3POL CTRRST2 CAP2POL CTRRST1 CAP1POL

Capture Event Polarity


0 = trigger on rising edge
1 = trigger on falling edge

TMS320C28x MCU Workshop - Control Peripherals 7 - 33


eCAP

eCAP Control Register 2


ECapxRegs.ECCTL2

Upper Register:
Capture / APWM mode
0 = capture mode
1 = APWM mode

15 - 11 10 9 8
reserved APWMPOL CAP_APWM SWSYNC

APWM Output Polarity Software Force


(valid only in APWM mode) Counter Synchronization
0 = active high output 0 = no effect
1 = active low output 1 = TSCTR load of current
module and other modules
if SYNCO_SEL bits = 00

eCAP Control Register 2


ECapxRegs.ECCTL2

Lower Register:
Re-arm Continuous/One-Shot
Counter Sync-In (capture mode only) (capture mode only)
0 = disable 0 = no effect 0 = continuous mode
1 = enable 1 = arm sequence 1 = one-shot mode

7-6 5 4 3 2-1 0
SYNCO_SEL SYNCI_EN TSCTRSTOP REARM STOP_WRAP CONT_ONESHT

Sync-Out Select Time Stamp Stop Value for One-Shot Mode/


00 = sync-in to sync-out Counter Stop Wrap Value for Continuous Mode
01 = CTR = PRD event 0 = stop (capture mode only)
generates sync-out 1 = run 00 = stop/wrap after capture event 1
1X = disable 01 = stop/wrap after capture event 2
10 = stop/wrap after capture event 3
11 = stop/wrap after capture event 4

7 - 34 TMS320C28x MCU Workshop - Control Peripherals


eCAP

The capture unit interrupts offer immediate CPU notification of externally captured events. In
situations where this is not required, the interrupts can be masked and flag testing/polling can be
used instead. This offers increased flexibility for resource management. For example, consider a
servo application where a capture unit is being used for low-speed velocity estimation via a
pulsing sensor. The velocity estimate is not used until the next control law calculation is made,
which is driven in real-time using a timer interrupt. Upon entering the timer interrupt service
routine, software can test the capture interrupt flag bit. If sufficient servo motion has occurred
since the last control law calculation, the capture interrupt flag will be set and software can
proceed to compute a new velocity estimate. If the flag is not set, then sufficient motion has not
occurred and some alternate action would be taken for updating the velocity estimate. As a
second example, consider the case where two successive captures are needed before a
computation proceeds (e.g. measuring the width of a pulse). If the width of the pulse is needed as
soon as the pulse ends, then the capture interrupt is the best option. However, the capture
interrupt will occur after each of the two captures, the first of which will waste a small number of
cycles while the CPU is interrupted and then determines that it is indeed only the first capture. If
the width of the pulse is not needed as soon as the pulse ends, the CPU can check, as needed, the
capture registers to see if two captures have occurred, and proceed from there.

eCAP Interrupt Enable Register


ECapxRegs.ECEINT

CTR = CMP CTR = Overflow Capture Event 3 Capture Event 1


Interrupt Enable Interrupt Enable Interrupt Enable Interrupt Enable

15 - 8 7 6 5 4 3 2 1 0
reserved CTR=CMP CTR=PRD CTROVF CEVT4 CEVT3 CEVT2 CEVT1 reserved

CTR = PRD Capture Event 4 Capture Event 2


Interrupt Enable Interrupt Enable Interrupt Enable

0 = disable as interrupt source


1 = enable as interrupt source

TMS320C28x MCU Workshop - Control Peripherals 7 - 35


eQEP

eQEP
What is an Incremental Quadrature
Encoder?
A digital (angular) position sensor

photo sensors spaced θ/4 deg. apart

slots spaced θ deg. apart θ/4


light source (LED)
θ

Ch. A

Ch. B
shaft rotation

Incremental Optical Encoder Quadrature Output from Photo Sensors

The eQEP circuit, when enabled, decodes and counts the quadrature encoded input pulses. The
QEP circuit can be used to interface with an optical encoder to get position and speed information
from a rotating machine.

How is Position Determined from


Quadrature Signals?
Position resolution is θ/4 degrees

(00) (11)
increment decrement
(A,B) = counter 10 counter
(10) (01)

Illegal
Ch. A 00 Transitions;
generate 11
phase error
interrupt

Ch. B

01

Quadrature Decoder
State Machine

7 - 36 TMS320C28x MCU Workshop - Control Peripherals


eQEP

eQEP Block Diagram


Measure the elapsed time
between the unit position events;
used for low speed measurement
Quadrature
Generate periodic
Capture
interrupts for velocity Quadrature - Direction -
calculations clock mode count mode
Monitors the quadrature
clock to indicate proper
operation of the motion EQEPxA/XCLK
control system
32-Bit Unit EQEPxB/XDIR
Time-Base Quadrature
QEP Decoder EQEPxI
Watchdog
EQEPxS
SYSCLKOUT
Position/Counter
Compare
Generate the direction and
clock for the position counter
Generate a sync output in quadrature count mode
and/or interrupt on a
position compare match

eQEP Connections

Ch. A

Quadrature Ch. B
Capture

EQEPxA/XCLK
32-Bit Unit EQEPxB/XDIR
Time-Base Quadrature
QEP Decoder EQEPxI Index
Watchdog
EQEPxS Strobe
from homing sensor
SYSCL KOUT
Position/Counter
Compare

TMS320C28x MCU Workshop - Control Peripherals 7 - 37


Lab 7: Control Peripherals

Lab 7: Control Peripherals


¾ Objective

The objective of this lab is to become familiar with the programming and operation of the control
peripherals and their interrupts. ePWM1A will be setup to generate a 2 kHz, 25% duty cycle
symmetric PWM waveform. The waveform will then be sampled with the on-chip analog-to-
digital converter and displayed using the graphing feature of Code Composer Studio. Next,
eCAP1 will be setup to detect the rising and falling edges of the waveform. This information will
be used to determine the width of the pulse and duty cycle of the waveform. The results of this
step will be viewed numerically in a memory window.

Lab 7: Control Peripherals

ePWM1
TB Counter CPU copies
data
Compare ADC result to
memory
connector
wire buffer during
Action Qualifier RESULT0

pointer rewind
ADC ISR
eCAP1 ADC-
Capture 1 Register INA0

...
Capture 2 Register
Capture 3 Register
Capture 4 Register
View ADC
buffer PWM
ePWM2 triggering Samples
ADC on period match
using SOC A trigger
every 20.833 µs (48 kHz) ePWM2 Code Composer
Studio

¾ Procedure

Project File
1. A project named Lab7.pjt has been created for this lab. Open the project by clicking
on Project Æ Open… and look in C:\C28x\Labs\Lab7. All Build Options
have been configured the same as the previous lab. The files used in this lab are:
Adc_6_7_8.c Gpio.c
CodeStartBranch.asm Lab_5_6_7.cmd
DefaultIsr_7.c Main_7.c
DelayUs.asm PieCtrl_5_6_7_8_9_10.c
DSP2833x_GlobalVariableDefs.c PieVect_5_6_7_8_9_10.c
DSP2833x_Headers_nonBIOS.cmd SysCtrl.c
ECap_7_8_9_10_12.c Watchdog.c
EPwm_7_8_9_10_12.c

7 - 38 TMS320C28x MCU Workshop - Control Peripherals


Lab 7: Control Peripherals

Setup Shared I/O and ePWM1


2. Edit Gpio.c and adjust the shared I/O pin in GPIO0 for the PWM1A function.

3. In EPwm_7_8_9_10_12.c, setup ePWM1 to implement the PWM waveform as


described in the objective for this lab. The following registers need to be modified:
TBCTL (set clock prescales to divide-by-1, no software force, sync and phase disabled),
TBPRD, CMPA, CMPCTL (load on 0 or PRD), and AQCTLA (set on up count and clear
on down count for output A). Software force, deadband, PWM chopper and trip action
has been disabled. (Hint – notice the last steps enable the timer count mode and enable
the clock to the ePWM module). Either calculate the values for TBPRD and CMPA (as a
challenge) or make use of the global variable names and values that have been set using
#define in the beginning of Lab.h file. Notice that ePWM2 has been initialized earlier
in the code for the ADC lab. Save your work.

Build and Load


4. Save all changes to the files and click the “Build” button to build and load the project.

Run the Code – PWM Waveform


5. Open a memory window to view some of the contents of the ADC results buffer. The
address label for the ADC results buffer is AdcBuf. We will be running our code in real-
time mode, and will have our window continuously refresh.

6. Using a connector wire provided, connect the PWM1A (pin # P8-9) to ADCINA0 (pin #
P9-2) on the eZdsp™.

7. Run the code (real-time mode) using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset. Watch the window
update. Verify that the ADC result buffer contains the updated values.

8. Open and setup a graph to plot a 48-point window of the ADC results buffer.
Click: View Æ Graph Æ Time/Frequency… and set the following values:

Start Address AdcBuf

Acquisition Buffer Size 48

Display Data Size 48

DSP Data Type 16-bit unsigned integer

Sampling Rate (Hz) 48000

Time Display Unit μs

Select OK to save the graph options.

TMS320C28x MCU Workshop - Control Peripherals 7 - 39


Lab 7: Control Peripherals

9. The graphical display should show the generated 2 kHz, 25% duty cycle symmetric
PWM waveform. The period of a 2 kHz signal is 500 μs. You can confirm this by
measuring the period of the waveform using the graph (you may want to enlarge the
graph window using the mouse). The measurement is best done with the mouse. The
lower left-hand corner of the graph window will display the X and Y-axis values.
Subtract the X-axis values taken over a complete waveform period (you can use the PC
calculator program found in Microsoft Windows to do this).

Frequency Domain Graphing Feature of Code Composer Studio


10. Code Composer Studio also has the ability to make frequency domain plots. It does this
by using the PC to perform a Fast Fourier Transform (FFT) of the DSP data. Let's make
a frequency domain plot of the contents in the ADC results buffer (i.e. the PWM
waveform).

Click: View Æ Graph Æ Time/Frequency… and set the following values:

Display Type FFT Magnitude

Start Address AdcBuf

Acquisition Buffer Size 48

FFT Framesize 48

DSP Data Type 16-bit unsigned integer

Sampling Rate (Hz) 48000

Select OK to save the graph options.

11. On the plot window, left-click the mouse to move the vertical marker line and observe the
frequencies of the different magnitude peaks. Do the peaks occur at the expected
frequencies?

12. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

Setup eCAP1 to Measure Width of Pulse


The first part of this lab exercise generated a 2 kHz, 25% duty cycle symmetric PWM
waveform which was sampled with the on-chip analog-to-digital converter and displayed
using the graphing feature of Code Composer Studio. Next, eCAP1 will be setup to detect
the rising and falling edges of the waveform. This information will be used to determine the
period and duty cycle of the waveform. The results of this step will be viewed numerically in
a memory window and can be compared to the results obtained using the graphing features of
Code Composer Studio.
13. Add the following file to the project:
ECap_7_8_9_10_12.c

7 - 40 TMS320C28x MCU Workshop - Control Peripherals


Lab 7: Control Peripherals

Check your files list to make sure the file is there.

14. In Main_7.c, add code to call the InitECap() function. There are no passed
parameters or return values, so the call code is simply:
InitECap();

15. Edit Gpio.c and adjust the shared I/O pin in GPIO5 for the ECAP1 function.

16. Open and inspect the eCAP1 interrupt service routine (ECAP1_INT_ISR) in the file
DefaultIsr_7.c. Notice that PwmDuty is calculated by CAP2 – CAP1 (rising to
falling edge) and that PwmPeriod is calculated by CAP3 – CAP1 (rising to rising edge).

17. In ECap_7_8_9_10_12.c, setup eCAP1 to calculate PWM_duty and PWM_period.


The following registers need to be modified: ECCTL2 (continuous mode, re-arm disable,
and sync disable), ECCTL1 (set prescale to divide-by-1, configure capture event polarity
without reseting the counter), and ECEINT (enable desired eCAP interrupt).

18. Using the “PIE Interrupt Assignment Table” find the location for the
eCAP1 interrupt “ECAP1_INT” and fill in the following information:

PIE group #: # within group:

This information will be used in the next step.

19. Modify the end of ECap_7_8_9_10_12.c to do the following:


- Enable the “ECAP1_INT” interrupt in the PIE (Hint: use the PieCtrlRegs structure)
- Enable the appropriate core interrupt in the IER register

Build and Load


20. Save all changes to the files and click the “Build” button.

Run the Code – Pulse Width Measurement


21. Open a memory window to view the address label PwmPeriod. (Type &PwmPeriod in
the address box). The address label PwmDuty (address &PwmDuty) should appear in the
same memory window.

22. Set the memory window properties format to “32-Bit UnSigned Int”. Click OK.

23. Using the connector wire provided, connect the PWM1A (pin # P8-9) to ECAP1 (pin #
P8-14) on the eZdsp™.

24. Run the code (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset. Notice the values for
PwmDuty and PwmPeriod.

25. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

TMS320C28x MCU Workshop - Control Peripherals 7 - 41


Lab 7: Control Peripherals

Questions:
• How do the captured values for PwmDuty and PwmPeriod relate to the compare register
CMPA and time-base period TBPRD settings for ePWM1A?
• What is the value of PwmDuty in memory?
• What is the value of PwmPeriod in memory?
• How does it compare with the expected value?

End of Exercise

7 - 42 TMS320C28x MCU Workshop - Control Peripherals


Numerical Concepts

Introduction
In this module, numerical concepts will be explored. One of the first considerations concerns
multiplication – how does the user store the results of a multiplication, when the process of mul-
tiplication creates results larger than the inputs. A similar concern arises when considering accu-
mulation – especially when long summations are performed. Next, floating-point concepts will
be explored and IQmath will be described as a technique for implementing a “virtual floating-
point” system to simplify the design process.

The IQmath Library is a collection of highly optimized and high precision mathematical
functions used to seamlessly port floating-point algorithms into fixed-point code. These C/C++
routines are typically used in computationally intensive real-time applications where optimal
execution speed and high accuracy is needed. By using these routines a user can achieve
execution speeds considerable faster than equivalent code written in standard ANSI C language.
In addition, by incorporating the ready-to-use high precision functions, the IQmath library can
shorten significantly a DSP application development time. (The IQmath user's guide is included
in the application zip file, and can be found in the /docs folder once the file is extracted and
installed).

Learning Objectives
Learning Objectives

‹ Integers and Fractions


‹ IEEE-754 Floating-Point
‹ IQmath
‹ Format Conversion of ADC Results

TMS320C28x MCU Workshop - Numerical Concepts 8-1


Module Topics

Module Topics
Numerical Concepts .................................................................................................................................. 8-1

Module Topics......................................................................................................................................... 8-2


Numbering System Basics ....................................................................................................................... 8-3
Binary Numbers.................................................................................................................................. 8-3
Two's Complement Numbers ............................................................................................................. 8-3
Integer Basics ..................................................................................................................................... 8-4
Sign Extension Mode.......................................................................................................................... 8-5
Binary Multiplication.............................................................................................................................. 8-6
Binary Fractions ..................................................................................................................................... 8-8
Representing Fractions in Binary ....................................................................................................... 8-8
Fraction Basics ................................................................................................................................... 8-8
Multiplying Binary Fractions ............................................................................................................. 8-9
Fraction Coding.....................................................................................................................................8-11
Fractional vs. Integer Representation....................................................................................................8-12
Floating-Point........................................................................................................................................8-13
IQmath ...................................................................................................................................................8-16
IQ Fractional Representation.............................................................................................................8-16
Traditional “Q” Math Approach........................................................................................................8-17
IQmath Approach ..............................................................................................................................8-19
IQmath Library ......................................................................................................................................8-24
Converting ADC Results into IQ Format...............................................................................................8-26
AC Induction Motor Example ................................................................................................................8-28
IQmath Summary ...................................................................................................................................8-34
Lab 8: IQmath & Floating-Point FIR Filter..........................................................................................8-35

8-2 TMS320C28x MCU Workshop - Numerical Concepts


Numbering System Basics

Numbering System Basics


Given the ability to perform arithmetic processes (addition and multiplication) with the C28x, it is
important to understand the underlying mathematical issues which come into play. Therefore, we
shall examine the numerical concepts which apply to the C28x and, to a large degree, most
processors.

Binary Numbers
The binary numbering system is the simplest numbering scheme used in computers, and is the
basis for other schemes. Some details about this system are:
• It uses only two values: 1 and 0
• Each binary digit, commonly referred to as a bit, is one “place” in a binary number
and represents an increasing power of 2.
• The least significant bit (LSB) is to the right and has the value of 1.
• Values are represented by setting the appropriate 1's in the binary number.
• The number of bits used determines how large a number may be represented.

Examples:
01102 = (0 * 8) + (1 * 4) + (1 * 2) + (0 * 1) = 610
111102 = (1 * 16) + (1 * 8) + (1 * 4) + (1 * 2) + (0 * 1) = 3010

Two's Complement Numbers


Notice that binary numbers can only represent positive numbers. Often it is desirable to be able to
represent both positive and negative numbers. The two's complement numbering system modifies
the binary system to include negative numbers by making the most significant bit (MSB)
negative. Thus, two's complement numbers:
• Follow the binary progression of simple binary except that the MSB is negative — in
addition to its magnitude
• Can have any number of bits — more bits allow larger numbers to be represented

Examples:
01102 = (0 * -8) + (1 * 4) + (1 * 2) + (0 * 1) = 610
111102 = (1 * -16) + (1 * 8) + (1 * 4) + (1 * 2) + (0 * 1) = -210

The same binary values are used in these examples for two's complement as were used above for
binary. Notice that the decimal value is the same when the MSB is 0, but the decimal value is
quite different when the MSB is 1.

Two operations are useful in working with two's complement numbers:


• The ability to obtain an additive inverse of a value
• The ability to load small numbers into larger registers (by sign extending)

TMS320C28x MCU Workshop - Numerical Concepts 8-3


Numbering System Basics

To load small two's complement numbers into larger


registers:
The MSB of the original number must carry to the MSB of the number when represented in the
larger register.
1. Load the small number “right justified” into the larger register.
2. Copy the sign bit (the MSB) of the original number to all unfilled bits to the left in the
register (sign extension).

Consider our two previous values, copied into an 8-bit register:

Examples:
Original No. 0 1 1 02 = 610 1 1 1 1 02 = -210

1. Load low 0110 11110

2. Sign Extend 00000110 =4+2=6 11111110 = -128 + 64 + ... + 2 = -2

Integer Basics
Integer Basics

±±2n-1 2233 2222 2211 2200


2n-1

‹ Unsigned Binary Integers


0100b = (0*23)+(1*22)+(0*22)+(0*20) = 4
1101b = (1*23)+(1*22)+(0*21)+(1*20) = 13

‹ Signed Binary Integers (2’s Complement)


0100b = (0*-23)+(1*22)+(0*22)+(0*20) = 4
1101b = (1*-23)+(1*22)+(0*21)+(1*2 0) = -3

8-4 TMS320C28x MCU Workshop - Numerical Concepts


Numbering System Basics

Sign Extension Mode


The C28x can operate on either unsigned binary or two's complement operands. The “Sign
Extension Mode” (SXM) bit, present within a status register of the C28x, identifies whether or
not the sign extension process is used when a value is brought into the accumulator. It is good
programming practice to always select the desired SXM at the beginning of a module to assure
the proper mode.

What is Sign Extension?


‹ When moving a value from a narrowed width location
to a wider width location, the sign bit is extended to fill
the width of the destination
‹ Sign extension applies to signed numbers only
‹ It keeps negative numbers negative!
‹ Sign extension controlled by SXM bit in ST0 register;
When SXM = 1, sign extension happens automatically

4 bit Example: Load a memory value into the ACC


memory 1101 = -23 + 22 + 20 = -3
Load and sign extend

ACC 1111 1101 = -27 + 26 + 25 + 24 + 23 + 22 + 20


= -128 + 64 + 32 + 16 + 8 + 4 + 1
= -3

TMS320C28x MCU Workshop - Numerical Concepts 8-5


Binary Multiplication

Binary Multiplication
Now that you understand two's complement numbers, consider the process of multiplying two
two's complement values. As with “long hand” decimal multiplication, we can perform binary
multiplication one “place” at a time, and sum the results together at the end to obtain the total
product.

Note: This is not the method the C28x uses in multiplying numbers — it is merely a way of observing
how binary numbers work in arithmetic processes.

The C28x uses 16-bit operands and a 32-bit accumulator. For the sake of clarity, consider the
example below where we shall investigate the use of 4-bit values and an 8-bit accumulation:

Integer Multiplication (signed)


0100 4
x 1101 x -3
00000100
0000000
000100
11100
11110100 -12
Accumulator 11110100
11110100
Data Memory ?

In this example, consider the following:


• What are the two input values, and the expected result?
• Why are the “partial products” shifted left as the calculation continues?
• Why is the final partial product “different” than the others?
• What is the result obtained when adding the partial products?
• How shall this result be loaded into the accumulator?
• How shall we fill the remaining bit? Is this value still the expected one?
• How can the result be stored back to memory? What problems arise?

8-6 TMS320C28x MCU Workshop - Numerical Concepts


Binary Multiplication

Note: With two’s complement multiplication, the leading “1” in the second multiplicand is a
sign bit. If the sign bit is “1”, then take the 2’s complement of the first multiplicand.
Additionally, each partial product must be sign-extended for correct computation.

Note: All of the above questions except the final one are addressed in this module. The last
question may have several answers:

• Store the lower accumulator to memory. What problem is apparent using this
method in this example?
• Store the upper accumulator back to memory. Wouldn't this create a loss of
precision, and a problem in how to interpret the results later?
• Store both the upper and lower accumulator to memory. This solves the above
problems, but creates some new ones:
− Extra code space, memory space, and cycle time are used
− How can the result be used as the input to a subsequent calculation? Is such a
condition likely (consider any “feedback” system)?

From this analysis, it is clear that integers do not behave well when multiplied. Might some other
type of number system behave better? Is there a number system where the results of a
multiplication are bounded?

TMS320C28x MCU Workshop - Numerical Concepts 8-7


Binary Fractions

Binary Fractions
Given the problems associated with integers and multiplication, consider the possibilities of using
fractional values. Fractions do not grow when multiplied, therefore, they remain representable
within a given word size and solve the problem. Given the benefit of fractional multiplication,
consider the issues involved with using fractions:
• How are fractions represented in two's complement?
• What issues are involved when multiplying two fractions?

Representing Fractions in Binary


In order to represent both positive and negative values, the two's complement process will again
be used. However, in the case of fractions, we will not set the LSB to 1 (as was the case for
integers). When one considers that the range of fractions is from -1 to ~+1, and that the only bit
which conveys negative information is the MSB, it seems that the MSB must be the “negative
ones position.” Since binary representation is based on powers of two, it follows that the next bit
would be the “one-halves” position, and that each following bit would have half the magnitude
again. Considering, as before, a 4-bit model, we have the representation shown in the following
example.

1 . 0 1 1 = -1 + 1/4 + 1/8 = -5/8

-1 1/2 1/4 1/8

Fraction Basics
Fraction Basics

-2 0 22-1-1 22-2-2 22-3-3 22-(n-1)


-20 -(n-1)


1101b = (1*-20)+(1*2-1)+(0*2-2)+(1*2-3)
= -1 + 1/2 + 1/8
= -3/8

Fractions have the nice property that


fraction x fraction = fraction

8-8 TMS320C28x MCU Workshop - Numerical Concepts


Binary Fractions

Multiplying Binary Fractions


When the C28x performs multiplication, the process is identical for all operands, integers or
fractions. Therefore, the user must determine how to interpret the results. As before, consider the
4-bit multiply example:

Fraction Multiplication
0100
. 1/2
x 1101
. x -3/8
00000100
0000000
000100
11100
11110100 -3/16
Accumulator 11110100
11110100

Data Memory 1110


. -1/4

As before, consider the following:


• What are the two input values and the expected result?
• As before, “partial products” are shifted left and the final is negative.
• How is the result (obtained when adding the partial products) read?
• How shall this result be loaded into the accumulator?
• How shall we fill the remaining bit? Is this value still the expected one?
• How can the result be stored back to memory? What problems arise?

To “read” the results of the fractional multiply, it is necessary to locate the binary point (the base
2 equivalent of the base 10 decimal point). Start by identifying the location of the binary point in
the input values. The MSB is an integer and the next bit is 1/2, therefore, the binary point would
be located between them. In our example, therefore, we would have three bits to the right of the
binary point in each input value. For ease of description, we can refer to these as “Q3” numbers,
where Q refers to the number of places to the right of the point.

When multiplying numbers, the Q values add. Thus, we would (mentally) place a binary point
above the sixth LSB. We can now calculate the “Q6” result more readily.

TMS320C28x MCU Workshop - Numerical Concepts 8-9


Binary Fractions

As with integers, the results are loaded low and the MSB is a sign extension of the seventh bit. If
this value were loaded into the accumulator, we could store the results back to memory in a
variety of ways:
• Store both low and high accumulator values back to memory. This offers maximum
detail, but has the same problems as with integer multiply.
• Store only the high (or low) accumulator back to memory. This creates a potential for
a memory littered with varying Q-types.
• Store the upper accumulator shifted to the left by 1. This would store values back to
memory in the same Q format as the input values, and with equal precision to the
inputs. How shall the left shift be performed? Here’s three methods:
− Explicit shift (C or assembly code)
− Shift on store (assembly code)
− Use Product Mode shifter (assembly code)

8 - 10 TMS320C28x MCU Workshop - Numerical Concepts


Fraction Coding

Fraction Coding
Although COFF tools recognize values in integer, hex, binary, and other forms, they understand
only integer, or non-fractional values. To use fractions within the C28x, it is necessary to describe
them as though they were integers. This turns out to be a very simple trick. Consider the
following number lines:

Coding Traditional 16-bit Q15 Fractions


~1 32767 0x7FFF

½ 16384 0x4000

0
⇒ 0 0x0000
∗ 32768
-½ -16384 0xC000
(215)
-1 -32768 0x8000
Fraction Integer

‹ C-code example: y = 0.707 * x


void main(void)
{
int16 coef = 32768*707/1000; // 0.707 in Q15
int16 x, y;
y = (int16)( (int32)coef * (int32)x ) >> 15);
}

By multiplying a fraction by 32K (32768), a normalized fraction is created, which can be passed
through the COFF tools as an integer. Once in the C28x, the normalized fraction looks and
behaves exactly as a fraction. Thus, when using fractional constants in a C28x program, the coder
first multiplies the fraction by 32768, and uses the resulting integer (rounded to the nearest whole
value) to represent the fraction.

The following is a simple, but effective method for getting fractions past the assembler:
1. Express the fraction as a decimal number (drop the decimal point).
2. Multiply by 32768.
3. Divide by the proper multiple of 10 to restore the decimal position.

¾ Examples:
• To represent 0.62: 32768 x 62 / 100
• To represent 0.1405: 32768 x 1405 / 10000

This method produces a valid number accurate to 16 bits. You will not need to do the math
yourself, and changing values in your code becomes rather simple.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 11


Fractional vs. Integer Representation

Fractional vs. Integer Representation


Integer vs. Fractions
Range Precision
Integer determined 1
by # of bits
Fraction ~+1 to -1 determined
by # of bits

‹ Integers grow when you multiply them


‹ Fractions have limited range
Š Fractions can still grow when you add them
Š Scaling an application is time consuming

Are there any other alternatives?

The C28x accumulator, a 32-bit register, adds extra range to integer calculations, but this
becomes a problem in storing the results back to 16-bit memory.

Conversely, when using fractions, the extra accumulator bits increase precision, which helps
minimize accumulative errors. Since any number is accurate (at best) to ± one-half of a LSB,
summing two of these values together would yield a worst case result of 1 LSB error. Four
summations produce two LSBs of error. By 256 summations, eight LSBs are “noisy.” Since the
accumulator holds 32 bits of information, and fractional results are stored from the high
accumulator, the extra range of the accumulator is a major benefit in noise reduction for long
sum-of-products type calculations.

8 - 12 TMS320C28x MCU Workshop - Numerical Concepts


Floating-Point

Floating-Point
IEEE-754 Single Precision Floating-Point
31 30 23 22 0
s eeeeeeee fffffffffffffffffffffff
1 bit sign 8 bit exponent 23 bit mantissa (fraction)

Case 1: if e = 255 and f ≠ 0, then v = NaN


Case 2: if e = 255 and f = 0, then v = [(-1)s]*infinity
Normalized Case 3: if 0 < e < 255, then v = [(-1)s]*[2(e- 127)]*(1.f)
values Case 4: if e = 0 and f ≠ 0, then v = [(-1)s]*[2(-1 26)]*(0.f)
Case 5: if e = 0 and f = 0, then v = [(-1)s]*0

Example: 0x41200000 = 0 100 0001 0 010 0000 0000 ... 0000 b


s e = 130 f = 2-2 = 0.25

⇒ Case 3 v = (-10)*2(130-1 27)*1.25 = 10.0

Advantage ⇒ Exponent gives large dynamic range


Disadvantage ⇒ Precision of a number depends on its exponent

Number Line Insight

Floating-Point:

+∞ 0 -∞

‹ Non-uniform distribution
Š Precision greatest near zero
Š Less precision the further you get from zero

TMS320C28x MCU Workshop - Numerical Concepts 8 - 13


Floating-Point

Using Floating-Point
1) Should be using a C28x
device with hardware
floating-point support!
2) Add the floating-point RTS
library(s) to the CCS project
Š standard RTS lib (required)
Š rts2800_fpu32.lib
Š comes with compiler
Š fast RTS lib (optional)
Š C28x_FPU_FastRTS.lib
Š on TI web, #SPRC664
Š improved performance
Š Strongly Recommended
3) Select ‘fpu32’ support in
CCS project options

Getting the ADC Result into


Floating-Point Format
AdcMirror.
000 0x xxx xx xxx xx xxx xx
ADCRESULTx
ASM: C:
I16TOF32 (float)
31 15 0
s e e e e e e e e f f f f f f f f f f f f f f f f f f f f f f f 32-bit float

#define AdcFsVoltage float(3.0) // ADC full scale voltage


float Result; // ADC result
void main(void)
{
// Convert unsigned 16-bit result to 32-bit float. Gives value of 0 to 4095.
// Scale result by 1/4096. Gives value of 0 to ~1.
// Scale result by AdcFsVoltage. Gives value of 0 to ~3.0.
Result = (AdcFsVoltage/4096.0)*(float)AdcMirror.ADCRESULT0;
}

Compiler will pre-compute at build-time.


No runtime division!

8 - 14 TMS320C28x MCU Workshop - Numerical Concepts


Floating-Point

Floating-Point Pros and Cons

‹ Advantages
Š Easy to write code
Š No scaling required
‹ Disadvantages
Š Somewhat higher device cost
Š May offer insufficient precision for some
calculations due to 23 bit mantissa and
the influence of the exponent

What if you don’t have the luxury of


using a floating-point C28x device?

TMS320C28x MCU Workshop - Numerical Concepts 8 - 15


IQmath

IQmath
Implementing complex digital control algorithms on a Digital Signal Processor (DSP), or any
other DSP capable processor, typically come across the following issues:
• Algorithms are typically developed using floating-point math
• Floating-point devices are more expensive than fixed-point devices
• Converting floating-point algorithms to a fixed-point device is very time consuming
• Conversion process is one way and therefore backward simulation is not always possible

The design may initially start with a simulation (i.e. MatLab) of a control algorithm, which
typically would be written in floating-point math (C or C++). This algorithm can be easily ported
to a floating-point device, however because of cost reasons most likely a 16-bit or 32-bit fixed-
point device would be used in many target systems.

The effort and skill involved in converting a floating-point algorithm to function using a 16-bit or
32-bit fixed-point device is quite significant. A great deal of time (many days or weeks) would
be needed for reformatting, scaling and coding the problem. Additionally, the final
implementation typically has little resemblance to the original algorithm. Debugging is not an
easy task and the code is not easy to maintain or document.

IQ Fractional Representation
A new approach to fixed-point algorithm development, termed “IQmath”, can greatly simplify the
design development task. This approach can also be termed “virtual floating-point” since it looks
like floating-point, but it is implemented using fixed-point techniques.

IQ Fractional Representation

31 0
S IIIIIIII fffffffffffffffffffffff
32 bit mantissa

.
-2I + 2I-1 + … + 21 + 20 2-1 + 2-2 + … + 2-Q

I8Q24 Example: 0x41200000


= 0100 0001 . 0010 0000 0000 0000 0000 0000 b
= 26 + 20 + 2 -3 = 65.125

Advantage ⇒ Precision same for all numbers in an IQ format


Disadvantage ⇒ Limited dynamic range compared to floating-point

8 - 16 TMS320C28x MCU Workshop - Numerical Concepts


IQmath

The IQmath approach enables the seamless portability of code between fixed and floating-point
devices. This approach is applicable to many problems that do not require a large dynamic range,
such as motor or digital control applications.

Number Line Insight


Distributions

Floating-Point: non-uniform distribution (variable precision)

+∞ 0 -∞

IQ Fractions: uniform distribution (same precision everywhere)

+∞ 0 -∞

‹ Both floating-point and IQ formats have 232


possible values on the number line
‹ It’s how each distributes these values that differs

Traditional “Q” Math Approach


Traditional 32-bit “Q” Math Approach
y = mx + b

I8 Q24 M
I16 Q48
I8 Q24 X
ssssssssssssssssssI8 Q24 I8 Q24 B
Align Decimal
<< 24 Point for Add
ssssI8 Q48

I16 Q48

Align Decimal
>> 24 Point for Store
sssssssssssssssssI16 Q24 I8 Q24 Y

in C: Y = ((int64) M * (int64) X + (int64) B << Q) >> Q;


Note: Requires support for 64-bit integer data type in compiler

TMS320C28x MCU Workshop - Numerical Concepts 8 - 17


IQmath

The traditional approach to performing math operations, using fixed-point numerical techniques
can be demonstrated using a simple linear equation example. The floating-point code for a linear
equation would be:
float Y, M, X, B;
Y = M * X + B;

For the fixed-point implementation, assume all data is 32-bits, and that the "Q" value, or location
of the binary point, is set to 24 fractional bits (Q24). The numerical range and resolution for a
32-bit Q24 number is as follows:

Q value Min Value Max Value Resolution


(32-24) (32-24)
Q24 -2 = -128.000 000 00 2 – (½)24 = 127.999 999 94 24
(½) = 0.000 000 06

The C code implementation of the linear equation is:

int32 Y, M, X, B; // numbers are all Q24


Y = ((int64) M * (int64) X + (int64) B << 24) >> 24;

Compared to the floating-point representation, it looks quite cumbersome and has little resem-
blance to the floating-point equation. It is obvious why programmers prefer using floating-point
math.

The slide shows the implementation of the equation on a processor containing hardware that can
perform a 32x32 bit multiplication, 64-bit addition and 64-bit shifts (logical and arithmetic) effi-
ciently.

The basic approach in traditional fixed-point "Q" math is to align the binary point of the operands
that get added to or subtracted from the multiplication result. As shown in the slide, the multipli-
cation of M and X (two Q24 numbers) results in a Q48 value that is stored in a 64-bit register.
The value B (Q24) needs to be scaled to a Q48 number before addition to the M*X value (low
order bits zero filled, high order bits sign extended). The final result is then scaled back to a Q24
number (arithmetic shift right) before storing into Y (Q24). Many programmers may be familiar
with 16-bit fixed-point "Q" math that is in common use. The same example using 16-bit numbers
with 15 fractional bits (Q15) would be coded as follows:

int16 Y, M, X, B; // numbers are all Q15


Y = ((int32) M * (int32) X + (int32) B << 15) >> 15;

In both cases, the principal methodology is the same. The binary point of the operands that get
added to or subtracted from the multiplication result must be aligned.

8 - 18 TMS320C28x MCU Workshop - Numerical Concepts


IQmath

IQmath Approach
32-bit IQmath Approach
y = mx + b

I8 Q24 M
I16 Q48
I8 Q24 X
Align Decimal
Point Of Multiply
>> 24
sssssssssssssssssI16 Q24

I8 Q24 B

I8 Q24 I8 Q24 Y

in C: Y = ((int64) M * (int64) X) >> Q + B;

In the "IQmath" approach, rather then scaling the operands, which get added to or subtracted
from the multiplication result, we do the reverse. The multiplication result binary point is scaled
back such that it aligns to the operands, which are added to or subtracted from it. The C code
implementation of this is given by linear equation below:

int32 Y, M, X, B;
Y = ((int64) M * (int64) X) >> 24 + B;

The slide shows the implementation of the equation on a processor containing hardware that can
perform a 32x32 bit multiply, 32-bit addition/subtraction and 64-bit logical and arithmetic shifts
efficiently.

The key advantage of this approach is shown by what can then be done with the C and C++ com-
piler to simplify the coding of the linear equation example.

Let’s take an additional step and create a multiply function in C that performs the following op-
eration:

int32 _IQ24mpy(int32 M, int32 X) { return ((int64) M * (int64) X) >> 24; }

The linear equation can then be written as follows:

Y = _IQ24mpy(M , X) + B;

Already we can see a marked improvement in the readability of the linear equation.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 19


IQmath

Using the operator overloading features of C++, we can overload the multiplication operand "*"
such that when a particular data type is encountered, it will automatically implement the scaled
multiply operation. Let’s define a data type called "iq" and assign the linear variables to this data
type:

iq Y, M, X, B // numbers are all Q24

The overloading of the multiply operand in C++ can be defined as follows:

iq operator*(const iq &M, const iq &X){return((int64)M*(int64) X) >> 24;}

Then the linear equation, in C++, becomes:

Y = M * X + B;

This final equation looks identical to the floating-point representation. It looks "natural". The
four approaches are summarized in the table below:

Math Implementations Linear Equation Code


32-bit floating-point math in C Y = M * X + B;
32-bit fixed-point "Q" math in C Y = ((int64) M * (int64) X) + (int64) B << 24) >> 24;
32-bit IQmath in C Y = _IQ24mpy(M, X) + B;
32-bit IQmath in C++ Y = M * X + B;

Essentially, the mathematical approach of scaling the multiplier operand enables a cleaner and a
more "natural" approach to coding fixed-point problems. For want of a better term, we call this
approach "IQmath" or can also be described as "virtual floating-point".

8 - 20 TMS320C28x MCU Workshop - Numerical Concepts


IQmath

IQmath Approach
Multiply Operation

Y = ((i64) M * (i64) X) >> Q + B;

Redefine the multiply operation as follows:


_IQmpy(M,X) == ((i64) M * (i64) X) >> Q

This simplifies the equation as follows:


Y = _IQmpy(M,X) + B;

C28x compiler supports “_IQmpy” intrinsic; assembly code generated:


MOVL XT,@M
IMPYL P,XT,@X ; P = low 32-bits of M*X
QMPYL ACC,XT,@X ; ACC = high 32-bits of M*X
LSL64 ACC:P,#(32-Q) ; ACC = ACC:P << 32-Q
; (same as P = ACC:P >> Q)
ADDL ACC,@B ; Add B
MOVL @Y,ACC ; Result = Y = _IQmpy(M*X) + B
; 7 Cycles

IQmath Approach
It looks like floating-point!

float Y, M, X, B;
Floating-Point
Y = M * X + B;

long Y, M, X, B;
Traditional
Fix-Point Q Y = ((i64) M * (i64) X + (i64) B << Q)) >> Q;

“IQmath” _iq Y, M, X, B;

In C Y = _IQmpy(M, X) + B;

“IQmath” iq Y, M, X, B;

In C++ Y = M * X + B;

“IQmath” code is easy to read!

TMS320C28x MCU Workshop - Numerical Concepts 8 - 21


IQmath

IQmath Approach
GLOBAL_Q simplification
User selects “Global Q” value for the whole application
GLOBAL_Q
based on the required dynamic range or resolution, for example:
GLOBAL_Q Max Val Min Val Resolution
28 7.999 999 996 -8.000 000 000 0.000 000 004
24 127.999 999 94 -128.000 000 00 0.000 000 06
20 2047.999 999 -2048.000 000 0.000 001

#define GLOBAL_Q 18 // set in “IQmathLib.h” file


_iq Y, M, X, B;
Y = _IQmpy(M,X) + B; // all values are in Q = 18

The user can also explicitly specify the Q value to use:


_iq20 Y, M, X, B;
Y = _IQ20mpy(M,X) + B; // all values are in Q = 20

The basic "IQmath" approach was adopted in the creation of a standard math library for the Texas
Instruments TMS320C28x DSP fixed-point processor. This processor contains efficient hardware
for performing 32x32 bit multiply, 64-bit shifts (logical and arithmetic) and 32-bit add/subtract
operations, which are ideally suited for 32 bit "IQmath".

Some enhancements were made to the basic "IQmath" approach to improve flexibility. They are:

Setting of GLOBAL_Q Parameter Value: Depending on the application, the amount of numerical
resolution or dynamic range required may vary. In the linear equation example, we used a Q
value of 24 (Q24). There is no reason why any value of Q can't be used. In the "IQmath" library,
the user can set a GLOBAL_Q parameter, with a range of 1 to 30 (Q1 to Q30). All functions
used in the program will use this GLOBAL_Q value. For example:

#define GLOBAL_Q 18
Y = _IQmpy(M, X) + B; // all values use GLOBAL_Q = 18

If, for some reason a particular function or equation requires a different resolution, then the user
has the option to implicitly specify the Q value for the operation. For example:

Y = _IQ23mpy(M,X) + B; // all values use Q23, including B and Y

The Q value must be consistent for all expressions in the same line of code.

8 - 22 TMS320C28x MCU Workshop - Numerical Concepts


IQmath

IQmath Provides Compatibility Between


Floating-Point and Fixed-Point
1) Develop any mathematical function
Y = _IQmpy(M, X) + B;

2) Select math type in IQmathLib.h


#if MATH_TYPE == IQ_MATH #if MATH_TYPE == FLOAT_MATH

3) Compiler automatically converts to:


Y = (float)M * (float)X + (float)B;

Fixed-Point Floating-Point
Math Code Math Code
Compile & Run Compile & Run
on Fixed-Point on Floating-Point
F282xx F283xx *

All “IQmath” operations have an equivalent floating-point operation

* Can also compile floating-point code on any floating-point compiler (e.g., PC, Matlab, fixed-point w/ RTS lib, etc.)

Selecting FLOAT_MATH or IQ_MATH Mode: As was highlighted in the introduction, we would


ideally like to be able to have a single source code that can execute on a floating-point or fixed-
point target device simply by recompiling the code. The "IQmath" library supports this by setting
a mode, which selects either IQ_MATH or FLOAT_MATH. This operation is performed by
simply redefining the function in a header file. For example:

#if MATH_TYPE == IQ_MATH


#define _IQmpy(M , X) _IQmpy(M , X)
#elseif MATH_TYPE == FLOAT_MATH
#define _IQmpy(M , X) (float) M * (float) X
#endif

Essentially, the programmer writes the code using the "IQmath" library functions and the code
can be compiled for floating-point or "IQmath" operations.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 23


IQmath Library

IQmath Library
IQmath Library: Math & Trig Functions
Operation Floating-Point “IQmath” in C “IQmath” in C++
type float A, B; _iq A, B; iq A, B;
constant A = 1.2345 A = _IQ(1.2345) A = IQ(1.2345)
multiply A* B _IQmpy(A , B) A*B
divide A/ B _IQdiv (A , B) A/ B
add A+B A +B A+ B
substract A-B A- B A–B
boolean >, >=, <, <=, ==, |=, &&, || >, >=, <, <=, ==, |=, &&, || >, >=, <, <=, ==, |=, &&, ||
trig sin(A),cos(A) _IQsin(A), _IQcos(A) IQsin(A),IQcos(A)
and sin(A*2pi),cos(A*2pi) _IQsinPU(A), _IQcosPU(A) IQsinPU(A),IQcosPU(A)
power asin(A),acos(A) _IQasin(A),_IQacos(A) IQasin(A),IQacos(A)
functions atan(A),atan2(A,B) _IQatan(A), _IQatan2(A,B) IQatan(A),IQatan2(A,B)
atan2(A,B)/2pi _IQatan2PU(A,B) IQatan2PU(A,B)
sqrt(A),1/sqrt(A) _IQsqrt(A), _IQisqrt(A) IQsqrt(A),IQisqrt(A)
sqrt(A*A + B*B) _IQmag(A,B) IQmag(A,B)
exp(A) _IQexp(A) IQexp(A)
saturation if(A > Pos) A = Pos _IQsat(A,Pos,Neg) IQsat(A,Pos,Neg)
if(A < Neg) A = Neg

Accuracy of functions/operations approx ~28 to ~31 bits

Additionally, the "IQmath" library contains DSP library modules for filters (FIR & IIR) and Fast
Fourier Transforms (FFT & IFFT).

IQmath Library: Conversion Functions

Operation Floating-Point “IQmath” in C “IQmath” in C++


iq to iqN A _IQtoIQN(A) IQtoIQN(A)
iqN to iq A _IQNtoIQ(A) IQNtoIQ(A)
integer(iq) (long) A _IQint(A) IQint(A)
fraction(iq) A – (long) A _IQfrac(A) IQfrac(A)
iq = iq*long A * (float) B _IQmpyI32(A,B) IQmpyI32(A,B)
integer(iq*long) (long) (A * (float) B) _IQmpyI32int(A,B) IQmpyI32int(A,B)
fraction(iq*long) A - (long) (A * (float) B) _IQmpyI32frac(A,B) IQmpyI32frac(A,B)
qN to iq A _QNtoIQ(A) QNtoIQ(A)
iq to qN A _IQtoQN(A) IQtoQN(A)
string to iq atof(char) _atoIQ(char) atoIQ(char)
IQ to float A _IQtoF(A) IQtoF(A)
IQ to ASCII sprintf(A,B,C) _IQtoA(A,B,C) IQtoA(A,B,C)

IQmath.lib > contains library of math functions


IQmathLib.h > C header file
IQmathCPP.h > C++ header file

8 - 24 TMS320C28x MCU Workshop - Numerical Concepts


IQmath Library

16 vs. 32 Bits
The "IQmath" approach could also be used on 16-bit numbers and for many problems, this is suf-
ficient resolution. However, in many control cases, the user needs to use many different "Q" val-
ues to accommodate the limited resolution of a 16-bit number.

With DSP devices like the TMS320C28x processor, which can perform 16-bit and 32-bit math
with equal efficiency, the choice becomes more of productivity (time to market). Why bother
spending a whole lot of time trying to code using 16-bit numbers when you can simply use 32-bit
numbers, pick one value of "Q" that will accommodate all cases and not worry about spending
too much time optimizing.

Of course there is a concern on data RAM usage if numbers that could be represented in 16 bits
all use 32 bits. This is becoming less of an issue in today's processors because of the finer tech-
nology used and the amount of RAM that can be cheaply integrated. However, in many cases,
this problem can be mitigated by performing intermediate calculations using 32-bit numbers and
converting the input from 16 to 32 bits and converting the output back to 16 bits before storing
the final results. In many problems, it is the intermediate calculations that require additional ac-
curacy to avoid quantization problems.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 25


Converting ADC Results into IQ Format

Converting ADC Results into IQ Format


Getting the ADC Result into IQ Format
AdcMirror.
0 00 0xx xx xxx xx xxx xx xx
ADCRESULTx
Do not sign extend
31 15 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x x x x x x x x x x x x 32-bit long

Notice that the 32-bit long is already in IQ12 format


#define AdcFsVoltage _IQ(3.0) // ADC full scale voltage
_iq Result, temp; // ADC result
void main(void)
{
// convert the unsigned 16-bit result to unsigned 32-bit
// temp = AdcMirror.ADCRESULT0;
// convert resulting IQ12 to Global IQ format
// temp = _IQ12toIQ(temp);
// scale by ADC full-scale range (optional)
// Result = _IQmpy(AdcFsVoltage, temp);
Result = _IQmpy(AdcFsVoltage, _IQ12toIQ( (_iq)AdcMirror.ADCRESULT0));
}

As you may recall, the converted values of the ADC can be placed in the upper 12 bit of the
RESULT0 register (when not using AdcMirror register). Before these values are filtered using
the IQmath library, they need to to be put into the IQ format as a 32-bit long. For uni-polar ADC
inputs (i.e., 0 to 3 V inputs), a conversion to global IQ format can be achieved with:

IQresult_unipolar = _IQmpy(_IQ(3.0),_IQ12toIQ((_iq) AdcRegs.ADCRESULT0));

How can we modify the above to recover bi-polar inputs, for example +-1.5 volts? One could do
the following to offset the +1.5V analog biasing applied to the ADC input:

IQresult_bipolar =
_IQmpy(_IQ(3.0),_IQ12toIQ((_iq) AdcRegs.ADCRESULT0)) - _IQ(1.5);

However, one can see that the largest intermediate value the equation above could reach is 3.0.
This means that it cannot be used with an IQ data type of IQ30 (IQ30 range is -2 < x < ~2). Since
the IQmath library supports IQ types from IQ1 to IQ30, this could be an issue in some applica-
tions.

The following clever approach supports IQ types from IQ1 to IQ30:

IQresult_bipolar =
_IQmpy(_IQ(1.5),_IQ15toIQ((_iq) ((int16) (AdcRegs.ADCRESULT0 ^ 0x8000))));

The largest intermediate value that this equation could reach is 1.5. Therefore, IQ30 is easily
supported.

8 - 26 TMS320C28x MCU Workshop - Numerical Concepts


Converting ADC Results into IQ Format

Can a Single ADC Interface Code Line be


Written for IQmath and Floating-Point?

#if MATH_TYPE == IQ_MATH


#define AdcFsVoltage _IQ(3.0) // ADC full scale voltage
#else // MATH_TYPE is FLOAT_MATH
#define AdcFsVoltage _IQ(3.0/4096.0) // ADC full scale voltage
#endif

_iq Result; // ADC result


void main(void)
{
Result = _IQmpy(AdcFsVoltage, _IQ12toIQ( (_iq)AdcMirror.ADCRESULT0));
}

FLOAT_MATH
behavior: * does float
nothing

TMS320C28x MCU Workshop - Numerical Concepts 8 - 27


AC Induction Motor Example

AC Induction Motor Example


AC Induction Motor Example
One of the more complex motor control algorithms

‹ Sensorless, ACI induction machine direct rotor flux control


‹ Goal: motor speed estimation & alpha-axis stator current estimation

The "IQmath" approach is ideally suited for applications where a large numerical dynamic range
is not required. Motor control is an example of such an application (audio and communication
algorithms are other applications). As an example, the IQmath approach has been applied to the
sensor-less direct field control of an AC induction motor. This is probably one of the most chal-
lenging motor control problems and as will be shown later, requires numerical accuracy greater
then 16-bits in the control calculations.

The above slide is a block diagram representation of the key control blocks and their interconnec-
tions. Essentially this system implements a "Forward Control" block for controlling the d-q axis
motor current using PID controllers and a "Feedback Control" block using back emf's integration
with compensated voltage from current model for estimating rotor flux based on current and volt-
age measurements. The motor speed is simply estimated from rotor flux differentiation and open-
loop slip computation. The system was initially implemented on a "Simulator Test Bench" which
uses a simulation of an "AC Induction Motor Model" in place of a real motor. Once working, the
system was then tested using a real motor on an appropriate hardware platform.

Each individual block shown in the slide exists as a stand-alone C/C++ module, which can be
interconnected to form the complete control system. This modular approach allows reusability
and portability of the code. The next few slides show the coding of one particular block, PARK
Transform, using floating-point and "IQmath" approaches in C:

8 - 28 TMS320C28x MCU Workshop - Numerical Concepts


AC Induction Motor Example

AC Induction Motor Example


Park Transform – floating-point C code

#include “math.h”

#define TWO_PI 6.28318530717959


void park_calc(PARK *v)
{
float cos_ang , sin_ang;
sin_ang = sin(TWO_PI * v->ang);
cos_ang = cos(TWO_PI * v->ang);

v->de = (v->ds * cos_ang) + (v->qs * sin_ang);


v->qe = (v->qs * cos_ang) - (v->ds * sin_ang);
}

AC Induction Motor Example


Park Transform - converting to “IQmath” C code

#include “math.h”
#include “IQmathLib.h”
#define TWO_PI _IQ(6.28318530717959)
6.28318530717959
void park_calc(PARK *v)
{
float cos_ang , sin_ang;
_iq
_IQsin(_IQmpy(TWO_PI
sin_ang = sin(TWO_PI * v->ang);, v->ang));
_IQcos(_IQmpy(TWO_PI
cos_ang = cos(TWO_PI * v->ang);, v->ang));

v->de = _IQmpy(v->ds , cos_ang)


(v->ds * cos_ang) + _IQmpy(v->qs
+ (v->qs * sin_ang); , sin_ang);
v->qe = _IQmpy(v->qs , cos_ang)
(v->qs * cos_ang) - _IQmpy(v->ds
- (v->ds * sin_ang); , sin_ang);
}

The complete system was coded using "IQmath". Based on analysis of coefficients in the system,
the largest coefficient had a value of 33.3333. This indicated that a minimum dynamic range of 7
bits (+/-64 range) was required. Therefore, this translated to a GLOBAL_Q value of 32-7 = 25
(Q25). Just to be safe, the initial simulation runs were conducted with GLOBAL_Q = 24 (Q24)

TMS320C28x MCU Workshop - Numerical Concepts 8 - 29


AC Induction Motor Example

value. The plots start from a step change in reference speed from 0.0 to 0.5 and 1024 samples are
taken.

AC Induction Motor Example


GLOBAL_Q = 24, system stable

IQmath: speed IQmath: current

Floating-Point: speed Floating-Point: current

The speed eventually settles to the desired reference value and the stator current exhibits a clean
and stable oscillation. The block diagram slide shows at which points in the control system the
plots are taken from.

What’s Happening Here?


Equal Precision in the Computation Region

Floating-Point:

+∞ 0 -∞

Same precision as I8Q24


I8Q24 Fractions:

+∞ 0 -∞

In the region where these particular computations occur, the


precision of single-precision floating-point just happens to equal
the precision of the I8Q24 format.
So, both produce similar results!

8 - 30 TMS320C28x MCU Workshop - Numerical Concepts


AC Induction Motor Example

AC Induction Motor Example


GLOBAL_Q = 27, system unstable

IQmath: speed

IQmath: current

AC Induction Motor Example


GLOBAL_Q = 16, system unstable

IQmath: speed

IQmath: current

TMS320C28x MCU Workshop - Numerical Concepts 8 - 31


AC Induction Motor Example

With the ability to select the GLOBAL_Q value for all calculations in the "IQmath", an experi-
ment was conducted to see what maximum and minimum Q value the system could tolerate be-
fore it became unstable. The results are tabulated in the slide below:

AC Induction Motor Example


Q stability range

Q range Stability Range


Unstable
Q31 to Q27 (not enough dynamic range)

Q26 to Q19 Stable

Q18 to Q0 Unstable
(not enough resolution, quantization problems)

The developer must pick the right GLOBAL_Q value!

The above indicates that, the AC induction motor system that we simulated requires a minimum
of 7 bits of dynamic range (+/-64) and requires a minimum of 19 bits of numerical resolution (+/-
0.000002). This confirms our initial analysis that the largest coefficient value being 33.33333
required a minimum dynamic range of 7 bits. As a general guideline, users using IQmath should
examine the largest coefficient used in the equations and this would be a good starting point for
setting the initial GLOBAL_Q value. Then, through simulation or experimentation, the user can
reduce the GLOBAL_Q until the system resolution starts to cause instability or performance deg-
radation. The user then has a maximum and minimum limit and a safe approach is to pick a mid-
point.

What the above analysis also confirms is that this particular problem does require some calcula-
tions to be performed using greater then 16 bit precision. The above example requires a mini-
mum of 7 + 19 = 26 bits of numerical accuracy for some parts of the calculations. Hence, if one
was implementing the AC induction motor control algorithm using a 16 bit fixed-point DSP, it
would require the implementation of higher precision math for certain portions. This would take
more cycles and programming effort.

The great benefit of using GLOBAL_Q is that the user does not necessarily need to go into de-
tails to assign an individual Q for each variable in a whole system, as is typically done in conven-
tional fixed-point programming. This is time consuming work. By using 32-bit resolution and the
"IQmath" approach, the user can easily evaluate the overall resolution and quickly implement a
typical digital motor control application without quantization problems.

8 - 32 TMS320C28x MCU Workshop - Numerical Concepts


AC Induction Motor Example

AC Induction Motor Example


Performance comparisons

Benchmark C28x C C28x C C28x C


floating-point floating-point IQmath
std. RTS lib fast RTS lib v1.4d
(150 MHz) (150 MHz) (150 MHz)
B1: ACI module cycles 401 401 625
B2: Feedforward control cycles 421 371 403
B3: Feedback control cycles 2336 792 1011
Total control cycles (B2+B3) 2757 1163 1414
% of available MHz used 36.8% 15.5% 18.9%
(20 kHz control loop)

Notes: C28x compiled on codegen tools v5.0.0, -g (debug enabled), -o3 (max. optimization)
fast RTS lib v1.0beta1
IQmath lib v1.4d

Using the profiling capabilities of the respective DSP tools, the table above summarizes the num-
ber of cycles and code size of the forward and feedback control blocks.

The MIPS used is based on a system sampling frequency of 20 kHz, which is typical of such sys-
tems.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 33


IQmath Summary

IQmath Summary
IQmath Approach Summary
“IQmath” + fixed-point processor with 32-bit capabilities =
‹ Seamless portability of code between fixed and floating-
point devices
Š User selects target math type in “IQmathLib.h” file
Š #if MATH_TYPE == IQ_MATH
Š #if MATH_TYPE == FLOAT_MATH
‹ One source code set for simulation vs. target device
‹ Numerical resolution adjustability based on application
requirement
Š Set in “IQmathLib.h” file
Š #define GLOBAL_Q 18
Š Explicitly specify Q value
Š _iq20 X, Y, Z;
‹ Numerical accuracy without sacrificing time and cycles
‹ Rapid conversion/porting and implementation of algorithms

IQmath library is freeware - available from TI DSP website


http://www.ti.com/c2000

The IQmath approach, matched to a fixed-point processor with 32x32 bit capabilities enables the
following:

• Seamless portability of code between fixed and floating-point devices


• Maintenance and support of one source code set from simulation to target device
• Adjustability of numerical resolution (Q value) based on application requirement
• Implementation of systems that may otherwise require floating-point device
• Rapid conversion/porting and implementation of algorithms

8 - 34 TMS320C28x MCU Workshop - Numerical Concepts


Lab 8: IQmath & Floating-Point FIR Filter

Lab 8: IQmath & Floating-Point FIR Filter


¾ Objective

The objective of this lab is to become familiar with IQmath and floating-point programming. In
the previous lab, ePWM1A was setup to generate a 2 kHz, 25% duty cycle symmetric PWM
waveform. The waveform was then sampled with the on-chip analog-to-digital converter. In this
lab the sampled waveform will be passed through an FIR filter and displayed using the graphing
feature of Code Composer Studio. The filter math type (IQmath and floating-point) will be
selected in the “IQmathLib.h” file.

Lab 8: IQmath & Floating-Point FIR Filter

ePWM1 ADC
TB Counter ADCINA0 RESULT0
Compare FIR Filter
Action Qualifier
connector
wire

ePWM2 triggering ADC on period


match using SOC A trigger every data
20.833 µs (48 kHz) memory
ePWM2
pointer rewind
CPU copies
result to
buffer during

...
ADC ISR

Display
using CCS

¾ Procedure

Project File
1. A project named Lab8.pjt has been created for this lab. Open the project by clicking
on Project Æ Open… and look in C:\C28x\Labs\Lab8. All Build Options
have been configured the same as the previous lab. The files used in this lab are:
Adc_6_7_8.c Filter.c
CodeStartBranch.asm Gpio.c
DefaultIsr_8.c Lab_8.cmd
DelayUs.asm Main_8.c
DSP2833x_GlobalVariableDefs.c PieCtrl_5_6_7_8_9_10.c
DSP2833x_Headers_nonBIOS.cmd PieVect_5_6_7_8_9_10.c
ECap_7_8_9_10_12.c SysCtrl.c
EPwm_7_8_9_10_12.c Watchdog.c

TMS320C28x MCU Workshop - Numerical Concepts 8 - 35


Lab 8: IQmath & Floating-Point FIR Filter

Project Build Options


2. Setup the include search path to include the IQmath header file. Open the Build
Options and select the Compiler tab. In the Preprocessor Category, find the Include
Search Path (-i) box and add to the end of the line (preceeded with a semicolon to
append this directory to the existing search path):

;..\IQmath\include

3. Setup the library search path to include the IQmath library. Select the Linker tab.

a. In the Libraries Category, find the Search Path (-i) box and enter:

..\IQmath\lib

b. In the Include Libraries (-l) box add to the end of the line (preceeded with
a semicolon to append this library to the existing library):

;IQmath.lib

Then select OK to save the Build Options.

Include IQmathLib.h
4. In the CCS project window left click the plus sign (+) to the left of the Include folder.
Edit Lab.h to uncomment the line that includes the IQmathLib.h header file. Next,
in the Function Prototypes section, uncomment the function prototype for IQssfir(), the
IQ math single-sample FIR filter function. In the Global Variable References section
uncomment the four _iq references, and comment out the reference to
AdcBuf[ADC_BUF_LEN]. Save the changes and close the file.

Inspect Lab_8.cmd
5. Open and inspect Lab_8.cmd. First, notice that a section called “IQmath” is being
linked to L0123SARAM. The IQmath section contains the IQmath library functions
(code). Second, notice that a section called “IQmathTables” is being linked to the
IQTABLES with a TYPE = NOLOAD modifier after its allocation. The IQmath tables
are used by the IQmath library functions. The NOLOAD modifier allows the linker to
resolve all addresses in the section, but the section is not actually placed into the .out
file. This is done because the section is already present in the device ROM (you cannot
load data into ROM after the device is manufactured!). The tables were put in the ROM
by TI when the device was manufactured. All we need to do is link the section to the
addresses where it is known to already reside (the tables are the very first thing in the
BOOT ROM, starting at address 0x3FE000).

8 - 36 TMS320C28x MCU Workshop - Numerical Concepts


Lab 8: IQmath & Floating-Point FIR Filter

Select a Global IQ value


6. Use File Æ Open… to open c:\C28x\Labs\IQmath\include\IQmathLib.h.
Confirm that the GLOBAL_Q type (near beginning of file) is set to a value of 24. If it is not,
modify as necessary:
#define GLOBAL_Q 24

Recall that this Q type will provide 8 integer bits and 24 fractional bits. Dynamic range
is therefore -128 < x < +128, which is sufficient for our purposes in the workshop.

IQmath Single-Sample FIR Filter


7. Open and inspect DefaultIsr_8.c. Notice that the ADCINT_ISR calls the IQmath
single-sample FIR filter function, IQssfir(). The filter coefficients have been defined in
the beginning of Main_8.c. Also, as discussed in the lecture for this module, the ADC
results are read with the following instruction:
*AdcBufPtr = _IQmpy(ADC_FS_VOLTAGE,
_IQ12toIQ((_iq)AdcMirror.ADCRESULT0));

The value of ADC_FS_VOLTAGE will be discussed in the next lab step.

8. Open and inspect Lab.h. Notice that, as discussed in the lecture for this module,
ADC_FS_VOLTAGE is defined as:
#if MATH_TYPE == IQ_MATH
#define ADC_FS_VOLTAGE _IQ(3.0)
#else // MATH_TYPE is FLOAT_MATH
#define ADC_FS_VOLTAGE _IQ(3.0/4096.0)
#endif

9. Open and inspect the IQssfir() function in Filter.c. This is a simple, non-optimized
coding of a basic IQmath single-sample FIR filter. Close the inspected files.

Build and Load


10. Click the “Build” button to build and load the project.

Run the Code – Filtered Waveform


11. Open a memory window to view some of the contents of the filtered ADC results buffer.
The address label for the filtered ADC results buffer is AdcBufFiltered. Set the Format to
32-Bit Signed Integer. Open the memory window Property Window by clicking on the
icon in the lower left corner. Set the Q-Value to 24 (which matches the IQ format being
used for this variable) and then enter. We will be running our code in real-time mode,
and will have our window continuously refresh.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 37


Lab 8: IQmath & Floating-Point FIR Filter

Note: For the next step, check to be sure that the jumper wire connecting PWM1A (pin # P8-9)
to ADCINA0 (pin # P9-2) is in place on the eZdsp™.

12. Run the code in real-time mode using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset, and watch the memory
window update. Verify that the ADC result buffer contains updated values.

13. Open and setup a dual-time graph to plot a 48-point window of the filtered and unfiltered
ADC results buffer. Click: View Æ Graph Æ Time/Frequency… and set the
following values:

Display Type Dual Time

Start Address – upper display AdcBufFiltered

Start Address – lower display AdcBuf

Acquisition Buffer Size 48

Display Data Size 48

DSP Data Type 32-bit signed integer

Q-value 24

Sampling Rate (Hz) 48000

Time Display Unit μs

Select OK to save the graph options.

14. The graphical display should show the generated FIR filtered 2 kHz, 25% duty cycle
symmetric PWM waveform in the upper display and the unfiltered waveform generated
in the previous lab exercise in the lower display. Notice the shape and phase differences
between the waveform plots (the filtered curve has rounded edges, and lags the unfiltered
plot by several samples). The amplitudes of both plots should run from 0 to 3.0.

15. Open and setup two (2) frequency domain plots – one for the filtered and another for the
unfiltered ADC results buffer. Click: View Æ Graph Æ Time/Frequency…
and set the following values:

8 - 38 TMS320C28x MCU Workshop - Numerical Concepts


Lab 8: IQmath & Floating-Point FIR Filter

GRAPH #1 GRAPH #2

Display Type FFT Magnitude FFT Magnitude

Start Address AdcBuf AdcBufFiltered

Acquisition Buffer Size 48 48

FFT Framesize 48 48

DSP Data Type 32-bit signed integer 32-bit signed integer

Q-value 24 24

Sampling Rate (Hz) 48000 48000

Select OK to save the graph options.

16. The graphical displays should show the frequency components of the filtered and
unfiltered 2 kHz, 25% duty cycle symmetric PWM waveforms. Notice that the higher
frequency components are reduced using the Low-Pass FIR filter in the filtered graph as
compared to the unfiltered graph.

17. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

Changing Math Type to Floating-Point


18. In the CCS project window left click the plus sign (+) to the left of the Include folder.
Edit IQmathLib.h to define the math type as floating-point. Change #define

from: #define MATH_TYPE IQ_MATH

to: #define MATH_TYPE FLOAT_MATH

Save the change to the IQmathLib.h and close the file.

19. Open the Build Options and select the Compiler tab. In the Advanced Category set
the Floating Point Support to fpu32.

20. In the Build Options now select the Linker tab. In the Libraries Category change
from rts2800_ml.lib to rts2800_fpu32.lib. This library is required for floating-
point support. Select OK to save the Build Options.

Build and Load


21. Click the “Build” button to build and load the project.

TMS320C28x MCU Workshop - Numerical Concepts 8 - 39


Lab 8: IQmath & Floating-Point FIR Filter

Run the Code – Floating-Point Filtered Waveform


22. Change the dual time and FFT Magnitude graphs to display 32-bit floating-point rather
than 32-bit signed integer. Right click on the dual-time graph, select Properties…
and change the DSP Data Type to 32-bit floating-point. Next, right click on each FFT
Magnitude graph and change the DSP Data Type to 32-bit floating-point.

23. Run the code in real-time mode using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset.

24. The dual time graphical display should show the generated FIR filtered 2 kHz, 25% duty
cycle symmetric PWM waveform in the upper display and the unfiltered waveform
generated lower display. The FFT Magnitude graphical displays should show the
frequency components of the filtered and unfiltered 2 kHz, 25% duty cycle symmetric
PWM waveforms.

25. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

End of Exercise

8 - 40 TMS320C28x MCU Workshop - Numerical Concepts


Lab 8: IQmath & Floating-Point FIR Filter

Lab 8 Reference: Low-Pass FIR Filter

Bode Plot of Digital Low-Pass FIR Filter

Coefficients: [1/16, 4/16, 6/16, 4/16, 1/16]

Sample Rate: 48 kHz

TMS320C28x MCU Workshop - Numerical Concepts 8 - 41


Lab 8: IQmath & Floating-Point FIR Filter

8 - 42 TMS320C28x MCU Workshop - Numerical Concepts


Direct Memory Access Controller

Introduction
This module explains the operation of the direct memory access (DMA) controller. The DMA
provides a hardware method of transferring data between peripherals and/or memory without
intervention from the CPU, thus freeing up bandwidth for other system functions. The DMA has
six channels with independent PIE interrupts.

Learning Objectives
Learning Objectives

‹ Understand the operation of the


Direct Memory Access (DMA)
controller
‹ Show how to use the DMA to
transfer data between peripherals
and/or memory without intervention
from the CPU

TMS320C28x MCU Workshop - Direct Memory Access Controller 9-1


Module Topics

Module Topics
Direct Memory Access Controller ........................................................................................................... 9-1

Module Topics......................................................................................................................................... 9-2


Direct Memory Access (DMA)................................................................................................................ 9-3
Basic Operation .................................................................................................................................. 9-4
DMA Examples .................................................................................................................................. 9-6
DMA Priority Modes.......................................................................................................................... 9-9
DMA Throughput..............................................................................................................................9-10
DMA Registers..................................................................................................................................9-11
Lab 9: Servicing the ADC with DMA.....................................................................................................9-15

9-2 TMS320C28x MCU Workshop - Direct Memory Access Controller


Direct Memory Access (DMA)

Direct Memory Access (DMA)


DMA Triggers, Sources, and Destinations

PIE
DINTCH1-6
ADC XINTF
Result 0-15 Zone 0, 6, 7

DMA
L4 SARAM 6-channels
McBSP-A
Triggers
L5 SARAM McBSP-B
SEQ1INT / SEQ2INT
MXEVTA / MREVTA PWM1
L6 SARAM MXEVTB / MREVTB
XINT1-7 / 13 PWM2
TINT0 / 1 / 2 PWM3
L7 SARAM PWM4
PWM5
PWM6
SysCtrlRegs.MAPCNF.bit.MAPCNF
(re-maps PWM regs from PF1 to PF3)

DMA Definitions
‹ Word
Š 16 or 32 bits
Š Word size is configurable per DMA channel
‹ Burst
Š Consists of multiple words
Š Smallest amount of data transferred at one time
‹ Burst Size
Š Number of words per burst
Š Specified by BURST_SIZE register
Š 5-bit ‘N-1’ value (maximum of 32 words/burst)
‹ Transfer
Š Consists of multiple bursts
‹ Transfer Size
Š Number of bursts per transfer
Š Specified by TRANSFER_SIZE register
Š 16-bit ‘N-1’ value - exceeds any practical requirements

TMS320C28x MCU Workshop - Direct Memory Access Controller 9-3


Direct Memory Access (DMA)

Basic Operation
Simplified State Machine Operation
The DMA state machine at its most basic
level is two nested loops

Start Transfer

Move Word

Burst Size times

Transfer Size times

End Transfer

Basic Address Control Registers


32
SRC_ADDR
Active pointers
DST_ADDR

Pointer shadow registers SRC_ADDR_SHADOW


copied to active pointers at
start of transfer DST_ADDR_SHADOW

Signed value added to active SRC_BURST_STEP


pointer after each word DST_BURST_STEP

Signed value added to active SRC_TRANSFER_STEP


pointer after each burst DST_TRANSFER_STEP

9-4 TMS320C28x MCU Workshop - Direct Memory Access Controller


Direct Memory Access (DMA)

Simplified State Machine Example

3 words/burst Start Transfer


2 bursts/transfer
Wait for event
to start/continue
transfer

Read/Write Data

Moved N Add Burst Step


“Burst Size” to Address
Words? Pointer
Y

Moved N Add Transfer


“Transfer Size” Step to Address
Bursts? Pointer
Y

End Transfer

DMA Interrupts

Mode #1: Start Transfer


Interrupt
at start of Wait for event
transfer to start/continue
transfer

‹ Each DMA channel has


its own PIE interrupt Read/Write Data
‹ The mode for each
interrupt can be
configured individually Moved N Add Burst Step
‹ The CHINTMODE bit in “Burst Size” to Address
Words? Pointer
the MODE register selects
the interrupt mode Y

Moved N Add Transfer


“Transfer Size” Step to Address
Bursts? Pointer
Mode #2: Y
Interrupt
at end of
End Transfer
transfer

TMS320C28x MCU Workshop - Direct Memory Access Controller 9-5


Direct Memory Access (DMA)

DMA Examples
Simple Example
Objective: Move 4 words from L7 SARAM to XINTF Zone 0
and interrupt CPU at end of transfer
BURST_SIZE* 0x0001 2 words/burst
St art Transfer
TRANSFER_SIZE* 0x0001 2 bursts/transfer

* Size registers are N-1 Wait f or event


t o start/c ontinue
transfer
Source Registers Addr Value
SRC_ADDR 0x00000000
0x0000F000
0x0000F001
0x0000F002
0x0000F003 0xF000 0x1111 Read/Write D at a

0xF001 0x2222
SRC_ADDR_SHADOW 0x0000F000 Moved Add Burst Step
0xF002 0x3333 N
BURST_STEP 0x0001 “Burst Siz e” to Address
0xF003 0x4444 Words? Pointer
TRANSFER_STEP 0x0001
Y

Moved N Add Transfer


Destination Registers Addr Value “Transfer Siz e” Step to Address
Bursts ? Pointer
DST_ADDR 0x00000000
0x00004000
0x00004001
0x00004002
0x00004003 0x4000 0x0000
0x1111 Y
0x4001 0x0000
0x2222
DST_ADDR_SHADOW 0x00004000 Interrupt to PIE
0x4002 0x0000
0x3333
DST_BURST_STEP 0x0001 End Trans fer
0x4003 0x0000
0x4444
DST_TRANSFER_STEP 0x0001

Note: This example could also have been done using 1 word/burst and 4 bursts/transfer, or 4 words/burst
and 1 burst/transfer. This would affect Round-Robin progression, but not interrupts.

Data Binning Example


Objective: Bin 3 samples of 5 ADC channels, then interrupt the CPU

L7 SARAM

0xF000
CH0 0xF001
ADC Mirror Results
0xF002
1nd
23rd
st Conversion Sequence
Sequence 0xF003
CH1 0xF004
0x0B00 CH0 0xF005
0x0B01 CH1 0xF006
0x0B02 CH2 CH2 0xF007
0x0B03 CH3 0xF008
0x0B04 CH4 0xF009
CH3 0xF00A
0xF00B
0xF00C
CH4 0xF00D
0xF00E

9-6 TMS320C28x MCU Workshop - Direct Memory Access Controller


Direct Memory Access (DMA)

Data Binning Example Register Setup


Objective: Bin 3 samples of 5 ADC channels, then interrupt the CPU

ADC Registers:
ADCMAXCONV* 0x0004 5 conversions per sequence
Other: ADC configured for continuous conversion,
SEQ_OVERRIDE bit set so that state pointer wraps after 5 conversions

L7 SARAM
DMA Registers:
BURST_SIZE* 0x0004 5 words/burst 0xF000 CH0
0x0002 0xF001 CH0
TRANSFER_SIZE* 3 bursts/transfer
0xF002 CH0
SRC_ADDR_SHADOW 0x00000B00 ADC Mirror Results 0xF003 CH1
SRC_BURST_STEP 0x0001 CH1
0xF004
SRC_TRANSFER_STEP 0xFFFC (-4) CH0 CH1
0x0B00 0xF005
DST_ADDR_SHADOW 0x0000F000 starting address** 0x0B01 CH1 0xF006 CH2
DST_BURST_STEP 0x0003 0x0B02 CH2 0xF007 CH2
DST_TRANSFER_STEP 0xFFF5 (-11) 0x0B03 CH3 0xF008 CH2
0x0B04 CH4 0xF009 CH3
0xF00A CH3
0xF00B CH3
0xF00C CH4
0xF00D CH4
* Size registers are N-1 0xF00E CH4
** Typically use a relocatable symbol in your code, not a hard value

The State Machine ‘Wrap’ Function


Provides another resource to manipulate the address pointers
Start Transfer

Wait for event to


Wrap Function: start/continue transfer
‹ Reloads address
pointer after specified Read/Write Data
number of bursts
Moved Add Burst Step
‹ Allows a cumulative “Burst Size”
N
to Address
signed offset to be Words? Pointer
added each wrap Y
Add Transfer Step
to Address Pointer
New Registers N
Moved N Moved
• WRAP_SIZE = bursts/wrap - 1 “Transfer Size” “Wrap Size”
• BEG_ADDR = Wrap beginning Bursts? Bursts?
address Y Y
• WRAP_STEP = added to Add WRAP_STEP to
BEG_ADDR before wrapping BEG_ADDR and Load
End Transfer into Address Pointer

TMS320C28x MCU Workshop - Direct Memory Access Controller 9-7


Direct Memory Access (DMA)

Ping-Pong Buffer Example


Objective: Buffer ADC ch. 0 ping-pong style, 48 samples per buffer

ADC Mirror Results L4 SARAM


0xC140
0x0B00 ADCRESULT0
0x0B01 ADCRESULT1
0x0B02 ADCRESULT2
0x0B03 ADCRESULT3 48 word
0x0B04 ADCRESULT4 ‘Ping’ buffer
0x0B05 ADCRESULT5
0x0B06 ADCRESULT6
0x0B07 ADCRESULT7 DMA
0x0B08 ADCRESULT8 Interrupt
0x0B09 ADCRESULT9
0x0B0A ADCRESULT10
0x0B0B ADCRESULT11 48 word
0x0B0C ADCRESULT12 ‘Pong’ buffer
0x0B0D ADCRESULT13
0x0B0E ADCRESULT14
0x0B0F ADCRESULT15 DMA
Interrupt

Ping-Pong Example Register Setup


Objective: Buffer ADC ch. 0 ping-pong style, 48 samples per buffer
ADC Registers:
ADCMAXCONV* 0x0000 1 conversion per trigger - SEQ pointer auto wraps after 16 states
Other: All 16 Ch. selection fields configured for Ch. 0, ADC in non-continuous run mode
DMA Registers:
BURST_SIZE* 0x0000 1 word/burst
TRANSFER_SIZE* 0x002F 48 bursts/transfer Start T ransfer

SRC_ADDR_SHADOW 0x00000B00 starting address Wait for event to


SRC_BURST_STEP don’t care since BURST_SIZE = 0 star t/continue transfer

SRC_TRANSFER_STEP 0x0001 Read/W rite Data


SRC_BEG_ADDR_SHADOW 0x00000B00 starting wrap address
Moved N Add Burst Step
SRC_WRAP_SIZE* 0x000F wrap after 16 words “ Bur st Size” to Address
Words? Pointer
SRC_WRAP_STEP 0x0000
0x0000C140 Add Transfer Step
DST_ADDR_SHADOW starting address** Y to Address Pointer
DST_BURST_STEP 0x0000 since BURST_SIZE = 0 N
Moved N Moved
DST_TRANSFER_STEP 0x0001 “Transfer Size” “Wrap Size”
Bursts? Bur sts?
DST_BEG_ADDR_SHADOW don’t care not using dst wrap Y
DST_WRAP_SIZE* 0xFFFF no wrap Y Add W RAP_STEP to
BEG_ADDR and Load
DST_WRAP_STEP don’t care not using dst wrap End Transfer Into Address Pointer

Other: DMA configured to re-init after transfer (CONTINUOUS = 1)

* Size registers are N-1


** DST_ADDR_SHADOW must be changed between ping and pong buffer address in
the DMA ISR. Typically use a relocatable symbol in your code, not a hard value.

9-8 TMS320C28x MCU Workshop - Direct Memory Access Controller


Direct Memory Access (DMA)

DMA Priority Modes


Channel Priority Modes
‹ Round Robin Mode:
Š All channels have equal priority DMA Y
Š After each enabled channel has event?
transferred a burst of words, the
next enabled channel is serviced
in round robin fashion CH6 N CH1
‹ Channel 1 High Priority Mode:
Š Same as Round Robin except CH1
can interrupt DMA state machine
Š If CH1 trigger occurs, the current
word (not the complete burst) on
any other channel is completed CH5 CH2
and execution is halted
Š CH1 is serviced for complete burst
Š When completed, execution
returns to previous active channel
Š This mode is intended primarily CH4 CH3
for the ADC, but can be used by
any DMA event configured to
trigger CH1

Priority Modes and the State Machine


Start Transfer Point where other
pending channels
are serviced
Wait for event
to start/continue
transfer

Read/Write Data
Point where
CH1 can
interrupt other
Moved N Add Burst Step
channels in
“Burst Size” to Address
CH1 Priority Mode
Words? Pointer
Y

Moved N Add Transfer


“Transfer Size” Step to Address
Bursts? Pointer
Y

End Transfer

TMS320C28x MCU Workshop - Direct Memory Access Controller 9-9


Direct Memory Access (DMA)

DMA Throughput
DMA Throughput
‹ 4 cycles/word (5 for McBSP reads)
‹ 1 cycle delay to start each burst
‹ 1 cycle delay returning from CH1 high
priority interrupt
‹ 32-bit transfer doubles throughput
(except McBSP, which supports 16-bit transfers only)

Example: 128 16-bit words from ADC to RAM


8 bursts * [(4 cycles/word * 16 words/burst) + 1] = 520 cycles

Example: 64 32-bit words from ADC to RAM


8 bursts * [(4 cycles/word * 8 words/burst) + 1] = 264 cycles

DMA vs. CPU Access Arbitration


‹ DMA has priority over CPU
Š If a multi-cycle CPU access is already in
progress (e.g. XINTF), DMA stalls until
current CPU access finishes
Š The DMA will interrupt back-to-back CPU
accesses
‹ Can the CPU be locked out?
Š Generally No!
Š DMA is multi-cycle transfer; CPU will sneak
in an access when the DMA is accessing
the other end of the transfer (e.g. while DMA
accesses destination location, the CPU can
access the source location)

9 - 10 TMS320C28x MCU Workshop - Direct Memory Access Controller


Direct Memory Access (DMA)

DMA Registers
DMA Registers
DmaRegs.name (lab file: Dma.c)
Register Description
DMACTRL DMA Control Register
PRIORITYCTRL1 Priority Control Register 1
MODE Mode Register
CONTROL Control Register
BURST_SIZE Burst Size Register
BURST_COUNT Burst Count Register
DMA CHx Registers

SRC_BURST_STEP Source Burst Step Size Register


DST_BURST_STEP Destination Burst Step Size Register
TRANSFER_SIZE Transfer Size Register
TRANSFER_COUNT Transfer Count Register
SRC_TRANSFER_STEP Source Transfer Step Size Register
DST_TRANSFER_STEP Destination Transfer Step Size Register
SRC_ADDR_SHADOW Shadow Source Address Pointer Register
SRC_ADDR Active Source Address Pointer Register
DST_ADDR_SHADOW Shadow Destination Address Pointer Register
DST_ADDR Active Destination Address Pointer Register

For a complete list of registers refer to the DMA Module Reference Guide

DMA Control Register


DmaRegs.DMACTRL

Hard Reset
0 = writes ignored (always reads back 0)
1 = reset DMA module

15 - 2 1 0
reserved PRIORITYRESET HARDRESET

Priority Reset
0 = writes ignored (always reads back 0)
1 = reset state-machine after any pending
burst transfer complete

TMS320C28x MCU Workshop - Direct Memory Access Controller 9 - 11


Direct Memory Access (DMA)

Priority Control Register 1


DmaRegs.PRIORITYCTRL1

15 - 1 0
reserved CH1PRIORITY

DMA CH1 Priority


0 = same priority as other channels
1 = highest priority channel

Mode Register
DmaRegs.CHx.MODE

Upper Register:

Channel Interrupt Sync Mode Select One Shot Mode


0 = disable 0 = one burst transfer per trigger
0 = SRC wrap counter 1 = subsequent burst transfers
1 = enable 1 = DST wrap counter occur without additional trigger

15 14 13 12 11 10
CHINTE DATASIZE SYNCSEL SYNCE CONTINUOUS ONESHOT

Data Size Mode Sync Enable (PERINTSEL) Continuous Mode


0 = 16-bit transfer 0 = ADCSYNC ignored 0 = DMA stops
1 = 32-bit transfer 1 = ADCSYNC event 1 = DMA re-initializes

9 - 12 TMS320C28x MCU Workshop - Direct Memory Access Controller


Direct Memory Access (DMA)

Mode Register
DmaRegs.CHx.MODE

Lower Register: Peripheral Overflow


Interrupt Trigger Interrupt Enable
Channel Interrupt Generation 0 = disable 0 = disable
0 = at beginning of transfer 1 = enable 1 = enable
1 = at end of transfer

9 8 7 6-5 4- 0
CHINTMODE PERINTE OVRINTE reserved PERINTSEL

Peripheral Interrupt Source Select


Value Interrupt Sync Peripheral Value Interrupt Sync Peripheral
0 none none none 9 XINT7 none Ext. Int.
1 SEQ1INT ADCSYNC ADC 10 XINT13 none Ext. Int.
2 SEQ2INT none ADC 11 TINT0 none CPU Timer
3 XINT1 none Ext. Int. 12 TINT1 none CPU Timer
4 XINT2 none Ext. Int. 13 TINT2 none CPU Timer
5 XINT3 none Ext. Int. 14 MXEVTA none McBSP-A
6 XINT4 none Ext. Int. 15 MREVTA none McBSP-A
7 XINT5 none Ext. Int. 16 MXEVTB none McBSP-B
8 XINT6 none Ext. Int. 17 MREVTB none McBSP-B

Control Register
DmaRegs.CHx.CONTROL

Upper Register:
Overflow Flag * Burst Status * Sync Error * Sync Flag *
0 = no overflow 0 = no activity 0 = no error 0 = no sync event
1 = overflow 1 = servicing burst 1 = ADCSYNC error 1 = ADCSYNC event

15 14 13 12 11 10 9 8
reserved OVRFLG RUNSTS BURSTSTS TRANSFERRST SYNCERR SYNCFLG PERINTFLG

Run Status * Transfer Status * Peripheral Interrupt Trigger Flag *


0 = channel disabled 0 = no activity 0 = no interrupt event trigger
1 = channel enabled 1 = transferring 1 = interrupt event trigger

* = read-only

TMS320C28x MCU Workshop - Direct Memory Access Controller 9 - 13


Direct Memory Access (DMA)

Control Register
DmaRegs.CHx.CONTROL

Lower Register:
Error Clear Sync Force Peripheral Interrupt Force
0 = no effect 0 = no effect 0 = no effect
1 = clear SYNCERR 1 = sets SYNCFLG 1 = sets event and PERINTFLG

7 6 5 4 3 2 1 0
ERRCLR SYNCCLR SYNCFRC PERINTCLR PERINTFRC SOFTRESET HALT RUN

Sync Clear Soft Reset Run


0 = no effect 0 = no effect 0 = no effect
1 = clear SYNCFLG 1 = default state 1 = run

Peripheral Interrupt Clear Halt


0 = no effect 0 = no effect
1 = clears event and PERINTFLG 1 = halt

9 - 14 TMS320C28x MCU Workshop - Direct Memory Access Controller


Lab 9: Servicing the ADC with DMA

Lab 9: Servicing the ADC with DMA


¾ Objective

The objective of this lab is to become familiar with operation of the DMA. In the previous lab,
the CPU was used to store the ADC conversion result in the memory buffer during the ADC ISR.
In this lab the DMA will be configured to transfer the results directly from the ADC result
registers to the memory buffer. ADC channel A0 will be buffered ping-pong style with 48
samples per buffer. As an operational test, the filtered 2 kHz, 25% duty cycle symmetric PWM
waveform (ePWM1A) will be displayed using the graphing feature of Code Composer Studio.

Lab 9: Servicing the ADC with DMA

ePWM1 ADC DMA


TB Counter ADCINA0 RESULT0
Compare
Action Qualifier
connector
wire ping
data
memory
ePWM2 triggering ADC on period pong
match using SOC A trigger every
20.833 µs (48 kHz)
ePWM2 CPU runs
FIR data through
Filter filter during
DMA ISR

Objective:
Pointer
rewind

data
Configure the DMA to memory
buffer ADC Channel A0
ping-pong style with 48 Display
using CCS
samples per buffer

¾ Procedure

Project File
1. A project named Lab9.pjt has been created for this lab. Open the project by clicking
on Project Æ Open… and look in C:\C28x\Labs\Lab9. All Build Options
have been configured the same as the previous lab. The files used in this lab are:
Adc_9_10_12.c Filter.c
CodeStartBranch.asm Gpio.c
DefaultIsr_9_10_12a.c Lab_9.cmd
DelayUs.asm Main_9.c
Dma.c PieCtrl_5_6_7_8_9_10.c
DSP2833x_GlobalVariableDefs.c PieVect_5_6_7_8_9_10.c
DSP2833x_Headers_nonBIOS.cmd SysCtrl.c
ECap_7_8_9_10_12.c Watchdog.c
EPwm_7_8_9_10_12.c

TMS320C28x MCU Workshop - Direct Memory Access Controller 9 - 15


Lab 9: Servicing the ADC with DMA

Inspect Lab_9.cmd
2. Open and inspect Lab_9.cmd. Notice that a section called “dmaMemBufs” is being
linked to L4SARAM. This section links the destination buffer for the DMA transfer to a
DMA accessible memory space.

Setup DMA Initialization


The DMA controller needs to be configured to buffer ADC channel A0 ping-pong style with 48
samples per buffer. All 16 input channel selection sequences in the autosequencer need to be set
to channel A0. One conversion will be performed per trigger with the ADC operating in non-
continuous run mode. The autosequencer pointer will automatically wrap after 16 conversions.

3. Open Adc_9_10_12.c and notice that the ADCMAXCONV register has been set to
perform one conversion per trigger. Also, the ADC input channel select sequencing
control registers (ADCCHSELSEQx) have all been set to convert channel A0.

4. Edit Dma.c to implement the DMA operation as described in the objective for this lab
exercise. Configure the DMA Channel 1 Mode Register (MODE) so that the ADC
SEQ1INT is the peripheral interrupt source. Enable the channel interrupt and interrupt
trigger with the interrupt generation at the start of transfer. Configure for 16-bit data
transfers with one burst per trigger and auto re-initialization at the end of the transfer.
Disable the ADC sync. In the DMA Channel 1 Control Register (CONTROL) clear the
error, sync and peripheral interrupt bits and enable the channel to run.

Setup PIE Interrupt for DMA


Recall that ePWM2 is triggering the ADC at a 48 kHz rate. In the previous lab exercise, the ADC
generated an interrupt to the CPU, and the CPU implemented the FIR filter in the ADC ISR. For
this lab exercise, the ADC is instead triggering the DMA, and the DMA will generate an interrupt
to the CPU. The CPU will implement the FIR filter in the DMA ISR.

5. Edit Adc_9_10_12.c to comment out the code used to enable the ADC interrupt. This
is no longer being used. The DMA interrupt will be used instead.

6. Using the “PIE Interrupt Assignment Table” find the location for the DMA Channel 1
interrupt “DINTCH1” and fill in the following information:

PIE group #: # within group:


This information will be used in the next step.

7. Modify the end of Dma.c to do the following:


- Enable the "DINTCH1" interrupt in the PIE (Hint: use the PieCtrlRegs structure)
- Enable the appropriate core interrupt in the IER register
8. Open and inspect DefaultIsr_9_10_12a.c. Notice that this file contains the DMA
interrupt service routine. Save and close all modified files.

9 - 16 TMS320C28x MCU Workshop - Direct Memory Access Controller


Lab 9: Servicing the ADC with DMA

Build and Load


9. Click the “Build” button to build and load the project.

Run the Code – Test the DMA Operation


Note: For the next step, check to be sure that the jumper wire connecting PWM1A (pin # P8-9)
to ADCINA0 (pin # P9-2) is in place on the eZdsp™.

10. Run the code in real-time mode using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset, and watch the memory
window update. Verify that the ADC result buffer contains updated values.

11. Setup a dual-time graph of the filtered and unfiltered ADC results buffer. Click:
View Æ Graph Æ Time/Frequency… and set the following values:

Display Type Dual Time

Start Address – upper display AdcBufFiltered

Start Address – lower display AdcBuf

Acquisition Buffer Size 48

Display Data Size 48

DSP Data Type 32-bit floating-point

Sampling Rate (Hz) 48000

Time Display Unit μs

12. The graphical display should show the generated FIR filtered 2 kHz, 25% duty cycle
symmetric PWM waveform in the upper display and the unfiltered waveform in the lower
display. You should see that the results match the previous lab exercise.

13. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

End of Exercise

TMS320C28x MCU Workshop - Direct Memory Access Controller 9 - 17


Lab 9: Servicing the ADC with DMA

9 - 18 TMS320C28x MCU Workshop - Direct Memory Access Controller


System Design

Introduction
This module discusses various aspects of system design. Details of the emulation and analysis
block along with JTAG will be explored. Flash memory programming and the Code Security
Module will be described.

Learning Objectives
Learning Objectives

‹ Emulation and Analysis Block

‹ External Interface (XINTF)

‹ Flash Configuration and


Memory Performance

‹ Flash Programming

‹ Code Security Module (CSM)

TMS320C28x MCU Workshop - System Design 10 - 1


Module Topics

Module Topics
System Design ...........................................................................................................................................10-1

Module Topics........................................................................................................................................10-2
Emulation and Analysis Block ...............................................................................................................10-3
External Interface (XINTF)....................................................................................................................10-6
Flash Configuration and Memory Performance ..................................................................................10-10
Flash Programming .............................................................................................................................10-13
Code Security Module (CSM) ..............................................................................................................10-15
Lab 10: Programming the Flash..........................................................................................................10-18

10 - 2 TMS320C28x MCU Workshop - System Design


Emulation and Analysis Block

Emulation and Analysis Block


JTAG Emulation System
(based on IEEE 1149.1 Boundary Scan Standard)

System Under Test

SCAN IN
Emulator TMS320C2000
Pod

H
Some Available Emulators E
A
BlackHawk: USB2000 D
Olimex: TMS320-JTAG-USB E
Signum System: JTAGjet-TMS-C2000 TMS320C2000
R
Spectrum Digital: XDS-510LC

These emulators are C2000 specific,


and are much lower cost than emulators SCAN OUT
that support all TI DSP platforms
(although those can certainly be used)

Emulator Connections to the Device


Vcc (3.3 V)
Vcc (3.3 V)
JTAG Device Emulator Header
13 5
EMU0 EMU0 PD
14
EMU1 EMU1
2 4
TRST TRST GND
1 GND 6
TMS TMS
3 8
TDI TDI GND
7 10
TDO TDO GND
11 12
TCK TCK GND
9
TCK_RET
GND

= If distance between device and header is greater than 6 inches

TMS320C28x MCU Workshop - System Design 10 - 3


Emulation and Analysis Block

On-Chip Emulation Analysis Block:


Capabilities
Two hardware analysis units can be configured to provide
any one of the following advanced debug features:

Analysis Configuration Debug Activity


2 Hardware Breakpoints ⇒ Halt on a specified instruction
(for debugging in Flash)

2 Address Watchpoints ⇒ A memory location is getting


corrupted; halt the processor when
any value is written to this location

1 Address Watchpoint with Data ⇒ Halt program execution after a


specific value is written to a variable

1 Pair Chained Breakpoints ⇒ Halt on a specified instruction only


after some other specific routine has
executed

On-Chip Emulation Analysis Block:


Hardware Breakpoints
Symbolic or
numeric address

Mask value for


specifying
address ranges

Chained
breakpoint
selection

10 - 4 TMS320C28x MCU Workshop - System Design


Emulation and Analysis Block

On-Chip Emulation Analysis Block:


Watchpoints
Symbolic or
numeric address

Mask value for


specifying
address ranges

Bus selection

Address with Data


selection

On-Chip Emulation Analysis Block:


Online Stack Overflow Detection
‹ Emulation analysis registers are accessible to code as well!
‹ Configure a watchpoint to monitor for writes near the end of
the stack
‹ Watchpoint triggers maskable RTOSINT interrupt
‹ Works with DSP/BIOS and non-DSP/BIOS
Š See TI application report SPRA820 for implementation details

Region of Stack grows


memory towards higher
occupied memory
by the addresses
stack Monitor for data
writes in region near
the end of the stack
Data Memory

TMS320C28x MCU Workshop - System Design 10 - 5


External Interface (XINTF)

External Interface (XINTF)


TMS320F28335 XINTF Memory Map
Data Program
0x000000 0x010000
M0 SARAM (1Kw)
0x000400 reserved
M1 SARAM (1Kw) 0x100000
0x000800 XINTF Zone 6 (1Mw)
0x000D00 0x200000
PIE Vectors XINTF Zone 7 (1Mw)
(256 w ) 0x300000
0x000E00 reserved
PF 0 (6Kw) FLASH (256Kw)
0x002000
0x004000 0x33FFF8
PASSWORDS (8w)
XINTF Zone 0 (4Kw) 0x340000
0x005000 reserved
PF 3 (4Kw) 0x380080
0x006000 ADC calibration data
PF 1 (4Kw) reserved 0x380090
0x007000 reserved
PF 2 (4Kw) 0x380400
0x008000 User OTP (1Kw)
L0 SARAM (4Kw) 0x380800
0x009000 reserved Dual Mapped:
L1 SARAM (4Kw) 0x3F8000
0x00A000 L0 SARAM (4Kw) L0, L1, L2, L3
L2 SARAM (4Kw) 0x3F9000
0x00B000 L1 SARAM (4Kw)
L3 SARAM (4Kw) 0x3FA000 CSM Protected:
0x00C000 L2 SARAM (4Kw) L0, L1, L2, L3, OTP
L4 SARAM (4Kw) 0x3FB000 FLASH, ADC CAL,
0x00D000 L3 SARAM (4Kw)
L5 SARAM (4Kw) 0x3FC000 Flash regs in PF0
0x00E000 reserved
L6 SARAM (4Kw) 0x3FE000
0x00F000 Boot ROM (8Kw) DMA Accessible:
L7 SARAM (4Kw)
0x010000 0x3FFFC0 L4, L5, L6, L7,
BROM Vectors (64w)
0x3FFFFF XINTF Zone 0, 6, 7
Data Program

TMS320F28335 XINTF Signals


XD(31:16)
Data Bus
XD(15:0)
XA(19:1)
Address Bus
XA0/XWE1
XWE0 Write Enable Strobe
TMS320F28335

XRD Read Enable Strobe

XR/W Read Not Write Strobe

XZCS0
XZCS6 Zone selects

XZCS7
XREADY
Hardware wait-state support
XCLKOUT
XHOLD
Shared memory support
XHOLDA

10 - 6 TMS320C28x MCU Workshop - System Design


External Interface (XINTF)

Basic 16-bit Memory Interface


XD(31:16)
XD(15:0) D(15:0)

16-bit SRAM
XA(19:1) A(19:1)
Select XA0 A(0)
XA0/XWE1
XWE0 WE
TMS320F28335

XRD OE
XR/W CS

XZCS0
XZCS6
XZCS7
XREADY
XCLKOUT
XHOLD
XHOLDA

Basic 32-bit Memory Interface


XD(31:16) Low word
XD(15:0) D(15:0) 16-bit SRAM
XA(19:1) A(18:0)
Select XWE1
XA0/XWE1
XWE0 WE
TMS320F28335

XRD OE
XR/W CS

XZCS0 Hi word
XZCS6 D(15:0)
16-bit SRAM

XZCS7 A(18:0)
XREADY
XCLKOUT WE
XHOLD OE
XHOLDA CS

TMS320C28x MCU Workshop - System Design 10 - 7


External Interface (XINTF)

XINTF Timings
‹ Three external zones: 0, 6, 7
‹ Each zone has separate read and write timings
‹ XREADY signal can be used to extend ACTIVE phase

XRDLEAD XRDACTIVE XRDTRAIL

DSP latches data


XZCS

XRD

XA[19:0] valid address

XD[…] valid data

SRAM
ta(A)

Read Timing

XINTF Clocking
XTIMING0
XTIMING6 Lead/Active/Trail
XTIMING7
XBANK

C28x SYSCLKOUT
• /2 1 XTIMCLK XINTCNF2.CLKOFF
CPU 0 • • /2 1
0 XCLKOUT
XINTCNF2.XTIMCLK
XINTCNF2.CLKMODE

‹ Specify read timing and write timing separately, for


each zone:
Lead: 1-3 XTIMCLK Cycles
Active: 0-7 XTIMCLK Cycles
Trail: 0-3 XTIMCLK Cycles

‹ Each zone has a X2TIMING bit that can double the


timing values (both read and write affected)

10 - 8 TMS320C28x MCU Workshop - System Design


External Interface (XINTF)

XINTF Registers
Name Address Size (x16) Description
XTIMING0 0x00 0B20 2 XINTF Zone 0 Timing Register
XTIMING6 0x00 0B2C 2 XINTF Zone 6 Timing Register
XTIMING7 0x00 0B2E 2 XINTF Zone 7 Timing Register
XINTCNF2 0x00 0B34 2 XINTF Configuration Register
XBANK 0x00 0B38 1 XINTF Bank Control Register
XRESET 0x00 0B3D 1 XINTF Reset Register

‹ XTIMINGx specifies read and write timings (lead, active, trail),


interface size (16 or 32 bit), X2TIMING, XREADY usage
‹ XINTCNF2 selects SYSCLKOUT/1 or SYSCLKOUT/2 as
fundamental clock speed XTIMCLK (for lead, active, trail),
XHOLD control, write buffer control
‹ XBANK specifies the number of XTIMCLK cycles to add between
two specified zone (bank switching)
‹ XRESET used to do a hard reset in case where CPU detects a
stuck XREADY during a DMA transfer

XINTF Configuration Example


XINTCNF2 Example (XCLKOUT often only used during debug to check clocking)
XintfRegs.XINTCNF2.bit.XTIMCLK = 0; // XTIMCLK = SYSCLKOUT/1
XintfRegs.XINTCNF2.bit.CLKOFF = 0; // XCLKOUT enabled
XintfRegs.XINTCNF2.bit.CLKMODE = 0; // XCLKOUT = XTIMCLK/1

Zone 0 write and read timings example:


XintfRegs.XTIMING0.bit.X2TIMING = 0; // Timing scale factor = 1
XintfRegs.XTIMING0.bit.XSIZE = 3; // 16-bit interface
XintfREgs.XTIMING0.bit.USEREADY = 0; // Not using HW wait-states
XintfRegs.XTIMING0.bit.XRDLEAD = 1;
XintfRegs.XTIMING0.bit.XRDACTIVE = 2;
XintfRegs.XTIMING0.bit.XRDTRAIL = 0;
XintfRegs.XTIMING0.bit.XWRLEAD = 1;
XintfRegs.XTIMING0.bit.XWRACTIVE = 2;
XintfRegs.XTIMING0.bit.XWRTRAIL = 0;

Bank switching example: Suppose the external device in zone 7 is slow


getting off the bus; Add 3 additional cycles when switching from zone 7 to
another zone to avoid bus contention
XintfRegs.XBANK.bit.BANK = 7; // Select Zone 7
XintfRegs.XBANK.bit.BCYC = 3; // Add 3 XTIMCLK cycles

TMS320C28x MCU Workshop - System Design 10 - 9


Flash Configuration and Memory Performance

Flash Configuration and Memory Performance


Basic Flash Operation
‹ Flash is arranged in pages of 128 words
‹ Wait states are specified for consecutive accesses within a page,
and random accesses across pages
‹ OTP has random access only
‹ Must specify the number of SYSCLKOUT wait-states;
Reset defaults are maximum value (15)
‹ Flash configuration code should not be run from the Flash memory
15 12 11 8 7 4 3 0

FlashRegs.FBANKWAIT reserved PAGEWAIT reserved RANDWAIT

15 4 3 0

FlashRegs.FOTPWAIT reserved OTPWAIT

*** Refer to the F2833x datasheet for detailed numbers ***


For 150 MHz, PAGEWAIT = 5, RANDWAIT = 5, OTPWAIT = 8
For 100 MHz, PAGEWAIT = 3, RANDWAIT = 3, OTPWAIT = 5

Speeding Up Code Execution in Flash


Flash Pipelining (for code fetch only)
16

16 or 32
64 dispatched
64 C28x Core
decoder unit
Aligned 2-level deep
64-bit fetch buffer
fetch
Flash Pipeline Enable
0 = disable (default)
1 = enable

FlashRegs.FOPT.bit.ENPIPE = 1;
15 1 0
reserved ENPIPE

10 - 10 TMS320C28x MCU Workshop - System Design


Flash Configuration and Memory Performance

Code Execution Performance


‹ Assume 150 MHz SYSCLKOUT, 16-bit instructions
(80% of instructions are 16 bits wide – Rest are 32 bits)

Internal RAM: 150 MIPS


Fetch up to 32-bits every cycle Î 1 instruction/cycle * 150 MHz = 150 MIPS

Flash (w/ pipelining): 100 MIPS


RANDWAIT = 5
Fetch 64 bits every 6 cycles Î 4 instructions/6 cycles * 150 MHz = 100 MIPS
RPT will increase this; PC discontinuity will degrade this

32-bit External SRAM (10 or 12 ns): 75 MIPS


XRDLEAD=1, XRDACTIVE=2, XRDTRAIL=0
Fetch 32 bits every 4 cycles Î 2 instructions/4 cycles * 150 MHz = 75 MIPS
RPT will increase this

16-bit External SRAM (10 or 12 ns): 37.5 MIPS


XRDLEAD=1, XRDACTIVE=2, XRDTRAIL=0
Fetch 16 bits every 4 cycles Î 1 instruction/4 cycles * 150 MHz = 37.5 MIPS
RPT will increase this

Data Access Performance


(150 MHz SYSCLKOUT)

Memory 16-bit access 32-bit access Notes


(words/cycle) (words/cycle)

Internal RAM 1 1

Flash 0.167 0.167 RANDWAIT = 5


Flash is read only!
32-bit 0.5 0.25 XRDLEAD = 1,
ext. RAM
XRDACTIVE = 2,
(10 or 12 ns) 16-bit 0.25 0.125 XRDTRAIL = 0

‹ Internal RAM has best data performance – put time critical data here
‹ External RAM can generally outperform the flash for data access,
but increases cost and power consumption
‹ Flash performance usually sufficient for most constants and tables
‹ Note that the flash instruction fetch pipeline will also stall during a
flash data access

TMS320C28x MCU Workshop - System Design 10 - 11


Flash Configuration and Memory Performance

Other Flash Configuration Registers


FlashRegs.name
Address Name Description
0x00 0A80 FOPT Flash option register
0x00 0A82 FPWR Flash power modes registers
0x00 0A83 FSTATUS Flash status register
0x00 0A84 FSTDBYWAIT Flash sleep to standby wait register
0x00 0A85 FACTIVEWAIT Flash standby to active wait register
0x00 0A86 FBANKWAIT Flash read access wait state register
0x00 0A87 FOTPWAIT OTP read access wait state register

‹ FPWR: Save power by putting Flash/OTP to ‘Sleep’ or ‘Standby’


mode; Flash will automatically enter active mode if a Flash/OTP
access is made
‹ FSTATUS: Various status bits (e.g. PWR mode)
‹ FSTDBYWAIT, FACTIVEWAIT: Specify # of delay cycles during
wake-up from sleep to standby, and from standby to active,
respectively. The delay is needed to let the flash stabilize.
Leave these registers set to their default maximum value.
See the “TMS320x2833x System Control and Interrupts Reference Guide,”
SPRUFB0, for more information

10 - 12 TMS320C28x MCU Workshop - System Design


Flash Programming

Flash Programming
Flash Programming Basics
‹ The DSP CPU itself performs the flash programming
‹ The CPU executes Flash utility code from RAM that reads the
Flash data and writes it into the Flash
‹ We need to get the Flash utility code and the Flash data into RAM

FLASH CPU

Flash Emulator JTAG


Utility
Code RAM
RS232 SCI

SPI

Bootloader
I2C

ROM
Flash
Data eCAN

GPIO

XINTF
TMS320F2833x

Flash Programming Basics


‹ Sequence of steps for Flash programming:

Algorithm Function
1. Erase - Set all bits to zero, then to one
2. Program - Program selected bits with zero
3. Verify - Verify flash contents

‹ Minimum Erase size is a sector (32Kw or 16Kw)


‹ Minimum Program size is a bit!
‹ Important not to lose power during erase step:
If CSM passwords happen to be all zeros, the
CSM will be permanently locked!
‹ Chance of this happening is quite small! (Erase
step is performed sector by sector)

TMS320C28x MCU Workshop - System Design 10 - 13


Flash Programming

Flash Programming Utilities


‹ Code Composer Studio Plug-in (uses JTAG)
‹ Third-party JTAG utilities
Š SDFlash JTAG from Spectrum Digital (requires SD emulator)
Š Signum System Flash utilities (requires Signum emulator)
Š BlackHawk Flash utilities (requires Blackhawk emulator)
‹ SDFlash Serial utility (uses SCI boot)
‹ Gang Programmers (use GPIO boot)
Š BP Micro programmer
Š Data I/O programmer
‹ Build your own custom utility
Š Use a different ROM bootloader method than SCI
Š Embed flash programming into your application
Š Flash API algorithms provided by TI

* TI web has links to all utilities (http://www.ti.com/c2000)

Code Composer Studio Flash Plug-In

10 - 14 TMS320C28x MCU Workshop - System Design


Code Security Module (CSM)

Code Security Module (CSM)


Code Security Module (CSM)
‹ Access to the following on-chip memory is restricted:
0x000A80 Flash Registers

0x008000 L0 SARAM (4Kw)


0x009000 L1 SARAM (4Kw)
0x00A000 L2 SARAM (4Kw)
0x00B000 L3 SARAM (4Kw)

Dual
0x300000 FLASH (256Kw) Mapped
128-Bit Password
0x340000
0x380400 OTP (1Kw)
0x3F8000 L0 SARAM (4Kw)
0x3F9000 L1 SARAM (4Kw)
0x3FA000 L2 SARAM (4Kw)
0x3FB000 L3 SARAM (4Kw)

‹ Data reads and writes from restricted memory are only


allowed for code running from restricted memory
‹ All other data read/write accesses are blocked:
JTAG emulator/debugger, ROM bootloader, code running in
external memory or unrestricted internal memory

CSM Password

0x300000

FLASH (256Kw) CSM Password


Locations (PWL)
0x33FFF8 128-Bit Password
0x33FFF8 - 0x33FFFF

‹ 128-bit user defined password is stored in Flash

‹ 128-bit KEY registers are used to lock and unlock


the device
Š Mapped in memory space 0x00 0AE0 – 0x00 0AE7
Š Registers “EALLOW” protected

TMS320C28x MCU Workshop - System Design 10 - 15


Code Security Module (CSM)

CSM Registers
Key Registers – accessible by user; EALLOW protected
Address Name Description
0x00 0AE0 KEY0 Low word of 128-bit Key register
0x00 0AE1 KEY1 2nd word of 128-bit Key register
0x00 0AE2 KEY2 3rd word of 128-bit Key register
0x00 0AE3 KEY3 4th word of 128-bit Key register
0x00 0AE4 KEY4 5th word of 128-bit Key register
0x00 0AE5 KEY5 6th word of 128-bit Key register
0x00 0AE6 KEY6 7th word of 128-bit Key register
0x00 0AE7 KEY7 High word of 128-bit Key register
0x00 0AEF CSMSCR CSM status and control register
PWL in memory – reserved for passwords only
Address Name Description
0x33 FFF8 PWL0 Low word of 128-bit password
0x33 FFF9 PWL1 2nd word of 128-bit password
0x33 FFFA PWL2 3rd word of 128-bit password
0x33 FFFB PWL3 4th word of 128-bit password
0x33 FFFC PWL4 5th word of 128-bit password
0x33 FFFD PWL5 6th word of 128-bit password
0x33 FFFE PWL6 7th word of 128-bit password
0x33 FFFF PWL7 High word of 128-bit password

Locking and Unlocking the CSM


‹ The CSM is always locked after reset
‹ To unlock the CSM:
Š Perform a dummy read of each PWL
(passwords in the flash)
Š Write the correct password to each KEY
register
‹ Passwords are all 0xFFFF on new devices
Š When passwords are all 0xFFFF, only a read
of each PWL is required to unlock the device
Š The bootloader does these dummy reads and
hence unlocks devices that do not have
passwords programmed

10 - 16 TMS320C28x MCU Workshop - System Design


Code Security Module (CSM)

CSM Caveats
‹ Never program all the PWL’s as 0x0000
Š Doing so will permanently lock the CSM
‹ Flash addresses 0x33FF80 to 0x33FFF5,
inclusive, must be programmed to 0x0000 to
securely lock the CSM
‹ Remember that code running in unsecured
RAM cannot access data in secured memory
Š Don’t link the stack to secured RAM if you have
any code that runs from unsecured RAM
‹ Do not embed the passwords in your code!
Š Generally, the CSM is unlocked only for debug
Š Code Composer Studio can do the unlocking

CSM Password Match Flow

Start Is PWL = Yes


Device permanently locked
all 0s?
No
Flash device
secure after Yes
reset or runtime Is PWL =
all Fs?
No
Do dummy reads of PWL Write password to KEY registers
0x33 FFF8 – 0x33 FFFF 0x00 0AE0 – 0x00 0AE7
(EALLOW) protected

Device unlocked
Correct Yes
password? User can access on-
chip secure memory
No

TMS320C28x MCU Workshop - System Design 10 - 17


Lab 10: Programming the Flash

Lab 10: Programming the Flash


¾ Objective

The objective of this lab is to program and execute code from the on-chip flash memory. The
TMS320F28335 device has been designed for standalone operation in an embedded system.
Using the on-chip flash eliminates the need for external non-volatile memory or a host processor
from which to bootload. In this lab, the steps required to properly configure the software for
execution from internal flash memory will be covered.

Lab 10: Programming the Flash

ePWM1 ADC DMA


TB Counter ADCINA0 RESULT0
Compare
Action Qualifier
connector
wire ping
data
memory
ePWM2 triggering pong
ADC on period match
using SOC A trigger
every 20.833 µs (48 kHz) ePWM2 CPU runs
FIR data through
Objective: Filter filter during
DMA ISR
‹ Program system into Flash
Pointer

Memory
rewind

data
memory
‹ Learn use of CCS Flash
Plug-in Display
using CCS
‹ DO NOT PROGRAM
PASSWORDS

¾ Procedure

Project File
1. A project named Lab10.pjt has been created for this lab. Open the project by
clicking on Project Æ Open… and look in C:\C28x\Labs\Lab10. All Build
Options have been configured the same as the previous lab. The files used in this lab are:
Adc_9_10_12.c Filter.c
CodeStartBranch.asm Gpio.c
DefaultIsr_9_10_12a.c Lab_10.cmd
DelayUs.asm Main_10.c
Dma.c PieCtrl_5_6_7_8_9_10.c
DSP2833x_GlobalVariableDefs.c PieVect_5_6_7_8_9_10.c
DSP2833x_Headers_nonBIOS.cmd SysCtrl.c
ECap_7_8_9_10_12.c Watchdog.c
EPwm_7_8_9_10_12.c

10 - 18 TMS320C28x MCU Workshop - System Design


Lab 10: Programming the Flash

Link Initialized Sections to Flash


Initialized sections, such as code and constants, must contain valid values at device power-up.
For a stand-alone embedded system with the F28335 device, these initialized sections must be
linked to the on-chip flash memory. Note that a stand-alone embedded system must operate
without an emulator or debugger in use, and no host processor is used to perform bootloading.

Each initialized section actually has two addresses associated with it. First, it has a LOAD
address which is the address to which it gets loaded at load time (or at flash programming time).
Second, it has a RUN address which is the address from which the section is accessed at runtime.
The linker assigns both addresses to the section. Most initialized sections can have the same
LOAD and RUN address in the flash. However, some initialized sections need to be loaded to
flash, but then run from RAM. This is required, for example, if the contents of the section needs
to be modified at runtime by the code.

2. Open and inspect the linker command file Lab_10.cmd. Notice that a memory block
named FLASH_ABCDEFGH has been been created at origin = 0x300000, length =
0x03FF80 on Page 0. This flash memory block length has been selected to avoid
conflicts with other required flash memory spaces. See the reference slide at the end of
this lab exercise for further details showing the address origins and lengths of the various
memory blocks used.

3. Edit Lab_10.cmd to link the following compiler sections to on-chip flash memory
block FLASH_ABCDEFGH:

Compiler Sections

.text

.cinit

.const

.econst

.pinit

.switch

4. In Lab_10.cmd notice that the section named “IQmath” is an initialized section that
needs to load to and run from flash. Previously the “IQmath” section was linked to
L0123SARAM. Edit Lab_10.cmd so that this section is now linked to
FLASH_ABCDEFGH. Save your work and close the file.

Copying Interrupt Vectors from Flash to RAM


The interrupt vectors must be located in on-chip flash memory and at power-up needs to be
copied to the PIE RAM as part of the device initialization procedure. The code that performs this
copy is located in InitPieCtrl(). The C-compiler runtime support library contains a memory copy
function called memcpy() which will be used to perform the copy.

TMS320C28x MCU Workshop - System Design 10 - 19


Lab 10: Programming the Flash

5. Open and inspect InitPieCtrl() in PieCtrl_5_6_7_8_9_10.c. Notice the memcpy()


function used to initialize (copy) the PIE vectors. At the end of the file a structure is used
to enable the PIE.

Initializing the Flash Control Registers


The initialization code for the flash control registers cannot execute from the flash memory (since
it is changing the flash configuration!). Therefore, the initialization function for the flash control
registers must be copied from flash (load address) to RAM (run address) at runtime. The memory
copy function memcpy() will again be used to perform the copy. The initialization code for the
flash control registers InitFlash() is located in the Flash.c file.

6. Add Flash.c to the project.

7. Open and inspect Flash.c. The C compiler CODE_SECTION pragma is used to place
the InitFlash() function into a linkable section named “secureRamFuncs”.

8. The “secureRamFuncs” section will be linked using the user linker command file
Lab_10.cmd. Open and inspect Lab_10.cmd. The “secureRamFuncs” will load
to flash (load address) but will run from L0123SARAM (run address). Also notice that
the linker has been asked to generate symbols for the load start, load end, and run start
addresses.

While not a requirement from a DSP hardware or development tools perspective (since
the C28x DSP has a unified memory architecture), historical convention is to link code to
program memory space and data to data memory space. Therefore, notice that for the
L0123SARAM memory we are linking “secureRamFuncs” to, we are specifiying
“PAGE = 0” (which is program memory).

9. Open and inspect Main_10.c. Notice that the memory copy function memcpy() is
being used to copy the section “secureRamFuncs”, which contains the initialization
function for the flash control registers.

10. Add a line of code to main() to call the InitFlash() function. There are no passed
parameters or return values. You just type

InitFlash();

at the desired spot in main().

Code Security Module and Passwords


The CSM module provides protection against unwanted copying (i.e. pirating!) of your code from
flash, OTP memory, and the L0, L1, L2 and L3 RAM blocks. The CSM uses a 128-bit password
made up of 8 individual 16-bit words. They are located in flash at addresses 0x33FFF8 to
0x33FFFF. During this lab, dummy passwords of 0xFFFF will be used – therefore only dummy
reads of the password locations are needed to unsecure the CSM. DO NOT PROGRAM ANY
REAL PASSWORDS INTO THE DEVICE. After development, real passwords are typically

10 - 20 TMS320C28x MCU Workshop - System Design


Lab 10: Programming the Flash

placed in the password locations to protect your code. We will not be using real passwords in the
workshop.

The CSM module also requires programming values of 0x0000 into flash addresses 0x33FF80
through 0x33FFF5 in order to properly secure the CSM. Both tasks will be accomplished using a
simple assembly language file Passwords.asm.

11. Add Passwords.asm to the project.

12. Open and inspect Passwords.asm. This file specifies the desired password values
(DO NOT CHANGE THE VALUES FROM 0xFFFF) and places them in an initialized
section named “passwords”. It also creates an initialized section named
“csm_rsvd” which contains all 0x0000 values for locations 0x33FF80 to 0x33FFF5
(length of 0x76).

13. Open Lab_10.cmd and notice that the initialized sections for “passwords” and
“csm_rsvd” are linked to memories named PASSWORDS and CSM_RSVD,
respectively.

Executing from Flash after Reset


The F28335 device contains a ROM bootloader that will transfer code execution to the flash after
reset. When the boot mode selection pins are set for “Jump to Flash” mode, the bootloader will
branch to the instruction located at address 0x33FFF6 in the flash. An instruction that branches
to the beginning of your program needs to be placed at this address. Note that the CSM
passwords begin at address 0x33FFF8. There are exactly two words available to hold this branch
instruction, and not coincidentally, a long branch instruction “LB” in assembly code occupies
exactly two words. Generally, the branch instruction will branch to the start of the C-
environment initialization routine located in the C-compiler runtime support library. The entry
symbol for this routine is _c_int00. Recall that C code cannot be executed until this setup routine
is run. Therefore, assembly code must be used for the branch. We are using the assembly code
file named CodeStartBranch.asm.

14. Open and inspect CodeStartBranch.asm. This file creates an initialized section
named “codestart” that contains a long branch to the C-environment setup routine.
This section needs to be linked to a block of memory named BEGIN_FLASH.

15. In the earlier lab exercises, the section “codestart” was directed to the memory
named BEGIN_M0. Edit Lab_10.cmd so that the section “codestart” will be
directed to BEGIN_FLASH. Save your work and close the opened files.

16. The eZdsp™ board needs to be configured for “Jump to Flash” bootmode. Move switch
SW1 positions 1, 2, 3 and 4 to the “1” position (all switches to the Left) to accomplish
this. Details of switch positions can be found in Appendix A. This switch controls the
pullup/down resistor on the GPIO84, GPIO85, GPIO86 and GPIO87 pins, which are the
pins sampled by the bootloader to determine the bootmode. (For additional information
on configuring the “Jump to Flash” bootmode see the TMS320x2833x DSP Boot ROM
Reference Guide, and also the eZdsp F28335 Technical Reference).

TMS320C28x MCU Workshop - System Design 10 - 21


Lab 10: Programming the Flash

Build – Lab.out
17. At this point we need to build the project, but not have CCS automatically load it since
CCS cannot load code into the flash! (the flash must be programmed). On the menu bar
click: Option Æ Customize… and select the “Program/Project CIO” tab.
Uncheck “Load Program After Build”.

CCS has a feature that automatically steps over functions without debug information.
This can be useful for accelerating the debug process provided that you are not interested
in debugging the function that is being stepped-over. While single-stepping in this lab
exercise we do not want to step-over any functions. Therefore, select the “Debug
Properties” tab. Uncheck “Step over functions without debug
information when source stepping”, then click OK.

18. Click the “Build” button to generate the Lab.out file to be used with the CCS Flash
Plug-in.

CCS Flash Plug-in


19. Open the Flash Plug-in tool by clicking:

Tools Æ F28xx On-Chip Flash Programmer

20. A Clock Configuration window may open. If needed, in the Clock Configuration
window set “OSCCLK (MHz):” to 30, “DIVSEL:” to /2, and “PLLCR Value:” to 10.
Then click OK. In the next Flash Programmer Settings window confirm that the selected
DSP device to program is F28335 and all options have been checked. Click OK.

21. Notice that the eZdsp™ board uses a 30 MHz oscillator (located on the board near LED
DS1). Confirm the “Clock Configuration” in the upper left corner has the OSCCLK set
to 30 MHz, the DIVSEL set to /2, and the PLLCR value set to 10. Recall that the PLL is
divided by two, which gives a SYSCLKOUT of 150 MHz.

22. Confirm that all boxes are checked in the “Erase Sector Selection” area of the plug-in
window. We want to erase all the flash sectors.

23. We will not be using the plug-in to program the “Code Security Password”. Do not
modify the Code Security Password fields.

24. In the “Operation” block, notice that the “COFF file to Program/Verify” field
automatically defaults to the current .out file. Check to be sure that “Erase, Program,
Verify” is selected. We will be using the default wait states, as shown on the slide in this
module.

25. Click “Execute Operation” to program the flash memory. Watch the programming status
update in the plug-in window.

26. After successfully programming the flash memory, close the programmer window.

10 - 22 TMS320C28x MCU Workshop - System Design


Lab 10: Programming the Flash

Running the Code – Using CCS


27. In order to effectively debug with CCS, we need to load the symbolic debug information
(e.g., symbol and label addresses, source file links, etc.) so that CCS knows where
everything is in your code. Click:

File Æ Load Symbols Æ Load Symbols Only…

and select Lab10.out in the Debug folder.

28. Reset the DSP. The program counter should now be at 0x3FF9A9, which is the start of
the bootloader in the Boot ROM.

29. Single-Step <F11> through the bootloader code until you arrive at the beginning of the
codestart section in the CodeStartBranch.asm file. (Be patient, it will take about
125 single-steps). Notice that we have placed some code in CodeStartBranch.asm
to give an option to first disable the watchdog, if selected.

30. Step a few more times until you reach the start of the C-compiler initialization routine at
the symbol _c_int00.

31. Now do Debug Æ Go Main. The code should stop at the beginning of your main()
routine. If you got to that point succesfully, it confirms that the flash has been
programmed properly, and that the bootloader is properly configured for jump to flash
mode, and that the codestart section has been linked to the proper address.

32. You can now RUN the DSP, and you should observe the LED on the board blinking. Try
resetting the DSP and hitting RUN (without doing all the stepping and the Go Main
procedure). The LED should be blinking again.

Running the Code – Stand-alone Operation (No Emulator)


33. Close Code Composer Studio.

34. Disconnect the USB cable (emulator) from the eZdsp™ board.

35. Remove the power from the board.

36. Re-connect the power to the board.

37. The LED should be blinking, showing that the code is now running from flash memory.

Return Switch SW1 Back to Default Positions


38. Remove the power from the board.

39. Please return the settings of switch SW1 back to the default positions “Jump to
M0SARAM” bootmode as shown in the table below (see Appendix A for switch position
details):

TMS320C28x MCU Workshop - System Design 10 - 23


Lab 10: Programming the Flash

Position 4 Position 3 Position 2 Position 1 Boot


GPIO87 GPIO86 GPIO85 GPIO84 Mode

Right – 0 Left – 1 Right – 0 Right – 0 M0 SARAM

End of Exercise

10 - 24 TMS320C28x MCU Workshop - System Design


Lab 10: Programming the Flash

Lab 10 Reference: Programming the Flash

Flash Memory Section Blocks

origin =
0x30 0000
FLASH
length = 0x3FF80
page = 0 Lab_10.cmd
SECTIONS
{
0x33 FF80 CSM_RSVD codestart :> BEGIN_FLASH, PAGE = 0
length = 0x76 passwords :> PASSWORDS, PAGE = 0
page = 0 csm_rsvd :> CSM_RSVD, PAGE = 0
0x33 FFF6 BEGIN_FLASH }
length = 0x2
page = 0
0x33 FFF8 PASSWORDS
length = 0x8
page = 0

Startup Sequence from Flash Memory

0x30 0000 _c_int00 “rts2800_ml.lib”


FLASH (256Kw)

4
0x33 7FF6 LB
_c_int00 5
“user” code sections
Passwords (8w) main ( )
{
……
3 ……
……
0x3F F000 Boot ROM (8Kw) }
Boot Code
0x3F F9A9
{SCAN GPIO}
2
BROM vector (32w)
0x3F FFC0 0x3F F9A9
1

RESET

TMS320C28x MCU Workshop - System Design 10 - 25


Lab 10: Programming the Flash

10 - 26 TMS320C28x MCU Workshop - System Design


Communications

Introduction
The TMS320C28x contains features that allow several methods of communication and data
exchange between the C28x and other devices. Many of the most commonly used
communications techniques are presented in this module.

The intent of this module is not to give exhaustive design details of the communication
peripherals, but rather to provide an overview of the features and capabilities. Once these
features and capabilities are understood, additional information can be obtained from various
resources such as documentation, as needed. This module will cover the basic operation of the
communication peripherals, as well as some basic terms and how they work.

Learning Objectives
Learning Objectives

‹ Serial Peripheral Interface (SPI)


‹ Serial Communication Interface (SCI)
‹ Multichannel Buffered Serial Port (McBSP)

‹ Inter-Integrated Circuit (I2C)

‹ Enhanced Controller Area Network (eCAN)

Note: Up to 1 SPI module (A), 3 SCI modules (A/B/C), 2 McBSP modules (A/B), 1 I2C
module (A), and 2 eCAN modules (A/B) are available on the F2833x devices.

TMS320C28x MCU Workshop - Communications 11 - 1


Module Topics

Module Topics
Communications.......................................................................................................................................11-1

Module Topics........................................................................................................................................11-2
Communications Techniques .................................................................................................................11-3
Serial Peripheral Interface (SPI) ...........................................................................................................11-4
SPI Registers .....................................................................................................................................11-7
SPI Summary.....................................................................................................................................11-8
Serial Communications Interface (SCI) .................................................................................................11-9
Multiprocessor Wake-Up Modes.....................................................................................................11-11
SCI Registers ...................................................................................................................................11-14
SCI Summary ..................................................................................................................................11-15
Multichannel Buffered Serial Port (McBSP) .......................................................................................11-16
Inter-Integrated Circuit (I2C)..............................................................................................................11-19
I2C Operating Modes and Data Formats .........................................................................................11-20
I2C Summary...................................................................................................................................11-21
Enhanced Controller Area Network (eCAN) .......................................................................................11-22
CAN Bus and Node .........................................................................................................................11-23
Principles of Operation....................................................................................................................11-24
Message Format and Block Diagram...............................................................................................11-25
eCAN Summary ..............................................................................................................................11-26

11 - 2 TMS320C28x MCU Workshop - Communications


Communications Techniques

Communications Techniques
Several methods of implementing a TMS320C28x communications system are possible. The
method selected for a particular design should reflect the method that meets the required data rate
at the lowest cost. Various categories of interface are available and are summarized in the
learning objective slide. Each will be described in this module.

Synchronous vs. Asynchronous


‹ Synchronous ‹ Asynchronous
Š Short distances (on- Š longer distances
board) Š Lower data rate ( ≈ 1/8 of
SPI)
Š High data rate
Š Implied clock (clk/data
Š Explicit clock mixed)
Š Economical with
reasonable performance

C28x C28x

Port U2 Port
Destination

PCB PCB

Serial ports provide a simple, hardware-efficient means of high-level communication between


devices. Like the GPIO pins, they may be used in stand-alone or multiprocessing systems.

In a multiprocessing system, they are an excellent choice when both devices have an available
serial port and the data rate requirement is relatively low. Serial interface is even more desirable
when the devices are physically distant from each other because the inherently low number of
wires provides a simpler interconnection.

Serial ports require separate lines to implement, and they do not interfere in any way with the data
and address lines of the processor. The only overhead they require is to read/write new words
from/to the ports as each word is received/transmitted. This process can be performed as a short
interrupt service routine under hardware control, requiring only a few cycles to maintain.

The C28x family of devices have both synchronous and asynchronous serial ports. Detailed
features and operation will be described next.

TMS320C28x MCU Workshop - Communications 11 - 3


Serial Peripheral Interface (SPI)

Serial Peripheral Interface (SPI)


The SPI module is a synchronous serial I/O port that shifts a serial bit stream of variable length
and data rate between the C28x and other peripheral devices. During data transfers, one SPI
device must be configured as the transfer MASTER, and all other devices configured as
SLAVES. The master drives the transfer clock signal for all SLAVES on the bus. SPI
communications can be implemented in any of three different modes:

• MASTER sends data, SLAVES send dummy data

• MASTER sends data, one SLAVE sends data

• MASTER sends dummy data, one SLAVE sends data

In its simplest form, the SPI can be thought of as a programmable shift register. Data is shifted in
and out of the SPI through the SPIDAT register. Data to be transmitted is written directly to the
SPIDAT register, and received data is latched into the SPIBUF register for reading by the CPU.
This allows for double-buffered receive operation, in that the CPU need not read the current
received data from SPIBUF before a new receive operation can be started. However, the CPU
must read SPIBUF before the new operation is complete of a receiver overrun error will occur. In
addition, double-buffered transmit is not supported: the current transmission must be complete
before the next data character is written to SPIDAT or the current transmission will be corrupted.

The Master can initiate a data transfer at any time because it controls the SPICLK signal. The
software, however, determines how the Master detects when the Slave is ready to broadcast.

SPI Data Flow

‹ Simultaneous transmits and receive


‹ SPI Master provides the clock signal

SPI Device #1 - Master SPI Device #2 - Slave


shift shift

SPI
SPIShift
ShiftRegister
Register SPI
SPIShift
ShiftRegister
Register

clock

11 - 4 TMS320C28x MCU Workshop - Communications


Serial Peripheral Interface (SPI)

SPI Block Diagram


C28x - SPI Master Mode Shown
SPISIMO
RX FIFO_0

RX FIFO_15
SPIRXBUF.15-0

MSB LSB
SPIDAT.15-0 SPISOMI

SPITXBUF.15-0
TX FIFO_0

TX FIFO_15

LSPCLK baud clock clock SPICLK


rate polarity phase

SPI Transmit / Receive Sequence


1. Slave writes data to be sent to its shift register (SPIDAT)

2. Master writes data to be sent to its shift register (SPIDAT or SPITXBUF)

3. Completing Step 2 automatically starts SPICLK signal of the Master

4. MSB of the Master’s shift register (SPIDAT) is shifted out, and LSB of the Slave’s shift
register (SPIDAT) is loaded

5. Step 4 is repeated until specified number of bits are transmitted

6. SPIDAT register is copied to SPIRXBUF register

7. SPI INT Flag bit is set to 1

8. An interrupt is asserted if SPI INT ENA bit is set to 1

9. If data is in SPITXBUF (either Slave or Master), it is loaded into SPIDAT and transmission
starts again as soon as the Master’s SPIDAT is loaded

TMS320C28x MCU Workshop - Communications 11 - 5


Serial Peripheral Interface (SPI)

Since data is shifted out of the SPIDAT register MSB first, transmission characters of less than 16
bits must be left-justified by the CPU software prior to be written to SPIDAT.

Received data is shifted into SPIDAT from the left, MSB first. However, the entire sixteen bits
of SPIDAT is copied into SPIBUF after the character transmission is complete such that received
characters of less than 16 bits will be right-justified in SPIBUF. The non-utilized higher
significance bits must be masked-off by the CPU software when it interprets the character. For
example, a 9 bit character transmission would require masking-off the 7 MSB’s.

SPI Data Character Justification

‹ Programmable data
length of 1 to 16 bits
‹ Transmitted data of less SPIDAT - Processor #1
than 16 bits must be left 11001001XXXXXXXX
justified 11001001XXXXXXXX
Š MSB transmitted first

‹ Received data of less


than 16 bits are right
justified SPIDAT - Processor #2
XXXXXXXX11001001
XXXXXXXX11001001
‹ User software must
mask-off unused MSB’s

11 - 6 TMS320C28x MCU Workshop - Communications


Serial Peripheral Interface (SPI)

SPI Registers
SPI Baud Rate Register
SpixRegs.SPIBRR

Need to set this only when in master mode!


15-7 6-0
reserved SPI BIT RATE

LSPCLK
, SPIBRR = 3 to 127
(SPIBRR + 1)
SPICLK signal =
LSPCLK
, SPIBRR = 0, 1, or 2
4

Baud Rate Determination: The Master specifies the communication baud rate using its baud rate
register (SPIBRR.6-0):

LSPCLK
• For SPIBRR = 3 to 127: SPI Baud Rate = bits/sec
( SPIBRR + 1)

LSPCLK
• For SPIBRR = 0, 1, or 2: SPI Baud Rate = bits/sec
4

From the above equations, one can compute

Maximum data rate = 25 Mbps @ 100 MHz

Character Length Determination: The Master and Slave must be configured for the same
transmission character length. This is done with bits 0, 1, 2 and 3 of the configuration control
register (SPICCR.3-0). These four bits produce a binary number, from which the character length
is computed as binary + 1 (e.g. SPICCR.3-0 = 0010 gives a character length of 3).

TMS320C28x MCU Workshop - Communications 11 - 7


Serial Peripheral Interface (SPI)

Select SPI Registers


‹ Configuration Control SpixRegs.SPICCR
Š Reset, Clock Polarity, Loopback, Character Length

‹ Operation Control SpixRegs.SPICTL


Š Overrun Interrupt Enable, Clock Phase, Interrupt Enable
Š Master / Slave Transmit enable

‹ Status SpixRegs.SPIST
Š RX Overrun Flag, Interrupt Flag, TX Buffer Full Flag

‹ FIFO Transmit SpixRegs.SPIFFTX


FIFO Receive SpixRegs.SPIFFRX
Š FIFO Enable, FIFO Reset
Š FIFO Over-flow flag, Over-flow Clear
Š Number of Words in FIFO (FIFO Status)
Š FIFO Interrupt Enable, Interrupt Status, Interrupt Clear
Š FIFO Interrupt Level (Number of Words in FIFO)

Note: refer to the reference guide for a complete listing of registers

SPI Summary
SPI Summary

‹ Synchronous serial communications


Š Two wire transmit or receive (half duplex)
Š Three wire transmit and receive (full duplex)
‹ Software configurable as master or slave
Š C28x provides clock signal in master mode
‹ Data length programmable from 1-16 bits
‹ 125 different programmable baud rates

11 - 8 TMS320C28x MCU Workshop - Communications


Serial Communications Interface (SCI)

Serial Communications Interface (SCI)


The SCI module is a serial I/O port that permits Asynchronous communication between the C28x
and other peripheral devices. The SCI transmit and receive registers are both double-buffered to
prevent data collisions and allow for efficient CPU usage. In addition, the C28x SCI is a full
duplex interface which provides for simultaneous data transmit and receive. Parity checking and
data formatting is also designed to be done by the port hardware, further reducing software
overhead.

SCI Pin Connections


(Full Duplex Shown)

TX FIFO_0 TX FIFO_0

TX FIFO_15 TX FIFO_15
Transmitter-data Transmitter-data
buffer register buffer register

8 8

Transmitter SCITXD SCITXD Transmitter


shift register shift register

Receiver SCIRXD SCIRXD Receiver


shift register shift register
8 8
Receiver-data Receiver-data
buffer register buffer register
RX FIFO_0 RX FIFO_0

RX FIFO_15 RX FIFO_15

SCI Device #1 SCI Device #2

TMS320C28x MCU Workshop - Communications 11 - 9


Serial Communications Interface (SCI)

SCI Data Format

NRZ (non-return to zero) format

Addr/
Start LSB 2 3 4 5 6 7 MSB Parity Stop 1 Stop 2
Data

This bit present only in Address-bit mode

Communications Control Register (ScixRegs.SCICCR)


7 6 5 4 3 2 1 0
Stop Even/Odd Parity Loopback Addr/Idle SCI SCI SCI
Bits Parity Enable Enable Mode Char2 Char1 Char0

0 = 1 Stop bit 0 = Disabled 0 = Idle-line mode # of data bits = (binary + 1)


1 = 2 Stop bits 1 = Enabled 1 = Addr-bit mode e.g. 110b gives 7 data bits

0 = Odd 0 = Disabled
1 = Even 1 = Enabled

The basic unit of data is called a character and is 1 to 8 bits in length. Each character of data is
formatted with a start bit, 1 or 2 stop bits, an optional parity bit, and an optional address/data bit.
A character of data along with its formatting bits is called a frame. Frames are organized into
groups called blocks. If more than two serial ports exist on the SCI bus, a block of data will
usually begin with an address frame which specifies the destination port of the data as determined
by the user’s protocol.

The start bit is a low bit at the beginning of each frame which marks the beginning of a frame.
The SCI uses a NRZ (Non-Return-to-Zero) format which means that in an inactive state the
SCIRX and SCITX lines will be held high. Peripherals are expected to pull the SCIRX and
SCITX lines to a high level when they are not receiving or transmitting on their respective lines.

When configuring the SCICCR, the SCI port should first be held in an inactive state. This
is done using the SW RESET bit of the SCI Control Register 1 (SCICTL1.5). Writing a 0 to this
bit initializes and holds the SCI state machines and operating flags at their reset condition. The
SCICCR can then be configured. Afterwards, re-enable the SCI port by writing a 1 to the SW
RESET bit. At system reset, the SW RESET bit equals 0.

11 - 10 TMS320C28x MCU Workshop - Communications


Serial Communications Interface (SCI)

SCI Data Timing

• Start bit valid if 4 consecutive SCICLK periods of zero bits after falling edge
• Majority vote taken on 4th , 5 th, and 6 th SCICLK cycles

Majority
Vote

SCICLK
(Internal)
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2

SCIRXD

Start Bit LSB of Data

Falling Edge Detected

Note: 8 SCICLK periods per data bit

Multiprocessor Wake-Up Modes


Multiprocessor Wake-Up Modes

‹ Allows numerous processors to be hooked


up to the bus, but transmission occurs
between only two of them
‹ Idle-line or Address-bit modes
‹ Sequence of Operation
1. Potential receivers set SLEEP = 1, which disables RXINT
except when an address frame is received
2. All transmissions begin with an address frame
3. Incoming address frame temporarily wakes up all SCIs on bus
4. CPUs compare incoming SCI address to their SCI address
5. Process following data frames only if address matches

TMS320C28x MCU Workshop - Communications 11 - 11


Serial Communications Interface (SCI)

Idle-Line Wake-Up Mode


‹ Idle time separates blocks of frames
‹ Receiver wakes up when SCIRXD high for 10 or
more bit periods
‹ Two transmit address methods
Š Deliberate software delay of 10 or more bits
Š Set TXWAKE bit to automatically leave exactly
11 idle bits

Idle periods
of less than Block of Frames
10 bits

SCIRXD/ Last Data SP ST Addr SP ST Data SP ST Last Data SP ST Addr SP


SCITXD

Idle Address frame 1st data frame Idle


Period follows 10 bit Period
10 bits or greater idle 10 bits
or greater or greater

Address-Bit Wake-Up Mode

‹ All frames contain an extra address bit


‹ Receiver wakes up when address bit detected
‹ Automatic setting of Addr/Data bit in frame by
setting TXWAKE = 1 prior to writing address to
SCITXBUF
Block of Frames

SCIRXD/ Last Data 0 SP ST Addr 1 SP ST Data 0 SP ST Last Data 0 SP ST Addr 1 SP


SCITXD

First frame within 1st data frame


no additional
Idle Period block is Address. idle bits needed
length of no ADDR/DATA beyond stop bits
significance bit set to 1

11 - 12 TMS320C28x MCU Workshop - Communications


Serial Communications Interface (SCI)

The SCI interrupt logic generates interrupt flags when it receives or transmits a complete
character as determined by the SCI character length. This provides a convenient and efficient
way of timing and controlling the operation of the SCI transmitter and receiver. The interrupt
flag for the transmitter is TXRDY (SCICTL2.7), and for the receiver RXRDY (SCIRXST.6).
TXRDY is set when a character is transferred to TXSHF and SCITXBUF is ready to receive the
next character. In addition, when both the SCIBUF and TXSHF registers are empty, the TX
EMPTY flag (SCICTL2.6) is set. When a new character has been received and shifted into
SCIRXBUF, the RXRDY flag is set. In addition, the BRKDT flag is set if a break condition
occurs. A break condition is where the SCIRXD line remains continuously low for at least ten
bits, beginning after a missing stop bit. Each of the above flags can be polled by the CPU to
control SCI operations, or interrupts associated with the flags can be enabled by setting the
RX/BK INT ENA (SCICTL2.1) and/or the TX INT ENA (SCICTL2.0) bits active high.

Additional flag and interrupt capability exists for other receiver errors. The RX ERROR flag is
the logical OR of the break detect (BRKDT), framing error (FE), receiver overrun (OE), and
parity error (PE) bits. RX ERROR high indicates that at least one of these four errors has
occurred during transmission. This will also send an interrupt request to the CPU if the RX ERR
INT ENA (SCICTL1.6) bit is set.

TMS320C28x MCU Workshop - Communications 11 - 13


Serial Communications Interface (SCI)

SCI Registers
SCI Baud Rate Registers
LSPCLK
, BRR = 1 to 65535
(BRR + 1) x 8
SCI baud rate =
LSPCLK
, BRR = 0
16

Baud-Select MSbyte Register (ScixRegs.SCIHBAUD)


7 6 5 4 3 2 1 0
BAUD15
BAUD14 BAUD13 BAUD12 BAUD11 BAUD10 BAUD9 BAUD8
(MSB)

Baud-Select LSbyte Register (ScixRegs.SCILBAUD)


7 6 5 4 3 2 1 0
BAUD0
BAUD7 BAUD6 BAUD5 BAUD4 BAUD3 BAUD2 BAUD1
(LSB)

Baud Rate Determination: The values in the baud-select registers (SCIHBAUD and SCILBAUD)
concatenate to form a 16 bit number that specifies the baud rate for the SCI.

LSPCLK
• For BRR = 1 to 65535: SCI Baud Rate = bits/sec
( BRR + 1) × 8

LSPCLK
• For BRR = 0: SCI Baud Rate = bits/sec
16

Max data rate = 6.25 Mbps @ 100 MHz

Note that the CLKOUT for the SCI module is one-half the CPU clock rate.

11 - 14 TMS320C28x MCU Workshop - Communications


Serial Communications Interface (SCI)

Select SCI Registers


‹ Control 1 ScixRegs.SCICTL1
Š Reset, Transmitter / Receiver Enable
Š TX Wake-up, Sleep, RX Error Interrupt Enable

‹ Control 2 ScixRegs.SPICTL2
Š TX Buffer Full / Empty Flag, TX Ready Interrupt Enable
Š RX Break Interrupt Enable

‹ Receiver Status ScixRegs.SCIRXST


Š Error Flag, Ready, Flag Break-Detect Flag, Framing Error
Detect Flag, Parity Error Flag, RX Wake-up Detect Flag

‹ FIFO Transmit ScixRegs.SCIFFTX


FIFO Receive ScixRegs.SCIFFRX
Š FIFO Enable, FIFO Reset
Š FIFO Over-flow flag, Over-flow Clear
Š Number of Words in FIFO (FIFO Status)
Š FIFO Interrupt Enable, Interrupt Status, Interrupt Clear
Š FIFO Interrupt Level (Number of Words in FIFO)

Note: refer to the reference guide for a complete listing of registers

SCI Summary
SCI Summary
‹ Asynchronous communications format
‹ 65,000+ different programmable baud rates
‹ Two wake-up multiprocessor modes
Š Idle-line wake-up & Address-bit wake-up
‹ Programmable data word format
Š 1 to 8 bit data word length
Š 1 or 2 stop bits
Š even/odd/no parity
‹ Error Detection Flags
Š Parity error; Framing error; Overrun error; Break detection
‹ Transmit FIFO and receive FIFO
‹ Individual interrupts for transmit and receive

TMS320C28x MCU Workshop - Communications 11 - 15


Multichannel Buffered Serial Port (McBSP)

Multichannel Buffered Serial Port (McBSP)


McBSP Block Diagram

Peripheral / DMA Bus MFSXx


16 16
MCLKXx
DXR2 TX Buffer DXR1 TX Buffer
16 16

XSR2 XSR1 MDXx

CPU
RSR2 RSR1 MDRx
16 16

RBR2 Register RBR1 Register


16 16

DRR2 RX Buffer DRR1 RX Buffer MCLKRx


16 16
MFSRx
Peripheral / DMA Bus

Definition: Bit and Word

CLK

FS

D a1 a0 b7 b6 b5 b4 b3 b2 b1 b0

Word
Bit

‹ “Bit” - one data bit per serial clock period


‹ “Word” or “channel” contains
number of bits (8, 12, 16, 20, 24, 32)

11 - 16 TMS320C28x MCU Workshop - Communications


Multichannel Buffered Serial Port (McBSP)

Definition: Word and Frame

FS

D w6 w7 w0 w1 w2 w3 w4 w5 w6 w7

Frame
Word

‹ “Frame” - contains one or multiple words


‹ Number of words per frame: 1-128

Multi-Channel Selection
Ch0-0
Multi-channel
Frame TDM Bit Stream Ch0-1
M Transmit
C 0 Ch31 ... Ch1 Ch0
c & Ch5-0
O
D 1 Ch31 ... Ch1 Ch0
B Receive Ch5-1
E S only selected
C P Channels Ch27-0
Ch27-1

‹ Allows multiple channels (words) to be independently selected for transmit


and receive (e.g. only enable Ch0, 5, 27 for receive, then process via CPU)

‹ The McBSP keeps time sync with all channels, but only “listens” or “talks”
if the specific channel is enabled (reduces processing/bus overhead)

‹ Multi-channel mode controlled primarily via two registers:


Multi-channel Control Reg Rec/Xmt Channel Enable Regs
MCR R/XCER (A-H)
(enables Mc-mode) (enable/disable channels)
‹ Up to 128 channels can be enabled/disabled

TMS320C28x MCU Workshop - Communications 11 - 17


Multichannel Buffered Serial Port (McBSP)

McBSP Summary
‹ Independent clocking and framing for
transmit and receive
‹ Internal or external clock and frame sync
‹ Data size of 8, 12, 16, 20, 24, or 32 bits
‹ TDM mode - up to 128 channels
Š Used for T1/E1 interfacing
‹ μ-law and A-law companding
‹ SPI mode
‹ Direct Interface to many codecs
‹ Can be serviced by the DMA

11 - 18 TMS320C28x MCU Workshop - Communications


Inter-Integrated Circuit (I2C)

Inter-Integrated Circuit (I2C)


Inter-Integrated Circuit (I2C)
‹ Philips I2C-bus specification compliant, version 2.1
‹ Data transfer rate from 10 kbps up to 400 kbps
‹ Each device can be considered as a Master or Slave
‹ Master initiates data transfer and generates clock signal
‹ Device addressed by Master is considered a Slave
‹ Multi-Master mode supported
‹ Standard Mode – send exactly n data values (specified in register)
‹ Repeat Mode – keep sending data values (use software to initiate a
stop or new start condition)
VDD ..
Pull-up 28xx I2C
Resisters I2C Controller

Serial Data (SDA)


Serial Clock (SCL)
.. . . . . . . . .
I2C 28xx
EPROM I2C

I2C Block Diagram

I2CXSR I2CDXR

TX FIFO
SDA
RX FIFO

I2CRSR I2CDRR

Clock
SCL
Circuits

TMS320C28x MCU Workshop - Communications 11 - 19


Inter-Integrated Circuit (I2C)

I2C Operating Modes and Data Formats


I2C Operating Modes

Operating Mode Description

Slave-receiver mode Module is a slave and receives data from a master


(all slaves begin in this mode)

Slave-transmitter mode Module is a slave and transmits data to a master


(can only be entered from slave-receiver mode)

Master-receiver mode Module is a master and receives data from a slave


(can only be entered from master-transmit mode)

Master-transmitter mode Module is a master and transmits to a slave


(all masters begin in this mode)

I2C Serial Data Formats


7-Bit Addressing Format
1 7 1 1 n 1 n 1 1
S Slave Address R/W ACK Data ACK Data ACK P

10-Bit Addressing Format


1 7 1 1 8 1 n 1 1
S 11110AA R/W ACK AAAAAAAA ACK Data ACK P

Free Data Format


1 n 1 n 1 n 1 1
S Data ACK Data ACK Data ACK P

R/W = 0 – master writes data to addressed slave


R/W = 1 – master reads data from the slave
n = 1 to 8 bits
S = Start (high-to-low transition on SDA while SCL is high)
P = Stop (low-to-high transition on SDA while SCL is high)

11 - 20 TMS320C28x MCU Workshop - Communications


Inter-Integrated Circuit (I2C)

I2C Arbitration
‹ Arbitration procedure invoked if two or more master-
transmitters simultaneously start transmission
Š Procedure uses data presented on serial data bus (SDA) by
competing transmitters
Š First master-transmitter which drives SDA high is overruled
by another master-transmitter that drives SDA low
Š Procedure gives priority to the data stream with the lowest
binary value

SCL
Device #1 lost arbitration
and switches to slave-
Data from 1 0 receiver mode
device #1
Data from Device #2
1 0 0 1 0 1 drives SDA
device #2

SDA 1 0 0 1 0 1

I2C Summary
I2C Summary

‹ Compliance with Philips I2C-bus


specification (version 2.1)
‹ 7-bit and 10-bit addressing modes
‹ Configurable 1 to 8 bit data words
‹ Data transfer rate from 10 kbps up to
400 kbps
‹ Transmit FIFO and receive FIFO

TMS320C28x MCU Workshop - Communications 11 - 21


Enhanced Controller Area Network (eCAN)

Enhanced Controller Area Network (eCAN)


Controller Area Network (CAN)
A Multi-Master Serial Bus System

‹ CAN 2.0B Standard


‹ High speed (up to 1 Mbps)
‹ Add a node without disturbing the bus (number of nodes not
limited by protocol)
‹ Less wires (lower cost, less maintenance, and more reliable)
‹ Redundant error checking (high reliability)
‹ No node addressing (message identifiers)
‹ Broadcast based signaling
A
B
C

D E

CAN does not use physical addresses to address stations. Each message is sent with an identifier
that is recognized by the different nodes. The identifier has two functions – it is used for message
filtering and for message priority. The identifier determines if a transmitted message will be
received by CAN modules and determines the priority of the message when two or more nodes
want to transmit at the same time.

11 - 22 TMS320C28x MCU Workshop - Communications


Enhanced Controller Area Network (eCAN)

CAN Bus and Node


CAN Bus
‹ Two wire differential bus (usually twisted pair)
‹ Max. bus length depend on transmission rate
Š 40 meters @ 1 Mbps

CAN CAN CAN


NODE A NODE B NODE C

CAN_H

120Ω 120Ω
CAN_L

The DSP communicates to the CAN Bus using a transceiver. The CAN bus is a twisted pair wire,
and the transmission rate depends on the bus length. If the bus is less than 40 meters the
transmission rate is capable up to 1 Mbit/second.

CAN Node
Wired-AND Bus Connection

CAN_H

120Ω 120Ω
CAN_L

CAN Transceiver
(e.g. TI SN65HVD23x)

TX RX
CAN Controller
(e.g. TMS320F28335)

TMS320C28x MCU Workshop - Communications 11 - 23


Enhanced Controller Area Network (eCAN)

Principles of Operation
Principles of Operation
‹ Data messages transmitted are identifier based,
not address based
‹ Content of message is labeled by an identifier that
is unique throughout the network
Š (e.g. rpm, temperature, position, pressure, etc.)
‹ All nodes on network receive the message and
each performs an acceptance test on the identifier
‹ If message is relevant, it is processed (received);
otherwise it is ignored
‹ Unique identifier also determines the priority of the
message
Š (lower the numerical value of the identifier, the higher the
priority)
‹ When two or more nodes attempt to transmit at the
same time, a non-destructive arbitration technique
guarantees messages are sent in order of priority
and no messages are lost

Non-Destructive Bitwise Arbitration


‹ Bus arbitration resolved via arbitration with
wired-AND bus connections
Š Dominate state (logic 0, bus is high)
Š Recessive state (logic 1, bus is low)

Start
Bit
Node A Node A wins
arbitration
Node B
Node C

CAN Bus

Node B loses Node C loses


arbitration arbitration

11 - 24 TMS320C28x MCU Workshop - Communications


Enhanced Controller Area Network (eCAN)

Message Format and Block Diagram


CAN Message Format
‹ Data is transmitted and received using Message Frames
‹ 8 byte data payload per message
‹ Standard and Extended identifier formats

‹ Standard Frame: 11-bit Identifier (CAN v2.0A)


Arbitration Control
Field Field Data Field

S 11-bit R I E
O Identifier T D r0 DLC 0…8 Bytes Data CRC ACK O
F R E F

‹ Extended Frame: 29-bit Identifier (CAN v2.0B)


Control
Arbitration Field Field Data Field

S R
11-bit S I 18-bit E
O T r1 r0 DLC 0…8 Bytes Data
Identifier R D Identifier CRC ACK O
F R E R F

The DSP CAN module is a full CAN Controller. It contains a message handler for transmission
and reception management, and frame storage. The specification is CAN 2.0B Active – that is,
the module can send and accept standard (11-bit identifier) and extended frames (29-bit
identifier).

eCAN Block Diagram


eCAN0INT eCAN1INT
Address Data
32

Memory Management eCAN Memory


Mailbox RAM Unit (512 bytes)
(512 bytes)
CPU Interface, Register and Message
32 Mailboxes 32 Receive Control Unit 32 Object Control
(4 x 32-bit words) Timer Management Unit
A message mailbox
32
Identifier – MID
Control – MCF
Data low – MDL Receive Buffer
Data high - MDH Transmit Buffer
Control Buffer
Status Buffer

SN65HVD23x
3.3-V CAN Transceiver

CAN Bus

TMS320C28x MCU Workshop - Communications 11 - 25


Enhanced Controller Area Network (eCAN)

The CAN controller module contains 32 mailboxes for objects of 0 to 8-byte data lengths:
• configurable transmit/receive mailboxes
• configurable with standard or extended indentifier

The CAN module mailboxes are divided into several parts:


• MID – contains the identifier of the mailbox
• MCF (Message Control Field) – contains the length of the message (to transmit or
receive) and the RTR bit (Remote Transmission Request – used to send remote
frames)
• MDL and MDH – contains the data

The CAN module contains registers which are divided into five groups. These registers are
located in data memory from 0x006000 to 0x0061FF. The five register groups are:

• Control & Status Registers

• Local Acceptance Masks

• Message Object Time Stamps

• Message Object Timeout

• Mailboxes

eCAN Summary
eCAN Summary
‹ Fully compliant with CAN standard v2.0B
‹ Supports data rates up to 1 Mbps
‹ Thirty-two mailboxes
Š Configurable as receive or transmit
Š Configurable with standard or extended identifier
Š Programmable receive mask
Š Uses 32-bit time stamp on messages
Š Programmable interrupt scheme (two levels)
Š Programmable alarm time-out
‹ Programmable wake-up on bus activity
‹ Self-test mode

11 - 26 TMS320C28x MCU Workshop - Communications


DSP/BIOS

Introduction
This module discusses the basic features of using DSP/BIOS in a system. Scheduling threads,
periodic functions, and the use of real-time analysis tools will be demonstrated, in addition to
programming the flash with DSP/BIOS.

Learning Objectives
Learning Objectives

‹ Introduction to DSP/BIOS

‹ DSP/BIOS Configuration Tool

‹ Scheduling DSP/BIOS threads

‹ Periodic Functions

‹ Real-time Analysis Tools

‹ Flash Programming with DSP/BIOS

TMS320C28x MCU Workshop - DSP/BIOS 12 - 1


Module Topics

Module Topics
DSP/BIOS..................................................................................................................................................12-1

Module Topics........................................................................................................................................12-2
Introduction to DSP/BIOS .....................................................................................................................12-3
DSP/BIOS Configuration Tool...............................................................................................................12-4
Lab 12a: DSP/BIOS Configuration Tool ...............................................................................................12-9
Scheduling DSP/BIOS Threads............................................................................................................12-15
Periodic Functions...............................................................................................................................12-20
Real-time Analysis Tools......................................................................................................................12-21
Lab 12b: DSP/BIOS.............................................................................................................................12-22
DSP/BIOS and Programming the Flash ..............................................................................................12-34
Lab 12c: Flash Programming with DSP/BIOS ....................................................................................12-35

12 - 2 TMS320C28x MCU Workshop - DSP/BIOS


Introduction to DSP/BIOS

Introduction to DSP/BIOS
What is DSP/BIOS?
‹ A full-featured, scalable real-time kernel
Š System configuration tools
Š Preemptive multi-threading scheduler
Š Real-time analysis tools

Why Use DSP/BIOS?


‹ Helps Manage complex system resources
Š no need to develop or maintain a “home-brew” kernel
Š faster time to market
‹ Efficient debugging of real-time applications
Š Real-Time Analysis
‹ Create robust applications
Š industry proven kernel technology
‹ Reduce cost of software maintenance
Š code reuse and standardized software
‹ Integrated with Code Composer Studio IDE
Š requires no runtime license fees
Š fully supported by TI
‹ Uses minimal Mips and Memory (2-8Kw)
Š scalable – use only what is needed
Š easily fits in limited memory space

TMS320C28x MCU Workshop - DSP/BIOS 12 - 3


DSP/BIOS Configuration Tool

DSP/BIOS Configuration Tool


The DSP/BIOS Configuration Tool (often called Config Tool or GUI Tool or GUI) creates and
modifies a system file called the Text Configuration File (.tcf). If we talk about using .tcf files,
we’re also talking about using the Config Tool.

DSP/BIOS Configuration Tool (file .tcf)


‹ System Setup Tools
Š Handles memory configuration
(builds .cmd file), run-time
support libraries, interrupt
vectors, system setup and
reset, etc.
‹ Real-Time Analysis Tools
Š Allows application to run
uninterrupted while displaying
debug data
‹ Real-Time Scheduler
Š Preemptive tread manager
kernel configures DSP/BIOS
scheduling
‹ Real-Time I/O
Š Allows two way
communication between
threads or between target and
PC host

The GUI (graphical user interface) simplifies system design by:


• Automatically including the appropriate runtime support libraries
• Automatically handles interrupt vectors and system reset
• Handles system memory configuration (builds .cmd file)
• When a .tcf file is saved, the Config Tool generates 5 additional files:
Filename.tcf Text Configuration File
Filenamecfg_c.c C code created by Config Tool
Filenamecfg.s28 ASM code created by Config Tool
Filenamecfg.cmd Linker command file
Filenamecfg.h header file for *cfg_c.c
Filenamecfg.h28 header file for *cfg.s28

When you add a .tcf file to your project, CCS automatically adds the C and assembly
(.s28) files and the linker command file (.cmd) to the project under the Generated Files
folder.

12 - 4 TMS320C28x MCU Workshop - DSP/BIOS


DSP/BIOS Configuration Tool

1. Creating a New Memory Region (Using MEM)


First, to create a specific memory area, open up the .tcf file, right-click on the Memory Section
Manager and select “Insert MEM”. Give this area a unique name and then specify its base and
length. Once created, you can place sections into it (shown in the next step).

Memory Section Manager (MEM)


‹ Generates the main
linker command file for
your code project
Š Create memories
Š Place sections
‹ To create a new memory
area:
Š Right-click on MEM and
select insert memory
Š Enter your choice of a
name for the memory
Š Right-click on the
memory, and select
Properties
Š fill in base, length, space

TMS320C28x MCU Workshop - DSP/BIOS 12 - 5


DSP/BIOS Configuration Tool

2. Placing Sections – MEM Manager Properties


The configuration tool makes it easy to place sections. The predefined compiler sections that
were described earlier each have their own drop-down menu to select one of the memory regions
you defined (in step 1).

Memory Section Manager Properties

‹ To place a section
into a memory area:
Š Right-click on MEM
and select Properties
Š Select the desired tab
(e.g. Compiler)
Š Select the memory
you would like to link
each section to

12 - 6 TMS320C28x MCU Workshop - DSP/BIOS


DSP/BIOS Configuration Tool

3. PIE Interrupts – HWI Interrupts


The configuration tools is also used to assign the interrupt vectors. The vectors are placed into a
section named .hwi_vec. The memory manager (MEM) links this section to the proper location
in memory.

Hardware Interrupt Manager (HWI)


‹ Config Tool used to assign
interrupt vectors
‹ Vectors are placed in the
section .hwi_vec
‹ Use MEM manager to link
.hwi_vec to the proper memory

TMS320C28x MCU Workshop - DSP/BIOS 12 - 7


DSP/BIOS Configuration Tool

4. Running the Linker


Creating the Linker Command File (via .tcf)

When you have finished creating memory regions and allocating sections into these memory
areas (i.e. when you save the .tcf file), the CCS configuration tool creates five files. One of the
files is BIOS’s cfg.cmd file — a linker command file.

Files Created by the Configuration Tool

‹ Config tool generates


five different files
‹ .cmd file is generated
from your MEM settings
‹ Vectors put into *cfg_c.c

*cfg.cmd
*cfg.h
save to compiler
*.tcf *cfg_c.c
*cfg.h28
*cfg.s28

This file contains two main parts, MEMORY and SECTIONS. (Though, if you open and examine
it, it’s not quite as nicely laid out as shown above.)

Running the Linker

The linker’s main purpose is to link together various object files. It combines like-named input
sections from the various object files and places each new output section at specific locations in
memory. In the process, it resolves (provides actual addresses for) all of the symbols described in
your code. The linker can create two outputs, the executable (.out) file and a report which
describes the results of linking (.map).

Note: The linker gets run automatically when you BUILD or REBUILD your project.

12 - 8 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12a: DSP/BIOS Configuration Tool

Lab 12a: DSP/BIOS Configuration Tool


¾ Objective

Use Code Composer Studio and DSP/BIOS configuration tool to create a text configuration file
(*.tcf). The generated linker command file (Labcfg.cmd) will be then be tested with the same lab
files used in Lab 9 to verify its operation. This would show that the generated linker command
file from the configuration tools is functionally equivalent to the linker command file previously
used. The memory area of the lab linker command file will be deleted; however, part of the
sections area will be used to link sections that are not part of DSP/BIOS. This modified linker
command file will then be used with the remaining lab exercises in this module.

Lab 12a: Configuration Tool


Memory

on-chip
memory

F28335

System Description:
• TMS320F28335
• All internal memory
blocks allocated

Lab Objective:
‹ Use DSP/BIOS Configuration Tool to:
Š Handle system memory and interrupt vectors
Š Create a .tcf file

¾ Procedure

Project File
1. A project named Lab12a.pjt has been created for this lab. Open the project by
clicking on Project Æ Open… and look in C:\C28x\Labs\Lab12a. The lab
files from module 9 will be used as a starting point for the lab exercises in this DSP/BIOS
module. All Build Options have been configured the same as the previous lab. The files
used in this lab are:

TMS320C28x MCU Workshop - DSP/BIOS 12 - 9


Lab 12a: DSP/BIOS Configuration Tool

Adc_9_10_12.c EPwm_7_8_9_10_12.c
CodeStartBranch.asm Filter.c
DefaultIsr_9_10_12a.c Gpio.c
DelayUs.asm Lab_12a_12b.cmd
Dma.c Main_12a.c
DSP2833x_GlobalVariableDefs.c PieCtrl_12.c
DSP2833x_Headers_BIOS.cmd SysCtrl.c
ECap_7_8_9_10_12.c Watchdog.c

Edit Lab.h File


2. Edit Lab.h to uncomment the line that includes the labcfg.h header file. Next,
comment out the line that includes the “DSP2833x_DefaultIsr.h” ISR function
prototypes. DSP/BIOS will supply its own ISR function prototypes. Save and close the
file.

Remove “rts2800_fpu32.lib” and Inspect Lab_12a_12b.cmd


3. The DSP/BIOS configuration tool supplies its own rts library. Open the Build
Options and select the Linker tab. In the Libraries Category, find the Include
Libraries (-l) box and delete: rts2800_fpu32.lib.

4. When using the F28335 device, the DSP/BIOS rts library requires floating point support.
Select the Compiler tab and Advanced Category. Confirm that the Floating Point
Support is set to fpu32.

5. As the project is now configured, we would get a warning at build time stating that the
typedef name has already been declared with the same type. This is because it has been
defined twice; once in the header files and again in DSP/BIOS. To suppress the warning
select Diagnostics Category and find the Suppress Diagnostic <n> (-pds):
box and type code number 303. Select OK and the Build Options window will
close.

6. We will be using the DSP/BIOS configuration tool to create a linker command file. Open
and inspect Lab_12a_12b.cmd. Notice that the linker command file does not have a
memory area and includes only a limited sections area. These sections are not part of
DSP/BIOS and need to be included in a “user” linker command file. Close the inspected
file.

Using the DSP/BIOS Configuration Tool


7. The text configuration files (*.tcf), created by the Configuration Tool, controls a wide
range of CCS capabilities. In this lab exercise, the TCF file will be used to automatically
create and perform memory management. Create a new TCF file for this lab. On the
menu bar click:
File Æ New Æ DSP/BIOS Configuration…
A dialog box appears. The TCF files shown in the aforementioned dialog box are called
“seed” TCF files. TCF files are used to configure many objects specific to the processor.

12 - 10 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12a: DSP/BIOS Configuration Tool

On the 2xxx tab select the ti.platforms.ezdsp28335 template and click OK. A
configuration window will open.

8. Save the configuration file by selecting:


File Æ Save As…
and name it Lab.tcf in C:\C28x\Labs\Lab12a then click Save. Close the
configuration window and select YES to save changes to Lab.tcf.

9. Add the configuration file to the project. Click:


Project Æ Add Files to Project…

Make sure you’re looking in C:\C28x\Labs\Lab12a. Change the “files of type” to


view All Files (*.*) and select Lab.tcf. Click OPEN to add the file to the project.

10. In the project window left click the plus sign (+) to the left of DSP/BIOS Config.
Notice that the Lab.tcf file is listed.

11. Next, add the generated linker command file Labcfg.cmd to the project. After the file
has been added you will notice that it is listed under the source files.

Create New Memory Sections Using the TCF File


12. Open the Lab.tcf file by double clicking on Lab.tcf. In the configuration window,
left click the plus sign next to System and the plus sign next to MEM.
13. By default, the Memory Section Manager has combined the memory space for L0, L1, L2
and L3SARAM into a single memory block called L03SARAM; and L4, L5, L6 and
L7SARAM into a single memory block called L47SARAM. It has also combined M0
and M1SARAM into a single memory block called MSARAM.
14. Next, we will add some of the additional memory sections that will be needed for the lab
exercises in this module. To add a memory section:
Right click on MEM – Memory Section Manager and select Insert MEM.
Rename the newly added memory section to BEGIN_MSARAM. Repeat the process and
add the following memory sections: FPUTABLES, IQTABLES and IQTABLES2.
Double check and see that all four memory sections have been added.
15. Modify the base addresses, length, and space of each of the memory sections to
correspond to the memory mapping shown in the table below. To modify the length,
base address, and space of a memory section, right click on the memory in the
configuration tool, and select Properties.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 11


Lab 12a: DSP/BIOS Configuration Tool

Memory Base Length Space

BEGIN_MSARAM 0x00 0000 0x0002 code

FPUTABLES 0x3F EBDC 0x06A0 code

IQTABLES 0x3F E000 0x0B50 code

IQTABLES2 0x3F EB50 0x008C code

16. Modify the base addresses, length, and space of each of the memory sections to avoid
memory conflicts with the newly added memory sections as shown in the table below.

Memory Base Length Space

BOOTROM 0x3F F37C 0x0D44 code

MSARAM 0x00 0002 0x07FE data

17. Next, modify the space setting for L03SARAM to be “code” and the space setting for
L47SARAM to be “data”.

18. Right click on MEM – Memory Section Manager and select Properties.
Select the Compiler Sections tab and notice that defined sections have been
linked into the appropriate memories via the pull-down boxes. The .stack section has
been linked into memory using the BIOS Data tab. The default settings are sufficient
for getting started. Click OK to close the Properties window.

Set the Stack Size in the TCF File


19. Recall in the previous lab exercise that the stack size was set using the CCS project Build
Options. When using the DSP/BIOS configuration tool, the stack size is instead specified
in the TCF file. First we need to remove the stack size setting from the project Build
Options.

20. Click: Project Æ Build Options… and select the Linker tab. Delete the entry
for setting the Stack Size to 0x200. Select OK to close the Build Options window.

21. Right click on MEM – Memory Section Manager and select Properties.
Select the General tab. Notice that the Stack Size has been set to 0x200 by default, so
there is no need to modify this. Click OK to close the window.

Setup PIE Vectors for Interrupts in the TCF File


22. Next, we will setup all of the PIE interrupt vectors that will be needed for the lab
exercises in this module. This will include all of the vectors used in the previous lab
exercises. (Note: the PieVect.c file is not used and DSP/BIOS will generate the
interrupt vector table).

12 - 12 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12a: DSP/BIOS Configuration Tool

23. Modify the configuration file Lab.tcf to setup the PIE vector for the watchdog
interrupt. Click on the plus sign (+) to the left of Scheduling and again on the plus
sign (+) to the left of HWI – Hardware Interrupt Service Routine
Manager. Click the plus sign (+) to the left of PIE INTERRUPTS. Locate the
interrupt location for the watchdog at PIE_INT1_8. Right click, select Properties,
and type _WAKEINT_ISR (with a leading underscore) in the function field. Click OK
to save.

24. Setup the PIE vector for the ADC interrupt. Locate the interrupt location for the ADC at
PIE_INT1_6. Right click, select Properties, and type _ADCINT_ISR (with a
leading underscore) in the function field. Click OK to save.

25. Setup the PIE vector for the ECAP1 interrupt. Locate the interrupt location for the
ECAP1 at PIE_INT4_1. Right click, select Properties, and type
_ECAP1_INT_ISR (with a leading underscore) in the function field. Click OK to save.

26. Setup the PIE vector for the DMA channel 1 interrupt. Locate the interrupt location for
the DMA channel 1 at PIE_INT7_1. Right click, select Properties, and type
_DINTCH1_ISR (with a leading underscore) in the function field. Click OK to save.
Close the configuration window and select YES to save changes to Lab.tcf.

Build and Load the Project


27. Be sure that Code Composer Studio is set to automatically load the output file after a
successful build. On the menu bar click: Option Æ Customize… and select the
“Program/Project/CIO” tab, check “Load Program After Build”. Then
select the “Debug Properties” tab and check “Step over functions
without debug information when source stepping”. Click OK.
28. Click the “Build” button and watch the tools run in the build window. The output file
should automatically load. The Program Counter should be pointing to _c_int00 in
the Disassembly Window.

29. Under Debug on the menu bar click “Go Main”. This will run through the DSP/BIOS
C-environment initialization routine and stop at main() in Main_12a.c.

Run the Code


Note: For the next step, check to be sure that the jumper wire connecting PWM1A (pin # P8-9)
to ADCINA0 (pin # P9-2) is in place on the eZdsp™.

30. Open and setup a dual time graph to plot a 48-point window of the filtered and unfiltered
ADC results buffer. Click: View Æ Graph Æ Time/Frequency… and set the
following values:

TMS320C28x MCU Workshop - DSP/BIOS 12 - 13


Lab 12a: DSP/BIOS Configuration Tool

Display Type Dual Time

Start Address – upper display AdcBufFiltered

Start Address – lower display AdcBuf

Acquisition Buffer Size 48

Display Data Size 48

DSP Data Type 32-bit floating-point

Sampling Rate (Hz) 48000

Time Display Unit μs

Select OK to save the graph options.

(Note: the math type in IQmathlib.h has been defined as floating-point in the
previous lab exercise).

31. Run the code in real-time mode using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset, and watch the
graphical display update.

32. The graphical display should show the generated FIR filtered 2 kHz, 25% duty cycle
symmetric PWM waveform in the upper display and the unfiltered waveform in the lower
display. Confirm that the results match the Lab 9 exercise.

33. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

End of Exercise

12 - 14 TMS320C28x MCU Workshop - DSP/BIOS


Scheduling DSP/BIOS Threads

Scheduling DSP/BIOS Threads


DSP/BIOS Thread Types

HWI ‹ Used to implement ‘urgent’ part of real-time event


‹ Triggered by hardware interrupt
Hardware Interrupts ‹ HWI priorities fixed in hardware

‹ Use SWI to perform HWI ‘follow-up’ activity


SWI ‹ SWI's are ‘posted’ by software
Software Interrupts ‹ Multiple SWIs at each of 15 priority levels
Priority

‹ Use TSK to run different programs concurrently


TSK under separate contexts
Tasks ‹ TSK's enabled by posting ‘semaphore’ (a signal)

‹ Runs when no service routines are pending


IDL ‹ Runs as an infinite loop, like traditional while loop
Background ‹ All BIOS data transfers to host occur here

Enabling DSP/BIOS in main()


void main(void)
{
//*** Initialization
. . .
‹ BIOS will enable global
//*** Enable global interrupts
interrupts for you
// asm(“ CLRC INTM”);
‹ Must delete the
//*** Main Loop
endless loop at end of
// while(1);
main()
Š main() returns to BIOS
and goes to the IDLE
} //end of main() thread, allowing BIOS to
schedule events,
transfer data to the host,
etc.
Š An endless loop in
main() will keep BIOS
from running

TMS320C28x MCU Workshop - DSP/BIOS 12 - 15


Scheduling DSP/BIOS Threads

Using Hardware Interrupts - HWI

‹ Interrupt priority
fixed by hardware

The HWI Dispatcher


‹ For non-BIOS code, use the
interrupt keyword to declare an ISR interrupt void MyHwi(void)
{
‹ tells the compiler to perform
context save/restore }

‹ For DSP/BIOS code, use the


Dispatcher to perform the
save/restore
‹ Remove the interrupt keyword
from the MyHwi()
‹ Check the “Use Dispatcher” box
when you configure the interrupt
vector in the DSP/BIOS
configuration tool
‹ This is necessary if you want to
use any DSP/BIOS functionality
inside the ISR

12 - 16 TMS320C28x MCU Workshop - DSP/BIOS


Scheduling DSP/BIOS Threads

Using Software Interrupts - SWI

‹ Make each algorithm an


independent software interrupt
‹ SWI scheduling is handled by DSP/BIOS
‹ HWI function triggered by hardware
‹ SWI function triggered by software
e.g. a call to SWI_post()
‹ Why use a SWI?
‹ No limitation on number of SWIs, and
priorities for SWIs are user-defined
‹ SWI can be scheduled by hardware or
software event(s)
‹ Defer processing from HWI to SWI

SWI Properties

TMS320C28x MCU Workshop - DSP/BIOS 12 - 17


Scheduling DSP/BIOS Threads

Managing SWI Priority


‹
‹ Drag
Dragand
andDrop
DropSWIs
SWIsto
tochange
change
priority
priority
‹ Equal
‹ Equalpriority
prioritySWIs
SWIsrun
runin
inthe
the
order
orderthat
thatthey
theyare
areposted
posted

Priority Based Thread Scheduling


post3 rtn
HWI 2 SWI_post(&swi2);
(highest)
post2 rtn
HWI 1
post1 rtn
SWI 3

int2 rtn
SWI 2
rtn
SWI 1
rtn
MAIN
int1
IDLE
(lowest)
User sets the priority...BIOS does the scheduling

12 - 18 TMS320C28x MCU Workshop - DSP/BIOS


Scheduling DSP/BIOS Threads

Using Tasks (TSK)


SWI vs. TSK

SWI SWI_post TSK SEM_post

start end

“must run to SEM_pend Pause


completion” (blocked
start state)

end

Š Similar to hardware interrupt, Š SEM_post() readies the TSK


but triggered by SWI_post() which pends on an event
Š SWIs must run to completion Š TSKs can be terminated by S/W
Š All SWI's use system stack Š Each TSK has its own stack
Š faster context switching Š slower context switching
Š smaller code size Š larger code size

TMS320C28x MCU Workshop - DSP/BIOS 12 - 19


Periodic Functions

Periodic Functions
Using Periodic Functions - PRD
tick
DSP/BIOS
CLK

period

LED LED LED

‹ Periodic functions are a special type of SWI that are triggered by


DSP/BIOS
‹ Periodic functions run at a user specified rate:
- e.g. LED blink requires 0.5 Hz
‹ Use the CLK Manager to specify the DSP/BIOS CLK rate in
microseconds per “tick”
‹ Use the PRD Manager to specify the period (for the function) in ticks
‹ Allows multiple periodic functions with different rates

Creating a Periodic Function


tick
DSP/BIOS
CLK

period

func1 func1 func1

12 - 20 TMS320C28x MCU Workshop - DSP/BIOS


Real-time Analysis Tools

Real-time Analysis Tools


Built-in Real-Time Analysis Tools
‹ Gather data on target (3-10 CPU cycles)
‹ Send data during BIOS IDL (100s of cycles)
‹ Format data on host (1000s of cycles)
‹ Data gathering does NOT stop target CPU

Execution Graph
‹ Software logic analyzer
‹ Debug event timing
and priority

CPU Load Graph


‹ Shows amount of CPU
horsepower being
consumed

Built-in Real-Time Analysis Tools


Statistics View
‹ Profile routines w/o
halting the CPU

Message LOG
‹ Send debug msgs to host
‹ Doesn’t halt the DSP
‹ Deterministic, low DSP
cycle count
‹ More efficient than
traditional printf()

LOG_printf(&trace, “LedSwiCount = %u", LedSwiCount++);

TMS320C28x MCU Workshop - DSP/BIOS 12 - 21


Lab 12b: DSP/BIOS

Lab 12b: DSP/BIOS


¾ Objective

The objective of this lab is to become familiar with DSP/BIOS. In this lab exercise, we are going
to change the DMA DINTCH1_ISR HWI to a SWI. Then, we will replace the LED blink routine
with a Periodic Function. Also, some features of the real-time analysis tools will be
demonstrated.

Lab 12b: DSP/BIOS

ePWM1 ADC DMA


TB Counter ADCINA0 RESULT0
Compare
Action Qualifier
connector
wire ping
data
memory
ePWM2 triggering pong
ADC on period match
using SOC A trigger
every 20.833 µs (48 kHz) ePWM2 CPU runs
FIR data through
Filter filter during
DMA ISR
Objective:
‹ Change DMA
Pointer
rewind
DINTCH1_ISR HWI to data
SWI memory

‹ Replace LED blink Display


routine with a Periodic using CCS
Function

It will be interesting to investigate the DSP computational burden of the various parts of our
application, as well as the different pieces of DSP/BIOS that we will be using in this lab.
The ‘CPU Load Graph’ feature of DSP/BIOS will provide a quick and easy method for doing
this. We will be tabulating these results in the table that follows at various steps throughout the
remainder of this lab.

12 - 22 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12b: DSP/BIOS

Table 12-1: CPU Computational Burden Results

Case # Description CPU Load %

1 DMA processing handled in HWI. Filter inactive.

2 Case #1 + filter active.

3 DMA processing handled in SWI. Filter active.


LED blink handled in HWI.
RTA Global Host Enable disabled.

4 Case #3 + LED blink handled in PRD.

5 Case #4 + LOG_printf in SWI.

6 Case #5 + RTA SWI Logging enabled.

7 Case #6 + RTA SWI Accumulators enabled.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 23


Lab 12b: DSP/BIOS

¾ Procedure

Project File
1. A project named Lab12b.pjt has been created for this lab. Open the project by
clicking on Project Æ Open… and look in C:\C28x\Labs\Lab12b. All Build
Options have been configured the same as the previous lab. The files used in this lab are:
Adc_9_10_12.c Filter.c
CodeStartBranch.asm Gpio.c
DefaultIsr_12b.c Lab.tcf
DelayUs.asm Lab_12a_12b.cmd
Dma.c Labcfg.cmd
DSP2833x_GlobalVariableDefs.c Main_12b.c
DSP2833x_Headers_BIOS.cmd PieCtrl_12.c
ECap_7_8_9_10_12.c SysCtrl.c
EPwm_7_8_9_10_12.c Watchdog.c

Configuring DSP/BIOS Global Settings


2. Open the configuration file Lab.tcf and click on the plus sign (+) to the left of
System. Right click on Global Settings and select Properties. Confirm
that the “DSP Speed in MHz (CLKOUT)” field is set to 150 so that it matches the
processor speed. Click OK to save the value and close the configuration window. This
value is used by the CLK manager to calculate the register settings for the on-chip timers
and provide the proper time-base for executing CLK functions.

Prepare main() for DSP/BIOS


3. Open Main_12b.c and delete the inline assembly code from main() that is used to
enable global interrupts. DSP/BIOS will enable global interrupts after main().

4. In Main_12b.c, remove the endless while() loop from the end of main(). When using
DSP/BIOS, you must return from main(). In all DSP/BIOS programs, the main()
function should contain all one-time user-defined initialization functions. DSP/BIOS will
then take-over control of the software execution. Save and close the file.

Build and Load


5. Click the “Build” button to build and load the project.

Run the Code – HWI() Implementation


At this point, we have modified the code so that DSP/BIOS will take control after main()
completes. However, we have not made any other changes to the code since the previous lab.
Therefore, the computations we want performed in the DINTCH1_ISR() (e.g., reading the ADC
result, running the filter) are still taking place in the hardware ISR, or to use DSP/BIOS
terminology, the HWI.

12 - 24 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12b: DSP/BIOS

6. We will be running our code in real-time mode, and will have our window continuously
refresh. Run in Real-time Mode using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset.

Note: For the next step, check to be sure that the jumper wire connecting PWM1A (pin # P8-9)
to ADCINA0 (pin # P9-2) is still in place on the eZdsp™.

7. Open and setup a dual time graph to plot a 48-point window of the filtered and unfiltered
ADC results buffer. Click: View Æ Graph Æ Time/Frequency… and set the
following values:

Display Type Dual Time

Start Address – upper display AdcBufFiltered

Start Address – lower display AdcBuf

Acquisition Buffer Size 48

Display Data Size 48

DSP Data Type 32-bit floating-point

Sampling Rate (Hz) 48000

Time Display Unit μs

Select OK to save the graph options.

8. The graphical display should show the generated FIR filtered 2 kHz, 25% duty cycle
symmetric PWM waveform in the upper display and the unfiltered waveform in the lower
display. The results should be the same as the previous lab.

Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

9. Open the RTA Control Panel by clicking DSP/BIOS Æ RTA Control Panel.
Uncheck ALL of the boxes. This disables most of the realtime analysis tools. We will
selectively enable them later in the lab.

10. Open the CPU Load Graph by clicking DSP/BIOS Æ CPU Load Graph. The CPU
load graph displays the percentage of available CPU computing horsepower that the
application is consuming. The CPU may be running ISRs, software interrupts, periodic
functions, performing I/O with the host, or running any user routine. When the CPU is
not executing user code, it will be idle (in the DSP/BIOS idle thread).

Run the code (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 25


Lab 12b: DSP/BIOS

This graph should start updating, showing the percentage load on the DSP CPU. Keep
the DSP running to complete steps 11 through 15.

11. Open and inspect Main_12b.c. Notice that the global variable DEBUG_FILTER is
used to control the FIR filter in DINTCH1_ISR(). If DEBUG_FILTER = 1, the FIR filter
is called and the AdcBufFilter array is filled with the filtered data. On the other hand, if
DEBUG_FILTER = 0, the filter is not called and the AdcBufFilter array is filled with
the unfiltered data.

12. Open the watch window and add the variable DEBUG_FILTER to it. Change its value
to “0” to turn off the FIR filtering. Notice the decrease in the CPU Load Graph.

13. Record the value shown in the CPU Load Graph under “Case #1” in Table 12-1.

14. Change the value of DEBUG_FILTER back to “1” in the watch window in order to
bring the FIR filter back online. Notice the jump in the CPU Load Graph.

15. Record the value shown in the CPU Load Graph under “Case #2” in Table 12-1.

16. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

Create a SWI
17. Open Main_12b.c and notice that space has been added at the end of main() for two
new functions which will be used in this lab – Dma1Swi() and LedBlink(). (Space has
also been provided for AdcSwi() for the optional exercise). In the next few steps, we will
move part of the DINTCH1_ISR() routine from DefaultIsr_12b.c to this space in
Main_12b.c.

18. Open DefaultIsr_12b.c and locate the DINTCH1_ISR() routine. Move the entire
contents of the DINTCH1_ISR() routine to the Dma1Swi() function in Main_12b.c
with the following exceptions:

DO NOT MOVE:

• The instruction used to acknowledge the PIE group interrupt

• The static local variable declaration of GPIO32_count

• The GPIO pin toggle code / LED toggle code

Be sure to move all of the other static local variable declaration at the top of
DINTCH1_ISR() that is used to index into the ADC buffers. (Do not move the static
local variable declaration of GPIO32_count).

Comment: In almost all appplications, the PIE group acknowledge code is left in the HWI
(rather than move it to a SWI). This allows other interrupts to occur on that PIE group
even if the SWI has not yet executed. On the other hand, we are leaving the GPIO and

12 - 26 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12b: DSP/BIOS

LED toggle code in the HWI just as an example. It illustrates that you can post a SWI
and also do additional operations in the HWI. DSP/BIOS is extremely flexible!

19. Delete the interrupt key word from the DINTCH1_ISR. The interrupt keyword is
not used when a HWI is under DSP/BIOS control. A HWI is under DSP/BIOS control
when it uses any DSP/BIOS functionality, such as posting a SWI, or calling any
DSP/BIOS function or macro.

Post a SWI
20. In DefaultIsr_12b.c add the following SWI_post to the DINTCH1_ISR(), just
after the structure used to acknowledge the PIE group:

SWI_post(&DMA1_swi); // post a SWI

This posts a SWI that will execute the DMA1_swi() code you populated a few steps back
in the lab. In other words, the DMA1 interrupt still executes the same code as before.
However, most of that code is now in a posted SWI that DSP/BIOS will execute
according to the specified scheduling priorities. Save and close the modified files.

Add the SWI to the TCF File


21. In the configuration file Lab.tcf we need to add and setup the Dma1Swi() SWI. Open
Lab.tcf and click on the plus sign (+) to the left of Scheduling and again on the
plus sign (+) to the left of SWI – Software Interrupt Manager.

22. Right click on SWI – Software Interrupt Manager and select Insert SWI.
Rename SWI0 to DMA1_swi and click OK. This is just an arbitrary name. We want to
differentiate the Dma1Swi() function itself (which is nothing but an ordinary C function)
from the DSP/BIOS SWI object which we are calling DMA1_swi.

23. Select the Properties for DMA1_swi and type _Dma1Swi (with a leading
underscore) in the function field. Click OK. This tells DSP/BIOS that it should run the
function Dma1Swi() when it executes the DMA1_swi SWI.
24. We need to have the PIE for the DMA channel 1 interrupt use the dispatcher. The
dispatcher will automatically perform the context save and restore, and allow the
DSP/BIOS scheduler to have insight into the ISR. You may recall from an earlier lab
that the DMA channel 1 interrupt is located at PIE_INT7_1.

Click on the plus sign (+) to the left of HWI – Hardware Interrupt Service
Routine Manager. Click the plus sign (+) to the left of PIE INTERRUPTS. Locate
the interrupt location for the DMA channel 1: PIE_INT7_1. Right click, select
Properties, and select the Dispatcher tab.

Now check the “Use Dispatcher” box and select OK. Close the configuration file
and click YES to save changes.

Build and Load


25. Click the “Build” button to rebuild and load the project.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 27


Lab 12b: DSP/BIOS

Run the Code – Dma1Swi()


26. Run the code (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset. (Verify that all the
check boxes in the RTA Control Panel window are still unchecked).

27. Confirm that the graphical display is showing the correct results. The results should be
the same as before (i.e., filtered PWM in the upper graph, unfiltered PWM in the lower
graph).

28. Record the value shown in the CPU Load Graph under “Case #3” in Table 12-1.

29. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

Add a Periodic Function


Recall that an instruction was used in the DINTCH1_ISR to toggle the LED on the eZdsp™.
This instruction will be moved into a periodic function that will toggle the LED at the same rate.

30. Open DefaultIsr_12b.c and locate the DINTCH1_ISR routine. Move the
instruction used to toggle the LED to the LedBlink() function in Main_12b.c:

GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1; // Toggle the pin

Now delete from the DINTCH1_ISR() the code used to implement the interval counter
for the LED toggle (i.e., the GPIO32_count++ loop), and also delete the declaration of
the GPIO32_count itself from the beginning of DINTCH1_ISR(). These are no longer
needed, as DSP/BIOS will implement the interval counter for us in the periodic function
configuration (next step in the lab). Save and close the modified files.

31. In the configuration file Lab.tcf we need to add and setup the LedBlink_PRD. Open
Lab.tcf and click on the plus sign (+) to the left of Scheduling. Right click on
PRD – Periodic Function Manger and select Insert PRD. Rename PRD0
to LedBlink_PRD and click OK.

Select the Properties for LedBlink_PRD and type _LedBlink (with a leading
underscore) in the function field. This tells DSP/BIOS to run the LedBlink() function
when it executes the LedBlink_PRD periodic function object.

Next, in the period (ticks) field type 500. The default DSP/BIOS system timer
increments every 1 millisecond, so what we are doing is telling the DSP/BIOS scheduler
to schedule the LedBlink() function to execute every 500 milliseconds. A PRD object is
just a special type of SWI which gets scheduled periodically and runs in the context of
the SWI level at a specified SWI priority. Click OK. Close the configuration file and
click YES to save changes.

12 - 28 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12b: DSP/BIOS

Build and Load


32. Click the “Build” button to rebuild and load the project.

Run the Code – LedBlink_PRD


33. Run the code (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset, and check to see if the
LED on the eZdsp™ is blinking. (Verify that all the check boxes in the RTA Control
Panel window are still unchecked).

34. Record the value shown in the CPU Load Graph under “Case #4” in Table 12-1.

35. When done, fully halt the DSP (real-time mode) by using the GEL function: GEL Æ
Realtime Emulation Control Æ Full_Halt. If you would like, experiment
with different period (tick) values and notice that the blink rate changes.

DSP/BIOS – Real-time Analysis Tools


The DSP/BIOS analysis tools complement the CCS environment by enabling real-time program
analysis of a DSP/BIOS application. You can visually monitor a DSP application as it runs with
essentially no impact on the application’s real-time performance. In CCS, the DSP/BIOS realt-
time analysis (RTA) tools are found on the DSP/BIOS menu. Unlike traditional debugging,
which is external to the executing program, DSP/BIOS program analysis requires that the target
program be instrumented with analysis code. By using DSP/BIOS APIs and objects, developers
automatically instrument the target for capturing and uploading real-time information to CCS
using these tools.

We have actually been already using one piece of the RTA tools in this lab: the CPU Load Graph.
We will now utilize two other basic items from the RTA toolbox.

36. In the next few steps the Log Event Manager will be setup to capture an event in real-
time while the program executes. We will be using LOG_printf() to write to a log
buffer. The LOG_printf() function is a very efficient means of sending a message
from the code to the CCS display. Unlike an ordinary C-language printf(), which can
consume several hundred DSP cycles to format the data on the DSP before transmission
to the CCS host PC, a LOG_printf() transmits the raw data to the host. The host then
formats the data and displays it in CCS. This consumes only 10’s of cycles rather than
100’s of cycles.

Add the following to Main_12b.c at the top of the LedBlink() function just before the
instruction used to toggle the LED:

static Uint16 LedSwiCount=0; // used for LOG_printf

/*** Using LOG_printf() to write to a log buffer ***/

LOG_printf(&trace, "LedSwiCount = %u", LedSwiCount++);

Save and close the file.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 29


Lab 12b: DSP/BIOS

37. In the configuration file Lab.tcf we need to add and setup the trace buffer. Open
Lab.tcf and click on the plus sign (+) to the left of Instrumentation and again on
the plus sign (+) to the left of LOG – Event Log Manager.

38. Right click on LOG – Event Log Manager and select Insert LOG. Rename
LOG0 to trace and click OK.

39. Select the Properties for trace and confirm that the logtype is set to circular and
the datatype is set to printf. Click OK. Close the configuration file and click YES to save
changes.

40. Since the configuration file was modified, we need to rebuild the project. Click the
“Build” button.

Run the Code – Realtime Analysis Tools


41. Run the code (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset.

42. Open the Message Log. On the menu bar, click:

DSP/BIOS Æ Message Log

The message log dialog box is displaying the commanded LOG_printf() output, i.e. the
number of times (count value) that the LedSwi() has executed.

43. Verify that all the check boxes in the RTA Control Panel window are still unchecked
(from step 9). Then, check the box marked “Global Host Enable.” This is the main
control switch for most of the RTA tools. We will be selectively enabling the rest of the
check boxes in this portion of the exercise.

44. Record the value shown in the CPU Load Graph under “Case #5” in Table 12-1.

45. Open the Execution Graph. On the menu bar, click:

DSP/BIOS Æ Execution Graph

Presently, the execution graph is not displaying anything. This is because we have it
disabled in the RTA Control Panel.

In the RTA Control Panel, check the top four boxes to enable logging of all event types to
the execution graph. Notice that the Execution Graph is now displaying information
about the execution threads being taken by your software. This graph is not based on
time, but the activity of events (i.e. when an event happens, such as a SWI or periodic
function begins execution). Notice that the execution graph simply records DSP/BIOS
CLK events along with other system events (the DSP/BIOS clock periodically triggers
the DSP/BIOS scheduler). As a result, the time scale on the execution graph is not linear.

The logging of events to the execution graph consumes CPU cycles, which is why the
CPU Load Graph jumped as you enabled logging.

12 - 30 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12b: DSP/BIOS

46. Record the value shown in the CPU Load Graph under “Case #6” in Table 12-1.

47. Open the Statistics View window. On the menu bar, click:

DSP/BIOS Æ Statistics View

Presently, the statistics view window is not changing with the exception of the statistics
for the IDL_busyObj row (i.e., the idle loop). This is because we have it disabled in the
RTA Control Panel.

In the RTA Control Panel, check the next five boxes (i.e., those with the word
“Accumulator” in their description) to enable logging of statistics to the statistics view
window. The logging of statistics consumes CPU cycles, which is why the CPU Load
Graph jumped as you enabled logging.

48. Record the value shown in the CPU Load Graph under “Case #7” in Table 12-1.

49. Table 12-1 should now be completely filled in. Think about the results. Your instructor
will discuss them when the lecture starts again.

50. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

Note: In this lab exercise only the basic features of DSP/BIOS and the real-time analysis tools
have been used. For more information and details, please refer to the DSP/BIOS user’s
manuals and other DSP/BIOS related training.

End of Exercise

Optional Exercise:
Modify the lab to service the ADC without using the DMA as it was done in the Lab 8 exercise.
Remove the call to the InitDma() function and enable the interrupts in the Adc.c file. Then use
DSP/BIOS to convert the ADCINT_ISR HWI to SWI. Recalculate the CPU computational
burden servicing the ADC without using the DMA.

A. In Main_12b.c comment out the code used to call the InitDma() function.

B. In ADC_9_10_12.c uncomment the code used to enable the ADC interrupt. The ADC
will now trigger the interrupt rather than the DMA.

C. In DefaultIsr_12b.c locate the ADCINT_ISR() routine. Move the entire contents


of the ADCINT_ISR() routine to the AdcSwi() function in Main_12b.c with the
following exceptions: Do Not Move – the instruction used to acknowledge the PIE group
interrupt, the static local variable declaration of GPIO32_count, and the GPIO pin
toggle code / LED toggle code. Be sure to move the other static local variable
declaration at the top of ADCINT_ISR() that is used to index into the ADC buffers.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 31


Lab 12b: DSP/BIOS

D. In DefaultIsr_12b.c delete the interrupt key word from the ADCINT_ISR.


Next delete the LED toggle code and the declaration of the GPIO32_count from the
beginning of ADCINT_ISR(). This is already being done with a periodic function.

E. In DefaultIsr_12b.c add the following SWI_post to the ADCINT_ISR(), just after


the structure used to acknowledge the PIE group: SWI_post(&ADC_swi); //post a
SWI. Save and close the updated files.

F. In the configuration file Lab.tcf add and setup the AdcSwi() SWI. Open Lab.tcf
and click on the plus sign (+) to the left of Scheduling and again on the plus sign (+)
to the left of SWI – Software Interrupt Manager.

G. Right click on SWI – Software Interrupt Manager and select Insert SWI.
Rename SWI0 to ADC_swi and click OK. This is just an arbitrary name to differentiate
the AdcSwi() function itself (which is nothing but an ordinary C function) from the
DSP/BIOS SWI object which we are calling ADC_swi.

H. Select the Properties for ADC_swi and type _AdcSwi (with a leading underscore)
in the function field. Click OK. This tells DSP/BIOS that it should run the function
AdcSwi() when it executes the ADC_swi SWI.
I. Next, we need to have the PIE for the ADC interrupt use the dispatcher. The dispatcher
will automatically perform the context save and restore, and allow the DSP/BIOS
scheduler to have insight into the ISR. You may recall from an earlier lab that the ADC
interrupt is located at PIE_INT1_6.

Click on the plus sign (+) to the left of HWI – Hardware Interrupt Service
Routine Manager. Click the plus sign (+) to the left of PIE INTERRUPTS. Locate
the interrupt location for the ADC: PIE_INT1_6. Right click, select Properties, and
select the Dispatcher tab.

Now check the “Use Dispatcher” box and select OK. Close the configuration file
and click YES to save changes.

J. Click the “Build” button to rebuild and load the project.

K. Run the code (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Run_Realtime_with_Reset.

L. Confirm that the graphical display is showing the correct results. The results should be
the same as before (i.e., filtered PWM in the upper graph, unfiltered PWM in the lower
graph). Note that the Execution Graph shows the ADC_swi is being serviced rather than
the DMA1_swi.

M. Notice and compare the CPU computational burden servicing the ADC without using the
DMA. The CPU load is now at about 41.4% as compared to 12.8% for case #7.

N. Fully halt the DSP (real-time mode) by using the GEL function: GEL Æ Realtime
Emulation Control Æ Full_Halt.

End of Optional Exercise

12 - 32 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12b: DSP/BIOS

Table 12-2: CPU Computational Burden Results (Solution)

Case # Description CPU Load %

1 DMA processing handled in HWI. Filter inactive. 3.9

2 Case #1 + filter active. 11.5

3 DMA processing handled in SWI. Filter active. 12.0


LED blink handled in HWI.
RTA Global Host Enable disabled.

4 Case #3 + LED blink handled in PRD. 12.0

5 Case #4 + LOG_printf in SWI. 12.1

6 Case #5 + RTA SWI Logging enabled. 12.5

7 Case #6 + RTA SWI Accumulators enabled. 12.8

TMS320C28x MCU Workshop - DSP/BIOS 12 - 33


DSP/BIOS and Programming the Flash

DSP/BIOS and Programming the Flash


Programming the flash with DSP/BIOS is very similar to programming the flash without
DSP/BIOS. It requires that a few additionally created initialized sections be linked into flash
memory. These sections are linked using the memory section manager in the DSP/BIOS
configuration tool (*.tcf) on the BIOS Data and BIOS Code tabs. Also, the .hwi_vec and .trcdata
(if using certain real-time debugging features) sections need to be copied from flash to RAM.
The C-compiler runtime support library contains a memory copy function (memcopy) which can
be used to perform the copy. The following lab exercise will cover the details for programming
the flash with DSP/BIOS.

12 - 34 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12c: Flash Programming with DSP/BIOS

Lab 12c: Flash Programming with DSP/BIOS


¾ Objective

The objective of this lab is to program and execute code from the on-chip flash memory with
DSP/BIOS. The TMS320F28335 device has been designed for standalone operation in an
embedded system. Using the on-chip flash eliminates the need for external non-volatile memory
or a host processor from which to bootload. In this lab, the steps required to properly configure
the software for execution from internal flash memory will be covered.

Lab 12c: Flash Programming with


DSP/BIOS
ePWM1 ADC DMA
TB Counter ADCINA0 RESULT0
Compare
Action Qualifier
connector
wire ping
data
memory
ePWM2 triggering pong
ADC on period match
using SOC A trigger
every 20.833 µs (48 kHz) ePWM2 CPU runs
FIR data through
Objective: Filter filter during
DMA ISR
‹ Program system into Flash
Pointer

Memory
rewind

data
memory
‹ Learn use of CCS Flash
Plug-in Display
using CCS
‹ DO NOT PROGRAM
PASSWORDS

¾ Procedure

Project File
1. A project named Lab12c.pjt has been created for this lab. Open the project by
clicking on Project Æ Open… and look in C:\C28x\Labs\Lab12c. All Build
Options have been configured the same as the previous lab. The files used in this lab are:
Adc_9_10_12.c Filter.c
CodeStartBranch.asm Gpio.c
DefaultIsr_12c.c Lab.tcf
DelayUs.asm Lab_12c.cmd
Dma.c Labcfg.cmd
DSP2833x_GlobalVariableDefs.c Main_12c.c
DSP2833x_Headers_BIOS.cmd PieCtrl_12.c
ECap_7_8_9_10_12.c SysCtrl.c
EPwm_7_8_9_10_12.c Watchdog.c

TMS320C28x MCU Workshop - DSP/BIOS 12 - 35


Lab 12c: Flash Programming with DSP/BIOS

Link Initialized Sections to Flash


Initialized sections, such as code and constants, must contain valid values at device power-up.
For a stand-alone embedded system with the F28335 device, these initialized sections must be
linked to the on-chip flash memory. Note that a stand-alone embedded system must operate
without an emulator or debugger in use, and no host processor is used to perform bootloading.

Each initialized section actually has two addresses associated with it. First, it has a LOAD
address which is the address to which it gets loaded at load time (or at flash programming time).
Second, it has a RUN address which is the address from which the section is accessed at runtime.
The linker assigns both addresses to the section. Most initialized sections can have the same
LOAD and RUN address in the flash. However, some initialized sections need to be loaded to
flash, but then run from RAM. This is required, for example, if the contents of the section needs
to be modified at runtime by the code.

2. This step assigns the RUN address of those sections that need to run from flash. Using
the memory section manager in the DSP/BIOS configuration tool (Lab.tcf) link the
following sections to on-chip flash memory:

BIOS Data tab BIOS Code tab Compiler Sections tab

.gblinit .bios .text

.sysinit .switch

.hwi .cinit

.rtdx_text .pinit

.econst / .const

.data

3. This step assigns the LOAD address of those sections that need to load to flash. Again
using the memory section manager in the DSP/BIOS configuration tool (Lab.tcf),
select the Load Address tab and check the “Specify Separate Load
Addresses” box. Then set all entries to the flash memory block.

4. The section named “IQmath” is an initialized section that needs to load to and run from
flash. Recall that this section is not linked using the DSP/BIOS configuration tool
(Lab.tcf). Instead, this section is linked with the user linker command file
(Lab_12c.cmd). Open and inspect Lab_12c.cmd. Previously the “IQmath”
section was linked to L03SARAM. Notice that this section is now linked to FLASH.

12 - 36 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12c: Flash Programming with DSP/BIOS

Copying .hwi_vec Section from Flash to RAM


The DSP/BIOS .hwi_vec section contains the interrupt vectors. This section must be loaded to
flash (load address) but run from RAM (run address). The code that performs this copy is located
in InitPieCtrl(). The DSP/BIOS configuration tool generates global symbols that can be accessed
by code in order to determine the load address, run address, and length of the .hwi_vec section.
The C-compiler runtime support library contains a memory copy function called memcpy() which
will be used to perform the copy.

5. Open and inspect InitPieCtrl() in PieCtrl_12.c. Notice the memcpy() function and
the symbols used to initialize (copy) the .hwi_vec section.

Copying the .trcdata Section from Flash to RAM


The DSP/BIOS .trcdata section is used by CCS and DSP/BIOS for certain real-time debugging
features. This section must be loaded to flash (load address) but run from RAM (run address).
The DSP/BIOS configuration tool generates global symbols that can be accessed by code in order
to determine the load address, run address, and length of the .trcdata section. The memory copy
function memcpy() will again be used to perform the copy.

The copying of .trcdata must be performed prior to main(). This is because DSP/BIOS modifies
the contents of .trcdata during DSP/BIOS initialization, which also occurs prior to main(). The
DSP/BIOS configuration tool provides a user initialization function which will be used to
perform the .trcdata section copy prior to both main() and DSP/BIOS initialization.

6. Open the DSP/BIOS configuration file (Lab.tcf) and select the Properties for the
Global Settings. Check the box “Call User Init Function” and enter
the UserInit() function name with a leading underscore: _UserInit. This will
cause the function UserInit() to execute prior to main().

7. Open and inspect the file Main_12c.c. Notice that the function UserInit() is used
to copy the .trcdata section from its load address to its run address before main().

Initializing the Flash Control Registers


The initialization code for the flash control registers cannot execute from the flash memory (since
it is changing the flash configuration!). Therefore, the initialization function for the flash control
registers must be copied from flash (load address) to RAM (run address) at runtime. The memory
copy function memcpy() will again be used to perform the copy. The initialization code for the
flash control registers InitFlash() is located in the Flash.c file.

8. Add Flash.c to the project.

9. Open and inspect Flash.c. The C compiler CODE_SECTION pragma is used to place
the InitFlash() function into a linkable section named “secureRamFuncs”.

10. Since the DSP/BIOS configuration tool does not know about user defined sections, the
“secureRamFuncs” section will be linked using the user linker command file
Lab_12c.cmd. Open and inspect User_12c.cmd. The “secureRamFuncs” will

TMS320C28x MCU Workshop - DSP/BIOS 12 - 37


Lab 12c: Flash Programming with DSP/BIOS

load to flash (load address) but will run from L03SARAM (run address). Also notice that
the linker has been asked to generate symbols for the load start, load end, and run start
addresses.

While not a requirement from a DSP hardware or development tools perspective (since
the C28x DSP has a unified memory architecture), historical convention is to link code to
program memory space and data to data memory space. Therefore, notice that for the
L03SARAM memory we are linking “secureRamFuncs” to, we are specifiying
“PAGE = 0” (which is program space).

11. Using the DSP/BIOS configuration tool (Lab.tcf) confirm that the entry for
L03SARAM is defined as program space (code).

12. Open and inspect Main_12c.c. Notice that the memory copy function memcpy() is
being used to copy the section “secureRamFuncs”, which contains the initialization
function for the flash control registers.

13. Add a line of code to main() to call the InitFlash() function. There are no passed
parameters or return values. You just type

InitFlash();

at the desired spot in main().

Code Security Module and Passwords


The CSM module provides protection against unwanted copying (i.e. pirating!) of your code from
flash, OTP memory, and the L0, L1, L2 and L3 RAM blocks. The CSM uses a 128-bit password
made up of 8 individual 16-bit words. They are located in flash at addresses 0x33FFF8 to
0x33FFFF. During this lab, dummy passwords of 0xFFFF will be used – therefore only dummy
reads of the password locations are needed to unsecure the CSM. DO NOT PROGRAM ANY
REAL PASSWORDS INTO THE DEVICE. After development, real passwords are typically
placed in the password locations to protect your code. We will not be using real passwords in the
workshop.

The CSM module also requires programming values of 0x0000 into flash addresses 0x33FF80
through 0x33FFF5 in order to properly secure the CSM. Both tasks will be accomplished using a
simple assembly language file Passwords.asm.

14. Add Passwords.asm to your CCS project.

15. Open and inspect Passwords.asm. This file specifies the desired password values
(DO NOT CHANGE THE VALUES FROM 0xFFFF) and places them in an initialized
section named “passwords”. It also creates an initialized section named
“csm_rsvd” which contains all 0x0000 values for locations 0x33FF80 to 0x33FFF5
(length of 0x76).

16. Open Lab_12c.cmd and notice that the initialized sections for “passwords” and
“csm_rsvd” are linked to memories named PASSWORDS and CSM_RSVD,
respectively.

12 - 38 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12c: Flash Programming with DSP/BIOS

17. Using the DSP/BIOS configuration tool (Lab.tcf) define memory blocks for
PASSWORDS and CSM_RSVD. You will need to setup the MEM Properties for each
memory block with the proper base address and length. Set the space to code for both
memory blocks. (If needed, uncheck the “create a heap in this memory” box for each
block). You may also need to modify the existing flash memory block to avoid conflicts.
If needed, a slide is available at the end of this lab showing the base address and length
for the memory blocks.

Executing from Flash after Reset


The F28335 device contains a ROM bootloader that will transfer code execution to the flash after
reset. When the boot mode selection pins are set for “Jump to Flash” mode, the bootloader will
branch to the instruction located at address 0x33FFF6 in the flash. An instruction that branches
to the beginning of your program needs to be placed at this address. Note that the CSM
passwords begin at address 0x33FFF8. There are exactly two words available to hold this branch
instruction, and not coincidentally, a long branch instruction “LB” in assembly code occupies
exactly two words. Generally, the branch instruction will branch to the start of the C-
environment initialization routine located in the C-compiler runtime support library. The entry
symbol for this routine is _c_int00. Recall that C code cannot be executed until this setup routine
is run. Therefore, assembly code must be used for the branch. We are using the assembly code
file named CodeStartBranch.asm.

18. Open and inspect CodeStartBranch.asm. This file creates an initialized section
named “codestart” that contains a long branch to the C-environment setup routine.
This section needs to be placed in memory using the DSP/BIOS configuration tool.

19. Using the DSP/BIOS configuration tool (Lab.tcf) define a memory space named
BEGIN_FLASH.

20. Setup the MEM Properties with the proper base address, length, and space. (If
needed, uncheck the “create a heap in this memory” box). Be sure to avoid memory
section conflicts. If needed, a slide is available at the end of this lab showing the base
address and length for the memory block.

21. In the earlier lab exercises, the section “codestart” was directed to the memory
named BEGIN_MSARAM. Open and modify Lab_12c.cmd so that the section
“codestart” will be directed to BEGIN_FLASH. Save your work and close the
opened files.

22. The eZdsp™ board needs to be configured for “Jump to Flash” bootmode. Move switch
SW1 positions 1, 2, 3 and 4 to the “1” position (all switches to the Left) to accomplish
this. Details of switch positions can be found in Appendix A. This switch controls the
pullup/down resistor on the GPIO84, GPIO85, GPIO86 and GPIO87 pins, which are the
pins sampled by the bootloader to determine the bootmode. (For additional information
on configuring the “Jump to Flash” bootmode see the TMS320x2833x DSP Boot ROM
Reference Guide, and also the eZdsp F28335 Technical Reference).

TMS320C28x MCU Workshop - DSP/BIOS 12 - 39


Lab 12c: Flash Programming with DSP/BIOS

Build – Lab.out
23. At this point we need to build the project, but not have CCS automatically load it since
CCS cannot load code into the flash! (the flash must be programmed). On the menu bar
click: Option Æ Customize… and select the “Program/Project CIO” tab.
Uncheck “Load Program After Build”.

CCS has a feature that automatically steps over functions without debug information.
This can be useful for accelerating the debug process provided that you are not interested
in debugging the function that is being stepped-over. While single-stepping in this lab
exercise we do not want to step-over any functions. Therefore, select the “Debug
Properties” tab. Uncheck “Step over functions without debug
information when source stepping”, then click OK.

24. Click the “Build” button to generate the Lab.out file to be used with the CCS Flash
Plug-in.

CCS Flash Plug-in


25. Open the Flash Plug-in tool by clicking:

Tools Æ F28xx On-Chip Flash Programmer

26. A Clock Configuration window may open. If needed, in the Clock Configuration
window set “OSCCLK (MHz):” to 30, “DIVSEL:” to /2, and “PLLCR Value:” to 10.
Then click OK. In the next Flash Programmer Settings window confirm that the selected
DSP device to program is F28335 and all options have been checked. Click OK.

27. Notice that the eZdsp™ board uses a 30 MHz oscillator (located on the board near LED
DS1). Confirm the “Clock Configuration” in the upper left corner has the OSCCLK set
to 30 MHz, the DIVSEL set to /2, and the PLLCR value set to 10. Recall that the PLL is
divided by two, which gives a SYSCLKOUT of 150 MHz.

28. Confirm that all boxes are checked in the “Erase Sector Selection” area of the plug-in
window. We want to erase all the flash sectors.

29. We will not be using the plug-in to program the “Code Security Password”. Do not
modify the Code Security Password fields.

30. In the “Operation” block, notice that the “COFF file to Program/Verify” field
automatically defaults to the current .out file. Check to be sure that “Erase, Program,
Verify” is selected. We will be using the default wait states, as shown on the slide in this
module.

31. Click “Execute Operation” to program the flash memory. Watch the programming status
update in the plug-in window.

32. After successfully programming the flash memory, close the programmer window.

12 - 40 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12c: Flash Programming with DSP/BIOS

Running the Code – Using CCS


33. In order to effectively debug with CCS, we need to load the symbolic debug information
(e.g., symbol and label addresses, source file links, etc.) so that CCS knows where
everything is in your code. Click:

File Æ Load Symbols Æ Load Symbols Only…

and select Lab12c.out in the Debug folder.

34. Reset the DSP. The program counter should now be at 0x3FF9A9, which is the start of
the bootloader in the Boot ROM.

35. Single-Step <F11> through the bootloader code until you arrive at the beginning of the
codestart section in the CodeStartBranch.asm file. (Be patient, it will take about
125 single-steps). Notice that we have placed some code in CodeStartBranch.asm
to give an option to first disable the watchdog, if selected.

36. Step a few more times until you reach the start of the C-compiler initialization routine at
the symbol _c_int00.

37. Now do Debug Æ Go Main. The code should stop at the beginning of your main()
routine. If you got to that point succesfully, it confirms that the flash has been
programmed properly, and that the bootloader is properly configured for jump to flash
mode, and that the codestart section has been linked to the proper address.

38. You can now RUN the DSP, and you should observe the LED on the board blinking. Try
resetting the DSP and hitting RUN (without doing all the stepping and the Go Main
procedure). The LED should be blinking again.

Running the Code – Stand-alone Operation (No Emulator)


39. Close Code Composer Studio.

40. Disconnect the USB cable (emulator) from the eZdsp™ board.

41. Remove the power from the board.

42. Re-connect the power to the board.

43. The LED should be blinking, showing that the code is now running from flash memory.

TMS320C28x MCU Workshop - DSP/BIOS 12 - 41


Lab 12c: Flash Programming with DSP/BIOS

Return Switch SW1 Back to Default Positions


44. Remove the power from the board.

45. Please return the settings of switch SW1 back to the default positions “Jump to
M0SARAM” bootmode as shown in the table below (see Appendix A for switch position
details):

Position 4 Position 3 Position 2 Position 1 Boot


GPIO87 GPIO86 GPIO85 GPIO84 Mode

Right – 0 Left – 1 Right – 0 Right – 0 M0 SARAM

End of Exercise

12 - 42 TMS320C28x MCU Workshop - DSP/BIOS


Lab 12c: Flash Programming with DSP/BIOS

Lab 12c Reference: Programming the Flash


Flash Memory Section Blocks

base =
0x30 0000
FLASH
len = 0x3FF80
space = code Lab_12.cmd
SECTIONS
{
0x33 FF80 CSM_RSVD codestart :> BEGIN_FLASH, PAGE = 0
len = 0x76 passwords :> PASSWORDS, PAGE = 0
space = code csm_rsvd :> CSM_RSVD, PAGE = 0
0x33 FFF6 BEGIN_FLASH }
len = 0x2
space = code
0x33 FFF8 PASSWORDS
len = 0x8
space = code

BIOS Startup Sequence from Flash Memory

BIOS code Sections


0x30 0000 _c_int00 BIOS_reset( )
FLASH (256Kw) BIOS_init( )
main ( )
4
BIOS_start( )
0x33 7FF6 LB
7
_c_int00
IDL_run( )
Passwords (8w) 5
“rts2800_ml.lib”
6
3 “user” code sections
main ( )
0x3F F000 Boot ROM (8Kw) {
Boot Code ……
0x3F F9A9
return;
{SCAN GPIO}
2 }
BROM vector (32w)
0x3F FFC0 0x3F F9A9
1

RESET

TMS320C28x MCU Workshop - DSP/BIOS 12 - 43


Lab 12c: Flash Programming with DSP/BIOS

12 - 44 TMS320C28x MCU Workshop - DSP/BIOS


Development Support

Introduction
This module contains various references to support the development process.

Learning Objectives
Learning Objectives

‹ TI Workshops Download Site


‹ Signal Processing Libraries
‹ TI Development Tools
‹ Additional Resources
Š Internet
Š Product Information Center

TMS320C28x MCU Workshop - Development Support 13 - 1


Module Topics

Module Topics
Development Support ..............................................................................................................................13-1

Module Topics........................................................................................................................................13-2
TI Support Resources.............................................................................................................................13-3

13 - 2 TMS320C28x MCU Workshop - Development Support


TI Support Resources

TI Support Resources
TI Workshops Download Site

http://www.tiworkshop.com/survey/downloadsort.asp

Login Name: c28xmdw


Password: ttoc28

C28x Signal Processing Libraries


Signal Processing Libraries & Applications Software Literature #
ACI3-1: Control with Constant V/Hz SPRC194
ACI3-3: Sensored Indirect Flux Vector Control SPRC207
ACI3-3: Sensored Indirect Flux Vector Control (simulation) SPRC208
ACI3-4: Sensorless Direct Flux Vector Control SPRC195
ACI3-4: Sensorless Direct Flux Vector Control (simulation) SPRC209
PMSM3-1: Sensored Field Oriented Control using QEP SPRC210
PMSM3-2: Sensorless Field Oriented Control SPRC197
PMSM3-3: Sensored Field Oriented Control using Resolver SPRC211
PMSM3-4: Sensored Position Control using QEP SPRC212
BLDC3-1: Sensored Trapezoidal Control using Hall Sensors SPRC213
BLDC3-2: Sensorless Trapezoidal Drive SPRC196
DCMOTOR: Speed & Position Control using QEP without Index SPRC214
Digital Motor Control Library (F/C280x) SPRC215
Communications Driver Library SPRC183
DSP Fast Fourier Transform (FFT) Library SPRC081
DSP Filter Library SPRC082
DSP Fixed-Point Math Library SPRC085
DSP IQ Math Library SPRC087
DSP Signal Generator Library SPRC083
DSP Software Test Bench (STB) Library SPRC084
C28x FPU Fast RTS Library SPRC664
C2833x C/C++ Header Files and Peripheral Examples SPRC530

Available from TI Website ⇒ http://www.ti.com/c2000

TMS320C28x MCU Workshop - Development Support 13 - 3


TI Support Resources

C2000 controlCARDs
‹ New low cost single-board controllers
perfect for initial software development
and small volume system builds
‹ Small form factor (9cm x 2.5cm) with
standard 100-pin DIMM interface
Š analog I/O, digital I/O, and JTAG signals
available at DIMM interface
‹ Galvanically isolated RS-232 interface
‹ Single 5V power supply required (not
included)
‹ Available through TI authorized
distributors and on the TI web
Š Part Numbers:
Š TMDSCNCD2808 (100 MHz F2808)
Š TMDSCNCD28044 (100 MHz F28044)
Š TMDSCNCD28335 (150 MHz F28335)

C2000 Experimenter Kits


‹ Experimenter Kits include
Š F2808 or F28335 controlCARD
Š Docking station (motherboard)
Š C2000 Applications Software CD
with example code and full
hardware details
Š Code Composer Studio v3.3 with
code size limit of 32KB
Š 5V DC power supply
‹ Docking station features
Š Access to all controlCARD signals
Š Breadboard areas
Š RS-232 an JTAG connectors
‹ Available through TI authorized
distributors and on the TI web
Š Part Numbers:
Š TMDSDOCK2808
Š TMDSDOCK28335

13 - 4 TMS320C28x MCU Workshop - Development Support


TI Support Resources

C2000 Peripheral Explorer Kit


‹ Experimenter Kit includes
Š F28335 controlCARD
Š Peripheral Explorer (motherboard)
Š C2000 Applications Software CD
with example code and full
hardware details
Š Code Composer Studio v3.3 with
code size limit of 32KB
Š 5V DC power supply
‹ Peripheral Explorer features
Š ADC input variable resistors
Š GPIO hex encoder & push buttons
Š eCAP infrared sensor
Š GPIO LEDs, I2C & CAN connection
Š Analog I/O (AIC+McBSP)
‹ Available through TI authorized
distributors and on the TI web
Š Part Number:
Š TMDSPREX28335

C2000 Digital Power Experimenter Kit


‹ DPEK includes
Š 2-rail DC/DC EVM using TI
PowerTrain™ modules (10A)
Š F2808 controlCARD
Š On-board digital multi-meter
and active load for transient
response tuning
Š C2000 Applications Software
CD with example code and full
hardware details
Š Digital Power Supply Workshop
teaching material and lab
software
Š Code Composer Studio v3.3
with code size limit of 32KB
Š 9V DC power supply
‹ Available through TI
authorized distributors and
on the TI web
Š Part Number: TMDSDCDC2KIT

TMS320C28x MCU Workshop - Development Support 13 - 5


TI Support Resources

C2000 DC/DC Developer’s Kit

‹ DC/DC Kit includes


Š 8-rail DC/DC EVM using TI
PowerTrain™ modules (10A)
Š F28044 controlCARD
Š C2000 Applications Software
CD with example code and full
hardware details
Š Code Composer Studio v3.3
with code size limit of 32KB
Š 9V DC power supply
‹ Available through TI
authorized distributors and
on the TI web
Š Part Number: TMDSDCDC8KIT

C2000 AC/DC Developer’s Kit


‹ AC/DC Kit includes
Š AC/DC EVM with interleaved PFC
and phase-shifted full-bridge
Š F2808 controlCARD
Š C2000 Applications Software CD
with example code and full
hardware details
Š Code Composer Studio v3.3 with
code size limit of 32KB
‹ AC/DC EVM features
Š 12VAC in, 80W/10A output
Š Primary side control
Š Synchronous rectification
Š Peak current mode control
Š Two-phase PFC with current
balancing
‹ Available through TI authorized
distributors and on theTI web
Š Part Number: TMDSACDCKIT

13 - 6 TMS320C28x MCU Workshop - Development Support


TI Support Resources

For More Information . . .


Internet
Website: http://www.ti.com

FAQ: http://www-k.ext.ti.com/sc/technical_support/knowledgebase.htm
Š Device information Š my.ti.com
Š Application notes Š News and events
Š Technical documentation Š Training
Enroll in Technical Training: http://www.ti.com/sc/training

USA - Product Information Center (PIC)


Phone: 800-477-8924 or 972-644-5580
Email: [email protected]
Š Information and support for all TI Semiconductor products/tools
Š Submit suggestions and errata for tools, silicon and documents

European Product Information Center (EPIC)


Web: http://www-k.ext.ti.com/sc/technical_support/pic/euro.htm

Phone: Language Number


Belgium (English) +32 (0) 27 45 55 32
France +33 (0) 1 30 70 11 64
Germany +49 (0) 8161 80 33 11
Israel (English) 1800 949 0107 (free phone)
Italy 800 79 11 37 (free phone)
Netherlands (English) +31 (0) 546 87 95 45
Spain +34 902 35 40 28
Sweden (English) +46 (0) 8587 555 22
United Kingdom +44 (0) 1604 66 33 99
Finland (English) +358(0) 9 25 17 39 48

Fax: All Languages +49 (0) 8161 80 2045

Email: [email protected]

Š Literature, Sample Requests and Analog EVM Ordering


Š Information, Technical and Design support for all Catalog TI
Semiconductor products/tools
Š Submit suggestions and errata for tools, silicon and documents

TMS320C28x MCU Workshop - Development Support 13 - 7


TI Support Resources

13 - 8 TMS320C28x MCU Workshop - Development Support


Appendix A – eZdsp™ F28335

Note: This appendix only provides a description of the eZdsp™ F28335 interfaces used in this
workshop. For a complete description of all features and details, please see the eZdsp™
F28335 Technical Reference manual.

TMS320C28x MCU Workshop - Appendix A - eZdsp F28335 A-1


Appendix

Module Topics
Appendix A – eZdsp™ F28335.................................................................................................................A-1

Module Topics......................................................................................................................................... A-2


eZdsp™ F28335 ...................................................................................................................................... A-3
eZdsp™ F28335 Connector / Header and Pin Diagram ......................................................................A-3
P2 – Expansion Interface....................................................................................................................A-5
P4/P8/P7 – I/O Interface.....................................................................................................................A-6
P5/P9 – Analog Interface....................................................................................................................A-8
P10 – Expansion Interface ..................................................................................................................A-9
SW1 – Boot Load Option Switch .....................................................................................................A-10
DS1/DS2 – LEDs .............................................................................................................................A-11
TP1/TP2/TP3/TP4 – Test Points ......................................................................................................A-11

A-2 TMS320C28x MCU Workshop - Appendix A - eZdsp F28335


Appendix

eZdsp™ F28335
eZdsp™ F28335 Connector / Header and Pin Diagram

TMS320C28x MCU Workshop - Appendix A - eZdsp F28335 A-3


Appendix

A-4 TMS320C28x MCU Workshop - Appendix A - eZdsp F28335


Appendix

P2 – Expansion Interface

TMS320C28x MCU Workshop - Appendix A - eZdsp F28335 A-5


Appendix

P4/P8/P7 – I/O Interface

A-6 TMS320C28x MCU Workshop - Appendix A - eZdsp F28335


Appendix

TMS320C28x MCU Workshop - Appendix A - eZdsp F28335 A-7


Appendix

P5/P9 – Analog Interface

A-8 TMS320C28x MCU Workshop - Appendix A - eZdsp F28335


Appendix

P10 – Expansion Interface

TMS320C28x MCU Workshop - Appendix A - eZdsp F28335 A-9


Appendix

SW1 – Boot Load Option Switch

Position 4 Position 3 Position 2 Position 1 Boot


GPIO87 GPIO86 GPIO85 GPIO84 Mode

Right – 0 Left – 1 Right – 0 Right – 0 M0 SARAM

Left – 1 Left – 1 Left – 1 Left – 1 FLASH

A - 10 TMS320C28x MCU Workshop - Appendix A - eZdsp F28335


Appendix

DS1/DS2 – LEDs

TP1/TP2/TP3/TP4 – Test Points

TMS320C28x MCU Workshop - Appendix A - eZdsp F28335 A - 11


Appendix

A - 12 TMS320C28x MCU Workshop - Appendix A - eZdsp F28335


Appendix B – Addressing Modes

Introduction
Appendix B will describe the data addressing modes on the C28x. Immediate addressing allows
for constant expressions which are especially useful in the initialization process. Indirect
addressing uses auxiliary registers as pointers for accessing organized data in arrays. Direct
addressing is used to access general purpose memory. Techniques for managing data pages,
relevant to direct addressing will be covered as well. Finally, register addressing allows for
interchange between CPU registers.

Learning Objectives
Learning Objectives

‹ Explain .sect and .usect assembly directives

‹ Explain assembly addressing modes

‹ Understand instruction formats

‹ Describe options for each addressing mode

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B-1


Module Topics

Module Topics
Appendix B – Addressing Modes .............................................................................................................B-1

Module Topics......................................................................................................................................... B-2


Labels, Mnemonics and Assembly Directives ......................................................................................... B-3
Addressing Modes................................................................................................................................... B-4
Instruction Formats ................................................................................................................................ B-5
Register Addressing ................................................................................................................................ B-6
Immediate Addressing............................................................................................................................. B-7
Direct Addressing ................................................................................................................................... B-8
Indirect Addressing............................................................................................................................... B-10
Review................................................................................................................................................... B-13
Exercise B.........................................................................................................................................B-14
Lab B: Addressing................................................................................................................................. B-15
OPTIONAL Lab B-C: Array Initialization in C .................................................................................... B-17
Solutions................................................................................................................................................ B-18

B-2 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Labels, Mnemonics and Assembly Directives

Labels, Mnemonics and Assembly Directives


Labels and Mnemonics
‹ Labels
.ref start
.sect “vectors”
¾ Optional for all assembly ;make reset vector address 'start'
instructions and most reset: .long start
assembler directives
¾ Must begin in column 1 .def start
count .set 9
¾ The “ : ” is not treated as ;create an array x of 10 words
part of the label name x .usect “mydata”, 10
¾ Used as pointers to .sect “code”
memory or instructions start:C28OBJ ;operate in C28x mode
MOV ACC,#1
‹ Mnemonics next: MOVL XAR1,#x
¾ Lines of instructions MOV AR2,#count
loop: MOV *XAR1++,AL
¾ Use upper or lower case
BANZ loop,AR2--
¾ Become components of bump: ADD ACC,#1
program memory SB next,UNC

Assembly Directives
‹ Begin with a period (.) and are
lower case .ref start
.sect “vectors”
Used by the linker to locate
¾
;make reset vector address 'start'
code and data into specified reset: .long start
sections
‹ Directives allow you to: .def start
¾ Define a label as global count .set 9
; create an array x of 10 words
¾ Reserve space in memory x .usect “mydata”, 10
for un-initialized variables
.sect “code”
¾ Initialized memory start:C28OBJ ;operate in C28x mode
Directives MOV ACC,#1
initialized section next: MOVL XAR1,#x
.sect “name” MOV AR2,#count
loop: MOV *XAR1++,AL
used for code or constants
BANZ loop,AR2--
uninitialized section bump: ADD ACC,#1
label .usect “name”,5 SB next,UNC
used for variables

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B-3


Addressing Modes

Addressing Modes
Addressing Modes

Mode Symbol Purpose


(register) Register Operate between Registers

(constant) Immediate # Constants and Initialization

(paged) Direct @ General-purpose access to data


(pointer) Indirect * Support for pointers – access arrays,
lists, tables

Four main categories of addressing modes are available on the C28x. Register addressing mode
allows interchange between all CPU registers, convenient for solving intricate equations.
Immediate addressing is helpful for expressing constants easily. Direct addressing mode allows
information in memory to be accessed. Indirect addressing allows pointer support via dedicated
‘auxiliary registers’, and includes the ability to index, or increment through a structure. The C28x
supports a true software stack, desirable for supporting the needs of the C language and other
structured programming environments, and presents a stack-relative addressing mode for
efficiently accessing elements from the stack. Paged direct addressing offers general-purpose
single cycle memory access, but restricts the user to working in any single desired block of
memory at one time.

B-4 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Instruction Formats

Instruction Formats
Instruction Formats
INSTR dst ,src Example
INSTR REG NEG AL
INSTR REG,#imm MOV ACC,#1
INSTR REG,mem ADD AL,@x
INSTR mem,REG SUB AL,@AR0
INSTR mem,#imm MOV *XAR0++,#25

‹ What is a “REG”?
‹ 16-bit Access = AR0 through AR7, AH, AL, PH, PL, T and SP
‹ 32-bit Access = XAR0 through XAR7, ACC, P, XT
‹ What is an “#imm”?
‹ an immediate constant stored in the instruction
‹ What is a “mem”?
‹ A directly or indirectly addressed operand from data memory
‹ Or, one of the registers from “REG”!
‹ loc16 or loc32 (for 16-bit or 32-bit data access)

The C28x follows a convention that uses instruction, destination, then source operand order
(INSTR dst, src). Several general formats exist to allow modification of memory or registers
based on constants, memory, or register inputs. Different modes are identifiable by their leading
characters (# for immediate, * for indirect, and @ for direct). Note that registers or data memory
can be selected as a ‘mem’ value.

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B-5


Register Addressing

Register Addressing
Register Addressing
32-bit Registers
XAR0 – XAR7 ACC P XT
16-bit Registers
AR0 – AR7 AH AL PH PL T TL DP SP

‹ Allows for efficient register to register


operation
‹ 16-bit and 32-bit Register Address modes
‹ Reduces code overhead, memory
accesses, and memory overhead

Register addressing allows the exchange of values between registers, and with certain instructions
can be used in conjunction with other addressing modes, yielding a more efficient instruction set.
Remember that any ‘mem’ field allows the use of a register as the operand, and that no special
character (such as @, *, or #) need be used to specify the register mode.

Register Addressing – Example

Format MOV Ax,loc16 MOVL loc32,ACC


Instruction MOV AH,@AL MOVL @XT,ACC

Format MOV loc16,Ax,COND


Instruction MOV @AR1,AL,GT

User Guide & Dis-assembler


use @ for second register

B-6 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Immediate Addressing

Immediate Addressing
Immediate Addressing – “#”

one word instruction


OPCODE 8-bit OPERAND

two word instruction


OPCODE
16-bit OPERAND

‹ Fixed value part of program memory


instruction
‹ Supports short (8-bit) and long (16-bit)
immediate constants
‹ Long immediate can include a shift
‹ Used to initialize registers, and operate
with constants

Immediate addressing allows the user to specify a constant within an instruction mnemonic. Short
immediate are single word, and execute in a single cycle. Long (16-bit) immediate allow full
sized values, which become two-word instructions - yet execute in a single instruction cycle.

Immediate Addressing – Example

‹ Short Immediate, 1 Word (ANDB) ‹ Long Immediate, 2 Words (AND)

ANDB Ax,#8Bit AND loc16,#16Bit

ANDB Ax #8Bit AND loc16


#16Bit

AND automatically replaced by


ANDB if IMM value is 8 bits or less AND Ax,loc16,#16Bit
AND Ax loc16
#16Bit

AND ACC,#16Bit,<<0-16
AND ACC shift
#16Bit

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B-7


Direct Addressing

Direct Addressing
Direct addressing allows for access to the full 4-Meg words space in 64 word “page” groups. As
such, a 16-bit Data Page register is used to extend the 6-bit local address in the instruction word.
Programmers should note that poor DP management is a key source of programming errors.
Paged direct addressing is fast and reliable if the above considerations are followed. The watch
operation, recommended for use whenever debugging, extracts the data page and displays it as the
base address currently in use for direct addressing.

Direct Addressing – “@”


Data Page Offset Data Memory
00 0000 0000 0000 00 00 0000
• • • Page 0: 00 0000 – 00 003F
00 0000 0000 0000 00 11 1111
00 0000 0000 0000 01 00 0000
• • • Page 1: 00 0040 – 00 007F
00 0000 0000 0000 01 11 1111
00 0000 0000 0000 10 00 0000
• • • Page 2: 00 0080 – 00 00BF
00 0000 0000 0000 10 11 1111
• • • • •
• • • • •
11 1111 1111 1111 11 00 0000
• • • Page 65,535: 3F FFC0 – 3F FFFF
11 1111 1111 1111 11 11 1111

‹ Data memory space divided into 65,536 pages with


64 words on each page
‹ Data page pointer (DP) used to select active page
‹ 16-bit DP is concatenated with a 6-bit offset from the
instruction to generate an absolute 22-bit address
‹ Access data on a given page in any order

B-8 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Direct Addressing

Direct Addressing – Example

0 0 0 1 F F
Z=X+Y 0000 0000 0000 0001 1111 1111
DP offset

Data Memory
x .usect “samp”,3
address data
.sect “code”
Page7[00] 0001C0 0001
MOVW DP,#x … …
64 ...
MOV AL,@x Page7[3D] x: 0001FD 1000
ADD AL,@y Page7[3E] y: 0001FE 0500
MOV @z, AL Page7[3F] z: 0001FF 1500

DP=0007 Accumulator
- - - - - - - -
variations: MOV AL,@x 0 0 0 0 1 0 0 0
¾ MOVW DP,#imm ;2W, 16-bit (4 Meg) ADD AL,@y 0 0 0 0 1 5 0 0
¾ MOVZ DP,#imm ;1W, 10-bit (64K)
¾ MOV DP,#imm ;DP(15:10) unchanged MOV @z,AL

Direct Addressing – Caveats


(X and Y not on the same page)
Z=X+Y Data Memory
address data
DP offset Page7[00] 0001C0 0001
0000 0000 0000 0001 1111 1111 ... … …
0000 0000 0000 0010 0000 0000 Page7[3F] x: 0001FF 1000
Page8[00] y: 000200 0500
… …
DP=0007 Accumulator
0 0 0 7 - - - - - - - - x .usect “samp”,3
0 0 0 7 0 0 0 0 1 0 0 0 .sect “code”
0 0 0 7 0 0 0 0 1 0 0 1 MOVW DP,#x
MOV AL,@x
expecting 1500 ADD AL,@y
MOV @z, AL

Solution: Group and block variables in ASM file:


x .usect “samp”,3,1 ;Force all locations to same data
y .set x+1 ;page (1st hole, else linker error)
z .set x+2 ;Assign vars within block

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B-9


Indirect Addressing

Indirect Addressing
Indirect Addressing – “*”
Data Memory
XAR0
XAR1
XAR2
XAR3
XAR4
XAR5
XAR6
XAR7

ARAU

‹ Auxiliary Registers (XARn) used to access full


data memory space
‹ Address Register Arithmetic Unit (ARAU) used
to modify the XARn
‹ Access data from arrays anywhere in data
memory in an orderly fashion

Any of eight hardware pointers (ARs) may be employed to access values from the first 64K of
data memory. Auto-increment or decrement is supported at no additional cycle cost. XAR register
formats offer larger 32-bit widths, allowing them to access across the full 4-Giga words data
space.

Indirect Addressing Modes


‹ Auto-increment / decrement: *XARn++, *--XARn
Š Post-increment or Pre-decrement
‹ Offset: *+XARn[AR0 or AR1], *+XARn[3bit]
Š Offset by 16-bit AR0 or AR1, or 3-bit constant
‹ Stack Relative: *-SP[6bit]
Š Index by 6-bit offset (optimal for C)
‹ Immediate Direct: *(0:16bit)
Š Access low 64K
‹ Circular: *AR6%++
Š AR1(7:0) is buffer size
Š XAR6 is current address

B - 10 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Indirect Addressing

Indirect Addressing – Example


Autoincrement

x .usect “samp”,6 Data


4
y = ∑ xn
y .set (x + 5)
x x0 XAR2
.sect “code” x1
n =0 MOVL XAR2,#x x2
MOV ACC,*XAR2++ x3
ADD ACC,*XAR2++ x4
ADD ACC,*XAR2++ y
ADD ACC,*XAR2++
ADD ACC,*XAR2++ *(0:16bit) - 16 bit label
MOV *(0:y),AL - must be in lower 64K
- 2 word instruction

Fast, efficient access to arrays, lists, tables, etc.

Indexed addressing offers the ability to select operands from within an array without modification
to the base pointer. Stack-based operations are handled with a 16-bit Stack Pointer register, which
operates over the base 64K of data memory. It offers 6-bit non-destructive indexing to access
larger stack-based arrays efficiently.

Indirect Addressing – Example


Offset
Data

XAR2 x x0
x[2] = x[1] + x[3] x1
[3]
x2
x3
x4
x .usect “.samp”,5
.sect “.code”
x .usect “.samp”,5
MOVL XAR2,#x
.sect “.code”
MOV AR0,#1
MOV AR1,#3 MOVL XAR2,#x
MOV ACC,*+XAR2[AR0] MOV ACC,*+XAR2[1]
ADD ACC,*+XAR2[AR1] ADD ACC,*+XAR2[3]
MOV *+XAR2[2],AL
MOV *+XAR2[2],AL
16 bit offset 3 bit offset
Allows offset into arrays with fixed base pointer

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B - 11


Indirect Addressing

Indirect Addressing – Example


Stack Relative

Data Memory
x2 = x1 + x3 0 1 2 0 x3
0
? 3
0 2
? ? x2
5 0
?
0 2 0 0 x1
- SP - empty
empty

Instr. 3
.sect “.code”
Accumulator
MOV AL,*-SP[1]
Instr. 1 0 0 0 0 0 2 0 0
ADD AL,*-SP[3]
MOV *-SP[2],AL Instr. 2 0 0 0 0 0 3 2 0

Useful for stack based operations

Indirect Addressing – Example


Circular
start of buffer Buffer Size N
AAAA … AAAA AAAA AAAA 0000 0000 Element 0
(align on 256 word boundary)

access pointer XAR6 (32) circular


AAAA … AAAA AAAA AAAA xxxx xxxx buffer
range

AR1 Low (16)


end of buffer ---- ---- N-1 Element N-1
(AR1 Low is set to buffer size – 1)

MAC P,*AR6%++,*XAR7++
LINKER.CMD
SECTIONS
{ Buf_Mem: align(256) { } > RAM PAGE 1
. . .
}

B - 12 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Review

Review
Addressing Range Review
0x000000

0x00003F
Stack
Addressing
Direct
SP Addressing
64K DP(16+6) Indirect
Addressing
4M
XARn
0x00FFFF
4G

0x3FFFFF

0xFFFFFFFF

Data memory can be accessed in numerous ways:


• Stack Addressing: allows a range to 64K
• Direct Addressing: Offers a 16-bit DP plus a 6-bit offset, allowing a 4M range
• Indirect Addressing: Offers the full 4G range

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B - 13


Review

Exercise B
Exercise B: Addressing
Given: DP = 4000 DP = 4004 DP = 4006
Address/Data (hex) 100030 0025 100100 0105 100180 0100
Fill in the 100031 0120 100101 0060 100181 0030
table below 100032 100102 0020 100182 0040

Src Mode Program ACC DP AR1


XAR1 AR2
XAR2
MOVW DP,#4000h
MOVL XAR1,#100100h
MOVL XAR2,#100180h
MOV AL,@31h
ADD AL,*XAR1++
SUB AL,@30h
ADD AL,*XAR1++
MOVW DP,#4006h
ADD AL,@1
SUB AL,*XAR1
ADD AL,*XAR2
SUB AL,*+XAR2[1]
ADD AL,#32
SUB AL,*+XAR2[2]
MOV @32h,AL
Imm: Immediate; Dir: Direct;
Reg: Register; Idr: Indirect

In the table above, fill in the values for each of the registers for each of the instructions. Three
areas of data memory are displayed at the top of the diagram, showing both their addresses and
contents in hexadecimal. Watch out for surprises along the way. First, you should answer the
addressing mode for the source operand. Then, fill in the change values as the result of the in-
struction operation.

B - 14 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Lab B: Addressing

Lab B: Addressing
Note: The lab linker command file is based on the F28335 memory map – modify as needed, if
using a different F28xx device memory map.

¾ Objective

The objective of this lab is to practice and verify the mechanics of addressing. In this process we
will expand upon the ASM file from the previous lab to include new functions. Additionally, we
learn how to run and observe the operation of code using Code Composer Studio.

In this lab, we will initialize the “vars” arrays allocated in the previous lab with the contents of
the “const” table. How is this best accomplished? Consider the process of loading the first
“const” value into the accumulator and then storing this value to the first “vars” location,
and repeating this process for each of the succeeding values.
• What forms of addressing could be used for this purpose?
• Which addressing mode would be best in this case? Why?
• What problems could arise with using another mode?

¾ Procedure

Copy Files, Create Project File


1. Create a new project called LabB.pjt in C:\C28x\Labs\Appendix\LabB and
add LabB.asm and Lab.cmd to it. Check your file list to make sure all the files are
there. Be sure to setup the Build Options by clicking: Project Æ Build
Options on the menu bar. Select the Linker tab. In the middle of the screen select
“No Autoinitialization” under “Autoinit Model:”. Enter start in
the “Code Entry Point (-e):” field. Next, select the Compiler tab. Note that
“Full Symbolic Debug (-g)” under “Generate Debug Info:” is
selected. Then select OK to save the Build Options.

Initialize Allocated RAM Array from ROM Initialization Table


2. Edit LabB.asm and modify it to copy table[9] to data[9] using indirect addressing.
(Note: data[9] consists of the allocated arrays of data, coeff, and result). Initialize the
allocated RAM array from the ROM initialization table:
• Delete the NOP operations from the “code” section.
• Initialize pointers to the beginning of the “const” and “vars” arrays.
• Transfer the first value from “const” to the “vars” array.
• Repeat the process for all values to be initialized.
To perform the copy, consider using a load/store method via the accumulator. Which
part of an accumulator (low or high) should be used? Use the following when writing
your copy routine:
- use AR1 to hold the address of table
- use AR2 to hold the address of data

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B - 15


Lab B: Addressing

3. It is good practice to trap the end of the program (i.e. use either “end: B
end,UNC” or “end: B start,UNC”). Save your work.

Build and Load


4. Click the “Build” button and watch the tools run in the build window. Debug as
necessary. To open up more space, close any open files or windows that you do not need.
5. Load the output file onto the target. Click:
File Æ Load Program…

If you wish, right click on the LabB.asm source window and select Mixed Mode to
debug using both source and assembly.

Note: Code Composer Studio can automatically load the output file after a successful build. On
the menu bar click: Option Æ Customize… and select the “Program Load
Options” tab, check “Load Program After Build”, then click OK.

6. Single-step your routine. While single-stepping, it is helpful to see the values located in
table[9] and data[9] at the same time. Open two memory windows by using the “View
Memory” button on the vertical toolbar and using the address labels table and data.
Setting the properties filed to “Hex 16 Bit – TI style” will give you more viewable data in
the window. Additionally, it is useful to watch the CPU registers. Open the CPU
registers by using the “View Æ Registers Æ CPU Registers”. Deselect
“Allow Docking” and move/resize the window as needed. Check to see if the
program is working as expected.

End of Exercise

B - 16 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


OPTIONAL Lab B-C: Array Initialization in C

OPTIONAL Lab B-C: Array Initialization in C


Note: The lab linker command file is based on the F28335 memory map – modify as needed, if
using a different F28xx device memory map.

¾ Objective

The objective of this lab is to practice and verify the mechanics of initialization using C.
Additionally, we learn how to run and observe the operation of C code using Code Composer
Studio. In this lab, we will initialize the “vars” arrays with the contents of the “const” table.

¾ Procedure

Create Project File


1. In Code Composer Studio create a new project called LabB-C.pjt in
C:\C28x\Labs\Appendix\LabB\LabB-C and add LabB-C.c and Lab.cmd to
it. Check your file list to make sure all the files are there. Open the Build Options and
select the Linker tab. Select the “Libraries” Category and enter rts2800_ml.lib in
the “Incl. Libraries (-l):” box. Do not setup any other Build Options. The
default values will be used. In Appendix Lab D exercise, we will experiment and explore
the various build options when working with C.

Initialize Allocated RAM Array from ROM Initialization Table


2. Edit LabB-C.c and modify the “main” routine to copy table[9] to the allocated arrays
of data[4], coeff[4], and result[1]. (Note: data[9] consists of the allocated arrays of
data, coeff, and result).

Build and Load


3. Click the “Build” button and watch the tools run in the build window. Debug as
necessary.

Note: Have Code Composer Studio automatically load the output file after a successful build. On
the menu bar click: Option Æ Customize… and select the “Program Load Options”
tab, check “Load Program After Build”, then click OK.

4. Under Debug on the menu bar click “Go Main”. Single-step your routine. While
single-stepping, it is helpful to see the values located in table[9] and data[9] at the same
time. Open two memory windows by using the “View Memory” button on the vertical
toolbar and using the address labels table and data. Setting the properties field to
“Hex 16 Bit – TI style” will give you more viewable data in the window. Additionally,
you can watch the CPU registers. Open the CPU registers by using the “View Æ
Registers Æ CPU Registers. Deselect “Allow Docking” and move/resize
the window as needed. Check to see if the program is working as expected.

End of Exercise

TMS320C28x MCU Workshop - Appendix B - Addressing Modes B - 17


Solutions

Solutions

Exercise B: Addressing - Solution


Given: DP = 4000 DP = 4004 DP = 4006
Address/Data (hex) 100030 0025 100100 0105 100180 0100
Fill in the 100031 0120 100101 0060 100181 0030
table below 100032 100102 0020 100182 0040

Src Mode Program ACC DP XAR1 XAR2


Imm MOVW DP,#4000h 4000
Imm MOVL XAR1,#100100h 100100
Imm MOVL XAR2,#100180h 100180
Dir MOV AL,@31h 120
Idr ADD AL,*XAR1++ 225 100101
Dir SUB AL,@30h 200
Idr ADD AL,*XAR1++ 260 100102
Imm MOVW DP,#4006h 4006
Dir ADD AL,@1 290
Idr SUB AL,*XAR1 270
Idr ADD AL,*XAR2 370
Idr SUB AL,*+XAR2[1] 340 100180
Imm ADD AL,#32 360
Idr SUB AL,*+XAR2[2] 320 100180
Dir MOV @32h,AL 1001B2 0320
Imm: Immediate; Dir: Direct;
Reg: Register; Idr: Indirect

B - 18 TMS320C28x MCU Workshop - Appendix B - Addressing Modes


Appendix C – Assembly Programming

Introduction
Appendix C discusses the details of programming in assembly. It shows you how to use
different instructions that further utilize the advantage of the architecture data paths. It gives
you the ability to analyze the instruction set and pick the best instruction for the application.

Learning Objectives
Learning Objectives
‹ Perform simple program control using
branch and conditional codes
‹ Write C28x code to perform basic
arithmetic
‹ Use the multiplier to implement
sum-of-products equations
‹ Use the RPT instruction (repeat) to
optimize loops
‹ Use MAC for long sum-of-products
‹ Efficiently transfer the contents of one
area of memory to another
‹ Examine read-modify-write operations

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C-1


Module Topics

Module Topics
Appendix C – Assembly Programming ...................................................................................................C-1

Module Topics.........................................................................................................................................C-2
Program Control.....................................................................................................................................C-3
Branches .............................................................................................................................................C-3
Program Control Instructions .............................................................................................................C-4
ALU and Accumulator Operations..........................................................................................................C-6
Simple Math & Shift...........................................................................................................................C-7
Multiplier ................................................................................................................................................C-9
Basic Multiplier ................................................................................................................................C-10
Repeat Instruction.............................................................................................................................C-11
MAC Instruction...............................................................................................................................C-12
Data Move.............................................................................................................................................C-13
Logical Operations ...............................................................................................................................C-15
Byte Operations and Addressing ......................................................................................................C-15
Test and Change Memory Instructions.............................................................................................C-16
Min/Max Operations.........................................................................................................................C-17
Read Modify Write Operations .............................................................................................................C-18
Lab C: Assembly Programming............................................................................................................C-20
OPTIONAL Lab C-C: Sum-of-Products in C........................................................................................C-22

C-2 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Program Control

Program Control
The program control logic and program address generation logic work together to provide proper
program flow. Normally, the flow of a program is sequential: the CPU executes instructions at
consecutive program memory addresses. At times, a discontinuity is required; that is, a program
must branch to a nonsequential address and then execute instructions sequentially at that new
location. For this purpose, the C28x supports interrupts, branches, calls, returns, and repeats.
Proper program flow also requires smooth flow at the instruction level. To meet this need, the
C28x has a protected pipeline and an instruction-fetch mechanism that attempts to keep the
pipeline full.

Branches
Branch Types and Range
¾ 3 Branch Types
0x000000

Long
Short Branch Branch
offset +127/- Branch
Program 128
offset +/-32K
absolute 4M
Memory 1-word 2-word
instruction instruction 2-word
instruction

PC

0x3FFFFF

The PC can access the entire 4M words (8M bytes) range. Some branching operations offer 8-
and 16-bit relative jumps, while long branches, calls, and returns provide a full 22-bit absolute
address. Dynamic branching allows a run-time calculated destination. The C28x provides the fa-
miliar arithmetic results status bits (Zero, oVerflow, Negative, Carry) plus a Test Control bit
which holds the result of a binary test. The states of these bits in various combinations allow a
range of signed, unsigned, and binary branching conditions offered.

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C-3


Program Control

Program Control Instructions


Program Control - Branches
Function Instruction Cycles T/F Size

Short Branch SB 8bit,cond 7/4 1


Fast Short Branch SBF 8bit,EQ|NEQ|TC|NTC 4/4 1
Fast Relative Branch B 16bit,cond 7/4 2
Fast Branch BF 16bit,cond 4/4 2
Absolute Branch LB 22bit 4 2
Dynamic Branch LB *XAR7 4 1
Branch on AR BANZ 16bit,ARn-- 4/2 2
Branch on compare BAR 16bit,ARn,ARn,EQ|NEQ 4/2 2

Condition Code
NEQ LT LO (NC) NTC ‹ Condition flags are set on
EQ LEQ LOS TC the prior use of the ALU
GT HI NOV UNC
GEQ ‹ The assembler will optimize
HIS (C) OV NBIO
B to SB if possible

Program Control - Call/Return

Function Call Code Cycles Return code Cycles

Call LCR 22bit 4 LRETR 4


Dynamic Call LCR *XARn 4 LRETR 4
Interrupt Return IRET 8

‹ More Call variations LCR Func Stack


in the user guide are LRETR Local
for code backward Var
compatibility RPC Old RPC 22-bit old
New RPC Ret Addr RPC

Func
PC
Ret Addr

C-4 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Program Control

BANZ Loop Control Example


‹ Auxiliary register used as loop counter
‹ Branch if Auxiliary Register not zero
‹ Test performed on lower 16-bits of XARx only

4
y = ∑ xn len .set 5
n =0 Data x .usect “samp”,6
y .set (x+len)
x x0 XAR2
x1
.sect “code”
x2
MOVL XAR2,#x
x3
MOV AR3,#len-2
x4
y MOV AL,*XAR2++
sum: ADD AL,*XAR2++
BANZ sum,AR3--
AR3
MOV *(0:y),AL
COUNT

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C-5


ALU and Accumulator Operations

ALU and Accumulator Operations


ALU and Accumulator
16/32 data mem,
Product (32) 16/32 bit registers

MUX 8/16 Imm

ALU and Barrel Shifter ST0, ST1

ACC
AH (31-16) AL (15-0)
AH.MSB AH.LSB AL.MSB AL.LSB

One of the major components in the execution unit is the Arithmetic-Logical-Unit (ALU). To
support the traditional Digital Signal Processing (DSP) operation, the ALU also has the zero
cycle barrel shifter and the Accumulator. The enhancement that the C28x has is the additional
data paths added form the ALU to all internal CPU registers and data memory. The connection to
all internal registers helps the compiler to generate efficient C code. The data path to memory
allows the C28x performs single atomic instructions read-modify-write to the memory.

The following slides introduce you to various instructions that use the ALU hardware. Word,
byte, and long word 32-bit operation are supported.

C-6 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


ALU and Accumulator Operations

Simple Math & Shift


Accumulator - Basic Math Instructions

Format
xxx Ax, #16b ;word xxx = instruction: MOV, ADD, SUB, ...
xxxB Ax, #8b ;byte Ax = AH, or AL
Assembler will automatically convert to 1
xxxL ACC, #32b ;long word instruction.

ADD ACC, #01234h<<4 Two word instructions with shift option


Ex

ADDB AL, #34h One word instruction, no shift

Ax = AH or AL Operations
ACC Operations MOV Ax, loc16
MOV ACC,loc16<<shift ADD Ax, loc16

}
Variation

ADD SUB Ax, loc16


from memory (left shift
SUB optional) AND Ax, loc16
OR Ax, loc16
MOV ACC,#16b<<shift
ADD
SUB
} 16-bit constant (left shift
optional)
XOR
AND
NOT
Ax, loc16
Ax,loc16,#16b
Ax
MOV loc16,ACC <<shift ;AL NEG Ax
MOVH loc16,ACC <<shift ;AH MOV loc16,Ax

Shift the Accumulator


Shift full ACC 31 ……… 0
LSL
LSL ACC <<shift C ACC 0
(1-16)
SFR ACC >>shift
LSL ACC <<T (0-15) 31 ……… 0
SFR ACC >>T SXM ACC C SFR

15 ……… 0
LSL
Shift AL or AH C Ax 0
LSL AX <<shift
LSR AX <<shift 15 ……… 0
ASR AX >>shift SXM Ax C ASR
LSL AX <<T
LSR AX <<T 15 ……… 0
ASR AX >>T 0 Ax C LSR

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C-7


ALU and Accumulator Operations

32 Bit Shift Operations [ACC]

31 ……… 0
C ACC 0
Examples:
Logical Shift Left – Long: LSLL LSLL ACC, T
LSRL ACC, T
31 ……… 0
0 ACC C
ASRL ACC, T

Logical Shift Right – Long: LSRL Note: T(4:0) are used;


other bits are ignored
31 ……… 0
0 or 1 ACC C
based on SXM

Arithmetic Shift Right – Long: ASRL

C-8 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Multiplier

Multiplier
Multiply Unit
XT Register Data Mem
or Register
T Register

32x32 Multiply Unit

MUX
Prog Mem (16)
16x16 or
Immed (8,16)

P Register (32)

Shift (PM)

ACC (32)

Digital signal processors require many multiply and add math intensive operations. The single
cycle multiplier is the second major component in the execution unit. The C28x has the
traditional 16-bit-by-16-bit multiplier as previous TI DSP families. In-addition, the C28x has a
single cycle 32-bit-by-32-bit multiplier to perform extended precision math operations. The large
multiplier allows the C28x to support higher performance control systems requirement while
maintaining small or reduce code.

The following slides introduce instructions that use the 16-bit-by-16-bit multiplier and multiply
and add (MAC) operations. The 32-bit-by-32-bit multiplication will be covered in the appendix.

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C-9


Multiplier

Basic Multiplier
Multiplier Instructions
Instruction Execution Purpose
MOV T,loc16 T = loc16 Get first operand
MPY ACC,T,loc16 ACC = T*loc16 For single or first product
MPY P,T,loc16 P = T*loc16 For n th product
MPYB ACC,T,#8bu ACC = T*8bu Using 8-bit unsigned const
MPYB P,T,#8bu P = T*8bu Using 8-bit unsigned const
MOV ACC,P ACC = P Move 1st product<<PM to ACC
ADD ACC,P ACC += P Add nth product<<PM to ACC
SUB ACC,P ACC -= P Sub nth product<<PM fr. ACC
Instruction Execution
MOVP T, loc16 ACC = P<<PM T = loc16
MOVA T, loc16 ACC += P<<PM T = loc16
MOVS T, loc16 ACC - = P<<PM T = loc16
MPYA P, T, #16b ACC += P<<PM then P = T*#16b
MPYA P, T, loc16 ACC += P<<PM then P = T*loc16
MPYS P, T, loc16 ACC - = P<<PM then P = T*loc16

Sum-of-Products
Y = A*X1 + B*X2 + C*X3 + D*X4

ZAPA ;ACC = P = OVC = 0


MOV T,@X1 ;T = X1
MPY P,T,@A ;P = A*X1
MOVA T,@X2 ;T = X2 ;ACC = A*X1
MPY P,T,@B ;P = B*X2
MOVA T,@X3 ;T = X3 ;ACC = A*X1 + B*X2
MPY P,T,@C ;P = C*X3
MOVA T,@X4 ;T = X4;ACC = A*X1 + B*X2 + C*X3
MPY P,T,@D ;P = D*X4
ADDL ACC,P<<PM ;ACC = Y
MOVL @y,ACC

C - 10 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Multiplier

32x32 Long Multiplication


X
X Y
Integer long multiplication
XO * Y0
u(long) = u(long) * u(long)
Fraction long multiplication:
Y1 * X1
(long) = (long) * (long)
Z3 Z2 Z1 Z0 (long) 64 = (long) 32 * (long) 32
Accumulator P-register

IMPYAL P,XT,loc32 P = u(XT)*u(loc32)


QMPYAL ACC,XT,loc32 ACC = (XT)*(loc32)

IMACL P,loc32,*XAR7 ACC += P; P = u(loc32)*u(loc32)


QMACL P,loc32,*XAR7 ACC += P; P = (loc32)*(loc32)

Repeat Instruction
Repeat Next: RPT
‹ Options:
¾ RPT #8bit up to 256 iterations
¾ RPT loc16 location “loc16” holds count value

‹ Features: Example :
¾ Next instruction iterated N+1 times int x[5]={0,0,0,0,0};
¾ Saves code space - 1 word
¾ Low overhead - 1 cycle
x .usect “samp”,5
MOV AR1,#x
¾ Easy to use
RPT #4
¾ Non-interruptible
|| MOV *XAR1++,#0
¾ Requires use of | | before next line
¾ May be nested within BANZ loops
Instruction Cycles
RPT 1
BANZ 4 .N
Refer to User Guide for more repeatable instructions

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C - 11


Multiplier

Single repeat instruction (RPT) is used to reduce code size and speed up many operations in the
DSP application. Some of the most popular operations that use the RPT instruction to perform
multiple taps digital filters or perform block of data transfer.

MAC Instruction
Sum-of-Products: RPT / MAC
x .usect “sample”,20
19 y .usect “result”,2
y = ∑ xn a n .sect “coefficient”
a0: .word 0x0101
n =0 .word 0x0202
• • •
XAR1++ X0 .word 0x2020
X1 .sect “code”
SOP: SPM 0
... MOVW DP,#y
MOVL XAR1,#x
X19 MOVL XAR7,#a0
ZAPA Zero ACC & P
XAR7++ A0 RPT #19 Repeat single
Second operand || MAC P,*XAR1++,*XAR7++ Dual operand
must use XAR7 A1
ADDL ACC,P<<PM last ADD
... MOVL @y,ACC
A19 B SOP,UNC

MOV
ADD
T,loc16
ACC,P
MOVA T,loc16
MPY P,T,loc16
MAC { ACC+=P
T=*ARn++
P=T*(*ARn++)

C - 12 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Data Move

Data Move
Data Move Instructions
DATA ↔ DATA (4G ↔ 64K) DATA ↔ PGM (4G ↔ 4M)
MOV loc16, *(0:16bit) PREAD loc16 ,*XAR7
MOV *(0:16bit), loc16 PWRITE *XAR7, loc16

16-bit address concatenated 32-bit address memory pointer with a 22-bit


with 16 leading zeros location program memory address
.sect “.code”
START: MOVL XAR5,#x
MOVL XAR7,#TBL
RPT #len-1
|| PREAD *XAR5++,*XAR7
...
x .usect “.samp”,4
.sect “.coeff”
TBL: .word 1,2,3,4
len .set $-TBL

‹ Optimal with RPT (speed and code size) ‹ Faster than Load / Store, avoids
‹ In RPT, non-mem address is auto- accumulator
incremented in PC ‹ Allows access to program memory

Conditional Moves
Instruction Execution (if COND is met)
MOV loc16,AX,COND [loc16] = AX
MOVB loc16,#8bit,COND [loc16] = 8bit
Instruction Execution (if COND is met)
MOVL loc32,ACC,COND [loc32] = AX
Example
If A<B, Then B=A
Accumulator
A .usect “var”,2,1 0 0 0 0 0 1 2 0
B .set A+1
.sect “code”
Data Memory Data Memory
MOVW DP, #A
MOV AL, @A 0 1 2 0 A 0 1 2 0 A
CMP AL, @B 0 3 2 0 B 0 1 2 0B
MOV @B, AL, LT Before After

The conditional move instruction is an excellent way to avoid a discontinuity (branch or call)
based upon a condition code set prior to the instruction. In the above example, the 1st step is to

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C - 13


Data Move

place the contents of A into the accumulator. Once the Ax content is tested, by using the CMP
instruction, the conditional move can be executed.

If the specified condition being tested is true, then the location pointed to by the “loc16” address-
ing mode or the 8–bit zero extended constant will be loaded with the contents of the specified AX
register (AH or AL): if (COND == true) [loc16] = AX or 0:8bit;

Note: Addressing modes are not conditionally executed. Hence, if an addressing mode performs a
pre or post modification, it will execute regardless if the condition is true or not. This instruction
is not repeatable. If this instruction follows the RPT instruction, it resets the repeat counter
(RPTC) and executes only once.
Flags and Modes
N - If the condition is true, then after the move, AX is tested for a negative condition. The nega-
tive flag bit is set if bit 15 of AX is 1, otherwise it is cleared.
Z - If the condition then after the move, AX is tested for a zero condition. The zero flag bit is set
if AX = 0, otherwise it is cleared.
V - If the V flag is tested by the condition, then V is cleared.

C-Example
; if ( VarA > 20 )
; VarA = 0;

CMP @VarA,#20 ; Set flags on (VarA – 20)


MOVB @VarA,#0,GT ; Zero VarA if greater then

C - 14 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Logical Operations

Logical Operations
Byte Operations and Addressing
Byte Operations
MOVB AX.LSB,loc16 0000 0000 Byte AX

MOVB AX.MSB,loc16 Byte No change AX

MOVB loc16, AX.LSB No change Byte loc16

MOVB loc16, AX.MSB No change Byte loc16

Byte = 1. Low byte for register addressing


2. Low byte for direct addressing
3. Selected byte for offset indirect addressing

For loc16 = *+XARn[Offset] Odd Offset Even Offset loc16

Byte Addressing
AH.MSB AH.LSB AL.MSB AL.LSB
12 34 56 78

16 bit memory
01
78 00 AR2
03 56
02
05
34 04
07 06
12

Example of Byte Un-Packing Example of Byte Packing


MOVL XAR2, #MemA MOVL XAR2, #MemA
MOVB *+XAR2[1], AL.LSB MOVB AL.LSB,*+XAR2[1]
MOVB *+XAR2[2], AL.MSB MOVB AL.MSB,*+XAR2[2]
MOVB *+XAR2[5], AH.LSB MOVB AH.LSB,*+XAR2[4]
MOVB *+XAR2[6], AH.MSB MOVB AH.MSB,*+XAR2[7]

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C - 15


Logical Operations

Test and Change Memory Instructions


The compare (CMPx) and test (Txxx) instructions allow the ability to test values in memory. The
results of these operations can then trigger subsequent conditional branches. The CMPx instruc-
tion allows comparison of memory with respect to a specified constant value, while the Txxx in-
structions allow any single bit to be extracted to the test control (TC) field of status register 0.
The contents of the accumulator can also be non-destructively analyzed to establish branching
conditions, as seen below.

Test and Change Memory

Instruction Execution Affects


TBIT loc16,#(0-15) ST0(TC) = loc16(bit_no) TC
TSET loc16,#(0-15) Test (loc16(bit)) then set bit TC
TCLR loc16,#(0-15) Test (loc16(bit)) then clr bit TC
CMPB AX, #8bit Test (AX - 8bit unsigned) C,N,Z
CMP AX, loc16 Test (AX – loc16) C,N,Z
CMP loc16,#16b Test (loc16 - #16bit signed) C,N,Z
CMPL ACC, @P Test (ACC - P << PM) C,N,Z

C - 16 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Logical Operations

Min/Max Operations
MIN/MAX Operations
Instruction Execution
MAX ACC,loc16 if ACC < loc16, ACC = loc16
if ACC >= loc16, do nothing
MIN ACC,loc16 if ACC > loc16, ACC = loc16
if ACC <= loc16, do nothing
MAXL ACC,loc32 if ACC < loc32, ACC = loc32
if ACC >= loc32, do nothing
MINL ACC,loc32 if ACC > loc32, ACC = loc32
if ACC <= loc32, do nothing
MAXCUL P,loc32 if P < loc32, P = loc32
(for 64 bit math) if P >= loc32, do nothing
MINCUL P,loc32 if P > loc32, P = loc32
(for 64 bit math) if P <= loc32, do nothing

Find the maximum 32-bit number in a table:


MOVL ACC,#0
MOVL XAR1,#table
RPT #(table_length – 1)
|| MAXL ACC,*XAR1++

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C - 17


Read Modify Write Operations

Read Modify Write Operations


The accumulator (ACC) is the main working register for the C28x. It is the destination of all
ALU operations except those, which operate directly on memory or registers. The accumulator
supports single-cycle move, add, subtract and compare operations from 32-bit-wide data memory.
It can also accept the 32-bit result of a multiplication operation. These one or two cycle
operations are referred to as read-modify-write operations, or as atomic instructions.

Read-Modify-Write Instructions

‹ Work directly on memory – bypass ACC


‹ Atomic Operations – protected from interrupts

AND loc16,AX AND loc16,#16b


OR loc16,AX OR loc16,#16b
XOR loc16,AX XOR loc16,#16b 16- bit
AH, constant
ADD loc16,AX AL
ADD loc16,#16b
SUB loc16,AX SUBR loc16,#16b
SUBR loc16,AX
INC loc16 TSET loc16,#bit
DEC loc16 TCLR loc16,#bit

C - 18 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Read Modify Write Operations

Read-Modify-Write Examples
update with a mem update with a constant update by 1

VarA += VarB VarA += 100 VarA += 1


SETC INTM SETC INTM SETC INTM
MOV AL, @VarB MOV AL, @VarA MOV AL, @VarA
ADD AL, @VarA ADD AL, #100 ADD AL, #1
MOV @VarA, AL MOV @VarA, AL MOV @VarA, AL
CLRC INTM CLRC INTM CLRC INTM

MOV AL, @VarB ADD @VarA,#100 INC @VarA


ADD @VarA, AL

Benefits of Read-Modify-Write Instructions

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C - 19


Lab C: Assembly Programming

Lab C: Assembly Programming


Note: The lab linker command file is based on the F28335 memory map – modify as needed, if
using a different F28xx device memory map.

¾ Objective

The objective of this lab is to practice and verify the mechanics of performing assembly language
programming arithmetic on the TMS320C28x. In this exercise, we will expand upon the .asm
file from the previous lab to include new functions. Code will be added to obtain the sum of the
products of the values from each array.
Perform the sum of products using a MAC-based implementation. In a real system application,
the coeff array may well be constant (values do not change), therefore one can modify the
initialization routine to skip the transfer of this arrays, thus reducing the amount of data RAM and
cycles required for initialization. Also there is no need to copy the zero to clear the result
location. The initialization routine from the previous lab using the load/store operation will be
replaced with a looped BANZ implementation.

As in previous lab, consider which addressing modes are optimal for the tasks to be performed.
You may perform the lab based on this information alone, or may refer to the following
procedure.

¾ Procedure

Copy Files, Create Project File


1. Create a new project called LabC.pjt in C:\C28x\Labs\Appendix\LabC and
add LabC.asm and Lab.cmd to it. Check your file list to make sure all the files are
there. Be sure to setup the Build Options by clicking: Project Æ Build
Options on the menu bar. Select the Linker tab. In the middle of the screen select
“No Autoinitialization” under “Autoinit Model:”. Enter start in the
“Code Entry Point (-e):” field. Next, select the Compiler tab. Note that
“Full Symbolic Debug (-g)” under “Generate Debug Info:” is
selected. Then select OK to save the Build Options.

Initialization Routine using BANZ


2. Edit LabC.asm and modify it by replacing the initialization routine using the load/store
operation with a BANZ process. Remember, it is only necessary to copy the first four
values (i.e. initialize the data array). Do you still need the coeff array in the vars section?

3. Save your work. If you would like, you can use Code Composer Studio to verify the
correct operation of the block initialization before moving to the next step.

C - 20 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Lab C: Assembly Programming

Sum of Products using a RPT/MAC-based Implementation


4. Edit LabC.asm to add a RPT/MAC-based implementation to multiply the coeff array by
the data array and storing the final sum-of-product value to result.

Build and Load


5. Click the “Build” button and watch the tools run in the build window. Debug as
necessary. To open up more space, close any open files or windows that you do not need.

6. If the “Load program after build” option was not selected in Code Composer
Studio, load the output file onto the target. Click: File Æ Load Program…

If you wish, right click on the source window and select Mixed Mode to debug using
both source and assembly.
7. Single-step your routine. While single-stepping, open memory windows to see the values
located in table [9] and data [9]. Open the CPU Registers. Check to see if the program
is working as expected. Debug and modify, if needed.

Optional Exercise
After completing the above, edit LabC.asm and modify it to perform the initialization
process using a RTP/PREAD rather than a load/store/BANZ.

End of Exercise

TMS320C28x MCU Workshop - Appendix C - Assembly Programming C - 21


OPTIONAL Lab C-C: Sum-of-Products in C

OPTIONAL Lab C-C: Sum-of-Products in C


Note: The lab linker command file is based on the F28335 memory map – modify as needed, if
using a different F28xx device memory map.

¾ Objective

The objective of this lab is to practice and verify the mechanics of performing C programming
arithmetic on the TMS320C28x. The objective will be to add the code necessary to obtain the
sum of the products of the n-th values from each array.

¾ Procedure

Create Project File


1. In Code Composer Studio create a new project called LabC-C.pjt in
C:\C28x\Labs\Appendix\LabC\LabC-C and add LabC-C.c and Lab.cmd to
it. Check your file list to make sure all the files are there. Open the Build Options and
select the Linker tab. Select the “Libraries” Category and enter rts2800_ml.lib in
the “Incl. Libraries (-l):” box. Do not setup any other Build Options. The
default values will be used. In Appendix Lab D exercise, we will experiement and
explore the various build options when working with C.

Sum of Products using a MAC-based Implementation


2. Edit LabC-C.c and modify the “main” routine to perform a MAC-based
implementation in C. Since the MAC operation requires one array to be in program
memory, the initialization routine can skip the transfer of one of the arrays, thus reducing
the amount of data RAM and cycles required for initialization.

Build and Load


3. Click the “Build” button and watch the tools run in the build window. Debug as
necessary.

Note: Have Code Composer Studio automatically load the output file after a successful build. On
the menu bar click: Option Æ Customize… and select the “Program Load Options”
tab, check “Load Program After Build”, then click OK.

4. Under Debug on the menu bar click “Go Main”. Single-step your routine. While
single-stepping, open memory windows to see the values located in table [9] and data
[9] . (Note: data[9] consists of the allocated arrays of data, coeff, and result). Open the
CPU Registers. Check to see if the program is working as expected. Debug and modify,
if needed.

End of Exercise

C - 22 TMS320C28x MCU Workshop - Appendix C - Assembly Programming


Appendix D – C Programming

Introduction
The C28x architecture, hardware, and compiler have been designed to efficiently support C code
programming.

Appendix D will focus on how to program in C for an embedded system. Issues related to
programming in C and how C behaves in the C28x environment will be discussed. Also, the C
compiler optimization features will be explained.

Learning Objectives
Learning Objectives

‹ Learn the basic C environment for


the C28x family
‹ How to control the C environment
‹ How to use the C-compiler optimizer
‹ Discuss the importance of volatile
‹ Explain optimization tips

TMS320C28x MCU Workshop – Appendix D – C Programming D- 1


Module Topics

Module Topics
Appendix D – C Programming.................................................................................................................D-1

Module Topics.........................................................................................................................................D-2
Linking Boot code from RTS2800.lib ......................................................................................................D-3
Set up the Stack .......................................................................................................................................D-4
C28x Data Types.....................................................................................................................................D-5
Accessing Interrupts / Status Register.....................................................................................................D-6
Using Embedded Assembly .....................................................................................................................D-7
Using Pragma .........................................................................................................................................D-8
Optimization Levels ................................................................................................................................D-9
Volatile Usage ..................................................................................................................................D-11
Compiler Advanced Options ............................................................................................................D-12
Optimization Tips Summary.............................................................................................................D-13
Lab D: C Optimization..........................................................................................................................D-14
OPTIONAL Lab D2: C Callable Assembly...........................................................................................D-17
Solutions................................................................................................................................................D-20

D- 2 TMS320C28x MCU Workshop – Appendix D – C Programming


Linking Boot code from RTS2800.lib

Linking Boot code from RTS2800.lib


Boot.ASM - Invoked With “-C”

Reset : PC <- *0x3F FFC0


vectors.asm
.ref _c_int00
Reset:
.long _c_int00
_c_int00
1. Allocate stack
2. Init SP to top of stack
3. Initialize status bits
4. Copy .cinit to .bss (skip if “-cr”)
5. Call “_main”

_main ...

The boot routine is used to establish the environment for C before launching main. The boot
routine begins with the label _c_int00 and the reset vector should contain a ".long" to this address
to make boot.asm the reset routine. The contents of the boot routine have been extracted and
copied on the following page so they may be inspected. Note the various functions performed by
the boot routine, including the allocation and setup of the stack, setting of various C-requisite
statuses, the initialization of global and static variables, and the call to main. Note that if the link
was performed using the "–cr" option instead of the "–c" option that the global/static variable
initialization is not performed. This is useful on RAM-based C28x systems that were initialized
during reset by some external host processor, making transfer of initialization values unnecessary.
Later on in this chapter, there is an example on how to do the vectors in C code rather than
assembly.

TMS320C28x MCU Workshop – Appendix D – C Programming D-3


Set up the Stack

Set up the Stack

Data Memory
The Stack
The C/C++ compiler uses a
stack to:
‹ Allocate local variables
SP 0x400 Caller’s
(reset) local vars ‹ Pass arguments to
Arguments functions
passed on
stack ‹ Save the processor status
Return ‹ Save the function return
address .stack
address
Function
return addr ‹ Save temporary results
Temp results
The compiler uses the hardware
stack pointer (SP) to
64K manage the stack.
SP defaults to 0x400 at reset.
4M The run-time stack grows from
low addresses to higher
addresses.

The C28x has a 16-bit stack pointer (SP) allowing accesses to the base 64K of memory. The stack
grows from low to high memory and always points to the first unused location. The compiler
uses the hardware stack pointer (SP) to manage the stack. The stack size is set by the linker.

Setting Up the Stack


‹ Boot.asm sets up SP to
point at .stack
Linker command file: ‹ The .stack section has to
SECTIONS { be linked into the low 64k
.stack :> RAM align=2 of data memory. The SP is
... } a 16-bit register and cannot
access addresses beyond
64K.
‹ Stack size is set by the
linker. The linker creates a
Note: The compiler provides no global symbol,
means to check for stack --STACK-SIZE, and assigns
overflow during compilation or at it a value equal to the size
runtime. A stack overflow of the stack in bytes.
disrupts the run-time (default 1K words)
environment, causing your
‹ You can change stack size
program to fail. Be sure to allow
at link time by using the
enough space for the stack to
-stack linker command
grow.
option.

In order to allocate the stack the linker command file needs to have “align = 2.”

D- 4 TMS320C28x MCU Workshop – Appendix D – C Programming


C28x Data Types

C28x Data Types


C28x C-Language Data Types
Type Bit Value Range
char 16 Usually 0 .. 255, but can hold 16 bits
int (natural size CPU word) 16 -32K .. 32K, 16 bits signed
unsigned int 16 0 .. 64K, 16 bits unsigned
short (same as int or smaller) 16 same as int
unsigned short 16 same as unsigned int
long (same as int or larger) 32 -2M .. 2M, 32 bits signed
unsigned long 32 0 .. 4M, 32 bits unsigned
float 32 IEEE single precision
double 64 IEEE double precision
long double 64 IEEE double precision
Suggestion: Group all longs together, group all pointers together
Data which is 32-bits wide, such as longs, must begin on even word-addresses (i.e. 0x0,
0x2, etc). This can result in “holes” in structures allocated on the stack.

TMS320C28x MCU Workshop – Appendix D – C Programming D-5


Accessing Interrupts / Status Register

Accessing Interrupts / Status Register


Accessing Interrupts / Status Register
Initialize via C :
extern cregister volatile unsigned int IFR;
extern cregister volatile unsigned int IER;
. . .
IER &= ~Mask; //clear desired bits
IER |= Mask; //set desired bits
IFR = 0x0000; //clear prior interrupts

‹ Interrupt Enable & Interrupt Flag Registers (IER, IFR) are not
memory mapped
‹ Only limited instructions can access IER & IFR (more in interrupt
chapter)
‹ The compiler provides extern variables for accessing the IER & IFR

D- 6 TMS320C28x MCU Workshop – Appendix D – C Programming


Using Embedded Assembly

Using Embedded Assembly


Embedding Assembly in C
‹ Allows direct access to assembly language from C
‹ Useful for operating on components not used by C, ex:

asm ( “ CLRC INTM ; enable global interrupt” );

#define EINT asm ( “ CLRC INTM”)


‹ Note: first column after leading quote is label field - if no label,
should be blank space.
‹ Avoid modifying registers used by C
‹ Lengthy code should be written in ASM and called from C
¾ main C file retains portability
¾ yields more easily maintained structures
¾ eliminates risk of interfering with registers in use by C

The assembly function allows for C files to contain 28x assembly code. Care should be taken not
to modify registers in use by C, and to consider the label field with the assembly function. Also,
any significant amounts of assembly code should be written in an assembly file and called from
C.
There are two examples in this slide – the first one shows how to embed a single assembly
language instruction into the C code flow. The second example shows how to define a C term that
will invoke the assembly language instruction.

TMS320C28x MCU Workshop – Appendix D – C Programming D-7


Using Pragma

Using Pragma
Pragma is a preprocessor directive that provides directions to the compiler about how to treat a
particular statement. The following example shows how the DATA_SECTION pragma is used
to put a specific buffer into a different section of RAM than other buffers.

The example shows two buffers, bufferA and bufferB. The first buffer, bufferA is treated
normally by the C compiler by placing the buffer (512 words) into the ".bss" section. The second,
bufferB is specifically directed to go into the “my_sect” portion of data memory. Global
variables, normally ".bss", can be redirected as desired.

When using CODE_SECTION, code that is normally linked as ".text", can be identified
otherwise by using the code section pragma (like .sect in assembly).

Pragma Examples
‹ User defined sections from C :
#pragma CODE_SECTION (func, ”section name”)
#pragma DATA_SECTION (symbol, “section name”)

‹ Example - using the DATA_SECTION Pragma


‹ C source file
char bufferA[512];
#pragma DATA_SECTION(bufferB, ”my_sect”)
char bufferB[512];

‹ Resulting assembly file


.global _bufferA, _bufferB
.bss _bufferA,512
_bufferB: .usect “my_sect”,512

More #pragma are defined in the C compiler UG

D- 8 TMS320C28x MCU Workshop – Appendix D – C Programming


Optimization Levels

Optimization Levels
Optimization Scope
FILE1.C
-o0, -o1 -o2 -o3 -pm -o3
{
{
SESE
} LOCAL
single block
{ FUNCTION
... across FILE
} SESE: Single Entry, Single Exit blocks across
} functions PROGRAM
across files
{
. . .
}

FILE2.C
{
. . .
}

Optimizations fall into 4 categories. This is also a methodology that should be used to invoke the
optimizations. It is recommended that optimization be invoked in steps, and that code be verified
before advancing to the next step. Intermediate steps offer the gradual transition from fully sym-
bolic to fully optimized compilation. Compiler switched may be invoked in a variety of ways.

Here are 4 steps that could be considered:


1st: use –g
By starting out with –g, you do no optimization at all and keep symbols for debug.

2nd: use –g –o3


The option –o3 might be too big a jump, but it adds the optimizer and keeps symbols.

3rd: use –g –o3 –mn


This is a full optimization, but keeps some symbols

4th: use –o3


Full optimization, symbols are not kept.

TMS320C28x MCU Workshop – Appendix D – C Programming D-9


Optimization Levels

Optimization Performance
–o0 Performs control-flow-graph simplification
Allocates variables to registers
LOCAL Performs loop rotation
Eliminates unused code
Simplifies expressions and statements
Expands calls to functions declared inline
–o1 Performs local copy/constant propagation
Removes unused assignments
Eliminates local common expressions
–o2 Default (-o)
FUNCTION Performs loop optimizations
Eliminates global common sub-expressions
Eliminates global unused assignments
–o3 Removes all functions that are never called
FILE Simplifies functions with return values that are never used
Inlines calls to small functions
Identifies file-level variable characteristics
PROGRAM –o3 –pm

Optimizer levels zero through three, offer an increasing array of actions, as seen above. Higher
levels include all the functions of the lower ones. Increasing optimizer levels also increase the
scope of optimization, from considering the elements of single entry, single-exit functions only,
through all the elements in a file. The “-pm” option directs the optimizer to view numerous input
files as one large single file, so that optimization can be performed across the whole system.

D- 10 TMS320C28x MCU Workshop – Appendix D – C Programming


Optimization Levels

Volatile Usage
Optimization Issue: “Volatile” Variables
Problem: The compiler does not know that this pointer may refer to a
hardware register that may change outside the scope of the C program.
Hence it may be eliminated (optimized out of existence!)
Wrong: Wait loop for a hardware signal Optimizer removes
unsigned int *CTRL empty loop
while (*CTRL !=1); No
CTRL empty
Solution: = 1? loop
volatile unsigned int *CTRL
while (*CTRL !=1); Yes
‹ When using optimization, it is important to declare variables as
volatile when:
¾ The memory location may be modifed by something other than the
compiler (e.g. it’s a memory-mapped peripheral register).
¾ The order of operations should not be rearranged by the compiler
‹ Define the pointer as “volatile” to prevent the optimizer from optimizing

TMS320C28x MCU Workshop – Appendix D – C Programming D - 11


Optimization Levels

Compiler Advanced Options


To get to these options, go to Project Æ Build Options in Code Composer Studio.

In the category, pick Advanced.

The first thing to notice under advanced options is the Auto Inlining Threshold.

- Used with –o3 option

- Functions > size are not auto inlined

Note: To prevent code size increases when using –o3, disable auto inlining with -oi0

The next point we will cover is the Normal Optimization with Debug (-mn).

- Re-enables optimizations disabled by “–g” option (symbolic debug)


- Used for maximum optimization

Note: Some symbolic debug labels will be lost when –mn option is used.

Optimizer should be invoked incrementally:


-g test Symbols kept for debug

-g -o3 test Add optimizer, keep symbols

-g -o3 -mn test More optimize, some symbols

-o3 test Final rev: Full optimize, no symbols

[-mf] : Optimize for speed instead of the default optimization for code size

[-mi] : Avoid RPT instruction. Prevent compiler from generating RPT instruction. RPT instruc-
tion is not interruptible

[-mt] : Unified memory model. Use this switch with the unified memory map of the 281x &
280x. Allows compiler to generate the following:
-RPT PREAD for memory copy routines or structure assignments
-MAC instructions
-Improves efficiency of switch tables

D- 12 TMS320C28x MCU Workshop – Appendix D – C Programming


Optimization Levels

Optimization Tips Summary


Summary: Optimization Tips
‹ Within C functions :
¾ Use const with variables for parameter constants
¾ Minimize mixing signed & unsigned ops : SXM changes
¾ Keep frames <= 64 (locals + parameters + PC) : *-SP[6bit]
¾ Use structures <= 8 words : use 3 bit index mode
¾ Declare longs first, then declare ints : minimize stack holes
¾ Avoid: long = (int * int) : yields unpredictable results
‹ Optimizing : Use -o0, -o1, -o2, -o3 when compiling
¾ Inline short/key functions
¾ Pass inlines between files : static inlines in header files
¾ Invoke automatic inlining : -o3 -oi
¾ Give compiler project visibility : use -pm and -o3
‹ Tune memory map via linker command file
‹ Re-write key code segments to use intrinsics or in assembly
App notes 3rd Parties

The list above documents the steps that can be taken to achieve increasingly higher coding effi-
ciency. It is recommended that users first get their code to work with no optimization, and then
add optimizations until the required performance is obtained.

TMS320C28x MCU Workshop – Appendix D – C Programming D - 13


Lab D: C Optimization

Lab D: C Optimization
Note: The lab linker command file is based on the F28335 memory map – modify as needed, if
using a different F28xx device memory map.

¾ Objective

The objective of this lab is to practice and verify the mechanics of optimizing C programs. Using
Code Composer Studio profile capabilities, different routines in a project will be benchmarked.
This will allow you to analyze the performance of different functions. This lab will highlight the
profiler and the clock tools in CCS.

¾ Procedure

Create Project File


1. Create a new project in C:\C28x\Labs\Appendix\LabD called LabD.pjt and
add LabD.c, Lab.cmd, and sop-c.c to it. (Note that sop-asm.asm will be used in
the next part of the lab, and should not be added now).

2. Setup the Build Options. Select the Linker tab and notice that “Run-time
Autoinitialization” under “Autoinit Model:”is selected. Do not enter
anything in the “Code Entry Point (-e):” field (leave it blank). Set the stack
size to 0x200. In the Linker options select the “Libraries” Category and enter
rts2800_ml.lib in the “Incl. Libraries (-l):” box. Next, select the
Compiler tab. Note that “Full Symbolic Debug (-g)” under “Generate
Debug Info:” in the Basic Category is selected. On the Feedback Category pull
down the interlisting options and select “C and ASM (-ss)”. On the Assembly
Category check the Keep generated .asm Files (-k), Keep Labels as
Symbols (-as) and Generate Assembly Listing Files (-al). The –as
will allow you to see symbols in the memory window and the –al will generate an
assembly listing file (.lst file). The listing file has limited uses, but is sometime helpful to
view opcode values and instruction sizes. (The .lst file can be viewed with the editor).
Both of these options will help with debugging. Then select OK to save the Build
Options.

Build and Load


3. Click the “Build” button and watch the tools run in the build window. Be sure the
“Load program after build” option is selected in Code Composer Studio. The
output file should automatically load. The Program Counter should be pointing to
_c_int00 in the Disassembly Window.

Set Up the Profile Session


4. Restart the DSP (debug Æ restart) and then “Go Main”. This will run
through the C initialization routine in Boot.asm and stop at the main routine in
LabD.c.

D- 14 TMS320C28x MCU Workshop – Appendix D – C Programming


Lab D: C Optimization

5. Set a breakpoint on the NOP in the while(1) loop at the end of main() in LabD.c.

6. Set up the profile session by selecting Profiler Æ Start New Session. Enter
a session name of your choice (i.e. LabD).
7. In the profiler window, hover the mouse over the icons on the left region of the window
and select the icon for Profile All Functions. Click on the “+” to expand the
functions. Record the “Code Size” of the function sop C code in the table at the end of
this lab. Note: If you do not see a “+” beside the .out file, press “Profile All Functions”
on the horizontal tool bar. (You can close the build window to make the profiler window
easier to view by right clicking on the build window and selecting “hide”).

8. Select F5 or the run icon. Observe the values present in the profiling window. What do
the numbers mean? Click on each tab to determine what each displays.

Benchmarking Code
9. Let’s benchmark (i.e.count the cycles need by) only a portion of the code. This requires
you to set a breakpoint pair on the starting and ending points of the benchmark. Open the
file sop-c.c and set a breakpoint on the “for” statement and the “return”
statement.

10. In CCS, select Profile Æ Setup. Check “Profile all Functions and
Loops for Total Cycles” and click “Enable Profiling”. Then select
Profile Æ viewer.

11. Now “Restart” the program and then “Run” the program. The program should be
stopped at the first breakpoint in sop. Double click on the clock window to set the clock
to zero. Now you are ready to benchmark the code. “Run” to the second breakpoint.
The number of cycles are displayed in the viewer window. Record this value in the table
at the end of the lab under “C Code - Cycles”.

C Optimization
12. To optimize C code to the highest level, we must set up new Build Options for our
Project. Select the Compiler tab. In the Basic Category Panel, under “Opt Level”
select File (-o3). Then select OK to save the Build Options.

13. Now “Rebuild” the program and then “Run” the program. The program should be
stopped at the first breakpoint in sop. Double click on the clock window to set the clock
to zero. Now you are ready to benchmark the code. “Run” to the second breakpoint.
The number of cycles are displayed in the clock window. Record this value in the table
at the end of the lab under “Optimized C (-o3) - Cycles”.
14. Look in your profile window at the code size of sop. Record this value in the table at the
end of this lab.

Benchmarking Assembly Code


15. Remove sop-c.c from your project and replace it with sop-asm.asm. Rebuild
and set breakpoints at the beginning and end of the assembly code (MOVL & LRETR).

TMS320C28x MCU Workshop – Appendix D – C Programming D - 15


Lab D: C Optimization

16. Start a new profile session and set it to profile all functions. Run to the first breakpoint
and study the profiler window. Record the code size of the assembly code in the table.
17. Double Click on the clock to reset it. Run to the last breakpoint. Record the number of
cycles the assembly code ran.
18. How does assembly, C code, and optimized C code compare on the C28x?

C Code Optimized C Code (-o3) Assembly Code

Code Size

Cycles

End of Exercise

D- 16 TMS320C28x MCU Workshop – Appendix D – C Programming


OPTIONAL Lab D2: C Callable Assembly

OPTIONAL Lab D2: C Callable Assembly


Note: The lab linker command file is based on the F28335 memory map – modify as needed, if
using a different F28xx device memory map.

¾ Objective

The objective of this lab is to practice and verify the mechanics of implementing a C callable
assembly programming. In this lab, a C file will be used to call the sum-of-products (from the
previous Appendix LabC exercise) by the “main” routine. Additionally, we will learn how to use
Code Composer Studio to configure the C build options and add the run-time support library to
the project. As in previous labs, you may perform the lab based on this information alone, or may
refer to the following procedure.

¾ Procedure

Copy Files, Create Project File


1. Create a new project in C:\C28x\Labs\Appendix\LabD2 called LabD2.pjt and
add LabD2.c, Lab.cmd, and sop-c.c to it.

2. Do not add LabC.asm to the project (copy of file from Appendix Lab C). It is only
placed here for easy access. Parts of this file will be used later during this lab exercise.

3. Setup the Build Options. Select the Linker tab and notice that “Run-time
Autoinitialization” under “Autoinit Model:”is selected. Do not enter
anything in the “Code Entry Point (-e):” field (leave it blank). Set the stack
size to 0x200. In the Linker options select the “Libraries” Category and enter
rts2800_ml.lib in the “Incl. Libraries (-l):” box. Next, select the
Compiler tab. Note that “Full Symbolic Debug (-g)” under “Generate
Debug Info:” in the Basic Category is selected. On the Feedback Category pull
down the interlisting options and select “C and ASM (-ss)”. On the Assembly
Category check the Keep generated .asm Files (-k), Keep Labels as
Symbols (-as) and Generate Assembly Listing Files (-al). The –as
will allow you to see symbols in the memory window and the –al will generate an
assembly listing file (.lst file). The listing file has limited uses, but is sometime helpful to
view opcode values and instruction sizes. (The .lst file can be viewed with the editor).
Both of these options will help with debugging. Then select OK to save the Build
Options.

Build and Load


4. Click the “Build” button and watch the tools run in the build window. Be sure the
“Load program after build” option is selected in Code Composer Studio. The
output file should automatically load. The Program Counter should be pointing to
_c_int00 in the Disassembly Window.

5. Under Debug on the menu bar click “Go Main”. This will run through the C
initialization routine in Boot.asm and stop at the main routine in LabD2.c.

TMS320C28x MCU Workshop – Appendix D – C Programming D - 17


OPTIONAL Lab D2: C Callable Assembly

Verify C Sum of Products Routine


6. Debug using both source and assembly (by right clicking on the window and select
Mixed Mode or using View → Mixed Source/ASM).

7. Open a memory window to view result and data.


8. Single-step through the C code to verify that the C sum-of-products routine produces the
results as your assembly version.

Viewing Interlisted Files and Creating Assembly File


9. Using File → Open view the LabD2.asm and sop-c.asm generated files. The
compiler adds many items to the generated assembly file, most are not needed in the C-
callable assembly file. Some of the unneeded items are .func / .endfunc. .sym, and .line.

10. Look for the _sop function that is generated by the compiler. This code is the basis for
the C-callable assembly routine that is developed in this lab. Notice the comments
generated by the compiler on which registers are used for passing parameters. Also,
notice the C code is kept as comments in the interlisted file.

11. Create a new file (File → New, or clicking on the left most button on the horizontal
toolbar “New”) and save it as an assembly source file with the name sop-asm.asm.
Next copy ONLY the sum of products function from LabC.asm into this file. Add a
_sop label to the function and make it visible to the linker (.def). Also, be sure to add a
.sect directive to place this code in the “code” section. Finally, add the following
instruction to the end:

LRETR ; return statement

12. Next, we need to add code to initialize the sum-of-products parameters properly, based
on the passed parameters. Add the following code to the first few lines after entering the
_sop routine: (Note that the two pointers are passed in AR4 and AR5, but one needs to
be placed in AR7. The loop counter is the third argument, and it is passed in the
accumulator.)

MOVL XAR7,XAR5 ;XAR7 points to coeff [0]

MOV AR5,AL ;move n from ACC to AR5 (loop counter)

SUBB XAR5,#1 ;subtract 1 to make loop counter = n-1

Before beginning the MAC loop, add statements to set the sign extension mode, set the
SPM to zero, and a ZAPA instruction. Use the same MAC statement as in Lab 4, but use
XAR4 in place of XAR2. Make the repeat statement use the passed value of n-1 (i.e.
AR5).

RPT AR5 ;repeat next instruction AR5 times

D- 18 TMS320C28x MCU Workshop – Appendix D – C Programming


OPTIONAL Lab D2: C Callable Assembly

Now we need to return the result. To return a value to the calling routine you will need to
place your 32-bit value in the ACC. What register is the result currently in? Adjust your
code, if necessary.

13. Save the assembly file as sop-asm.asm. (Do not name it LabD2.asm because the
compiler has already created with that name from the original LabD2.c code).

Defining the Function Prototype as External


14. Note in LabD2.c an “extern” modifier is placed in front of the sum-of-products function
prototype:

extern int sop(int*,int*,int); //sop function prototype

Verify Assembly Sum of Products Routine


15. Remove the sop-c.c file from the project and add the new sop-asm.asm assembly
file to the project.

16. Rebuild and verify that the new assembly sum-of-products routine produces the same
results as the C function.

End of Exercise

TMS320C28x MCU Workshop – Appendix D – C Programming D - 19


Solutions

Solutions
Lab D Solutions

C Code Optimized Assembly


C Code Code
(-o3)
Code Size 27 12 11

Cycles 118 32 22

D- 20 TMS320C28x MCU Workshop – Appendix D – C Programming


Appendix E – Floating-Point Unit

Introduction
Appendix E discusses the details of the TMS320F2833x floating-point unit (FPU). The floating-
point number format will be described, including the associated FPU registers and pipeline.
Various floating-point instructions will be explained as well as the use of delay slots. Parallel
instructions, repeat blocks, interrupts and code comparisions will be covered. The complete
floating-point instruction set is included for reference.

Learning Objectives
Learning Objectives

‹ Architecture – floating-point format,


registers, and pipeline

‹ Instructions – instruction types, delay


slots, parallel instructions, RPTB,
floating-point flags

‹ Instruction Summary

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E-1


Module Topics

Module Topics
Appendix E – Floating-Point Unit............................................................................................................E-1

Module Topics......................................................................................................................................... E-2


FPU Format, Registers, and Pipeline..................................................................................................... E-3
Instruction Types and Formats ............................................................................................................... E-6
Interrupts and Code Comparisions....................................................................................................... E-12
Instruction Summary............................................................................................................................. E-17

E-2 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


FPU Format, Registers, and Pipeline

FPU Format, Registers, and Pipeline


IEEE Single-Precision Floating-Point
Format
1 Sign Bit (0 = Positive, 1 = Negative) SS EE M
M
8-bit Exponent (Biased)
23-bit Mantissa (Implicit Leading Bit + Fraction Bits)

S E M Value
0 1 0 0 Positive or Negative Zero
0 1 0 Non-Zero Denormalized Number
0 1 1-254 0-0x7FFFF Positive or Negative Values*
0 1 255 (max) 0 Positive or Negative Infinity
0 1 255 (max) Non-Zero Not a Number (NaN)

* Normal Positive and Negative Values are Calculated as:


( -1 ) s x 2 (E-127) x 1.M
+/- ~1.7 x 10 -38 to +/- ~3.4 x 10 +38
The
The Normalized
Normalized IEEE
IEEE numbers
numbers have
have aa hidden
hidden 1;
1; thus
thus the
the equivalent
equivalent
signed
signed integer resolution
resolution is
is the
the number
number ofof mantissa
mantissa bits
bits ++ sign
sign + 11

IEEE Single-Precision Floating-Point


Format (IEEE 754)
‹ Most widely used standard for floating-point
Š Standard number formats, Special values (NaN, Infinity)
Š Rounding modes & floating-point operations
Š Used on many CPUs
‹ Simplifications for the C28x floating-point unit
Š Flags & Compare Operations:
Š Negative zero is treated as positive zero
Š Denormalized values are treated as zero
Š Not-a-number (NaN) is treated as infinity
Š Round-to-Zero Mode Supported (truncate)
Š Round-to-Nearest Mode Supported (even)
‹ These formats are commonly handled this way on
embedded processors

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E-3


FPU Format, Registers, and Pipeline

C28x CPU and FPU Registers


Standard C28x CPU Extended for FPU
C28 Register Set FPU Registers
ACC
R0H
P R0H 32-bit
32-bit
XT R1H
R1H
XAR0 8 FPU Result
Accumulator R2H
R2H
Product XAR1 Registers
XAR2 R3H
Temporary R3H
XAR3 FPU Status
XAR4 R4H
8 Auxiliary R4H Repeat Block
XAR5
R5H
22-bit XAR6 R5H
XAR7 R6H
R6H
Program Counter PC
Return PC RPC R7H
R7H
DP
16-bit SP STF
STF
ST0
Data Page Pointer RB
ST1
Stack Pointer
IER
IFR
R0H – R7H and
2 Status STF are shadowed
DBGIER
Interrupt Enable for fast context save
Interrupt Flag
and restore

Floating-Point Unit Pipeline


Fetch Decode Read Exe Write
C28x Pipeline F1 F2 D1 D2 R1 R 2 E W

FPU Instruction D R E1 E2/W


Load
Store
No required delay slot instruction CMP/MIN/MAX/NEG/ABS
1 required delay slot instruction MPY/ADD/SUB/MACF32

‹ Floating-point operations are not pipeline protected


‹ Some instructions require delay slots for the
operation to complete
‹ Insert NOPs or other non-conflicting instructions
between operations

E-4 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


FPU Format, Registers, and Pipeline

Floating-Point Unit Pipeline Delay Slots


‹ Instructions requiring delay slots have a ‘p’ after
their cycle count
‹ 2p stands for 2 pipelined cycles
Š A new instruction can be started on each cycle
Š The result is valid only 2 instructions later
‹ Assembler issues errors for pipeline conflicts
‹ Fill delay slots with non-conflicting instructions
to improve performance
‹ 3 general guidelines:
Math MPYF32, ADDF32, 2p cycles
SUBF32, MACF32
One delay slot
Conversion I16TOF32, F32TOI16, 2p cycles
F32TOI16R, etc… One delay slot
Everything Else* Load, Store, Compare, Single cycle
Min, Max, Absolute
and Negative value No delay slot

* Note: MOV32 between FPU and CPU registers is a special case

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E-5


Instruction Types and Formats

Instruction Types and Formats


Floating-Point Instruction Format

‹ Same instruction format as the


fixed-point instructions
Š Destination operand is always on the left

Fixed-Point: MPY ACC, T, loc16


Floating-Point: MPYF32 R0H, R1H, R2H

Destination Source Operands

To enable floating-point on the 5.x compiler use the switch:


--float_support=fpu32

Types of Floating-Point Instructions (1 of 2)

Type Example Cycles


Load (Conditional) MOV32 R0H,mem32{,CONDF} 1
Store MOV32 mem32,R1H 1
Load With Data Move MOVD32 R3H,mem32 1
FPU Register To 28x Register MOV32 XAR6, R2H 1*
28x Register To FPU Register MOV32 R3H, XAR7 1*
Compare, Min, Max CMPF32 R2H,R3H 1
Absolute, Negative Value ABSF32 R2H,R3H 1
Context Save SAVE 1
Unsigned Integer To Float UI16TOF32 R1H,mem32 2p
Integer To Float I32TOF32 R1H,mem32 2p
Float To Integer & Round F32TOI16R R2H,R1H 2p
Float To Integer F32TOI32 R2H,R1H 2p

* Moves between CPU and FPU registers require additional pipeline alignment

E-6 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


Instruction Types and Formats

Types of Floating-Point Instructions (2 of 2)

Type Example Cycles


Multiply, Add, Subtract, MAC MPYF32 R2H,R1H,R0H 2p
1/X (16-bit Accurate) EINVF32 R2H,R1H 2p
1/Sqrt(x) (16-bit Accurate) EISQRTF32 R3H,R0H 2p
Repeat MAC RPT (#N-1)
2p+N
|| MACF32 R7H,R3H,mem32,*XAR7++
Min or Max MINF32 RaH,RbH
1/1
& Parallel Move || MOV32 RcH,RdH
Multiply MPYF32 R2H,R1H,R0H
2p/2p
& Parallel Add or Subtract || ADDF32 R4H,R4H,R2H
Multiply, Add, Subtract, MAC MPYF32 R2H,R1H,R0H 2p/1
& Parallel Load || MOV32 R0H,mem32
Multiply, Add, Subtract, MAC MPYF32 R2H,R1H,R0H
2p/1
& Parallel Store || MOV32 mem32,R0H

Math Operations
MPYF32 R2H, R1H, R0H ; 2p instruction
NOP ; 1 cycle delay
; <- MPYF32 completes, R2H valid
<any instruction> ; Can use R2H
;

MPYF32 R2H, R1H, R0H ; 2p instruction


NOP
ADDF32 R3H, R3H, R1H ; 1 cycle delay for MPYF32
; <- MPYF32 completes, R2H valid
<any instruction>
NOP
MOV32 *XAR7, R2H ; 1
Can
cycle
use delay
R2H for ADDF32
; <- ADDF32 complete, R3H valid
; <- MOV32 complete

Math Operations: 2p (2 pipelined) cycles


Can be launched every cycle
Result is valid 2 instructions later

Move Operation: 1 cycle

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E-7


Instruction Types and Formats

Parallel Instructions

Single Instruction
Single Opcode Parallel Bars Indicate A
Performs 2 Operations Parallel Instruction

Example:
ADDF32 R3H, R3H, R1H
Add + Parallel Store
|| MOV32 *XAR7, R3H

Instruction Example Cycles


Multiply MPYF32 RaH,RbH,RcH
& Parallel Add/Subtract || SUBF32 RdH,ReH,RfH 2p/2p
Multiply, Add, Subtract, Mac ADDF32 RaH,RbH,RcH
|| MOV32 mem32,ReH 2p/1
& Parallel Load/Store
Min or Max MAXF32 RaH,RbH 1/1
& Parallel Move || MOV32 RdH,ReH

Note: cycle information is given for both operation

Multiply and Store Parallel Instruction


; Before: R0H = 2.0, R1H = 3.0, R2H = 10.0

MPYF32 R2H, R1H, R0H ; 2p/1 instruction


|| MOV32 *XAR3, R2H
; <- MOV32 complete
NOP ; Delay for MPYF32
; <- R2H updated
<any instruction> ; Can use R2H

; After: R2H = R1H


? * R0H = 3.0 * 2.0
; *XAR3 = 10.0
?

Math Operations: 2p (2 pipelined) cycles


Can be launched every cycle
Result is valid 2 instructions later

Move Operation: 1 cycle

Parallel Instruction: MOV32 used the value of R2H before the MPY32 update

E-8 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


Instruction Types and Formats

Multiply and Store Parallel Instruction


;

MPYF32 R2H, R1H, R0H ; 2p/1 instruction


|| MOV32 *XAR3, R2H
; <- MOV32 complete
MOV32 R1H, *XAR4 ; Delay for MPYF32
; <- R2H updated, R1H updated
ADDF32 R2H, R2H, R1H ; Can use R2H

Math Operations: 2p (2 pipelined) cycles


Can be launched every cycle
Result is valid 2 instructions later

Move Operation: 1 cycle

Parallel Instruction: MOV32 used the value of R2H before the MPY32 update

Using Floating-Point Status Flags


Floating-Point Status Register STF (32-bits)
RND
SHDWS rsvd rsvd TF ZI NI ZF NF LUF LVF
F32

LVF Latched Math: MPYF32, ADDF32, SUBF32, 1/X


LUF overflow & underflow Connected to the PIE for debug
NF, ZF Negative & Zero Float Move operations on registers
Result of compare, min/max,
NI, ZI Negative & Zero Integer absolute value and negative value
TF Test flag TESTTF Instruction
RND32 Rounding mode To Zero (truncate) or To Nearest (even)
SHDWS Shadow status For fast interrupt context save/restore

Program control is
Loop:
through the C28x status
register (ST0) flags MOV32 R0H,*XAR4++
MOV32 R1H,*XAR3++
CMPF32 R1H, R0H
Use MOVST0 to copy FPU
MOVST0 ZF, NF
flags to ST0
BF Loop, GT ; Loop if (R1H > R0H)

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E-9


Instruction Types and Formats

Repeat Block
‹ Improves performance of block algorithms (FFT, IIR)
‹ 0 cycles after the first iteration
RPTB #label, #RC 1+0 Cycles
RPTB #label, loc16 4+0 Cycles

Repeat Block Register RB (32)


Hardware
RAS RA RSIZE(7) RE(7) RC(15)
Manages RB
31 30 29:23 22:16 15:0

; find the largest element and


; put its address in XAR6
Assembler .align 2 RC: Repeat Count
Checks Size & NOP Block Executes RC+1
Alignment
RPTB VECTOR_MAX_END, AR7
MOVL ACC,XAR0
MOV32 R1H,*XAR0++ RSIZE: RPTB Block Size
RA = 1 Max: 127 x 16 Words
RPTB Active MAXF32 R0H,R1H
Min: 8 words (odd aligned)
MOVST0 NF,ZF
9 words (even aligned)
RA = 0 MOVL XAR6,ACC,LT
VECTOR_MAX_END:
RE: End address

Repeat Block (RPTB)


_ISR: RAS = RA, RA = 0
...
‹ The RPTB is PUSH RB Save RB
interruptible and allows ...
for nested interrupts CLRC INTM Enable Interrupts
... Only After PUSH RB
‹ High Priority ISR: .align 2
Save/Restore RB if RPTB NOP
is used RPTB VECTOR_MAX_END, AR7
MOVL ACC,XAR0
‹ Low Priority ISR: ...
Always save/restore RB ...
MOVL XAR6,ACC,LT
‹ No other discontinuities VECTOR_MAX_END:
are allowed (TRAP, ... Disable Interrupts
CALL, BRANCH etc) SETC INTM
... Restore RB Only After
‹ Single RPT || POP RB Disabling Interrupts
instructions are allowed ...
IRET RA = RAS, RAS = 0

E - 10 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


Instruction Types and Formats

Move Between CPU and FPU Registers


‹ Register to register moves between
FPU and CPU are typically infrequent
CPU Register to FPU Register FPU Register to CPU Register
MOV32 RaH,@XARn MOV32 @XARn,RaH
MOV32 RaH,@ACC MOV32 @ACC,RaH
MOV32 RaH,@T MOV32 @XT,RaH
MOV32 RaH,@P MOV32 @P,RaH
1 Cycle FPU Operation:
Requires 4 delay slots Requires 1 instruction delay

MOV32 R0H, @ACC MINF32 R0H,R1H


NOP NOP
NOP MOV32 @ACC,R0H
NOP
NOP 2p Cycle FPU Operation:
Requires 2 delay slots
ADDF32 R2H,R1H,R0H
ADDF32 R0H,R1H,R2H
Do not use these in the delay slots: NOP
FRACF32, UI16TOF32, I16TOF32, NOP
F32TOUI32, F32TOI32 MOV32 @ACC,R0H

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E - 11


Interrupts and Code Comparisions

Interrupts and Code Comparisions


Interrupt Context Save & Restore
Highest Priority Interrupt

Full Context Save Full Context Restore


_HighestPriorityISR:
ASP ; Align stack ...
PUSH RB ; Save RB if used ...
PUSH AR1H:AR0H ; Save if used RESTORE ; FPU registers
PUSH XAR2 POP XT ; Restore registers
PUSH XAR3 POP XAR7
PUSH XAR4 POP XAR6
PUSH XAR5 POP XAR5
PUSH XAR6 POP XAR4
PUSH XAR7 POP XAR3
PUSH XT POP XAR2
SPM 0 ; Set C28 modes POP AR1H:AR0H
CLRC AMODE POP RB ; Restore RB
CLRC PAGE0,OVM NASP ; Un-align stack
SAVE RNDF32=1 ; FPU registers IRET ; Return
; set FPU mode
...
...

22 Cycles (worst case if all registers are saved) 19 Cycles (worst case if all registers are restored)

Note: The following critical registers are automatically saved on an interrupt:


ACC, P, XT, ST0, ST1, IER, DP, AR0, AR1, PC

Interrupt Context Save & Restore


Low Priority Interrupt

Full Context Save


(with interrupt prioritization) Full Context Restore
_LowerPr iorityISR: .
MOVW DP,#PIE ; Set PIE Interrupt P riority .
MOV AL,@PIEIE Rn MOV32 R 7H,*--SP ; Restore R0 H to R7H
OR IER,#INTn _PRIORITY_MAS K .
AND IER,#IER_ PRIORITY_MASK .
MOV @PIEIERn, #PIEIERn_PRIO RITY_MASK MOV32 R 0H,*--SP
MOV @PIEACK,# 0xFFFF MOV32 S TF,*--SP ; Restore ST F
MOV *SP++,AL POP XT ; Restore XT
ASP ; Align S tack Pointer POP X AR7 ; Restore XA R0 to XAR7
PUSH RB ; Save RB POP X AR6
CLRC INTM ; Enable Interrupts POP X AR5
PUSH AR1H:AR0H ; Save XA R0 to XAR7 POP X AR4
PUSH XAR2 POP X AR3
PUSH XAR3 POP X AR2
PUSH XAR4 POP A R1H:AR0H
PUSH XAR5 MOVW D P,#PIE
PUSH XAR6 SETC I NTM ; Disable Int errupts
PUSH XAR7 POP RB ; Restore RB
PUSH XT ; Save XT NASP ; Un-align St ack Pointer
MOV3 2 *SP++,STF ; Save ST F MOV A L,*--SP
MOV3 2 *SP++,R0H ; Save R0 H to R7H MOV @ PIEIERn,AL ; Restore PIE Interrupt P riority
. IRET ; Return From Interrupt
.
MOV3 2 *SP++,R7H
SPM 0 ; Set def ault C28 mod es
CLRC AMODE
CLRC PAGE0,OVM
SETF LG RNDF32=1 ; Set def ault FPU mod es
.
.

42 cycles (worst case if need to save all registers) 32 cycles (worst case if need to restore all registers)
(interrupt disabled for 21 cycles) (interrupt disabled for 14 cycles)

E - 12 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


Interrupts and Code Comparisions

Interrupt Priority in C/C++


Specify a High Priority Interrupt:
#pragma INTERRUPT (function_name, HPI)

Specify a Low Priority Interrupt:


#pragma INTERRUPT (function_name, LPI)

The floating-point compiler:


‹ Never sets or clears INTM
Š It is always up to the user to enable interrupts
‹ Always saves & restores RB in low priority interrupts
Š Only saves & restores RB in high priority interrupts if used
‹ Only uses SAVE & RESTORE in high priority interrupts
‹ Assumes interrupts are low priority by default
Š Compatible with existing C28x code

Floating-Point vs. Fixed-Point 32-bit


Division
; Fixed-Point Division
_div: SUBL ACC,@XAR6 ASR64 ACC:P,T
MOVL *SP++,ACC NEG ACC ADDUL P,*XAR7++
MOVL ACC,*-SP[6] IMPYL P,XT,@ACC ADDCL ACC,*XAR7++
CSB ACC MPYL ACC,XT,@ACC MINL ACC,*+XAR7[2]
LSLL ACC,T LSL64 ACC:P,#3 MINCUL P,*+XAR7[0]
MOVL @XAR4,ACC MOVL XT,@ACC MAXL ACC,*+XAR7[6]
LSR AH,#6 IMPYL P,XT,@XAR4 MAXCUL P,*+XAR7[4]
SBF $10,EQ QMPYL ACC,XT,@XAR4 ASR64 ACC:P,#1
MOVZ AR0,@AH LSL64 ACC:P,#1 MOVL
LRETR
ACC,@P
71 Words
MOVL XAR7,#(_IQdivTable-254)
MOVB AH,#(61 - GLOBAL_Q)
SUBL
NEG
ACC,@XAR6
ACC $10: 72 Cycles
SUBR @T,AH IMPYL P,XT,@ACC MOV @AL,#0xFFFF
MOVL XAR5,@XT QMPYL ACC,XT,@ACC MOV @AH,#0x7FFF
MOVL XT,*+XAR7[AR0] LSL64 ACC:P,#3 SUBB SP,#2
MOVL XAR7,#_IQdivRoundSatTable MOVL XT,*--SP LRETR
MOVL XAR6,*XAR7++ IMPYL P,XT,@ACC
IMPYL QMPYL ACC,XT,@ACC
IMPYL P,XT,@XAR4 LSL64 ACC:P,#2
QMPYL ACC,XT,@XAR4 MOVL XT,@XAR5
LSL64 ACC:P,#1

; Floating-Point Division
_div: MPYF32 R4H,R2H,R1H
MOV32 *SP++,R4H NOP
EINVF32 R2H,R1H SUBF32 R4H,R3H,R4H
MOVIZF32 R3H,#2.0 NOP 29 Words
MPYF32 R4H,R2H,R1H MPYF32 R2H,R2H,R4H 33 Cycles
NOP NOP
SUBF32 R4H,R3H,R4H MPYF32 R0H,R0H,R2H
NOP MOV32 R4H,*--SP
MPYF32 R2H,R2H,R4H LRETR
NOP

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E - 13


Interrupts and Code Comparisions

Floating-Point vs. Fixed-Point Division


Newton-Raphson Algorithm
Ye = Estimate(1/X)
Ye = Ye*(2.0 - Ye*X)
Ye = Ye*(2.0 - Ye*X)

‹ Use delay slots to further improve performance


_div:
MOV32 *SP++,R4H MPYF32 R4H,R2H,R1H
EINVF32 R2H,R1H NOP
MOVIZF32 R3H,#2.0 SUBF32 R4H,R3H,R4H
MPYF32 R4H,R2H,R1H NOP
NOP MPYF32 R2H,R2H,R4H
SUBF32 R4H,R3H,R4H NOP
NOP MPYF32 R0H,R0H,R2H
MPYF32 R2H,R2H,R4H MOV32 R4H,*--SP
NOP LRETR

Floating-Point vs. Fixed-Point SQRT


; Fixed Point Square Root MOVL XT,@XAR5 QMPYL ACC,XT,@ACC
__sqrt: SUBL @XT,ACC MOVL XT,*+XAR7[AR0]
CSB ACC QMPYL ACC,XT,@XAR4 IMPYL P,XT,@ACC
LSLL ACC,T LSL ACC,#2 QMPYL ACC,XT,@ACC
MOVL XAR6,@ACC MOVL XAR4,@ACC .if GLOBAL_Q >= 24
ASR AH,#6 MOVL XT,@XAR4 LSL64 ACC:P,#((GLOBAL_Q - 22)/2)
MOVB @AH,#0xFE,LEQ QMPYL ACC,XT,@XT .endif
SUB @AH,#254 MOVL XT,@XAR6 .if GLOBAL_Q <= 21
MOVZ AR0,@AH LSL ACC,#2 ASR64 ACC:P,#((23 - GLOBAL_Q)/2)
TBIT @T,#0 QMPYL ACC,XT,@ACC .endif
MOV AH,@T MOVL XT,@XAR5 MOVL XT,*--SP
LSR AH,#1 SUBL @XT,ACC ASR64 ACC:P,T
QMPYL ACC,XT,@XAR4
MOVL *SP++,ACC
MOVL XAR7,#_IQsqrtTable LSL ACC,#2
ADD @PH,#-32768
ADDCL ACC,*+XAR7[2]
66 Words
MOVL XAR4,*+XAR7[AR0] MOVL XT,@XAR6 LRETR 70 Cycles
MOVL XAR7,#_IQsqrtRoundSatTable
MOVL XAR5,*XAR7++ ; Floating-Point Square Root
MPYF32 R1H,R1H,R4H
.if (GLOBAL_Q & 0x0001)==0; __sqrt:
NOP
MOVB @AR0,#12,NTC MOV32 *SP++,R4H
MPYF32 R4H,R1H,R2H
MOVB @AR0,#10,TC CMPF32 R0H,#0.0
NOP
endif MOVST0 ZF,NF
MPYF32 R4H,R1H,R4H
.if (GLOBAL_Q & 0x0001)==1 B L1,EQ
NOP
MOVB @AR0,#12,TC EISQRTF32 R1H,R0H
SUBF32 R4H,R3H,R4H
MOVB @AR0,#8,NTC MOVIZF32 R2H,#0.5
NOP
.endif MPYF32 R2H,R0H,R2H
MPYF32 R1H,R1H,R4H
MOVL XT,@XAR4 MOVIZF32 R3H,#1.5
NOP
QMPYL ACC,XT,@XT MPYF32 R4H,R1H,R2H
MPYF32 R0H,R0H,R1H
MOVL XT,@XAR6 NOP
L1: MOV31 R4H,*--SP
LSL ACC,#2 MPYF32 R4H,R1H,R4H
LRETR
QMPYL ACC,XT,@ACC NOP
SUBF32 R4H,R3H,R4H
42 Words
NOP 31 Cycles

E - 14 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


Interrupts and Code Comparisions

Floating-Point vs. Fixed-Point SQRT


Ye = Estimate(1/sqrt(X))
Ye = Ye*(1.5 - Ye*Ye*X*0.5)
Ye = Ye*(1.5 - Ye*Ye*X*0.5)
Y = X*Ye

‹ Use delay slots to further improve performance


__sqrt: MPYF32 R1H,R1H,R4H
MOV32 *SP++,R4H NOP
CMPF32 R0H,#0.0 MPYF32 R4H,R1H,R2H
MOVST0 ZF,NF NOP
B L1,EQ MPYF32 R4H,R1H,R4H
EISQRTF32 R1H,R0H NOP
MOVIZF32 R2H,#0.5 SUBF32 R4H,R3H,R4H
MPYF32 R2H,R0H,R2H NOP
MOVIZF32 R3H,#1.5 MPYF32 R1H,R1H,R4H
MPYF32 R4H,R1H,R2H NOP
NOP MPYF32 R0H,R0H,R1H
MPYF32 R4H,R1H,R4H L1: MOV31 R4H,*--SP
NOP LRETR
SUBF32 R4H,R3H,R4H
NOP

Take Advantage of Pipeline Delay Slots

‹ Improve performance by placing non-conflicting


instructions in floating-point pipeline delay slots
‹ Most instructions can be used
Š Math, move, min/max, C28x instructions etc….
‹ What makes an instruction conflicting?
Š A source or destination register resource conflict
Š An instruction that accesses or changes the STF
flags: SAVE, SETFLG, RESTORE, MOVEST0
Š Special case: moves between CPU and FPU registers
‹ Assembler issues errors for conflicts

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E - 15


Interrupts and Code Comparisions

Take Advantage of Delay Slots


32-bit Floating Point
Y1 = M1*X1 + B1 Compiler
32-bit Fixed-Point
Y2 = M2*X2 + B2 Optimized
Y1=(M1*X1)>> Q + B1
Code
Y2=(M2*X2)>> Q + B2 MOV32 R0H,@M1
MOV32 R1H,@X1 32-bit Floating-Point
MOVL XT,@M1 MPYF32 R1H,R1H,R0H Y1 = M1*X1 + B1
IMPYL P,XT,@X1 ||MOV32 R0H,@B1 Y2 = M2*X2 + B2
QMPYL ACC,XT,@X1 NOP MOV32 R2H,@X1
ASR64 ACC:P,#Q ADDF32 R1H,R1H,R0H MOV32 R1H,@M1
ADDL ACC,@B1 NOP
MOVL @Y1,ACC MPYF32 R3H,R2H,R1H
MOV32 @Y1,R1H
MOV32 R0H,@M2 ||MOV32 R0H,@M2
MOVL XT,@M2 MOV32 R1H,@X2 MOV32 R1H,@X2
IMPYL P,XT,@X2 MPYF32 R1H,R1H,R0H MPYF32 R0H,R1H,R0H
QMPYL ACC,XT,@X2 ||MOV32 R0H,@B2 ||MOV32 R4H,@B1
ASR64 ACC:P,#Q NOP ADDF32 R1H,R4H,R3H
ADDL ACC,@B2 ADDF32 R1H,R1H,R0H ||MOV32 R2H,@B2
MOVL @Y2,ACC NOP ADDF32 R0H,R2H,R0H
MOV32 @Y2,R1H MOV32 @Y1,R1H
; 14 cycles ; 14 cycles MOV32 @Y2,R0H
; 32 bytes ; 48 bytes ; 9 cycles, 36 bytes

E - 16 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit


Instruction Summary

Instruction Summary
Floating-Point Instructions

Instructions Cycles Instruction Cycles


MOVIZ RaH,#16F 1 MOV32 STF,mem32 1
MOVXI RaH,#16I 1 MOV32 mem32,STF 1
MOV32 RaH,mem32{,CNDF} 1 MOVST0 FLAG 1
MOVD32 RaH,mem32 1 SETFLG FLAG,VALUE 1
MOV32 mem32,RaH 1 SAVE FLAG,VALUE 1
MOV16 mem16,RaH 1 RESTORE 1
MOV32 CPUReg,FPUReg 1*
MOV32 FPUReg,CPUReg 1*
PUSH RB 1
POP RB 1
ZEROA 1 RPTB #Label,#count 1
ZERO RaH 1 RPTB #Label,loc16 1
TESTTF CNDF 1
SWAPF Ra,Rb{,CNDF} 1
MOV32 RaH,RbH{,CNDF} 1

* Note: Move between CPU and FPU registers requires special pipeline alignment

Floating-Point Instructions

Instruction Cycles Instruction Cycles


I16TOF32 RaH,mem16 2p CMPF32 RaH,RbH 1
CMPF32 RaH,#16F 1
I16TOF32 RaH,RbH 2p CMPF32 RaH,#0.0 1
UI16TOF32 RaH,mem16 2p
UI16TOF32 RaH,RbH 2p MAXF32 RaH,RbH 1
MAXF32 RaH,#16F 1
F32TOI16 RaH,RbH 2p
MINF32 RaH,RbH 1
F32TOI16R RaH,RbH 2p MINF32 RaH,#16F 1
F32TOUI16 RaH,RbH 2p
ABSF32 RaH,RbH 1
F32TOUI16R RaH,RbH 2p
NEGF32 RaH,RbH{,CNDF} 1

I32TOF32 RaH,mem32 2p MAXF32 RaH,RbH 1/1


|| MOV32 RcH,RdH
I32TOF32 RaH,RbH 2p MINF32 RaH,RbH
1/1
UI32TOF32 RaH,mem32 2p || MOV32 RcH,RdH
UI32TOF32 RaH,RbH 2p
F32TOI32 RaH,RbH 2p
F32TOUI32 RaH,RbH 2p

TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit E - 17


Instruction Summary

Floating-Point Instructions
Instruction Cycles Instruction Cycles
EISQRTF32 RaH,RbH 2p MPYF32 RdH,ReH,RfH
|| MOV32 RaH,mem32 2p/1
EINVF32 RaH,RbH 2p
MPYF32 RdH,ReH,RfH 2p/1
FRACF32 RaH,RbH 2p || MOV32 mem32,RaH
ADDF32 RdH,ReH,RfH
2p/1
MPYF32 RaH,RbH,RcH 2p || MOV32 RaH,mem32
ADDF32 RdH,ReH,RfH
ADDF32 RaH,RbH,RcH 2p || MOV32 mem32,RaH 2p/1
SUBF32 RaH,RbH,RcH 2p SUBF32 RdH,ReH,RfH 2p/1
MPYF32 RaH,RbH,#16F 2p || MOV32 RaH,mem32
MPYF32 RaH,#16F,RbH 2p SUBF32 RdH,ReH,RfH 2p/1
|| MOV32 mem32,RaH
ADDF32 RaH,RbH,#16F 2p MACF32 R3H,R2H,RdH,ReH,RfH
|| MOV32 RaH,mem32 2p/1
ADDF32 RaH,#16F,RbH 2p
SUBF32 RaH,#16F,RbH 2p MACF32 R7H,R6H,RdH,ReH,RfH 2p/1
|| MOV32 RaH,mem32

MPYF32 RaH,RbH,RcH
2p/2p
|| SUBF32 RdH,ReH,RfH
MPYF32 RaH,RbH,RcH 2p/2p
|| ADDF32 RdH,ReH,RfH

This instruction
is repeatable Instruction Cycles
(RPT || ) MACF32 R7H,R3H, mem32,*XAR7++ 2p+N

Floating-Point Conditional Instructions

C OND Test
NEQ != 0 (ZF = = 0)
EQ == 0 (ZF = = 1)
GT > 0 (ZF = = 0) A ND (NF = = 0)
GEQ >= 0 (NF = = 0)
LT < 0 (NF = = 1)
LEQ <= 0 (ZF = = 1) O R (NF == 1)
TF TF == 1
NTF TF == 0
LU Latched Un derflo w Set (L UF == 1 )
LV Latched Ov erflow Set (L VF == 1 )
UNC Unconditio nal
U NCF Unconditio nal, F lags Aff ected

Note: UNCF: This test in conditional operations can modify flags (based on destination register value).
UNC, NEQ, EQ, GT, GEQ, LT, LEQ, TF, NTF, LU, LV: These tests in conditional operations do not modify flags.

E - 18 TMS320C28x MCU Workshop - Appendix E - Floating-Point Unit

You might also like