DSP Tutorial | Everything You Need to Know

DSP Tutorial title image

TI2000 DSP Tutorial

This DSP Tutorial is an exceptional crash course and will gives you extraordinary information about DSPs to find your path to the sweet world of DSP processors (even if you are a beginner). On this page you will read one of the most comprehensive training of TI2000 series DSP.

Introduction to DSP processors

DSP processors works like microcontrollers (like ARM) and they are programmable in C and assembly languages. But they are more optimized for digital signal processing. These processors work at very high frequencies. The first series of DSP manufacturing in the late 1970 was entered into the market with 10MHz frequency. The power of this processor in analyzing an FFT was extremely high that 20 years later, the Intel Pentium processor at 200MHz could do so.
In addition to signal processing with these processors, it can be used as a powerful microcontroller (the frequencies of these processors with available versions in the market are more than 150 MHz to a few GHz). Even some of these processors can work up to 8 times faster than their standard working frequency, e.g., if their frequency is 1GHz, the execution speed of them is 8GIPS.

The signal processing is usually done with FPGA and DSP. But due to the very high price of the FPGA, usually people in light weight processing prefer DSP. For example, to compare a DSP with a price of 100 thousand Tomans, it can do something that a FPGA will do with a price of 2 million Tomans. Of course, FPGAs are much more flexible than DSPs due to their parallel processing capability.

Programming these processors are a bit complicated and challenging (fortunately easier than FPGA programming).

Why working with DSPs is challenging?

  1. The I/Os of these DSPs are so sensitive and it can be damaged due to short circuit or volts more than 3.3v.
  2. The IDE for programming these processors is Code Composer Studio, which is a professional software with an un-user-friendly UX.
  3. There is no good learning source for beginners. Even in the most training courses instead of working with DSP in action, they only teach you about the IDE.
  4. For getting started with these processors there are hundreds of documentation pdfs that confuses the developer.
  5. In my opinion a developer who wants to learn DSP, should first master microcontrollers and then start learning DSPs. I have started working with DSPs only in 3 days, because I was already mastered other microcontrollers. For me, the most annoying part of learning DSPs was finding good documentations and contents to learn it.
  6. JTAG Programmer: there are two programmers for these DSPs. XDS560 and XDS510, that they are so expensive. Even the Chinese fake one is too expensive. Of course, you can program them via serial or USB ports, but for debugging your code you need a debugger.

What is special about this DSP Tutorial?

Fortunately, this DSP Tutorial almost solves the above problems. This DSP Tutorial will gives you extraordinary information about DSPs and a bright path to the sweet world of DSP processors.
Note: after learning these processors, writing code for them is so easy because we use C language to program them so, we don’t have problems such as writing code in VHDL or Verilog. Also, we don’t have long code synthesis time like FPGA based platforms.

The OMAP series of DSPs/microcontrollers that is manufactured by TI have low power consumption and suitable for longer battery life. These DSPs are supported by the Code Composer Studio IDE. They have been used in many cell phones and mobile platforms.
In this tutorial we’re going to use Code Composer Studio 3.3 software and TI 2000 hardware (Especially TMS320F2812).

Enough intro! Let’s dive in and start learning in action.

Before starting reading this DSP Tutorial, make sure you have downloaded 281x C/C++ Header Files and Peripheral Examples from www.ti.com website. You can simply copy and paste “281x C/C++ Header Files and Peripheral Examples” into the TI webpage’s search bar.
After downloading and opening the zip file, you should see something like the below figure.

dsp header files opened in winrar software

Extract the zip file and open the setup exe file to install the examples and header files (read the documentation pdf (included in the zip file) for more info). After installing, go to the installation location (usually in “C:/tidcs”). You can see below files in the installation location:

  1. DSP281x_common: Contains registers and functions of peripherals
  2. DSP281x_headers: Contains function prototypes of DSP281x_common
  3. DSP281x_examples: Contains examples for peripherals
  4. Doc: Contains the documentation

Now it’s time to install the Code Composer Studio software. After downloading and installing the software, you should see the icons on your desktop as below figure.

CCStudio and CCStudio setup files on desktop

Now open the “Setup CCStudio v3.3” and in the “Family” section choose “C28xx” and in the “platform” section choose “Simulator”. Other options are for configuring the JTAG programmer (don’t change them). Now you should select “F28xx Simulator Tutorial” (also you can choose the “F2812 Device Simulator”) and then click on the “Add” button.

Code Composer Studio Setup menu

Now like the below figure click on the “Save and Quit” and then click on the “Yes” button to open the CCStudio IDE.

