cancel
Showing results for 
Search instead for 
Did you mean: 

Problem on Interrupt (VIC0 and VIC1)

acorradini9
Associate II
Posted on September 19, 2007 at 07:53

Problem on Interrupt (VIC0 and VIC1)

11 REPLIES 11
acorradini9
Associate II
Posted on May 17, 2011 at 09:33

My program have three routine of response to the interrupt:

1 routine) it is the routine of response to the interrupt TIMER0; programmed like PWM (VIC0).

2 routine) it is the routine of response to the interrupt TIMER3; programmed like cycle interrupt to 1mS (VIC0).

3 routine) it is the routine of response to the interrupt VIC1.10; programmed like interrupt on external entry. (P3.6 -- line 6 from WIU -- VIC1).

If I enable the interrupt of the first and of the second routine, all functions regularly.

If I enable the third also then, in casual way, it is had that the cpu jumps the address 0 (RESET).

It seem the problem in the document:

- STR91xF Errata sheet.

- STR91xF Rev B and D limitations and correction

- 12280.pdf pag.6.like ''Silicon limitations --> VIC interrupt controller wrong vector fetch''

but I have the D revisone already (on the micro appears number 631).

There is it a mode for resolve this problem?

Best Regards

acorradini9
Associate II
Posted on May 17, 2011 at 09:33

Example software that from the problem.

You read the line ''ReportToST.doc'' contained in STError.zip.

Where do I be making a mistake?

Best Regards

d_steffen
Associate II
Posted on May 17, 2011 at 09:33

Do you resolve this problem ?

I've also a reset problem If I use Timer and Uart interrupts.

Best regards

jiri23
Associate
Posted on May 17, 2011 at 09:33

Hi,

the solution is to assign the both DVAR registers to a dummy IRQ hanlers. In case of not using the library IRQ handler (so jumping directly to the ISRs), the VARs should be also written to 0 at the end of the dummy ISRs.

Jiri

d_steffen
Associate II
Posted on May 17, 2011 at 09:33

Hi Jiri,

that is not clear for me.

1.) I use the STLIB sources in my projects, which includes

f.e. the file IRQ.s and all the other STLIB assembly files.

2.) I use also the 91x_it.c file which includes all

interupthandlers.

3.) I use the Keil startup file Str91x.s which includes

following

....

;// Setup Library Exception Handlers

LEH_SETUP EQU 1

....

Vectors LDR PC, Reset_Addr

LDR PC, Undef_Addr

LDR PC, SWI_Addr

LDR PC, PAbt_Addr

LDR PC, DAbt_Addr

NOP ; Reserved Vector

LDR PC, IRQ_Addr

