I am developing with the TMS570 using the IAR development environment and I am trying to use the "Error Forcing Mode" of the CCMR4 module to invoke an FIQ interrupt through the ESM.
I was successful in invoking the "Error Forcing Mode" of the CCMR4 and detecting the failure by polling the error flag in theESMSSR2 reg. However, when I initialize the VIM with an Interrupt Service Routine at vector 0 (not the Phantom vector) and enable the FIQ (clear the F bit in the CPSR), I cannot detect the error when forced. I also do not see the nERROR pin go active. It seems as if control vectors to somewhere because code immediately after the CCMR4Reg->CCMKEYR = 0x00000009 force does not execute yet I do not see control resume in the ISR. JTAG debugger is disconnected. I am using the LEDs of the reference board to debug.
Should I be able to catch this is an ISR? That interrupt is non-maskable (NMI) so I shouldn't have to do any other configuration to catch it correct? Using similar IAR code I was able to setup RTI and SCI low level interrupts so I'm fairly certain the VIM module is being setup correctly however after forcing the error, control seems to vector to an unknown location.
>>>>>>>>>>>>>>>> POLLING method successful <<<<<<<<<<<<
CCMR4Reg->CCMKEYR = 0x00000009;
if (esmREG->ESMSSR2 == (1 << CCM_R4_compare_ESM_Channel))
{ // // Clear the corresponding channel Group 2 ESM error by writing a 1 // to it. // esmREG->ESMSSR2 = (1 << CCM_R4_compare_ESM_Channel);
}
>>>>>>>>>>>>> INTERRUPT method unsuccessful <<<<<<<<<<<<<<<
typedef void(__irq __arm * p_intr_hadler_t)(void);p_intr_hadler_t * const IntTable = (p_intr_hadler_t *)&VIM_RAM_BASE;
// // Setup and enable the ESM interrupt & ISR // IntTable[1] = ESM_ISR_HI; // defined below
__enable_irq(); // defined below
;;; --------------------------------------------------------------;;;; void __enable_irq(void);; SECTION .text:CODE:NOROOT(2) CFI_ARM_BLOCK_start __iar_enable_irq CFI NoCalls ARM__iar_enable_irq:
#if !defined(__ARM6__) ;;ARM7, ARM9 and ARM10E MRS R12,CPSR BIC R12,R12,#0x0080 ;Clearss the I bit MSR CPSR_c,R12#else /* !defined(__ARM6__) */ ;;ARM11 CPSIE i ;Clears the I bit#endif /* !defined(__ARM6__) */ BX lr CFI_ARM_BLOCK_end __iar_enable_irq
/************************************************************************* * Function Name: ESM_ISR * Parameters: none * * Description: ISR * *************************************************************************/
__irq __arm void ESM_ISR_HI (void){ esmREG->ESMSSR2 = (1 << CCM_R4_compare_ESM_Channel); CCMR4Reg->CCCMSR = (1 << 16); __disable_fiq(); esmREG->ESMEKR = 0; // clear the error pin esmREG->ESMEKR = 5; // reset to normal state HET1DOUT_bit.HETDOUT29 = 1; // Set LED 29
Good afternoon:
We have received your post. We are reviewing it to provide an answer.
Regards,
Enrique Lizarraga
Correction to the code snippet I posted. I am calling __enable_fiq() not __enable_irq() to enable the FIQ interrupt. The __enable_irq() was used for the RTI and SCI interrupts. Here is the code for the __enable_fiq() routine which clears the F bit;
;;; --------------------------------------------------------------;;;; void __enable_fiq(void);; SECTION .text:CODE:NOROOT(2) CFI_ARM_BLOCK_start __iar_enable_fiq CFI NoCalls ARM__iar_enable_fiq:#if !defined(__ARM6__) ;;ARM7, ARM9 and ARM10E MRS R12,CPSR BIC R12,R12,#0x0040 ;Clearss the F bit MSR CPSR_c,R12#else /* !defined(__ARM6__) */ ;;ARM11 CPSIE f ;Clears the F bit#endif /* !defined(__ARM6__) */ BX lr CFI_ARM_BLOCK_end __iar_enable_fiq
Hello:
Could you share your code so we can try to replicate the behavior and provide you an answer?
Bruce,
The way the CCMR4 works, doesn't allow debug mode.
Will it be possible in your case to run your code, without stopping the CPU?In other words, can you set a break point in your ISR, run your code and will the CPU is running, assert a nRST to force the device to restart from reset.
I your code is correct, you should end up in your ISR.
Please let me know if this will help.
As Enrique asked you, sharing your project will be the best way to debug your problem.
Jean-Marc
Best regards,
Application Engineer
If my reply answers your question please click on the green button "Verify Answer".
The ISR does not appear to be invoked using the method you described or with the JTAG pod completely disconnecrted.
-BL
We will take a look into your code and let you know what we find.
Hello,
I noticed one thing that you declared the ESM_ISR_HI/LO as _irq while the ESM_ISR_HI will be executed as FIQ.
this may cause a problem for your return because the SPSR_FRQ is returned to your CPSR instead of SPSR_IRQ.
can you pls. double check this?
Henry Nguyen
Best Regards,
Application Engineers
Good catch on that however it did not solve the problem. But it leads to the question of how the IntTable should be defined if there are two different types for the table entries?
Here is the code as I retested it;
#include <texasinstruments/iotms570LS3137zwt.h>#include "ccmr4.h"#include "sci.h"#include "het.h"#include "esm.h"#include "arm_comm.h"typedef void(__fiq __arm * p_intr_hadler_t)(void);p_intr_hadler_t * const IntTable = (p_intr_hadler_t *)&VIM_RAM_BASE;//__irq __arm void ESM_ISR_LO (void);__fiq __arm void ESM_ISR_HI (void);//__irq __arm void SCI_RX_ISR (void);#if 0/************************************************************************* * Function Name: SCI_RX_ISR * Parameters: none * * Return: none * * Description: ISR * *************************************************************************/__irq __arm void SCI_RX_ISR (void){ unsigned int data; data = SCI1RD; // read the data transfered so as to clear RXRDY //esmREG->ESMEKR = 0; // clear the error pin// esmREG->ESMEKR = 5; // reset to normal state // HET1DOUT_bit.HETDOUT17 = 1; // set LED 17 // HET1DOUT_bit.HETDOUT0 = 1; // set led 0 // // Force the CCM-R4 error by setting "Error Forcing Mode" // in the CCM-R4 module. // /* set system mode */ // asm(" mrs r0, spsr"); // Get copy of Program Status Register // asm(" bic r0, r0, #0x1f"); // Clear mode bits // asm(" orr r0, r0, #0x1f"); // Set System Mode // asm(" msr spsr, r0"); // Write back modified SPSR __no_operation();// CCMR4Reg->CCMKEYR = 0x0000000F; // force the CCM-R4 error // REQENACLR0 = 1 << VIM_LIN0; }/************************************************************************* * Function Name: ESM_ISR_LO * * Description: ISR * *************************************************************************/__irq __arm void ESM_ISR_LO (void){ HET1DOUT_bit.HETDOUT0 = 1;}#endif 0/************************************************************************* * Function Name: ESM_ISR_HI * * Description: ISR * *************************************************************************/__fiq __arm void ESM_ISR_HI (void){// esmREG->ESMSSR2 = (1 << CCM_R4_compare_ESM_Channel);// CCMR4Reg->CCCMSR = (1 << 16); // esmREG->ESMEKR = 0; // clear the error pin // esmREG->ESMEKR = 5; // reset to normal state HET1DOUT_bit.HETDOUT29 = 1; // Set LED 29 }/*************************************************************************** Main**************************************************************************/int main(void){ // // Init HET1[00 & 29] for LEDs // HET1DOUT_bit.HETDOUT0 = 0; HET1DIR_bit.HETDIR0 = 1; HET1DOUT_bit.HETDOUT29 = 0; HET1DIR_bit.HETDIR29 = 1; // // Init the SCI module. // sciInit(); // // Init the ESM module. // esmInit(); // // Turn off all the LEDs // hetREG->DIR = 0xAA178035; hetREG->DOUT = 0x08110034; // take all LEDs low esmREG->ESMEKR = 0; // clear the error pin esmREG->ESMEKR = 5; // reset to normal state // // Setup and enable the ESM interrupt & ISR // IntTable[1] = ESM_ISR_HI; // IntTable[20 + 1] = ESM_ISR_LO; // ESM Low Level Int is VIM interrupt/channel 20 // // Setup and enable the SCI Rx interrupt & ISR // // IntTable[VIM_LIN0 + 1] = SCI_RX_ISR; // REQENASET0 = 1 << VIM_LIN0; //__enable_interrupt(); //__enable_irq(); __enable_fiq(); while(1) { CCMR4Reg->CCMKEYR = 0x00000009; // Should invoke the ESM_ISR_HI ISR esmREG->ESMEKR = 0x0A; __no_operation();#if 0 HET1DOUT_bit.HETDOUT31 =1; // // Check the ESM module for an error. // if(esmREG->ESMSSR2 == (1 << CCM_R4_compare_ESM_Channel)) { // // Clear the corresponding channel Group 2 ESM error by writing a 1 // to it. // // esmREG->ESMSSR2 = (1 << CCM_R4_compare_ESM_Channel); // // Indicate a failure. // HET1DOUT_bit.HETDOUT31 =1; // light led at 3'oclock pos } else { // HET1DOUT_bit.HETDOUT31 =1; // clear led at 3'oclock pos HET1DOUT_bit.HETDOUT17 = 0; // set LED 17 }#endif }}
In order to use a FIQ or IRQ interrupt, you need to first enable FIQ or IRQ in Cortex R4's CPSR register then follow the steps described in the following forum thread,
http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/183311.aspx
Here is an example of assembly code for a FIQ or IRQ ISR (assuming that data_proc() is a 32 bit function)
.global FIQ_IRQ_ISR
.global data_proc
FIQ_IRQ_ISR:
stmfd sp!,{r0-r11, LR} ; Store registers onto stack
BL data_proc
ldmfd sp!,{r0-r11,LR}
SUBS PC, LR, #4
Regards