This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28069: problem in operating CLA

Part Number: TMS320F28069

Tool/software: Code Composer Studio

Hello team,

my customer has the issue with initializing the CLA (getting ILLEGAL_ISR error), please find attached his CLA init function code based TI example and memory mapping.

Could you please advise if you can spot what he doing wrong, Thanks in advance 

//###########################################################################
// Description:
//! \addtogroup f2806x_example_cla_list
//! <h1> ACOS Table-Lookup Algorithm</h1>
//!
//! This example implements a table lookup method of determining
//! the arccosine of a value.
//!
//! \b Watch \b Variables \n
//!  - y - Accumulated results (angles in radians)
//
//###########################################################################
// $TI Release: F2806x C/C++ Header Files and Peripheral Examples V151 $
// $Release Date: February  2, 2016 $
// $Copyright: Copyright (C) 2011-2016 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

#include "DSP28x_Project.h"     // DSP28x Headerfile
#include "F2806x_Cla_defines.h"

// Include the test header file whose name is based on the test name
// which is defined by the macro TEST on the command line
#include "CLA_shared.h"


#define CLA_PROG_ENABLE      0x0001
#define CLARAM0_ENABLE       0x0010
#define CLARAM1_ENABLE       0x0020
#define CLARAM2_ENABLE       0x0040
#define CLA_RAM0CPUE         0x0100
#define CLA_RAM1CPUE         0x0200
#define CLA_RAM2CPUE         0x0400


#define HARDWARE 1


// Constants
#define OSCCLK	     (10000000UL) 	         // < Internal OSC frequency
#define SYSCLK	     (80000000UL) 			 // < System Clock frequency
#define PER_CLK_DIV  (4)					 // < Low speed peripheral clock dividers
#define PER_CLK	     (SYSCLK/PER_CLK_DIV)	 // < Low speed peripheral clock
#define DIV_SEL	     (2)		             // < Clock divider selection
#define CLK_DIV	     ((SYSCLK * DIV_SEL)/OSCCLK) // < Clock divider


//CLA ISRs
__interrupt void cla1_task1_isr( void );
__interrupt void cla1_task2_isr( void );
__interrupt void cla1_task3_isr( void );
__interrupt void cla1_task4_isr( void );
__interrupt void cla1_task5_isr( void );
__interrupt void cla1_task6_isr( void );
__interrupt void cla1_task7_isr( void );
__interrupt void cla1_task8_isr( void );