Exiting CCStudio setup

You can see the CCStudio splash screen in the below figure.

Code Composer Studio Splash Screen

Now at the top ribbon, click on “Project —> New”.

Clicking on new button

In the opened windows, choose a path for your project then click on “ok” button.

project path in DSP tutorial

Now for configuring your project, go to “Project —> Build Options”.

Clicking on Build options

In the opened window, go to “compiler” then in the “advanced” Category, deselect the “Large Memory Model”(Use Large Memory Model when your code size is more than 64KB).

Compiler options menu

Configuring the project

Now in the “Preprocessor” category, enter the below address in the “Include Search Path” field and then click on “Ok”.
$(Proj_dir)\DSP281x_headers\include, $(Proj_dir)\DSP281x_Common\include
These two addresses are the addresses of those files that you have already downloaded it from ti.com, i.e. “DSP281x_common” and “DSP281x_headers”. Also, you need to copy these to directories to the project path.

Preproccesor options menu

Now you should add an important library to your project. This library is located in the below path.
Add it to the project as shown the below figure by right-clicking on it and selecting Add Files.
Note: Instead of this, you can type “rts2800.lib” in “Project -> Build Options -> Linker -> Libraries -> Incl Libraries”.

adding nessesary files to the project
choosing lib folder

Now for configuring your project, go to “Project —> Build Options”.

Clicking on Build options

Now you should add an important library to your project. This library is located in the below path.
Add it to the project as shown the below figure by right-clicking on it and selecting Add Files.
Note: Instead of this, you can type “rts2800.lib” in “Project -> Build Options -> Linker -> Libraries -> Incl Libraries”.

adding include path used in this DSP Tutorial

Now in the “Linker -> Basic”, specify the stack size (This memory stores local variables and the address of interrupt functions). The default stack size is 0x400.

By right-clicking on the Library folder and selecting the Add Files option, add the two following folders to the project. “DSP281x_common, DSP281x_headers”.

adding nessesary files to the project

The below figure, shows the address of DSP281x_Common.

choosing source directory

Just make sure that the “All Files” option is selected in the “File Of Types” section as shown below to add all these files to the project.

After adding these files, you must delete two files named DSP281x_SWPrioritized.

clicking on remove from project

Configuring the cmd files

Now we need to add the Command file to the project. I will explain more about this file below. In the cmd folder in two folders
DSP281x_common, DSP281x_headers
This file exists. Add the following two files to the project as shown below:
F2812_EzDSP_RAM_lnk.cmd, DSP281x_Headers_nonBIOS.cmd

adding linker command files to the project

In the figure above, the F2812_XintBoot.cmd file is for reading program code from external memory and the F2812.cmd file is for reading code written in the program’s permanent memory, and the F2812_EzDSO_RAM_lnk.cmd file is for reading code written in RAM. This means that the DSP can read and execute program code from RAM, or from internal Flash memory, or from external Flash memory, which we currently select to execute code from RAM. I will explain more about this.

adding dsp headers non bios file

The following figure shows some of the contents of the DSP281x_Headers_nonBIOS.cmd file.

Contents of DSP Headers nonBIOS file

