Application Report
SPRAA85D–November2005–Revised January2013 Programming TMS320x28xx and28xxx Peripherals in
C/C++ Lori Heustess AEC C2000
ABSTRACT
This application report explores a hardware abstraction layer implementation to make C/C++coding easier on C28x devices.This method is compared to traditional#define macros and topics of code efficiency and special case registers are also addressed.
Contents
1Introduction (1)
2Traditional#define Approach (3)
3Bit Field and Register-File Structure Approach (5)
4Bit Field and Register-File Structure Advantages (11)
5Code Size and Performance Using Bit Fields (12)
6Read-Modify-Write Considerations When Using Bit Fields (16)
7A Special Case:eCAN Control Registers (21)
8References (23)
List of Figures
1SCI SCICCR Register (9)
2SCI SCICTL1Register (9)
3Code Composer Studio v5.1Autocomplete Feature (12)
4Code Composer Studio v5.1Expression Window (12)
5Peripheral Clock Control0Register(PCLKCR0) (13)
List of Tables
1SCI-A,SCI-B Configuration and Control Registers (3)
2SCI-A and SCI-B Common Register File (5)
3CPU-Pipeline Activity For Read-Modify-Write Instructions in (14)
4Read-Modify-Write Sensitive Registers (21)
1Introduction
The TMS320x28xx and TMS328x28xxx are members of the C2000™generation for embedded control applications.To facilitate writing efficient and easy-to-maintain embedded C/C++code on these devices, Texas Instruments provides a hardware abstraction layer method for accessing memory-mapped
peripheral registers.This method is the bit field and register-file structure approach.This application report explains the implementation of this hardware abstraction layer and compares it to traditional#define
macros.Topics of code efficiency and special case registers are also addressed.
C2000,controlSUITE,Concerto,Piccolo,Delfino,Code Composer Studio are trademarks of Texas Instruments.
All other trademarks are the property of their respective owners.
Introduction www.ti The hardware abstraction layer discussed in this application report has been implemented as a collection of C/C++header files available for download in controlSUITE™from Texas Instruments:
Support for all new microcontrollers is available in the device support section of controlSUITE.At this time, this includes the following:
•Concerto™Series Microcontrollers(C28x Subsystem)
–28M35x
•Piccolo™Series Microcontrollers
–2806x
–2802x
–2803x
•Delfino™Series
–C2833x/C2823x
–C2834x
•Older C28x devices are supported in the following downloads
–C281x C/C++Header Files and Peripheral Examples(SPRC097)
–C280x,C2801x C/C++Header Files and Peripheral Examples(SPRC191)
–C2804x C/C++Header Files and Peripheral Examples(SPRC324)
Depending on your current needs,the software included in these downloads are learning tools or the
basis for a development platform.
•Learning Tool:
The C/C++Header Files and Peripheral Examples include several example Code Composer Studio™
projects.These examples explain the steps required to initialize the device and utilize on-chip
peripherals.The examples can be copied and modified to quickly experiment with peripheral
configurations.
•Development Platform:
The header files can be incorporated into a project as a hardware abstraction layer for accessing on-
chip peripherals using C or C++code.You can also pick and choose functions as needed and discard the rest.
This application report does not provide a tutorial on C,C++,C28xx assembly,or emulation tools.You should have a basic understanding of C code and the ability to load and run code using Code Comp
oser Studio.While knowledge of C28xx assembly is not required to understand the hardware abstraction layer, it is useful to understand the code optimization and read-modify-write sections.If you have assembly
instruction-related questions,see the TMS320C28x CPU and Instruction Set Reference Guide
(SPRU430).
Examples are based on the following software versions:
•C281x C/C++Header Files and Peripheral Examples(SPRC097)V1.00
•C280x,C2801x C/C++Header Files and Peripheral Examples(SPRC191)V1.41
•C2804x C/C++Header Files and Peripheral Examples(SPRC324)V1.00
•C28x Compiler V4.1.1
The following abbreviations are used:
•C/C++Header Files and Peripheral Examples refers to any of the header file or device support pack
ages.
•TMS320x280x and280x refer to all devices in the TMS320x280x and TMS320x2801x family and the UCD9501.For example:TMS320F2801,TMS320F2806,TMS320F2808,TMS320F28015and
TMS320F28016.
•TMS320x2804x and2804x refers all devices in the TMS320x2804x family.For example,the TMS320F28044.
•TMS320x281x and281x refer to all devices in the TMS320x281x family.For example:TMS320F2810, TMS320F2811,and TMS320F2812,TMS320C2810,and so forth.
www.ti Traditional#define Approach •C28x refers to the TMS320C28x CPU;this CPU is used on all of the above DSPs.
2Traditional#define Approach
Developers have traditionally used#define macros to access registers in C or C++.To illustrate this
approach,consider the SCI-A and SCI-B register files shown in Table1.
Table1.SCI-A,SCI-B Configuration and Control Registers
(SPRU051).
(2)These registers are reserved on devices without the SCI-B peripheral.See the data manual for details.
A developer can implement#define macros for the SCI peripherals by adding definitions like those in
Example1to an application header file.These macros provide an address label,or a pointer,to each
register location.Even if a peripheral is an identical copy a macro is defined for every register.For
example,every register in SCI-A and SCI-B is specified separately.
Traditional#define Approach www.ti Example1.Traditional#define Macros
/********************************************************************
*Traditional header file
********************************************************************/
#define Uint16unsigned int
#define Uint32unsigned long
//Memory Map
//Addr Register
#define SCICCRA(volatile Uint16*)0x7050//0x7050SCI-A Communications Control
#define SCICTL1A(volatile Uint16*)0x7051//0x7051SCI-A Control Register1
#define SCIHBAUDA(volatile Uint16*)0x7052//0x7052SCI-A Baud Register,High Bits
#define SCILBAUDA(volatile Uint16*)0x7053//0x7053SCI-A Baud Register,Low Bits
#define SCICTL2A(volatile Uint16*)0x7054//0x7054SCI-A Control Register2
#define SCIRXSTA(volatile Uint16*)0x7055//0x7055SCI-A Receive Status
#define SCIRXEMUA(volatile Uint16*)0x7056//0x7056SCI-A Receive Emulation Data Buffer
#define SCIRXBUFA(volatile Uint16*)0x7057//0x7057SCI-A Receive Data Buffer
#define SCITXBUFA(volatile Uint16*)0x7059//0x7059SCI-A Transmit Data Buffer
#define SCIFFTXA(volatile Uint16*)0x705A//0x705A SCI-A FIFO Transmit
#define SCIFFRXA(volatile Uint16*)0x705B//0x705B SCI-A FIFO Receive
#define SCIFFCTA(volatile Uint16*)0x705C//0x705C SCI-A FIFO Control
#define SCIPRIA(volatile Uint16*)0x705F//0x705F SCI-A Priority Control
#define SCICCRB(volatile Uint16*)0x7750//0x7750SCI-B Communications Control
#define SCICTL1B(volatile Uint16*)0x7751//0x7751SCI-B Control Register1
#define SCIHBAUDB(volatile Uint16*)0x7752//0x7752SCI-B Baud Register,High Bits
#define SCILBAUDB(volatile Uint16*)0x7753//0x7753SCI-B Baud Register,Low Bits
#define SCICTL2B(volatile Uint16*)0x7754//0x7754SCI-B Control Register2
#define SCIRXSTB(volatile Uint16*)0x7755//0x7755SCI-B Receive Status
#define SCIRXEMUB(volatile Uint16*)0x7756//0x7756SCI-B Receive Emulation Data Buffer
#define SCIRXBUFB(volatile Uint16*)0x7757//0x7757SCI-B Receive Data Buffer
#define SCITXBUFB(volatile Uint16*)0x7759//0x7759SCI-B Transmit Data Buffer
#define SCIFFTXB(volatile Uint16*)0x775A//0x775A SCI-B FIFO Transmit
#define SCIFFRXB(volatile Uint16*)0x775B//0x775B SCI-B FIFO Receive
#define SCIFFCTB(volatile Uint16*)0x775C//0x775C SCI-B FIFO Control
#define SCIPRIB(volatile Uint16*)0x775F//0x775F SCI-B Priority Control
Each macro definition can then be used as a pointer to the register's location as shown in Example2. Example2.Accessing Registers Using#define Macros
/********************************************************************
*Source file using#define macros
********************************************************************/
...
*SCICTL1A=0x0003;//write entire register
*SCICTL1B|=0x0001;//enable RX
...
Some advantages of traditional#define macros are:
•Macros are simple,fast,and easy to type.
•Variable names exactly match register names;variable names are easy to remember.
Disadvantages to traditional#define macros include the following:
•Bit fields are not easily accessible;you must generate masks to manipulate individual bits.
•You cannot easily display bit fields within the Code Composer Studio watch window.
•Macros do not take advantage of Code Composer Studio's auto-completion feature.
•Macros do not benefit from duplicate peripheral reuse.
www.ti Bit Field and Register-File Structure Approach 3Bit Field and Register-File Structure Approach
Instead of accessing registers using#define macros,it is more flexible and efficient to use a bit field and register-file structure approach.
•Register-File Structures:
A register file is the collection of registers belonging to a peripheral.These registers are grouped
together in C/C++as members of a structure;this is called a register-file structure.Each register-file
structure is mapped in memory directly over the peripheral registers at compile time.This mapping
allows the compiler to efficiently access the registers using the CPU's data page pointer(DP).
•Bit Field Definitions:
Bit fields can be used to assign a name and width to each functional field within a register.Registers
defined in terms of bit fields allow the compiler to manipulate single elements within a register.For
example,a flag can be read by referencing the bit field name corresponding to that flag.
The remainder of this section describes a register-file structure with bit-field implementation for the SCI peripherals.This process consists of the following steps:
1.Create a simple SCI register-file structure variable type;this implementation does not include bit fields.
2.Create a variable of this new type for each of the SCI instances.
3.Map the register-file structure variables to the first address of the registers using the linker.
4.Add bit-field definitions for select SCI registers.
5.Add union definitions to provide access to either bit fields or the entire register.
6.Rewrite the register-file structure type to include the bit-field and union definitions.
In the C/C++Header Files and Peripheral Examples,the register-file structures and bit fields have bee
n implemented for all peripherals on the TMS320x28xx and TMS320x28xxx devicess.
3.1Defining A Register-File Structure
Example1showed a hardware abstraction implementation using#define macros.In this section,the
implementation is changed to a simple register file structure.Table2lists the registers that belong to the SCI peripheral.This register file is identical for each instance of the ,SCI-A and SCI-B.
Table2.SCI-A and SCI-B Common Register File
Name Size Address Offset Description
SCICCR16bits0SCI Communications Control Register
SCICTL116bits1SCI Control Register1
SCIHBAUD16bits2SCI Baud Register,High Bits
SCILBAUD16bits3SCI Baud Register,Low Bits
SCICTL216bits4SCI Control Register2
SCIRXST16bits5SCI Receive Status Register
SCIRXEMU16bits6SCI Receive Emulation Data Buffer Register
SCIRXBUF16bits7SCI Receive Data Buffer Register
SCITXBUF16bits9SCI Transmit Data Buffer Register
SCIFFTX16bits10SCI FIFO Transmit Register
编程语言下载SCIFFRX16bits11SCI FIFO Receive Register
SCIFFCT16bits12SCI FIFO Control Register
SCIPRI16bits15SCI Priority Control Register
The code in Example3groups the SCI registers together as members of a C/C++structure.The register in the lowest memory location is listed first in the structure and the register in the highest memory location is listed last.Reserved memory locations are held with variables that are not used except as space
,rsvd1,rsvd2,rsvd3,and so forth.The register's size is indicated by its type:Uint16for16-bit (unsigned int)and Uint32for32-bit(unsigned long).The SCI peripheral registers are all16-bits so only Uint16has been used.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。