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()

Other Parts Discussed in Thread: CONTROLSUITE

I've programmed to flash 320F2808 Docking Station).  Compilation ok, program ok.  Then I run and get illegal_isr().  I've tracked it down to the initialization of the adc (InitAdc) where the initialization goes into DELAY_US(ADC_usDELAY).

File is:  

     DSP280x_usDelay.asm

Command is: 

     LRETR

Assembly code is:

0x0080E0:   CBDC        OR         AH,*+XAR4[3]
0x0080E1:   FE5D        ADDB       SP,#93
0x0080E2:   47AD        TBIT       @SP,#7
0x0080E3:   FFDF        LSR        AH,16
0x0080E4:   2757        MOV        PL,*-SP[23]
0x0080E5:   9F5D        SUB        AH,*-SP[29]
0x0080E6:   FED7        SUBB       SP,#87
0x0080E7:   BEEF        MOVB       XAR6,#239
0x0080E8:   B886        MOVZ       DP,#134
0x0080E9:   77FC        NOP        *+XAR4[7]
0x0080EA:   B8FE        MOVZ       DP,#254
0x0080EB:   F16F        XORB       AH,#0x6F
0x0080EC:   7FDE        MOV        *+XAR6[3],AR7
0x0080ED:   B3B5        MOVH       *ARP5,ACC << 1
0x0080EE:   74DB        SUB        *+XAR3[3],AL
0x0080EF:   7F5D        MOV        *-SP[29],AR7
0x0080F0:   CB7E        OR         AH,*-SP[62]
0x0080F1:   BFDFD56E    MOV32      *+XAR7[3],*(0:0xD56E)  <= It's either this line or the next that trips illegal_isr.
0x0080F3:   378B        MPYU       P,T,*--XAR3

 

Processor is set for 100MHz.  I tried to attach my Examples.h but it is not an allowed file type to attach.

