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.

ILLEGAL_ISR is not welcome

I have a small test program running on a F2810 and CCS5.5 and there is a timer ISR that fires every 1ms(but also tried 2ms, 4ms and 10ms but the problem seems unaffected), I saw in other postings that this issue has been related to stack issues and I do in fact see what appears to be garbage values in some of the automatic variables,(notice the "cmd" var is circled on the stack).  The problem goes away when I comment out a call to routines that would put more on the stack, just by a deeper call tree, but this is just a small program with 1 or two variables in each routine, I can't believe the stack is full, non the less I increased the stack size in the .cmd file and this did not help. I realize that if I inadvertently wrote junk to the stack it's not good, so I checked but the code is not doing much.

I suspect there is a problem in the setup of the timer ISR but this code is straight of the the Example_281xEvTimerPeriod.c(although I'm just using a single timer)

attached is a screen shot, I filled the stack memory area with 0x0033 and then ran it, so it looks like not much of the stack is used. 

Any ideas would be welcomed!

  • Hi Dan,

    I just checked the sample code. Did you delete the all the below isr initializations and kept only the one you require?
    interrupt void eva_timer1_isr(void);
    interrupt void eva_timer2_isr(void);
    interrupt void evb_timer3_isr(void);
    interrupt void evb_timer4_isr(void);

    Similarly, in PieVectTable entries, initializations, PieCtrlRegs etc... there should be no existence of other 3 interrupts.
    Do share your code if still you're unable to make it work.

    Regards,
    Gautam
  • Hi Gautam,

    Yes I deleted(commented out) the 3 other interrupts.  What I did was copy that file(Example_281xEvTimerPeriod.c) into my project and rename their main() to be my new function init_event_timer(), the modified file is attached, also attached is my main.c.  My main() calls init_event_timer() and also calls the InitPieCtrl() function which is the unmodified function from the example DSP281x_PieCtrl.c, and my main also calls InitPieVectTable() which is unmodified from the example file DSP281x_PieVect.c, these last two example files are common to all the 281x examples.

    1512.main.c
    
    
    /******************************************************************************^
    *                                                        Maximum page width----|
    *                                                                              v
    * Module name: main.c
    *
    * Copyright 2015 Acumentrics Corporation as an unpublished work.
    * All Rights Reserved.
    *
    *  The information contained herein is confidential
    * property of Acumentrics Corporation. The use, copying, transfer or
    * disclosure of such information is prohibited except
    * by express written agreement with Acumentrics Corporation.
    *
     *  Created on: May 14, 2015
     *      Author: dan_mezynski
    *
    * 	Module Description:
    *
    *
    ***************************************************************
    *		HISTORY
    * 2015-05-10 DJM File created
    *
    * 2015-05-27 DJM Modified
    *
    ***************************************************************/
    
    
    
    
    
    // TI File $Revision: /main/3 $
    // Checkin $Date: July 2, 2007   11:28:05 $
    //###########################################################################
    //
    // FILE:   Example_281xSpi_FFDLB.c
    //
    // TITLE:  DSP281x Device Spi Digital Loop Back program.
    //
    // ASSUMPTIONS:
    //
    //         This program requires the DSP281x V1.00 header files.
    //         As supplied, this project is configured for "boot to H0" operation.
    //
    //         Other then boot mode pin configuration, no other hardware configuration
    //         is required.
    //
    // DESCRIPTION:
    //
    // This program is a SPI example that uses the internal loopback of
    // the peripheral.  Interrupts are not used.
    //
    // A stream of data is sent and then compared to the recieved stream.
    //
    // The sent data looks like this:
    // 0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF
    //
    // This pattern is repeated forever.
    //
    //          Watch Variables:
    //                sdata - sent data
    //                rdata - received data
    //
    ////###########################################################################
    // $TI Release: DSP281x C/C++ Header Files V1.20 $
    // $Release Date: July 27, 2009 $
    //###########################################################################
    
    
    #define GPIO_INPUT 0
    #define GPIO_OUTPUT 1
    
    #define SPI_release() GpioDataRegs.GPBSET.all |= 0xC000
    
    
    
    #include "DSP281x_Device.h"     // DSP281x Headerfile Include File
    #include "DSP281x_Examples.h"   // DSP281x Examples Include File
    #include "DS_main.h"
    
    // Prototype statements for functions found within this file.
    // interrupt void ISRTimer2(void);
    void spi_xmit(Uint16 a);
    void spi_fifo_init(void);
    void spi_init(void);
    void error(void);
    void	Init_dan_Gpio(void);
    void SPI_setSelects(Uint16 a);
    //Uint16 do_supervisor_loop(void);
    void init_sci_comm(void);
    void sci_xmit(char a);
    void init_event_timer(void);
    
    
    //extern LOG_Obj logDebug;
    
    
    void main(void)
    {
       Uint16 sdataz;  // send data
       Uint16 rdataz;  // received data
       long cnt;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP281x_SysCtrl.c file.
       InitSysCtrl();
      // LOG_printf(&logDebug, "Starting stuff up");
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP281x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    // Setup only the GP I/O only for SPI functionality
       EALLOW;
       GpioMuxRegs.GPFMUX.all=0x000F;	// Select GPIOs to be SPI pins
     									// Port F MUX - x000 0000 0000 1111
    
    
    
    
    
    
       EDIS;
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP281x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP281x_DefaultIsr.c.
    // This function is found in DSP281x_PieVect.c.
       InitPieVectTable();
    
    
    	
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP281x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       spi_fifo_init();	  // Initialize the Spi FIFO
       spi_init();		  // init SPI
    
       Init_dan_Gpio(); // XXX
       cnt = 2;
    
    //   init_sci_comm(); SSS
    
       init_event_timer();
    
       init_sim_times();
    
    //   adc_config_init(); AAA
    
    // Step 5. User specific code:
    // Interrupts are not used in this example.
       sdataz = 0x0000;
       rdataz = 0;
       for(;;)
       {
         // Transmit data
         spi_xmit(sdataz);
         // Wait until data is received
    //     while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
         // Check against sent data
    //     rdata = SpiaRegs.SPIRXBUF;
         // if(rdata != sdata) error();
         sdataz = sdataz + 5;
    
         if(sdataz > 0x00ff){
       // 	 LOG_printf(&logDebug, "Starting do_intr_loop");
             sdataz = 0x0;
             rdataz++;
             if(rdataz >= 0x0001){   //do_supervisor_loop();
    
            	   for(;;);  // stay here forever
             }
             //if(rdata >= 0x00ff)cnt = 10; // do_intr_loop();
         }
    
        // if(sdata == 0x0000)
        //	 sdata = 0x5555; // was 0008
        // else
        //	 sdata = 0x0000;
    
         delay_time(cnt);
    
       }
    }
    
    //====================================================================================
    // This tests the modbus connection
    void get_modbus(void){ // XXX
    
    
    
    
    
    
    
    }
    
    
    //====================================================================================
    
    // Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:
    
    void delay_time(long num)
    {
        long      i, j;
    
    
        for(j = 0; j < num; j++)
           for (i = 0; i < 20000; i++) {}
    }
    
    //====================================================================================
    
    void error(void)
    {
        asm("     ESTOP0");						// Test failed!! Stop!
        for (;;);
    }
    //====================================================================================
    
    void spi_init()
    {
    	SpiaRegs.SPICCR.all =0x0008; // was F;	             // Reset on, rising edge, 16-bit char bits
    	SpiaRegs.SPICTL.all =0x0006;    		     // Enable master mode, normal phase,
                                                     // enable talk, and SPI int disabled.
    	SpiaRegs.SPIBRR =0x007F;
        SpiaRegs.SPICCR.all =0x009F;		         // Relinquish SPI from Reset
        SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission
    }
    //====================================================================================
    
    void spi_xmit(Uint16 a)
    {
    	Uint16 rdata;
    
    
    
        SpiaRegs.SPITXBUF=a;
    
    
    
        SPI_setSelects(5); // need 5 to enable it
    
        // XXX maybe need a delay here to let all the SPI bits clock into shift reg
        // delay(1);
    
    
        // XXX This thing must be in loopback mode so I guess we need to read it, but not sure
        // in any case we should make a diagnostic test
        // Wait until data is received
        while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
        // Check against sent data
        rdata = SpiaRegs.SPIRXBUF;
    
    
        SPI_release();
    }
    
    void spi_fifo_init()
    {
    // Initialize SPI FIFO registers
        SpiaRegs.SPIFFTX.all=0xE040;
        SpiaRegs.SPIFFRX.all=0x204f;
        SpiaRegs.SPIFFCT.all=0x0;
    }
    
    
    
    // Parallel load shift Reg
    //void SPI_setSelects(enum SPI_ControlLines spiSelects)
    void SPI_setSelects(Uint16 spiSelects)
    {
    /*  De-assert (set) the chip selects, clear the select lines.
    * 	Set the select lines bits 11-13.
    *		Set the chip selects (active low). */
    	GpioDataRegs.GPBSET.all = 0xC000;							// De-assert chip selects
    	GpioDataRegs.GPBCLEAR.all = 0x3800;						// Clear select lines
    	GpioDataRegs.GPBSET.all = (spiSelects & 0x07) << 11;	// Set select lines
    	if (spiSelects < 8)								// Assert appropriate chip select.
    	{
    		GpioDataRegs.GPBCLEAR.bit.GPIOB14 = 1;
    	}
    	else
    	{
    		GpioDataRegs.GPBCLEAR.bit.GPIOB15 = 1;
    	}
    }
    
    
    //====================================================================================
    // use this to test the SCI serial port
    void sci_xmit(char a){
    
    
    	SciaRegs.SCITXBUF = a;
    	ScibRegs.SCITXBUF = a;
    
    }
    //====================================================================================
    void	Init_dan_Gpio(void){
    #define GPIO 0
    
    
    	 EALLOW;
    
    	 // XXX as a quick test set everything to inputs then re-set some as needed
    /*
    	 // sets GPIO Muxs as I/Os
    		GpioMuxRegs.GPAMUX.all=0x0000;
    	    GpioMuxRegs.GPBMUX.all=0x0000;
    	    GpioMuxRegs.GPDMUX.all=0x0000;
    	    GpioMuxRegs.GPFMUX.all=0x0000;
    	    GpioMuxRegs.GPEMUX.all=0x0000;
    	    GpioMuxRegs.GPGMUX.all=0x0000;
    
    
    	    GpioMuxRegs.GPADIR.all=0x0000;		// GPIO PORTs  as inputs
    	    GpioMuxRegs.GPBDIR.all=0x0000;   		// GPIO DIR select
    	    GpioMuxRegs.GPDDIR.all=0x0000;
    	    GpioMuxRegs.GPEDIR.all=0x0000;
    	    GpioMuxRegs.GPFDIR.all=0x0000;
    	    GpioMuxRegs.GPGDIR.all=0x0000;
    
    */
    
    	 GpioMuxRegs.GPAMUX.bit.CAP1Q1_GPIOA8   = 0;  // a8 - a15   0 2 4 6 7   Set pin function to GPIO
    	 GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9   = 0;
    	 GpioMuxRegs.GPAMUX.bit.CAP3QI1_GPIOA10 = 0;
    	 GpioMuxRegs.GPAMUX.bit.TDIRA_GPIOA11   = 0;
    	 GpioMuxRegs.GPAMUX.bit.TCLKINA_GPIOA12 = 0;
    	 GpioMuxRegs.GPAMUX.bit.C1TRIP_GPIOA13  = 0;
    	 GpioMuxRegs.GPAMUX.bit.C2TRIP_GPIOA14  = 0;
    	 GpioMuxRegs.GPAMUX.bit.C3TRIP_GPIOA15  = 0;
    	 GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0     = 0;
    	 GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2     = 0;
    	 GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4     = 0;
    	 GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6    = 0;
    	 GpioMuxRegs.GPAMUX.bit.T2PWM_GPIOA7    = 0;
    
    	 GpioMuxRegs.GPADIR.bit.GPIOA8	=	GPIO_OUTPUT;  // a8 - a15   0 2 4 6 7
    	 GpioMuxRegs.GPADIR.bit.GPIOA9	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA10	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA11	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA12	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA13	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA14	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA15	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA0	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA2	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA4	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA6	=	GPIO_OUTPUT;
    	 GpioMuxRegs.GPADIR.bit.GPIOA7	=	GPIO_OUTPUT;
    
    	 GpioDataRegs.GPACLEAR.bit.GPIOA8 	= 	1;				// a8 - a15   0 2 4 6 7   set outputs to 0
    	 GpioDataRegs.GPACLEAR.bit.GPIOA9	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA10	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA11	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA12	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA13	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA14	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA15	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA0	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA2	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA4	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA6	=	1;
    	 GpioDataRegs.GPACLEAR.bit.GPIOA7	=	1;
    
    
    	 GpioMuxRegs.GPDMUX.bit.T1CTRIP_PDPA_GPIOD0 = GPIO;  // PORTD 0 1 5 6   Set pin function to GPIO
    	 GpioMuxRegs.GPDMUX.bit.T2CTRIP_SOCA_GPIOD1 = GPIO;
    	 GpioMuxRegs.GPDMUX.bit.T3CTRIP_PDPB_GPIOD5 = GPIO;
    	 GpioMuxRegs.GPDMUX.bit.T4CTRIP_SOCB_GPIOD6 = GPIO;
    
    
    	 GpioMuxRegs.GPDDIR.bit.GPIOD0 = GPIO_OUTPUT;  // PORTD 0 1 5 6    Set direction to output
    	 GpioMuxRegs.GPDDIR.bit.GPIOD1 = GPIO_OUTPUT;
    	 GpioMuxRegs.GPDDIR.bit.GPIOD5 = GPIO_OUTPUT;
    	 GpioMuxRegs.GPDDIR.bit.GPIOD6 = GPIO_OUTPUT;
    
    	 GpioDataRegs.GPDCLEAR.bit.GPIOD0	=	1;
    	 GpioDataRegs.GPDCLEAR.bit.GPIOD1	=	1;
    	 GpioDataRegs.GPDCLEAR.bit.GPIOD5	=	1;
    	 GpioDataRegs.GPDCLEAR.bit.GPIOD6	=	1;
    
    
    	// GpioMuxRegs.GPBMUX.all=0x0000;  // B 0 2 4 7   6
    
    
    	//GpioMuxRegs.GPBMUX.bit.TDIRB_GPIOB11 = GPIO;
    
    	GpioMuxRegs.GPBMUX.all=0;  // sets GPIO Muxs as I/Os
    
    	GpioMuxRegs.GPBDIR.bit.GPIOB10	=	GPIO_OUTPUT;
    
    	GpioMuxRegs.GPBDIR.bit.GPIOB11	=	GPIO_OUTPUT;
    	GpioMuxRegs.GPBDIR.bit.GPIOB12	=	GPIO_OUTPUT;
    	GpioMuxRegs.GPBDIR.bit.GPIOB13	=	GPIO_OUTPUT;
    
    	GpioMuxRegs.GPBDIR.bit.GPIOB14	=	GPIO_OUTPUT;
    
    
    
    	// XXX one bit for test, TODO define all bits for port B, see P2 schem
    	GpioMuxRegs.GPAMUX.all=0;  // sets GPIO Muxs as I/Os
    	GpioMuxRegs.GPADIR.bit.GPIOA11	=	GPIO_OUTPUT;
    
    
    	// Define the rest of what goes into the 3 octal driver buffers so I don't fry something
    //	GpioMuxRegs.GPADIR.bit.GPIOA11
    //	GpioMuxRegs.GPBDIR.bit.GPIOB1	=	GPIO_OUTPUT;
    
    
    	EDIS;
    
    
    }
    //====================================================================================
    
    //===========================================================================
    // No more.
    //===========================================================================
    
    
    
    DS_EventTimer.c
    /*
     * DS_EventTimer.c
     *
     *  Created on: May 13, 2015
     *      Author: dan_mezynski
     */
    
    // TI File $Revision: /main/3 $
    // Checkin $Date: July 2, 2007   11:32:13 $
    //###########################################################################
    //
    // FILE:    Example_281xEvTimerPeriod.c
    //
    // TITLE:   DSP281x Event Manager GP Timer example program.
    //
    // ASSUMPTIONS:
    //
    //          This program requires the DSP281x V1.00 header files.
    //          As supplied, this project is configured for "boot to H0" operation.
    //
    //          Other then boot mode pin configuration, no other hardware configuration
    //          is required.
    //
    // DESCRIPTION:
    //
    //          This program sets up EVA Timer 1, EVA Timer 2, EVB Timer 3
    //          and EVB Timer 4 to fire an interrupt on a period overflow.
    //          A count is kept each time each interrupt passes through
    //          the interrupt service routine.
    //
    //          EVA Timer 1 has the shortest period while EVB Timer4 has the
    //          longest period.
    //
    //          Watch Variables:
    //
    //                EvaTimer1InterruptCount;
    //                EvaTimer2InterruptCount;
    //                EvbTimer3InterruptCount;
    //                EvbTimer4InterruptCount;
    //
    //###########################################################################
    // $TI Release: DSP281x C/C++ Header Files V1.20 $
    // $Release Date: July 27, 2009 $
    //###########################################################################
    
    
    #include "DSP281x_Device.h"     // DSP281x Headerfile Include File
    #include "DSP281x_Examples.h"   // DSP281x Examples Include File
    #include "DS_main.h"
    
    
    void round_robin_control(void);
    void test_time_pulse(void);
    
    
    Uint32 call_cnt = 0;
    Uint16 call_toggle = 0;
    
    
    // Prototype statements for functions found within this file.
    interrupt void eva_timer1_isr(void);
    //interrupt void eva_timer2_isr(void);
    //interrupt void evb_timer3_isr(void);
    //interrupt void evb_timer4_isr(void);
    void init_eva_timer1(void);
    //void init_eva_timer2(void);
    //void init_evb_timer3(void);
    //void init_evb_timer4(void);
    
    // Global counts used in this example
    Uint32  EvaTimer1InterruptCount;
    //Uint32  EvaTimer2InterruptCount;
    //Uint32  EvbTimer3InterruptCount;
    //Uint32  EvbTimer4InterruptCount;
    
    void init_event_timer(void)
    {
    
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP281x_SysCtrl.c file.
       //InitSysCtrl();
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP281x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP281x_PieCtrl.c file.
       //InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP281x_DefaultIsr.c.
    // This function is found in DSP281x_PieVect.c.
       //InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;  // This is needed to write to EALLOW protected registers
       PieVectTable.T1PINT = &eva_timer1_isr;
      // PieVectTable.T2PINT = &eva_timer2_isr;
      // PieVectTable.T3PINT = &evb_timer3_isr;
      // PieVectTable.T4PINT = &evb_timer4_isr;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP281x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       init_eva_timer1(); // DDD
     //  init_eva_timer2();
     //  init_evb_timer3();
     //  init_evb_timer4();
    
    // Step 5. User specific code, enable interrupts:
    
        // Initialize count values to 0
        EvaTimer1InterruptCount = 0;
     //   EvaTimer2InterruptCount = 0;
     //   EvbTimer3InterruptCount = 0;
     //   EvbTimer4InterruptCount = 0;
    
        // Enable PIE group 2 interrupt 4 for T1PINT
        PieCtrlRegs.PIEIER2.all = M_INT4;
        // Enable PIE group 3 interrupt 1 for T2PINT
    //    PieCtrlRegs.PIEIER3.all = M_INT1;
        // Enable PIE group 4 interrupt 4 for T3PINT
    //    PieCtrlRegs.PIEIER4.all = M_INT4;
        // Enable PIE group 5 interrupt 1 for T4PINT
    //    PieCtrlRegs.PIEIER5.all = M_INT1;
    
        // Enable CPU INT2 for T1PINT, INT3 for T2PINT, INT4 for T3PINT
        // and INT5 for T4PINT:
        //IER |= (M_INT2 | M_INT3 | M_INT4 | M_INT5);
        IER |= M_INT2;
    
        // Enable global Interrupts and higher priority real-time debug events:
        EINT;   // Enable Global interrupt INTM
        ERTM;   // Enable Global realtime interrupt DBGM
    
        // Step 6. IDLE loop. Just sit and loop forever:
    //    for(;;);
    
    }
    
    void init_eva_timer1(void)
    {
        // Initialize EVA Timer 1:
        // Setup Timer 1 Registers (EV A)
        EvaRegs.GPTCONA.all = 0;
    
        // Set the Period for the GP timer 1 to 0x0200;
        // The timing is currently 1ms
        EvaRegs.T1PR = 0x1400;       // 0x0200 is about 1ms Period  try 1400 for 10ms
        EvaRegs.T1CMPR = 0x0000;     // Compare Reg
    
        // Enable Period interrupt bits for GP timer 1
        // Count up, x128, internal clk, enable compare, use own period
        EvaRegs.EVAIMRA.bit.T1PINT = 1;
        EvaRegs.EVAIFRA.bit.T1PINT = 1;
    
        // Clear the counter for GP timer 1
        EvaRegs.T1CNT = 0x0000;
        EvaRegs.T1CON.all = 0x1742;
    
        // Start EVA ADC Conversion on timer 1 Period interrupt  XXX
    // DDD    EvaRegs.GPTCONA.bit.T1TOADC = 2;
    
    }
    
    /*
    void init_eva_timer2(void)
    {
        // Initialize EVA Timer 2:
        // Setup Timer 2 Registers (EV A)
        EvaRegs.GPTCONA.all = 0;
    
        // Set the Period for the GP timer 2 to 0x0200;
        EvaRegs.T2PR = 0x0400;       // Period
        EvaRegs.T2CMPR = 0x0000;     // Compare Reg
    
        // Enable Period interrupt bits for GP timer 2
        // Count up, x128, internal clk, enable compare, use own period
        EvaRegs.EVAIMRB.bit.T2PINT = 1;
        EvaRegs.EVAIFRB.bit.T2PINT = 1;
    
        // Clear the counter for GP timer 2
        EvaRegs.T2CNT = 0x0000;
        EvaRegs.T2CON.all = 0x1742;
    
        // Start EVA ADC Conversion on timer 2 Period interrupt
        EvaRegs.GPTCONA.bit.T2TOADC = 2;
    }
    
    void init_evb_timer3(void)
    {
        // Initialize EVB Timer 3:
        // Setup Timer 3 Registers (EV B)
        EvbRegs.GPTCONB.all = 0;
    
        // Set the Period for the GP timer 3 to 0x0200;
        EvbRegs.T3PR = 0x0800;       // Period
        EvbRegs.T3CMPR = 0x0000;     // Compare Reg
    
        // Enable Period interrupt bits for GP timer 3
        // Count up, x128, internal clk, enable compare, use own period
        EvbRegs.EVBIMRA.bit.T3PINT = 1;
        EvbRegs.EVBIFRA.bit.T3PINT = 1;
    
        // Clear the counter for GP timer 3
        EvbRegs.T3CNT = 0x0000;
        EvbRegs.T3CON.all = 0x1742;
    
        // Start EVA ADC Conversion on timer 3 Period interrupt
        EvbRegs.GPTCONB.bit.T3TOADC = 2;
    }
    
    void init_evb_timer4(void)
    {
        // Initialize EVB Timer 4:
        // Setup Timer 4 Registers (EV B)
        EvbRegs.GPTCONB.all = 0;
    
        // Set the Period for the GP timer 4 to 0x0200;
        EvbRegs.T4PR = 0x1000;       // Period
        EvbRegs.T4CMPR = 0x0000;     // Compare Reg
    
        // Enable Period interrupt bits for GP timer 4
        // Count up, x128, internal clk, enable compare, use own period
        EvbRegs.EVBIMRB.bit.T4PINT = 1;
        EvbRegs.EVBIFRB.bit.T4PINT = 1;
    
        // Clear the counter for GP timer 4
        EvbRegs.T4CNT = 0x0000;
        EvbRegs.T4CON.all = 0x1742;
    
        // Start EVA ADC Conversion on timer 4 Period interrupt
        EvbRegs.GPTCONB.bit.T4TOADC = 2;
    }
    */
    
    
    interrupt void eva_timer1_isr(void)
    {
       EvaTimer1InterruptCount++;
    
       call_cnt++;
    
       if(call_cnt > 100){ // DDD
    	   call_cnt = 0;
    
    //	   serial_send(); SSS
       }
    
    
       round_robin_control();
    
       /*
       if(call_toggle == 1){
    	   call_toggle = 0;
    	      GpioDataRegs.GPASET.bit.GPIOA11 = 1;	// Set 24v line high
       GpioDataRegs.GPBCLEAR.bit.GPIOB10 = 1;  // enable line (lo active)
      // GpioDataRegs.GPBSET.bit.GPIOB10 = 1;
       }
       else {
    	   call_toggle = 1;
     // 	  	  	  	  	  	  spi_xmit(0x0070); delay_time(3500);
       GpioDataRegs.GPACLEAR.bit.GPIOA11 = 1;  // clear 24v line low
      // GpioDataRegs.GPBCLEAR.bit.GPIOB10 = 1;  // enable line (lo active)
       GpioDataRegs.GPBSET.bit.GPIOB10 = 1;
       }
       */
    
       // Enable more interrupts from this timer
       EvaRegs.EVAIMRA.bit.T1PINT = 1;
    
       // Note: To be safe, use a mask value to write to the entire
       // EVAIFRA register.  Writing to one bit will cause a read-modify-write
       // operation that may have the result of writing 1's to clear
       // bits other then those intended.
       EvaRegs.EVAIFRA.all = BIT7;
    
       // Acknowledge interrupt to receive more interrupts from PIE group 2
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
    }
    
    
    // =========================================================================
    void round_robin_control(void){
    	Uint16 cmd;  //command to sendto supervisor, which is normally nul but otherwise might cause super to pause or shutdown etc.
    
    
    	cmd = 0;
    	//update_watch_dog();
    
    
    	// cmd = check_modbus();
    
    	// cmd2 = check_can();
    
    	// cmd3 = other_state_machine();
    
    	// maintain_adc_counters();  (this is not a good name, should only use high level here)
    
    	do_supervisor_loop(cmd);
    
    	test_time_pulse();
    
    
    
    
    }
    
    // ==========================================================
    // this test puts a pulse on a 24v line to be used for timing checks.
    // Will the code grow to take enough time so that heart beats merge?  Aliasing?
    void test_time_pulse(void){
    
    	if(call_toggle == 1){
    		   call_toggle = 0;
    		      GpioDataRegs.GPASET.bit.GPIOA11 = 1;	// Set 24v line high
    	   GpioDataRegs.GPBCLEAR.bit.GPIOB10 = 1;  // enable line (lo active)
    	  // GpioDataRegs.GPBSET.bit.GPIOB10 = 1;
    	   }
    	   else {
    		   call_toggle = 1;
    	 // 	  	  	  	  	  	  spi_xmit(0x0070); delay_time(3500);
    	   GpioDataRegs.GPACLEAR.bit.GPIOA11 = 1;  // clear 24v line low
    	  // GpioDataRegs.GPBCLEAR.bit.GPIOB10 = 1;  // enable line (lo active)
    	   GpioDataRegs.GPBSET.bit.GPIOB10 = 1;
    	   }
    
    
    }
    
    /*
    interrupt void eva_timer2_isr(void)
    {
      EvaTimer2InterruptCount++;
      // Enable more interrupts from this timer
      EvaRegs.EVAIMRB.bit.T2PINT = 1;
    
      // Note: To be safe, use a mask value to write to the entire
      // EVAIFRB register.  Writing to one bit will cause a read-modify-write
      // operation that may have the result of writing 1's to clear
      // bits other then those intended.
      EvaRegs.EVAIFRB.all = BIT0;
    
      // Acknowledge interrupt to receive more interrupts from PIE group 3
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    interrupt void evb_timer3_isr(void)
    {
      EvbTimer3InterruptCount++;
      // Note: To be safe, use a mask value to write to the entire
      // EVBIFRA register.  Writing to one bit will cause a read-modify-write
      // operation that may have the result of writing 1's to clear
      // bits other then those intended.
      EvbRegs.EVBIFRA.all = BIT7;
    
      // Acknowledge interrupt to receive more interrupts from PIE group 4
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    
    }
    
    interrupt void evb_timer4_isr(void)
    {
       EvbTimer4InterruptCount++;
       // Note: To be safe, use a mask value to write to the entire
       // EVBIFRB register.  Writing to one bit will cause a read-modify-write
       // operation that may have the result of writing 1's to clear
       // bits other then those intended.
       EvbRegs.EVBIFRB.all = BIT0;
    
       // Acknowledge interrupt to receive more interrupts from PIE group 5
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP5;
    
    }
    */
    
    //===========================================================================
    // No more.
    //===========================================================================
    
    
    
    

  • One line that I'm not sure about is line 138 in the file DS_EventTimer.c, this could be a problem but I don't quite understand it

    PieCtrlRegs.PIEIER2.all = M_INT4;
  • It's a little odd that everything was fine for the last couple weeks until I added a little more dept on the call stack, I would have thought if it was a interrupt configuration problem it would have appeared sooner.
  • I think that line...
    PieCtrlRegs.PIEIER2.all = M_INT4;
    Is probably ok because it runs for a while. (although I don't understand why)

    But to be honest setting up the PieCtrlRegs registers appears not straight forward.. I'm looking in the SPRU078g.pdf which is F281x_System_Control_and_Interrupts as well as the SPRU065e.pdf Event Manager Guide and it's not clear how to do this.

    Could someone direct me to the pages that describe: to use Ev timer 1 interrupt then enable PIE group 2 interrupt 4? (If it exists)
  • I believe I found the fix for the ILLEGAL_ISR, the unmodified example F2812_RAM_lnk.cmd file that I was using looked like this...
    -
    -
    -
    MEMORY
    {
    PAGE 0 :
    /* For this example, H0 is split between PAGE 0 and PAGE 1 */
    /* BEGIN is used for the "boot to HO" bootloader mode */
    /* RESET is loaded with the reset vector only if */
    /* the boot is from XINTF Zone 7. Otherwise reset vector */
    /* is fetched from boot ROM. See .reset section below */

    RAMM0 : origin = 0x000000, length = 0x000400
    BEGIN : origin = 0x3F8000, length = 0x000002
    PRAMH0 : origin = 0x3F8002, length = 0x000FFE
    RESET : origin = 0x3FFFC0, length = 0x000002

    After changing the line for RAMM0 to...
    RAMM0 : origin = 0x000040, length = 0x000400

    Then they were no more ILLEGAL_ISR problems. It looks like from the memory map that the ISR Vectors were stored here and getting corrupted, but I'm not quite sure since it appears the vector map can be in several places. What is the default?

    Is this a bug in the F2812_RAM_lnk.cmd file?
  • Is this a bug in the F2812_RAM_lnk.cmd file?

    Actually its 0 to 400 only... but yes SARAM0 starts from 40 to 400. So is the code functioning as required?