; LDR PC, [PC, #-0x0FF0]

LDR PC, FIQ_Addr

IF LEH_SETUP <> 0

EXTERN UndefHandler

EXTERN SWIHandler

EXTERN PAbtHandler

EXTERN DAbtHandler

EXTERN IRQHandler

EXTERN FIQHandler

ENDIF

Reset_Addr DCD Reset_Handler

Undef_Addr DCD UndefHandler

SWI_Addr DCD SWIHandler

PAbt_Addr DCD PAbtHandler

DAbt_Addr DCD DAbtHandler

DCD 0 ; Reserved Address

IRQ_Addr DCD IRQHandler

FIQ_Addr DCD FIQHandler

....

Please give an example for using the dummy interrupthandler

for my application.

Thank you and best regards

B.

jens239955_stm1
Associate II
Posted on May 17, 2011 at 09:33

Hello,

I use the Timer0 and the UART2 without any of the original STM libraries. The addresses of the ISR are directly programmed into the belonging registers, i.e. VIC1_VA2R = (dword)UART_vIsr; and VIC0_VA5R = (dword)TMR_vIsr;

In case of enabling both interrupts with high interrupt cycles (timer0 every 100µs, UART2 Rx with 115200 baud), the system runs only a few seconds until the UART2-ISR will be stopped.

Searching the problem, I generated three test signals (toggling external pins) in the Timer0-ISR, the UART2-ISR and the main(). After a few seconds of running the programm, the UART2 toggling stopps. With other words it looks like a UART2 interrupt disable. But the interrupt was definitely NOT disabled by the software.

Setting a breakpoint into the so called spuriuos interrupt routine the system halted at this point.

As a second step I made two ''spuriuos ISR'', one for VIC0 and one for VIC1, but only the VIC0 spurious ISR will be started. I programmed a dummy write to the belonging register (VIC0_VAR = 0;) and it seams, that the problem would have been fixed. Note: For testing purpose I counted the spurious interrupt events and I found more than 200 spurious ISR during a transfer of more than 500,000 bytes into UART2???

But then I tried to activate the I2C0. The I2C0 channel is located at VIC1.

Guess what happens if I enable the I2C0 ISR? Yeah, you are right, the UART2 - ISR will never be reached!!!!

That's awful. What in the hell is wrong with the VIC0 and/or VIC1 hardware logic? What does a spurious interrupt do? And why is there no documentation about that behavior available?

Questions about question and no answer.

Best regards,

Jens

P.S. Sorry about my harsh comments, but I spent lots of hours to look at a problem other micros don't have.

mark10
Associate II
Posted on May 17, 2011 at 09:33

Hi,

Spent a week on this issue and I think I have a workable workaround that does work. Tried all the idea's mentioned here but alas they don't work, so here's mine which has been working for more than 24 hours errors and all.

We all seem to have the same issue which is that occasionally the VIC0_VAR reports an address of 0x00000000 for what is an interrupt from VIC1 which is documented in the ST documents:

- STR91xF Errata sheet.

- STR91xF Rev B and D limitations and correction

- 12280.pdf pag.6.like ''Silicon limitations --> VIC interrupt controller wrong vector fetch''

I'm running an interrupt off the watchdog timer at a rate of 10mS and hammering characters out via UART0 also under interrupt. All the usual stuff interrupt enables, vector priority is set up as per the manual.

I'm using the Raisonance tool set with the GNU compiler.

This is my solution.

Set a common interrupt handler which is called for all interrupts, i.e

set the address at 0x0000018 to ''ldr pc,=KerCpuIrqHandler''

These are my vectors:

ldr pc,=ResetHandler

ldr pc,=UndefinedHandler

ldr pc,=SWIHandler

ldr pc,=PrefetchAbortHandler

ldr pc,=DataAbortHandler

nop

ldr pc,=KerCpuIrqHandler

ldr pc,=KerCpuFiqHandler

Set the VICx_VAiR register to the address of the function to handle the interrupt i.e.

VIC0_VA0R to the watchdog function and

VIC1_VA0R to the UART0 function

Code up the common interrupt handler as shown below:

typedef void (*TdVoidFuncPtrVoid)(void);

unsigned int irqcounter;

void KerCpuIrqHandler(void)

{

TdVoidFuncPtrVoid ptr0;

ptr0 = (TdVoidFuncPtrVoid)VIC0->VAR;

if(ptr0)

(*ptr0)();

else

{

ptr0 = (TdVoidFuncPtrVoid)VIC1->VAR;

irqcounter++;

if(ptr0)

(*ptr0)();

}

VIC0->VAR = 0;

VIC1->VAR = 0;

}

When the function is called via the jump from the IRQ vector it reads the VIC0_VAR register, if a non zero address is passed back then call the function at that address to service the appropriate interrupt, this would be the VIC0 or VIC1 interrupt (the way it should work).

If the returned address is zero then read the value from VIC1_VAR and run the function given by the address passed back as this is the VIC1 interrupt that needs to be serviced and is always returned.

I make tha assumption that as an interrupt is being serviced and the returned address from VIC0 is zero and I have interrupts enabled on VIC1 then this interrupt must be from from VIC1.

The variable ''irqcounter'' is incremented every time the VIC0_VAR zero address value is returned which with my code is about 5 failures per hour but the interrupt is served correctly.

My conclusion is that silicon wise something is going wrong with the daisy chaining of the 2 VIC controllers but the controllers are individually working OK.

Hope this solution helps, feedback would be much appreciated

Mark

d_steffen
Associate II
Posted on May 17, 2011 at 09:33

Hello,

my solution now, together with the STRLIB is using the following:

....

void DummyFuncVic0 ()

{

++Vic0Cnt;

}

void DummyFuncVic1 ()

{

++Vic1Cnt;

}

...

VIC0->DVAR = &DummyFuncVic0;

VIC1->DVAR = &DummyFuncVic1;

....

Vic0Cnt was incremented multiple times, in 2 hours 100 times or more.

Vic1Cnt was never incremented.

I use Timer3-, Uart0- and SPI0 interrupts.

Best regards

B.

[ This message was edited by: Barricade on 22-01-2007 19:16 ]

jens239955_stm1
Associate II
Posted on May 17, 2011 at 09:33

Hi,

As I wrote, I thought I have fixed the problem. Using two independend spurious ISR with updating the hardware logic at VIC0 and VIC1 looks like the solution I need.

But, adding the I2C0 to VIC1 (UART2 was still in use) shows the well known effect (ISR were lost).

Looking about the forum entries, I think some of the describted problems looks like basing on the same reason. There must be an error in the VICs!

Please have a look on my code fragments and say what is wrong with it:

static unsigned spuriousInterruptCount0 = 0;

void defaultISR0( void ) __attribute ((interrupt(''IRQ'')));

void defaultISR0( void ){

spuriousInterruptCount0++;

VIC0_VAR = 0;

}

static unsigned spuriousInterruptCount1 = 0;

void defaultISR1( void ) __attribute ((interrupt(''IRQ'')));

void defaultISR1( void ){

spuriousInterruptCount1++;

VIC1_VAR = 0;

}

....

VIC0_DVAR = (unsigned int)defaultISR0;

VIC1_DVAR = (unsigned int)defaultISR1;

VIC0_VA5R = (unsigned int)TMR_vIsr;

VIC1_VA2R = (unsigned int)UART_vIsr;

VIC1_VA2R = (unsigned int)I2C_vIsr;

As you see I'm not a friend of complex interrupt handlers, like the STM library.

I'm also wouldn't agree with some of describted solutions. I fear that the problem in the hardware interrupt handler was only covered not fixed!

Best regards,

Jens