CCS Note 07: Lesson 2. Timer Setting And Application & Debug Tips

Hsueh-Ju Wu 吳學儒
TI Code Composer Studio
7 min readJul 1, 2023

Instruction

How to set up Timers and basic Interrupt applications for F28379D

Environment

This document utilizes the following setup:
Operating System: Windows x64
Code Composer Studio Version: 11.2.0.00007
Development Board: LAUNCHXL-F28379D (STM320F28379D)

Tutorial List

Reference Materials

Register Data, System, and Module Details

TMS320F2837xD Dual-Core Delfino Microcontrollers Technical Reference Manual (Rev. I) (ti.com)

Pin Mapping

LAUNCHXL-F28379D Overview User’s Guide (Rev. C) (ti.com)

Module Memory & Flash Architecture

The TMS320F2837xD Architecture: Achieving a New Level of High Performance (ti.com)

Memory Allocation Setting

TMS320C28x Assembly Language Tools v22.6.0.LTS User’s Guide (Rev. Y) (ti.com)

Some Magic Bugs Records

TMS320F2837xD Dual-Core Real-Time MCUs Silicon Errata (Rev. M)

Import Example from C2000Ware

Example: CPU1 — cpu_timers(CPU1 means single core.)

Project Path: C:\ti\c2000\C2000Ware_4_01_00_00\device_support\f2837xd\examples\cpu1\cpu_timers

Section 1. Basics Exercise

Use Timer0 to generate an interrupt every 50us. Each time the interrupt is entered, the state of GPIO0(Pin 40) is toggled.

Section 1.1 Setup for Initialization

cpu_timers_cpu01.c (Main program)

A. Declaration of the interrupt function (before void main(void){})

B. Re-mapped the PieVectTable to ISR function

After PieVectTable initialization. Re-mapped the PieVectTable (interrupt vector, 中斷向量) to ISR (Interrupt Service Routine) function, aka interrupt function (中斷函數) that set in A.

C. Initialize timers and set the period of the timer.

Ensure that CPU freq. is 200MHz.

Check void InitSysCtrl(void) in F2837xD_SysCtrl.c

Tip. Ctrl + Left-click on function / variable name can goto definition directly.

D. Enable timer interrupt

TCR Register, CPU-Timer Control Register
Write 14-bit to enable the interrupt.

E. Configure CPU to respond to Timer 0, 1, 2 interrupts.

F. Must action in ISR function

There are four important aspects to remember when utilizing interrupts in MCU programming:

A. The Timer Counter must be enabled, otherwise, it won’t count.
(Enable, 啟用Timer計數器)

B. The corresponding interrupt event must be enabled in order to use the interrupt function. (Enable, 啟用特定中斷事件)

C. In the interrupt service routine, the flag for the corresponding event must be cleared. (Clear, 清除特定中斷旗標)

D. The timing of clear-flag event will cause the different bugs.

Detailed descriptions and names of relevant functions can be found in the device manual.

Based on the TI C2000 series, the interrupt flag for a CPU timer is automatically cleared when the ISR function is entered. Therefore, there is no need to clear the interrupt flag manually. Just reload the ISR request.

Section 1.2 Introduction to ISR

https://malabdali.com/arduino-and-esp32-interrupts/

Interrupt Priority for multi-ISR triggered at the same time