Anybody have any ideas?  Thanks in advance.

  • The reason you are getting an ITRAP on that line is because MOV32 is an FPU command not supported by the F2808.  Now as for the reason this command exists in your disassembly is a mystery.  Are you able to list the C code which goes with the disassembly? (a screenshot of CCS will do) The associated C code may help.

    One possible explanation to the mystery is that what you are listing is data, not code.  Somehow your program is getting into data space, which usually ends up in an ITRAP when it finds something it doesnt recognise.  The most likely reason it would deviate into data space is an error with the stack.  Check the size of your stack.

    Anyway, if you are able to attach/list (copy and paste into the message) your linker command file, it may help answer some questions.

    Tim

  • I suspect your second paragraph is the problem.  I'm a hardware engineer and I don't know CCS very well so I don't know how to check my stack size (or even which stack).

    Anyway, here is a screen shot of the code which generated the assembly.  I didn't write it.  It came with the development kit.  Also I have attached the f2808.cmd file I am using that came with the development kit.

    MEMORY
    {
    PAGE 0:    /* Program Memory */
               /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
    
       RAML0       : origin = 0x008000, length = 0x001000     /* on-chip RAM block L0 */
       OTP         : origin = 0x3D7800, length = 0x000400     /* on-chip OTP */
       FLASHD      : origin = 0x3E8000, length = 0x004000     /* on-chip FLASH */
       FLASHC      : origin = 0x3EC000, length = 0x004000     /* on-chip FLASH */
       FLASHA      : origin = 0x3F4000, length = 0x003F80     /* on-chip FLASH */
       CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
       BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
       CSM_PWL     : origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */
       
       ROM         : origin = 0x3FF000, length = 0x000FC0     /* Boot ROM */
       RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
       VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */
    
    PAGE 1 :   /* Data Memory */
               /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
               /* Registers remain on PAGE1                                                  */
    
       RAMM0       : origin = 0x000000, length = 0x000400     /* on-chip RAM block M0 */
       BOOT_RSVD   : origin = 0x000400, length = 0x000080     /* Part of M1, BOOT rom will use this for stack */
       RAMM1       : origin = 0x000480, length = 0x000380     /* on-chip RAM block M1 */
       RAML1       : origin = 0x009000, length = 0x001000     /* on-chip RAM block L1 */
       FLASHB      : origin = 0x3F0000, length = 0x004000     /* on-chip FLASH */
       RAMH0       : origin = 0x3FA000, length = 0x002000     /* on-chip RAM block H0 */
    }
    
    /* Allocate sections to memory blocks.
       Note:
             codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code 
                       execution when booting to flash
             ramfuncs  user defined section to store functions that will be copied from Flash into RAM
    */ 
     
    SECTIONS
    {
     
       /* Allocate program areas: */
       .cinit              : > FLASHA      PAGE = 0
       .pinit              : > FLASHA,     PAGE = 0
       .text               : > FLASHA      PAGE = 0
       codestart           : > BEGIN       PAGE = 0
       ramfuncs            : LOAD = FLASHD, 
                             RUN = RAML0, 
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             PAGE = 0
    
       csmpasswds          : > CSM_PWL     PAGE = 0
       csm_rsvd            : > CSM_RSVD    PAGE = 0
       
       /* Allocate uninitalized data sections: */
       .stack              : > RAMM0       PAGE = 1
       .ebss               : > RAML1       PAGE = 1
       .esysmem            : > RAMH0       PAGE = 1
    
       /* Initalized sections go in Flash */
       /* For SDFlash to program these, they must be allocated to page 0 */
       .econst             : > FLASHA      PAGE = 0
       .switch             : > FLASHA      PAGE = 0      
    
       /* Allocate IQ math areas: */
       IQmath              : > FLASHC      PAGE = 0                  /* Math Code */
       IQmathTables        : > ROM         PAGE = 0, TYPE = NOLOAD   /* Math Tables In ROM */
    
       /* .reset is a standard section used by the compiler.  It contains the */ 
       /* the address of the start of _c_int00 for C Code.   /*
       /* When using the boot ROM this section and the CPU vector */
       /* table is not needed.  Thus the default type is set here to  */
       /* DSECT  */ 
       .reset              : > RESET,      PAGE = 0, TYPE = DSECT
       vectors             : > VECTORS     PAGE = 0, TYPE = DSECT
    
    }
    

    MEMORY
    {
     PAGE 0:    /* Program Memory */
    
     PAGE 1:    /* Data Memory */
     
       DEV_EMU     : origin = 0x000880, length = 0x000180     /* device emulation registers */
       FLASH_REGS  : origin = 0x000A80, length = 0x000060     /* FLASH registers */
       CSM         : origin = 0x000AE0, length = 0x000010     /* code security module registers */
       
       ADC_MIRROR  : origin = 0x000B00, length = 0x000010     /* ADC Results register mirror */
       
       CPU_TIMER0  : origin = 0x000C00, length = 0x000008     /* CPU Timer0 registers */
       CPU_TIMER1  : origin = 0x000C08, length = 0x000008     /* CPU Timer0 registers (CPU Timer1 & Timer2 reserved TI use)*/
       CPU_TIMER2  : origin = 0x000C10, length = 0x000008     /* CPU Timer0 registers (CPU Timer1 & Timer2 reserved TI use)*/
    
       PIE_CTRL    : origin = 0x000CE0, length = 0x000020     /* PIE control registers */
       PIE_VECT    : origin = 0x000D00, length = 0x000100     /* PIE Vector Table */
    
       ECANA       : origin = 0x006000, length = 0x000040     /* eCAN-A control and status registers */ 
       ECANA_LAM   : origin = 0x006040, length = 0x000040     /* eCAN-A local acceptance masks */
       ECANA_MOTS  : origin = 0x006080, length = 0x000040     /* eCAN-A message object time stamps */
       ECANA_MOTO  : origin = 0x0060C0, length = 0x000040     /* eCAN-A object time-out registers */
       ECANA_MBOX  : origin = 0x006100, length = 0x000100     /* eCAN-A mailboxes */
    
       ECANB       : origin = 0x006200, length = 0x000040     /* eCAN-B control and status registers */ 
       ECANB_LAM   : origin = 0x006240, length = 0x000040     /* eCAN-B local acceptance masks */
       ECANB_MOTS  : origin = 0x006280, length = 0x000040     /* eCAN-B message object time stamps */
       ECANB_MOTO  : origin = 0x0062C0, length = 0x000040     /* eCAN-B object time-out registers */
       ECANB_MBOX  : origin = 0x006300, length = 0x000100     /* eCAN-B mailboxes */
    
       EPWM1       : origin = 0x006800, length = 0x000022     /* Enhanced PWM 1 registers */
       EPWM2       : origin = 0x006840, length = 0x000022     /* Enhanced PWM 2 registers */
       EPWM3       : origin = 0x006880, length = 0x000022     /* Enhanced PWM 3 registers */
       EPWM4       : origin = 0x0068C0, length = 0x000022     /* Enhanced PWM 4 registers */
       EPWM5       : origin = 0x006900, length = 0x000022     /* Enhanced PWM 5 registers */
       EPWM6       : origin = 0x006940, length = 0x000022     /* Enhanced PWM 6 registers */
    
       ECAP1       : origin = 0x006A00, length = 0x000020     /* Enhanced Capture 1 registers */
       ECAP2       : origin = 0x006A20, length = 0x000020     /* Enhanced Capture 2 registers */
       ECAP3       : origin = 0x006A40, length = 0x000020     /* Enhanced Capture 3 registers */
       ECAP4       : origin = 0x006A60, length = 0x000020     /* Enhanced Capture 4 registers */         
     
       EQEP1       : origin = 0x006B00, length = 0x000040     /* Enhanced QEP 1 registers */
       EQEP2       : origin = 0x006B40, length = 0x000040     /* Enhanced QEP 2 registers */   
    
       GPIOCTRL    : origin = 0x006F80, length = 0x000040     /* GPIO control registers */
       GPIODAT     : origin = 0x006FC0, length = 0x000020     /* GPIO data registers */
       GPIOINT     : origin = 0x006FE0, length = 0x000020     /* GPIO interrupt/LPM registers */
                     
       SYSTEM      : origin = 0x007010, length = 0x000020     /* System control registers */
       SPIA        : origin = 0x007040, length = 0x000010     /* SPI-A registers */
       SCIA        : origin = 0x007050, length = 0x000010     /* SCI-A registers */
       XINTRUPT    : origin = 0x007070, length = 0x000010     /* external interrupt registers */
    
       ADC         : origin = 0x007100, length = 0x000020     /* ADC registers */
       SPIB        : origin = 0x007740, length = 0x000010     /* SPI-B registers */
    
       SCIB        : origin = 0x007750, length = 0x000010     /* SCI-B registers */
       SPIC        : origin = 0x007760, length = 0x000010     /* SPI-C registers */
    
       SPID        : origin = 0x007780, length = 0x000010     /* SPI-D registers */
       
       I2CA        : origin = 0x007900, length = 0x000040     /* I2C-A registers */
       
       CSM_PWL     : origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations. */
    }
    
     
    SECTIONS
    {
       PieVectTableFile : > PIE_VECT,   PAGE = 1
    
    /*** Peripheral Frame 0 Register Structures ***/
       DevEmuRegsFile    : > DEV_EMU,     PAGE = 1
       FlashRegsFile     : > FLASH_REGS,  PAGE = 1
       CsmRegsFile       : > CSM,         PAGE = 1
       AdcMirrorFile     : > ADC_MIRROR,  PAGE = 1   
       CpuTimer0RegsFile : > CPU_TIMER0,  PAGE = 1
       CpuTimer1RegsFile : > CPU_TIMER1,  PAGE = 1
       CpuTimer2RegsFile : > CPU_TIMER2,  PAGE = 1  
       PieCtrlRegsFile   : > PIE_CTRL,    PAGE = 1      
    
    /*** Peripheral Frame 1 Register Structures ***/
       ECanaRegsFile     : > ECANA,       PAGE = 1
       ECanaLAMRegsFile  : > ECANA_LAM    PAGE = 1   
       ECanaMboxesFile   : > ECANA_MBOX   PAGE = 1
       ECanaMOTSRegsFile : > ECANA_MOTS   PAGE = 1
       ECanaMOTORegsFile : > ECANA_MOTO   PAGE = 1
       
       ECanbRegsFile     : > ECANB,       PAGE = 1
       ECanbLAMRegsFile  : > ECANB_LAM    PAGE = 1   
       ECanbMboxesFile   : > ECANB_MBOX   PAGE = 1
       ECanbMOTSRegsFile : > ECANB_MOTS   PAGE = 1
       ECanbMOTORegsFile : > ECANB_MOTO   PAGE = 1
       
       EPwm1RegsFile     : > EPWM1        PAGE = 1   
       EPwm2RegsFile     : > EPWM2        PAGE = 1   
       EPwm3RegsFile     : > EPWM3        PAGE = 1   
       EPwm4RegsFile     : > EPWM4        PAGE = 1   
       EPwm5RegsFile     : > EPWM5        PAGE = 1   
       EPwm6RegsFile     : > EPWM6        PAGE = 1
       
       ECap1RegsFile     : > ECAP1        PAGE = 1   
       ECap2RegsFile     : > ECAP2        PAGE = 1   
       ECap3RegsFile     : > ECAP3        PAGE = 1   
       ECap4RegsFile     : > ECAP4        PAGE = 1
    
       EQep1RegsFile     : > EQEP1        PAGE = 1   
       EQep2RegsFile     : > EQEP2        PAGE = 1               
    
       GpioCtrlRegsFile  : > GPIOCTRL     PAGE = 1
       GpioDataRegsFile  : > GPIODAT      PAGE = 1
       GpioIntRegsFile   : > GPIOINT      PAGE = 1
       
    /*** Peripheral Frame 2 Register Structures ***/
       SysCtrlRegsFile   : > SYSTEM,      PAGE = 1
       SpiaRegsFile      : > SPIA,        PAGE = 1
       SciaRegsFile      : > SCIA,        PAGE = 1
       XIntruptRegsFile  : > XINTRUPT,    PAGE = 1
       AdcRegsFile       : > ADC,         PAGE = 1
       SpibRegsFile      : > SPIB,        PAGE = 1
       ScibRegsFile      : > SCIB,        PAGE = 1
       SpicRegsFile      : > SPIC,        PAGE = 1
       SpidRegsFile      : > SPID,        PAGE = 1
       I2caRegsFile      : > I2CA,        PAGE = 1 
                   
    /*** Code Security Module Register Structures ***/
       CsmPwlFile        : > CSM_PWL,     PAGE = 1
    }
    
    
     

    Thanks for your help. 

  • After looking at the code and disassembly I have come to the conclusion that your code has been written over by data or something else.  I say this as if you look at the first line it should be something like sub acc,#1 like the code but it is movl *XAR6++, XT.  On the other hand your code is where it is supposed to be so its unlikely to be a stack issue.

    I just had a thought.  After looking at your command file and the code this is in the section ramfuncs (code in Flash written to RAM).  Are you calling InitADC() before you are copying the functions from Flash to RAM?  If so, you are calling random data instead of code.  Move your MemCopy to be almost the first thing you do in your program.

    If that doesnt work try:

    1) Reload the program and run it until just after you copy ramfuncs to RAM.  In CCS go to 0x0080DB (_DSP28x_usDelay) and check its disassembly.  If it is not something similar to SUB ACC, #1(possibly DEC ACC - they are the same command) then you have a compile/link time issue.  If it is what it should be you have a run time issue.

    2) Run the example given by TI with 0 user code and then see if this occurs.  If it does, then its likely to be something at fault with their code otherwise its in your code.

    3) Plot a graph at 0x0080DB.  It may be garbage, but it may be familiar and help find out what data is wiping it over.

     

    Tim

  • Hi Tim,

    Thanks a lot for your help.  I am calling InitAdc before MemCopy but this is similar to what TI does with their Example_280xFlash.c example.  They initialize the peripherals and then do MemCopy.  I have attached the beginning of my code up to InitFlash.

    // Functions that will be run from RAM need to be assigned to 
    // a different section.  This section will then be mapped using
    // the linker cmd file.
    
    #pragma CODE_SECTION(ecap2_isr, "ramfuncs");
    #pragma CODE_SECTION(cpu_timer0_isr, "ramfuncs");
    #pragma CODE_SECTION(InitAdc, "ramfuncs");
    
    // Prototype statements for functions found within this file.
    interrupt void ecap2_isr(void);
    interrupt void cpu_timer0_isr(void);
    
    void InitECapture(void);
    void InitEPwmTimer(void);
    void InitMessage(void);
    void GetADC(void);
    void InitGenGpio(void);
    void Start_Motor (void);
    void Stop(void);
    void Fail(void);
    
    void ReceiveCANMsg(void);
    void SendCANMsg(void);
    Uint16 crc16(Uint32, Uint16);
    
    
    // Global variables 
    
    Uint16 CRC;
    
    
    // These are defined by the linker (see F2808.cmd)
    
    extern Uint16 RamfuncsLoadStart;
    extern Uint16 RamfuncsLoadEnd;
    extern Uint16 RamfuncsRunStart;
    
    
    void main(void)
    {
    
    // CAN stuff
     
       struct ECAN_MBOXES MBoxesShadow;
       struct ECAN_REGS ECanaShadow;
    
    // CRC test
    //	FlashAddr = &Flash;
    	CRC = crc16(FLASH_BASE, FLASH_SIZE);
    //	if (CRC != CRC)
    //	{
    //		Fail();
    //	}
    
    
      
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP280x_SysCtrl.c file.
       InitSysCtrl();
    
    // Specific clock setting for this example:
    
       EALLOW;
       SysCtrlRegs.HISPCP.all = ADC_MODCLK;	// HSPCLK = SYSCLKOUT/ADC_MODCLK
       EDIS;
    
    
    
    // Step 2. Initalize GPIO: 
       
       InitEPwm3Gpio();
       InitECap2Gpio();
       InitGenGpio();
       InitECanaGpio();
       InitMessage();
          
          
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts 
    
       DINT;
    
    // Initialize the 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 DSP280x_PieCtrl.c file.
    //   XIntruptRegs.XNMICR.bit.ENABLE = 1;
    //   XIntruptRegs.XNMICR.bit.SELECT = 0;
    
       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 DSP280x_DefaultIsr.c.
    // This function is found in DSP280x_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.ECAP2_INT = &ecap2_isr;
       PieVectTable.TINT0 = &cpu_timer0_isr;
       PieVectTable.SEQ1INT = &SEQ1INT_ISR;
       PieVectTable.SEQ2INT = &SEQ2INT_ISR;
       PieVectTable.ADCINT = &ADCINT_ISR;
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP280x_InitPeripherals.c
    
       InitEPwmTimer();    
       InitECapture();
       InitAdc();  
       InitECana();
       InitCpuTimers();   
    
    // Copy time critical code and Flash setup code to RAM
    // This includes the following ISR functions: epwm1_timer_isr(), epwm2_timer_isr()
    // epwm3_timer_isr and and InitFlash();
    // The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
    // symbols are created by the linker. Refer to the F2808.cmd file. 
    
       MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
    
    // Call Flash Initialization to setup flash waitstates
    // This function must reside in RAM
    
       InitFlash();
    
    ...

    Here is the same section of code from TI's Example_280xFlash.c example.

    // Functions that will be run from RAM need to be assigned to 
    // a different section.  This section will then be mapped using
    // the linker cmd file.
    #pragma CODE_SECTION(epwm1_timer_isr, "ramfuncs");
    #pragma CODE_SECTION(epwm2_timer_isr, "ramfuncs");
    
    // Prototype statements for functions found within this file.
    interrupt void epwm1_timer_isr(void);
    interrupt void epwm2_timer_isr(void);
    interrupt void epwm3_timer_isr(void);
    void InitEPwmTimer(void);
    
    // Global variables used in this example
    Uint32  EPwm1TimerIntCount;
    Uint32  EPwm2TimerIntCount;
    Uint32  EPwm3TimerIntCount;
    Uint32  LoopCount;
    
    // These are defined by the linker (see F2808.cmd)
    extern Uint16 RamfuncsLoadStart;
    extern Uint16 RamfuncsLoadEnd;
    extern Uint16 RamfuncsRunStart;
    
    void main(void)
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP280x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO: 
    // This example function is found in the DSP280x_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 the 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 DSP280x_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 DSP280x_DefaultIsr.c.
    // This function is found in DSP280x_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.EPWM1_INT = &epwm1_timer_isr;
       PieVectTable.EPWM2_INT = &epwm2_timer_isr;
       PieVectTable.EPWM3_INT = &epwm3_timer_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP280x_InitPeripherals.c
    // InitPeripherals();  // Not required for this example
       InitEPwmTimer();    // For this example, only initialize the ePWM Timers
    
    // Step 5. User specific code, enable interrupts:
    
    // Copy time critical code and Flash setup code to RAM
    // This includes the following ISR functions: epwm1_timer_isr(), epwm2_timer_isr()
    // epwm3_timer_isr and and InitFlash();
    // The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
    // symbols are created by the linker. Refer to the F2808.cmd file. 
       MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
    
    // Call Flash Initialization to setup flash waitstates
    // This function must reside in RAM
       InitFlash();
    

    I've not verified their Flash.c code works yet.  To verify their code means I have to remove all my wiring from the development kit so I don't risk shorting something out.  I've verified all the other functions I've used though and found their examples to work as advertised so far.  Incidentally, my code works fine if I program to RAM.  I only ran into issues when I tried to program to flash.  That's why I was pretty sure your original guess was correct (running into data space) and not some other bug in my code.  That being said, I'm sure the bug is in my code but it most likely has to do with how I'm moving flash to ram.

    Thanks again for your assistance.  I'll now start looking at your steps 1, 2, and 3 and see where that leads me.

  • Hi Tim,

    I just tried moving the InitAdc to after the MemCopy and I no longer get an illegal ISR.  Thanks for your help.  Now I have to figure out why the processor doesn't boot from flash.  Everything runs fine from flash but when it boots, I get nothing.  I can only run it from the debugger.

  • One reason may be the hardware boot mode.  Somewhere in the datasheet/technical guides will be a table with a few pull ups and pull downs you have to set for different boot modes (SCI, SPI, Flash, RAM, JTAG).  It is likely to be on JTAG at the moment which is why it works with the debugger and not stand alone.

    Tim

  • Hi Tim,

    I've been wondering about that for about  a month now.  I got the impression from the documentation that those 3 GPIOs were pulled up by internal pull-ups by default.  The development kit doesn't have any pull-ups for those three pins.  The development kit has pull-downs for those three pins but those pull-downs aren't connected unless I supply my own jumpers.  The 3 pins in question are not connected to anything outside the processor except the unconnected jumpers.

    Thanks,

    Rick

  • Rick,

    I am not familiar with the kit, but if the boot jumpers are left open I would guess they are pulled up inside the chip rather than floating.  I guess one way to test it is make/find a simple program which toggles a GPIO or LED and program this to flash.  Then have a look whether it works stand alone.  If it doesn't, maybe try pulling up the lines externally and see if that helps.  Otherwise I'm out of ideas unfortunately.

    As for the software side of things, your linker file has all the parts necessary to put the boot vector at the right location in boot to flash mode.  One thing is to possibly check if there is a branch instruction at 0x3F7FF6 (probably LB _CINT_00).  If this is not there then it may explain it not running, but I would think it is there if it runs fine in JTAG mode.

    Tim

  • Hi Tim,

    I just tested it with external pull-ups on the three pins in question and it still doesn't boot.  It appears to be doing something like it's lost or something.  Booting on JTAG is not an issue.  It's consistent and works fine.

    I wonder if I'm supposed to move the watchdog interrupt over to RAM also.  It too works fine in JTAG but I'm lost again.  I think my next promotion here is from 'intellect" to "idiot savant".  ;^)

  • I wouldn't worry about copying the watchdog interrupt into RAM.  It will work perfectly fine from flash.  Basically the idea of running from RAM is for one of three categories:

    1) Speed dependent/ frequent functions.  This is because RAM is faster and it simply cuts down on overhead running these from RAM.

    2) Cycle dependent - The delay_us function is an example.  It is designed to run a certain number of cycles to give a certain time delay.  Running this from Flash with its wait states and pipelining would give the wrong delay.

    3) Flash functions - You can't program/erase the flash from flash.

    The watchdog doesnt fall into one of the above categories so shouldn't need to be run from RAM. 

    However, it is worth testing if the watchdog is causing your issues.  I would suggest running a version with the watchdog disabled and see if you have any issues.  If the problem is fixed, you have found the source of your problem, if you still do you can probably disregard the watchdog as a source of issue.

     

    Tim

  • Converting Code to Run from Flash instead of RAM: Different CMD Linker File and MemCopy Needed

    I had this exact problem and was really confused.  I had been under the impression that all that was needed to switch from executing code from RAM to FLASH was to simply switch out the "_RAM" CMD linker file for the regular one for your chip.

     

    Now I understand that you also need to take care of loading functions defined as RAM functions in the "ramfuncs" section into RAM before they are executed, otherwise the function pointers point to RAM that is uninitialized garbage.  At least, I think that's right?  If something is declared in the ramfuncs section, it isn't also allocated in .text as a slower version backup, right?

     

    Doing a keyword search for "ramfuncs" in the DSP2802x_common directory yielded two files that make use of RAM functions.  One of them - as deduced earlier - was the _usDelay.asm that is called from the InitADC routine that needs a software delay during initialization of the Analog to Digital Converter.  I also stepped through and found my disassembly didn't match the C code window on that same line before I fixed it.

     

    The other file that used RAM functions was the _SysCtrl.c file.  Since InitSysCtrl() is called from every example code file in "step 1", I think the memcopy code needs to not only go before InitADC or any calls to usDelay, but also before InitSysCtrl.  So pretty much the first part of "Main()" after any variable declarations.

     

    Possible Bug in Example Code - Example_2802xFlash.c

    If that is true, then I concur that the Example_2802xFlash.c example code (directory TI\controlSUITE\device_support\f2802x\v129\DSP2802x_examples_ccsv4\flash_f28027) is in error and that the memcopy in Step 5 should go before the InitSysCtrl in Step 1.

     

    How to Implement MemCopy

    By looking at the Flash.c example, it looks like you need to do 3 things to get RAM functions to work.

    • Add the "_MemCopy.c" file to your project.
    • Add the external declarations.
      • // These are defined by the linker (see F2808.cmd)
        extern Uint16 RamfuncsLoadStart;
        extern Uint16 RamfuncsLoadEnd;
        extern Uint16 RamfuncsRunStart;
    • Add the call to MemCopy near the start of "main()"
      • MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

     

    My code seems to more or less work now, so I think the information is right, but please correct me if I'm wrong on any points.