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.

WFI instruction goes to undefined interruption

Hello,

First of all thank you for always answering my questions extremely fast and sorry for bombarding you with questions every day.

The question today is:

- Why does the WFI instruction (going into idle mode during stc self check) causes an undefined interruption? This just causes the boot process to stop and it doesn't reset.

void stcSelfCheck(void) {
    unsigned int i;

    SYSReg2->STCCLKDIV = (0x3U << 24);

    STCReg->STCGCR0 = (1U << 16U)
                        | 1U;

    STCReg->STCSCSCR = 0x1AU;   
    STCReg->STCTPR = 0xFFFFFFFFU;

    for (i = 0U; i < (32U); i++)
    STCReg->STCGCR1 = 0xAU;
    for(i = 0U; i < 32U; i++);
   
    asm("	WFI");										/*Idle the CPU so that the self-test can start*/
	asm("	NOP");
	asm("	NOP");
	asm("	NOP");
	asm("	NOP");

}

I really don't understand what's going on. This behaviour occurs every single time the system is booting when it should've gone into reset due to the stc self check

EDIT:

Which is strange, because whenever I execute the stcSelfCheck, it changes SYSESR (@0xFFFFFFE4) to 0x20, which means that a CPU reset occured (bit 5 of SYSESR), which, in turn, means that a reset occurred, but instead of going to address 0x0 it goes into the next form of interruption (undefined)

  • Checking everything more carefully I can see that de LR register contains the address for:

    fmdrr d0, r0, r0

    Which is  the first instruction for initializing the floating point registers. And I already checked that the error occurs. When the application goes into the undefined interrupt I force the application into going to the reset interruption (@0x0). Then I go instruction by instruction and I see that the fmdrr instruction actually generated the undefined interrupt, which is strange, because when I execute the code the first time this doesn't happen. 

    Any ideas?

  • Pablo,

    What part/board are you running this code on?  We have some devices without FPU...

     

  • Hitex safety development kit. RM48L952ZWT.

    As far as I know this part has an FPU. And when I execute the instruction the first time it works perfectly, the problem lies when I execute it a second time.

  • Initially I thought it was the wfi instruction, because whenever I executed a step on it, it went into an undefined interruption, but when I checked more carefully I noticed that it gave me address for the fmdrr instruction, which is strange, because it was running perfectly.

    When I forced the PC register to this instruction I noticed that it actually had gone into undefined interruption. This only happens after the STC self check.

  • Pablo,

    Ok. Yes it does include an FPU.  

    The FPU has to be enabled, and it might also be setup for privilege access only.

    The 2nd time you run the instruction and you get the undefined exception,  right before you execute the instruction you should check the settings of the FPU.

    The VFP is coprocessor 10-11.  You can check the access rights to it in the coprocessor access register, CP15 C1,0,c0,2.  If it is set for privilege mode access and you're trying to run the 2nd instruction in user mode this might be the problem.

    Also check that the FPU is enabled.  I believe I've seen a case before where the FPU was enabled in the startup code but disabled afterwards in the OS scheduler of some RTOS -sorry I don't remember which though.   That might be going on here as well..  The enable is controlled by the EN bit of the FPEXC register.

    You can refer to the Cortex R4 and R4F Technical Reference Manual (from ARM Ltd.) for more information.  Use the r1p3 version.

  • Hello,

    I've checked and the VFP isn't enabled in the part. Which is strange because the first thing that happens is the function to enable the VFP.

    	mrc		p15,	#0,	r0,	c1,	c0,	#2		
    	orr		r0,	r0,	#0xC0000000
    	mcr		p15,	#0,	r0,	c1,	c0,	#2		
    mov r0, #0x40000000 fmxr fpexc, r0

    - I read FPEXC register and put it in r0

    - Enable bits 30 and 31 of FPEXC

    -Write r0 to FPEXC

    - Move 0x40000000 to r0 (Just EN bit)

    - Move it to FPEXC

    The first time around it works perfectly, but the second time it simply doesn't enable the VFP.

    Afterwards I tried inserting:

    	mrc		p15,	#0,	r0,	c1,	c0,	#2	

    Just to check if FPEXC was actually written. The first thing I noticed is that in the register watch during debug, it is possible to see the value 0x40000000 an it doesn't change, no matter what I do to it (mcr instruction) and when I read it to a register AFTER I've written to it, I can see that it has the value 0x00F00000 in it, which doesn't coincide with what is written in the watch window in the debug mode.

    PS: I am in supervisor mode (M=10011)

  • Hi Pablo,

    What's the next step?  I'd assume it would be to understand where the FPU is being disabled, but I didn't completely understand your observations.

     

  • First of all, thnak you very much for your attention.

    Second, sorry for my english, but as you can see it's not my first language, so maybe I didn't take enough time to write my observations. So here it comes:

    - I thought it was strange that, even though I was enabling the VFP, an error occurred whenever i tried to write to the VFP. It was my mistake, I was writing the wrong value to CPACR when enabling the VFP coprocessor. It was a typo that was killing my application and it took me a while to find the error.

    - I thought that the watch window in CCS wasn't matching the value I was reading. Again, it was a typo, I added an extra 0 (zero) in my code, which was killing my attempts to write/read to/from fpexc.

    It was just a careless typo that was defeating me. Sorry for taking such a long time for a simple mistake.

  • Pablo,

    No need to apologize.  I also missed the typo and sometimes the hardest problems are the ones that are staring you in the face but for some reason you just miss seeing them for a while.
    Glad you're up and going again and don't hesitate to keep posting!