//  Main Function
void CLA_Init_Interrupts(void)
{
   /*  Assign user defined ISR to the PIE vector table */
	EALLOW;
   PieVectTable.CLA1_INT1  = &cla1_task1_isr;
   PieVectTable.CLA1_INT2  = &cla1_task2_isr;
   PieVectTable.CLA1_INT3  = &cla1_task3_isr;
   PieVectTable.CLA1_INT4  = &cla1_task4_isr;
   PieVectTable.CLA1_INT5  = &cla1_task5_isr;
   PieVectTable.CLA1_INT6  = &cla1_task6_isr;
   PieVectTable.CLA1_INT7  = &cla1_task7_isr;
   PieVectTable.CLA1_INT8  = &cla1_task8_isr;
	EDIS;

   //Copy over the CLA code(if running in standalone mode from FLASH)
   //memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart, (Uint32)&Cla1funcsLoadSize);
   //Copy over the CLA math tables(if running in standalone mode from FLASH 
   //and using the CLAMath Library)
   //memcpy(&Cla1mathTablesRunStart, &Cla1mathTablesLoadStart, (Uint32)&Cla1mathTablesLoadSize);

	
   /*  Compute all CLA task vectors */ 
    EALLOW;
    Cla1Regs.MVECT1 = (Uint16)((Uint32)&Cla1Task1 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT2 = (Uint16)((Uint32)&Cla1Task2 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT3 = (Uint16)((Uint32)&Cla1Task3 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT4 = (Uint16)((Uint32)&Cla1Task4 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT5 = (Uint16)((Uint32)&Cla1Task5 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT6 = (Uint16)((Uint32)&Cla1Task6 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT7 = (Uint16)((Uint32)&Cla1Task7 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT8 = (Uint16)((Uint32)&Cla1Task8 -(Uint32)&Cla1Prog_Start);
    EDIS;
   
    //  Step 3 : Mapping CLA tasks
    /*  All tasks are enabled and will be started by an ePWM trigger
     *  Map CLA program memory to the CLA and enable software breakpoints
     */
    EALLOW;
	Cla1Regs.MPISRCSEL1.bit.PERINT1SEL 	= CLA_INT1_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT2SEL 	= CLA_INT2_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT3SEL 	= CLA_INT3_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT4SEL 	= CLA_INT4_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT5SEL 	= CLA_INT5_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT6SEL 	= CLA_INT6_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT7SEL 	= CLA_INT7_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT8SEL 	= CLA_INT8_NONE;
	Cla1Regs.MIER.all 		 		    = 0x00FF;
	EDIS;	
    
 
    /*  Enable CLA interrupts at the group and subgroup levels */
    PieCtrlRegs.PIEIER11.all       = 0xFFFF;
    IER = (M_INT11 );
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

    /* Switch the CLA program space to the CLA and enable software forcing
     * Also switch over CLA data ram 0,1 and 2
	 * CAUTION: The RAMxCPUE bits can only be enabled by writing to the register
	 * and not the individual bit field. Furthermore, the status of these bitfields
	 * is not reflected in either the watch or register views - they always read as 
	 * zeros. This is a known bug and the user is advised to test CPU accessibilty
	 * first before proceeding
   	 */
	EALLOW;
	Cla1Regs.MMEMCFG.all = CLA_PROG_ENABLE|CLARAM0_ENABLE|CLARAM1_ENABLE|CLARAM2_ENABLE|CLA_RAM0CPUE|CLA_RAM1CPUE|CLA_RAM2CPUE;
	Cla1Regs.MCTL.bit.IACKE = 1;
	EDIS;
//--- Force one-time initialization Task 8 - zero delay buffer
    Cla1Regs.MIER.all = 0x0080;            // Enable CLA interrupt 8
    asm("  IACK  #0x0080");                // IACK - CLA task force instruction
    asm("  RPT #3 || NOP");                // Wait at least 4 cycles
    while(Cla1Regs.MIRUN.bit.INT8 == 1);   // Loop until task completes

//--- Enable CLA task interrupts
    Cla1Regs.MIER.all = 0x0001;        // Enable CLA interrupt 1 (and disable interrupt 8)

    asm(" EDIS");                      // Disable EALLOW protected register access

//--- Enable the CLA interrupt
   // PieCtrlRegs.PIEIER11.bit.INTx1 = 1;    // Enable CLA Task1 in PIE group #11
  //  IER |= 0x0400;                         // Enable INT11 in IER to enable PIE group 11
             // Enable INT11 in IER to enable PIE group 11

}

//###########################################################################
// CLA ISRs
//###########################################################################
__interrupt void cla1_task1_isr( void)
{
    ESTOP0;
        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task2_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task3_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task4_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task5_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task6_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task7_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

__interrupt void cla1_task8_isr( void)
{
    ESTOP0;

        PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}

Best regards,

Shai

  • Shai,

    An ILLEGAL_ISR occurs when the C28x tries to execute invalid code. An ITRAP (ILLEGAL_ISR) is often a sign of stack overflowing or a buffer overflowing or memory not correctly initialized with code. Here are some things to check:

    1. To quickly see if it is the stack you can fill the region with a known value and then run the application. By the addresses written to you will be able to see how big the stack grew.
    2. Make sure code isn't getting too close to the end of a valid memory block (which is followed by invalid memory). This is explained in the device errata.
    3. Make sure that if any code is being loaded into flash and run from RAM is properly copied to RAM before the function is called.
    4. Make sure the CPU is not pre-fetching into the code security password location.   Basically do not fill memory up close to the security passwords.
    5. Insert a return instruction into the ILLEGAL_ISR. Set a breakpoint on this instruction.  When the CPU stops here, step to see where the code came from.  This will provide clues as to where the problem is.
    6. Inspect the stack. When you take an illegal instruction trap, registers are automatically pushed on the stack, including the return address. By looking at the return address value on the stack, you can find out where the ITRAP occurred.  Below shows the stack contents when an ILLEGAL_TRAP is taken.
    T:ST0
    ACC
    P
    AR1:AR0
    DP:ST1
    DBGSTAT:IER
    Return Addr
    empty  < SP points here (even or odd address)

    Regards
    Lori

  • Hi Shai,

    I haven’t heard from you for a few days, so I’m assuming you were able to resolve your issue. If this isn’t the case, please click the "This did NOT resolve my issue" button and reply to this thread with more information.

    If this thread locks, please click the "Ask a related question" button and in the new thread describe the current status of your issue and any additional details you may have to assist us in helping to solve your issues.

    Regards,
    Lori