Interrupt priority is a fundamental concept in microcontroller systems, it decides the sequence in which interrupts are processed when multiple interrupts occur simultaneously. [TI cannot?!] Higher priority interrupts can preempt currently executing lower priority interrupts, allowing critical tasks to be performed first. This hierarchy ensures optimal system performance, responsiveness, and efficient resource utilization. Setting and managing these priorities is crucial for reliable, deterministic real-time system behavior.

  1. IER |= M_INT1; IER |= M_INT13; IER |= M_INT14; These lines of code set the Interrupt Enable Register (IER) bits for CPU-Timer 0, CPU-Timer 1, and CPU-Timer 2. The |= the operator sets the corresponding bits without affecting the other bits in the IER. M_INT1, M_INT13 and M_INT14 mask constants represent the interrupts for CPU-Timer 0, CPU-Timer 1, and CPU-Timer 2, respectively.
  2. PieCtrlRegs.PIEIER1.bit.INTx7 = 1; This line enables the Timer 0 interrupt in the Processor Interrupt Expansion (PIE) control register. INTx7 refers to the 7th interrupt of the group 1 interrupt, which corresponds to the Timer 0 interrupt. Setting it to 1 enable this interrupt.
  3. EINT; // Enable Global interrupt INTM This line of code enables global interrupts. EINT is a function that clears the Global Interrupt Mask (INTM), allowing the CPU to respond to interrupt requests.
  4. ERTM; // Enable Global realtime interrupt DBGM This line of code enables real-time interrupts. ERTM is a function that clears the Debug Interrupt Mask (DBGM), allowing the CPU to respond to real-time interrupt requests even when the CPU is halted for debugging.

Section 1.3 Experiment Code

[Hidden] Do it yourself!!

[Hidden] Do it yourself!!

[Hidden] Do it yourself!!

Section 1.4 Experimental Results

We can observe the generation of a square wave with a period of 100us (toggling every 50us), which indicates that the results are accurate and as expected.

Section 1.5 Software Debug

A. Debug Mode — Register Window

We can use the debug mode register window in Code Composer Studio to monitor the operation of the Timer (TIM) Register, ensuring that everything functions correctly. This tool provides valuable real-time insight into the hardware behavior, which is particularly useful when configuring and debugging low-level peripheral operations such as timers.

Turn on auto-refresh to ensure data updates automatically.

B. Set breakpoints in ISR function

Step 1. Add breakpoints in the code view by double-clicking the line head.

Step 2. Basic debugging functionality is located in the bar at the top of the Debug view.

Use the below two button control execution (will pause at the breakpoint).

  • Resume: Starts execution of the target core.
  • Suspend: Halts the execution of the target core.

Extra information

  • Terminate: Disconnects from all hardware (cores, devices, Debug Probes) and terminates the Debug Session. Closes the CCS Debug perspective and returns of the CCS Edit perspective.
  • Step Into: Executes a single source line, jumping into subroutines or functions, allowing you to run the its internal code step-by-step.
  • Step Over: Similar as above, but jumping over subroutines or functions, running its internal code all at once.
  • Step Return: Similar as above, but running all lines, subroutines or functions until it reaches the caller function (given by the call stack or return()).

Section 2. Advanced Exercise

(a) Utilize Timer1 to generate an interrupt every 100 ms.
Upon every 4th interrupt from Timer1, enter the Timer2 interrupt. During this interrupt routine, measure the frequency and timing of both Timer1 and Timer2 interrupts using GPIO1(Pin 39) and GPIO2(Pin 38). Examine the waveform generated to verify the priority between Timer1 and Timer2 interrupts.

(b) Use Timer1 to generate a signal with a period of 40 ms and a duty cycle of 75%, outputted at GPIO0(Pin 40).

Section 2.1 Experiment Code

[Hidden] Do it yourself!!

[Hidden] Do it yourself!!

[Hidden] Do it yourself!!

Section 2.2 Experiment Results

(a) Upon every 4th interrupt from Timer1, enter the Timer2 interrupt.

Examine the waveform generated to verify the priority between Timer1 and Timer2 interrupts.

(b) Use Timer1 to generate a signal with a period of 40 ms and a duty cycle of 75%, outputted at GPIO0(Pin 40).

How to set CPU freq. to 200MHz

A. Check void InitSysCtrl(void) in F2837xD_SysCtrl.c

B. Pre-define the marco _LAUNCHXL_F28379D

XTAL_OSC = 10MHz from the datasheet.
The ratio of the multiplier is set to 40. And PLL prescale by 2.

System freq. = 10MHz * 40 / 2 = 200MHz

--

--