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.

instruction RPTB seems to cause PC going crazy

Subject:               instruction RPTB seems to cause PC going crazy

Package:             TMS320F28069PZT
CA-31AYGRW
G4

CCS:                      Version: 6.1.1.00022

C Compiler:        c2000_6.2.5, no optimization

Math library:     basic rts2800_fpu32.lib

Emulator:            XDS200 USB JTAG (not relevant)

Hardware:          custom board

Symptoms:        It seems that the Program Counter (PC) goes crazy when 4 interrupts are nested and a RPTB instruction resides at a specific location and is executed 6 times. The issue happens ca. 10-15 minutes after reset. The issue does not happen anymore if either
1) the RPTB code is shifted by some words (e.g.2, 4, 6, 8), or
2) the fourth interrupt source is disabled, or
3) the RPTB
 
instruction is replaced by two NOPS, causing the block to be executed just once without modifying the mapping, or
4) the RPTB instruction is in place but executed just once or twice(?) (counter=0 or 1).

The application has been compiled without optimization. I have checked that the compiler inserts a PUSH RB code on every interrupt entry, as it should be.

The interrupts are nested as follows:
main(), interrupted by …
… timer1() = int.13, which calls SQRT() and is interrupted by …
… timer0() = int.1.7, interrupted by …
… adc() = int.1.1, interrupted by …
… SpiA_RX() = int.6.1

The math library function sqrt() which executes RPTB, resides in flash at address 0x3de67c. Displacing sqrt() by few bytes, the issue doesn’t happen anymore.

Thanks for any hint helping me out of the darkness :-)

  • Hi,

    Please check if you are disabling the interrupt before returning from nested interrupts. This is a requirement and if not done then an interrupt could interrupt the POP RB instruction which will impact the CPU operation (since that's not supported).

    Basically "if user has enabled the interrupt inside ISR (using EINT instruction) then they must disable interrupt (using DINT instruction) before existing the ISR to avoid unexpected issues. "

    Regards,

    Vivek Singh

     

  • Marco,

    Also, I notice you are prioritizing two group 1 interrupts (1.1 & 1.7) so presumably you are manipulating the PIEIER1 register.  I just want to check you are following the correct steps for doing that.  

    Please check section 1.6.3 in the F28069 device User's Guide for details.  My apologies if you have already done that.

    Regards,

    Richard

  • Hi Richard,

    many thanks for the fast feedback.
    To your question, I would say yes, as we are just modifying PIEIER1 following Texas recommendations, as follows

    interrupt void Timer0Isr (void) // this is PIE group1 interrupt 1.7
    L_TempSave = PieCtrlRegs.PIEIER1.all; // save current state for PIEIER1
    IER |= k_MaskInt1 + k_MaskInt6; // re-enable group INT1/INT6 in CPU
    IER &= k_MaskInt1 + k_MaskInt6;
    PieCtrlRegs.PIEIER1.all &= 1; // only INT1.1 in PIE GROUP 1
    PieCtrlRegs.PIEACK.all = 0xFFFF; // re-enable PIE interrupts
    __asm (" nop"); // wait 1 cycle for internal synchronization
    EINT; // global interrupt enable

    Regards,
    Marco
  • Hi Marco,

    As suggested in my post, have you made sure that interrupts are disable before existing of ISR? It'll be helpful if you could post the full ISR code.

    Regards,
    Vivek Singh
  • Hi Vivek,

    many thanks for your fast reply.
    Your comment seems to address exactly the issue I am experiencing. Nevertheless, there are some questions which remain unexplained. For instance

    - why displacing the sqrt() code by 2 words in the flash memory, the issue does not happens anymore?

    My question is not just academic. Modifying in some way the memory map, the issue could “disappear”, as I told you. Therefore, introducing a couple of DINT, it is possible that the issue is not anymore manifest, but then appears again in a successive release after having modified the program code with a displacement of the sqrt() in the memory map.

    Could you explain a relation between the RPTB issue and the position of the code in memory?

    Thank you so much for investing your time in investigating this strange behavior.
  • Hi Marco,

    As I mentioned issue occurs if "POP RB" instruction gets interrupted.

    Please refer the "POP RB" instruction definition in the CPU Instruction user guide for more detail on this.

    Now when you change the code it'll change the sequence of operation and it's possible that POP RB instruction may not get interrupted (interrupt will happen at some other place) so same issue will not be seen. 

    Hope that helps. Let us know if you have any further query on this.

    Regards,

    Vivek Singh

  • Hi Vivek,

    following your suggestion, and inserting a DINT just before exiting the interrupt procedures, the issue seems to be solved. Now, after more than 30 hours, the program is running very stable, compared to before when I had a watchdog each 15 minutes.

    I would say that this problem could have been solved by the c-compiler: it inserts automatically a POP RB instruction and does not precede this by a DINT instruction.

    any thanks for your support.
    Kind Regards,
    Marco
  • Hi Marco,

    Good to know issue is resolved and thank you for the update and feedback . We understand your concern and would forward your valuable feedback to our compiler team.

    Regards,
    Vivek Singh
  • It would be really great if the compiler would handle this. It keeps track of register usage and it knows when this is needed. Also this seems like silicon issue with SW workaround similar to inserting NOPs to solve the FPU pipeline issues, which compiler does happily.

    Regards, Mitja
  • We'll look into this. Thanks !!

    Regards,

    Vivek Singh

  • I also support the idea of handling the DINT in nested interrupts in the compiler very much!

    I've spent HOURS tracking down the problem, until I found information on your C2000 wiki page. I've read most of the compiler and assembly pdf's with no luck (later on I found some info in assembly doc when I know what to look for).

    I'm not sure if this information is treated with more attention in the compiler manual now, bot if not, it really deserves a lot of it.

    Best regards,

    Andy

  • I agree it is difficult issue to find. And while I can understand that there was probably a conscious decision to design a FPU with this issue, the description of it should be at least in the errata (though to the TI people this does not seem as a errata). To the user this seems like a silicon issue. It certainly is not a feature.

    I can also see that having the compiler meddling with DINT is not a smart thing to do (and the decision on this will be hard) one would appreciate a compiler warning (or even assembler warning).
  • All,

    Thank you all for valuable feedback. We have raised a request to take care of this in compiler and compiler team started looking into this. About documentation, we are planning to include this in device errata document (as "usage note").

    Regards,

    Vivek Singh