In the figure above, remember the GPIOMUX address which is 0x70C0 with a length of 32 bytes (20 hex) and the GPIODAT address which is 0x70E0 with a length of 32 bytes, which will be useful later.
At all, in the DSP281x_Headers_nonBIOS.cmd file the addresses of all DSP registers (such as ADC, SCI (UART), SPI, etc. is defined.
The F2812_EzDSP_RAM_lnk.cmd file specifies where the program is stored in the DSP’s memory, which I will explain it later.

Congratulation! The IDE is configured and it’s time to write some code!

Now create a new (New – > File menu) and name it “main.c”.

clicking on new file

Now add “main.c” file by clicking on “Add Files to Project” on the left CCStudio window as shown below.

saving main.c file
adding nessesary files to the project
adding main.c file to the project

Copy the contents of the attached file to “main.c” file and Save the file and project (Project -> Save).

DSP Tutorial sample project to get started
saving the DSP CCStudio project

Now it’s time to compile the program. Go to the “Project” menu and click “Build” (note that each time you select “Build”, only the modified files are compiled, while selecting “Build All” compiles all the files from scratch. Obviously, Build is much faster than Build All (Of course, in the first time, they are the same)).

Clicking on Rebuild All

After compiling, you will see 3 warnings that have been created due to not writing three lines in the cmd file, which do not cause any problems:

DSP build complete: 0 errors, 3 warnings

So far you have managed to blink an LED light with the DSP. Now I should describe how this program can blink an LED light.
Now it’s time to take a look at documentations.

Documentations (take a look at them after finishing this DSP Tutorial)

The image below is a part of the 2812 DSP Datasheet. The exact name of this datasheet is TMS320F2812 Data Manual.

list of documantations that are useful for developing DSP projects

In the above figure, you can see a list of documentation. For example, for communicating with SPI, you should use SPI peripheral registers to configure and transmit/receive data from other SPI components.
As shown as the above figure the SPI registers documentation are located in the SPRU059.PDF file (you can download these files from www.ti.com or find it at the CCStudio installation location (C:\CCStudio_v3.3\docs\PDF)).
One of the most important documentations that is critical for working with DSP, is SPRU078. PDF that is related to all parts and peripherals of DSP and this file actually describes the overall DSP system control and interrupts registers and IO control registers.

spru078b.pdf dsp documentation file

In the figure above, you can see the SPRU078 file in the CCStudio installation folder.
The following figure shows a part of the SPRU078 file, page 92:

GPIOMUX Registers are EALLOW Protected but GPIO Data is not EALLOW protected

EALLOW Command

If you remember, I said that 0x70C0 address is for GPIOMUX and 0x70E0 address is for GPIODAT and Now the question is where did these addresses come from. These addresses are specified by the DSP datasheet. Look at the figure above again. In the GPIO MUX Registers section it is written:
EALLOW Protected
And in the GPIO Data Registers section, “Not EALLOW Protected” is written. And this means for accessing the “GPIOMUX”, the “EALLOW” assembly command should be executed.
The 14th line of the below code this command is executed and “EDIS” assembly command disables the “EALLOW”.

This is how we use assembly commands inside C file:
#define EALLOW #asm(“      EALLOW”);
#define EDIS #asm(“      EDIS”);
You don’t need to run the “EALLOW” assembly command to set ADC registers or external interrupts registers or…

DSP Tutorial sample project to get started

In the above figure, in line 10, the program disables the DINT command interrupts (like cli in a microcontroller) (and the EINT command enables the interrupts).

GPIO Registers

Now you may ask “what GPIOMUX and GPIODAT do?”. Ok let’s take a look at these two registers too.
We used them four times in the above program!

This below command makes all pins of port-A output:
GpioMuxRegs.GPADIR.all = 0xFFFF;

This command configures all port-A pins as normal IOs (they can be in other modes):
GpioMuxRegs.GPAMUX.all = 0;

This command makes all pins of the port-A digitally low (0):
GpioDataRegs.GPACLEAR.all = 0xFFFF;

This command makes all pins of the port-A digitally high (1):
GpioDataRegs.GPASET.all = 0xFFFF;

In AVR microcontrollers we use “DDR” for configuring pins as output and “PORT” for making pins digitally high or low (0 or 1) but here in this DSP Tutorial, you should learn the IO control register that is more advanced and used more professionally in these processors. Let’s take a look at the DSP281x_GPIO.h file. Find this file in the Include folder as shown below and open it.

DSP281x_Gpio.h file in the Include directory

You can see a part of this file in the below figure:

DSP GPIO registers definition in the header file

As you can see, the GPAMUX register is defined both in bits and halfword formats and at the end of the file, this register is defined as shown as the below figure.

DSP GPIO external references and function declarations

What GPIOMUX register do?

To access the GPAMUX register, we must first write “GpioMuxRegs” and then write a dot “.” And then a window will open in CCS software and we can select one of the Mux registers, which one of them is GPADIR and the other is GPAMUX.
Now for accessing the register in halfword (16 bits), you should write a dot and “all” infront of it.
Also, for accessing a specific pin (e.g., Port A.0), according to the above figures we should write:
GpioMuxRegs.GPAMUX.PWM1_GPIOA0 = “Value”;
If you want to use that pin as IO, instead of “value” write ‘0’ and if you want to use it as PWM1, write ‘1’.

Similar example in AVR

Of course, in other microcontrollers (e.g., AVR) we can do the same e.g., for “DDRA” register in AVR, consider we are using 4 first pins to control a stepper motor and the 5th and 6th pins to control a relay and the 7th and 8th pin for on/off button and In this case we have:

struct of pins

In the above figure, the 0x3A is the DDRA memory mapped physical address (refer to the AVR datasheet for registers addresses).
The below figure describes how to assign values to DDRA register.
The motor control pins and the relay pins are configured as output and on/off button as input.


Clock Sources and Interrupt VTable

In the DSP example program, the “delay” function makes delay by executing 600,000 times.
Also, the “InitSysCtrl” function, configures the system clock frequency and PLL registers. Search the name of this function by going to “Find In File” menu and typing the name of the function that you want to find. For DSP there are 3 clock sources which the first one is “CPU clock” that can be taken from PLL and the second one is “LOPCLK” and the last one is “HIPCLK”. The “LOPCLK” is for low speed peripherals, e.g., SPI, UART or CSI. And the “HIPCLK” clock source is for high speed peripherals, e.g., USB or CAN or etc…
Search for the valid assignable values of these clocks in the SPRU078 file.

The “initPieCtrl” function is used for enabling clocks for different parts of DSP. And “InitPieVectTable” function is used for configuring the interrupts vector table. And the “IFR” and “IER” as I mentioned before, is for controlling the interrupts which we set them to ‘0’.

DSP Memory Regions

Now it’s time to take a look at “F2812_EzDSP_RAM_lnk.cmd” file that as I mentioned before, it is for configuring memory regions for the compiler. As you can see, the below figure shows the contents of this file.
As you can see in the below figure, our code (BEGIN) has 2bytes of length and 0x3F8000 address offset and the “RESET” address is 0x3F8004 (the default address is 0x3FFFC0 which is wrong and I have changed it (I’ll explain it later)) with 2bytes of length. The “RAMH0” has 4KBytes of length (We have to subtract 8 from that, i.e. FF7, which FFE is wrong in the above figure) and 0x3F8008 offset.

DSP Memory configuration file

The below figure shows us the memory space of DSP 2812:

DSP Memory Space Addresses

Boot Modes

As you can see, the start address of RAMH0 is 0x3F8000 and the start address of RAMM0 is 0x000000. At address 0x3FF000 there is a 4 KB code that is stored in this memory by TI. This code is actually the boot code (in other word, BOOT ROM) and when the DSP turns on, this code executed and puts the DSP in one of the following six modes:

DSP Boot Modes Table

Boot modes in DSP depends on these four pins: “GPIOF4, GPIOF12, FPIOF3 and GPIOF2”, as shown in the figure above. If only the GPIOF3 pin becomes ‘1’ while DSP is turning on, the code starts running from RAMH0. That’s why I have changed RESET address to RAMH0.

In the above figure, in the first mode, the program executes from internal Flash. And in the second, the program executes from external EEPROM memory. The third mode, BOOT is via UART. In the fourth mode, Boot is through RAMH0. In the fifth mode, the dsp boots from OTP (One Time Programmable) storage. And the sixth mode Boot through the ports of port B. Of course, there is a seventh mode and it is External Flash and that is when the “MP/MC” pin of DSP becomes ‘1’, i.e. in this case the dsp goes to microprocessor mode. In this mode, the DSP is capable of addressing about 2MB of memory.

Simulating (useful part of this DSP Tutorial)

So now you may ask how do we simulate the program? To simulate a 280x DSP model like the TMS320F28027, you can use Proteus software, which is an excellent software (at the end of this article I have put a program to work with these models that works with Proteus software). But now you can only use the CCS software to simulate a 281x model like the TMS320F2812. To do this, first enter the “File” menu and select “Load Program”.

clicking on Load program

Then enter the address of the “Blink_LED.out” file (located in the Debug folder). (For 280x models that you can simulate it with Proteus software, you need to change the extension of this file from “out” to “cof” with a simple Rename).

selecting Blink_LED.out file

Then a page like the one below opens:

assembly code of the sample program

The above figure shows the code compiled in assembly language. Close this page and open the “Main.c” file and right-click on the area shown in the figure below and select the “Toggle Software Breakpoint”.

putting break point

Then click on the option shown on the left side of the screen in the below figure (or hit the F5 key).

clicking on run button

Then there should be a yellow arrow next to the Breakpoint according to the following figure:

the program stopped at the break point

Now, by pressing F10 and F11, you can run the program line by line. The difference between these two is that the F11 key enters inside the functions, but the F10 key executes the function and passes through it. If you have selected XDS510 or XDS560 in the Platform section of the CCS Software Setup window (as shown below).

Code Composer Studio Setup menu
clicking on xds510 emulator

In this case, if you enter the “GEL” menu, you can see all the registers and change them in Realtime but in the simulation, as shown as in the below figure, this menu has only two options.

addressing modes in GEL menu


The following figures shows the pinout of DSP 2812 and As you can see, each port has a maximum of 16 pins (or less).


Do you like FPGA system designing too? So, checkout our complete VHDL Project Pack.

Posted in DSP

Leave a Reply

Your email address will not be published. Required fields are marked *