Yahoo Groups archive

68300

Index last updated: 2026-04-29 00:01 UTC

Thread

Not able to clear pending CISR Flag in interrupt routine *>Help please

Not able to clear pending CISR Flag in interrupt routine *>Help please

2006-07-03 by Ivo Strebel

Hello 68300 community,

CPU: 68332

I have no clue what's going on. I use six TPU-Channels as UART (3*Rx,3*Tx).
At some point one of those channels * not always the same * is not able to delete 
his own CISR flag. This leads to an endless interrupt loop -> system crash. 

The CIER and the TICR register looks fine to me; they contain the same
value like before the crash. 

I even can not change the CISR flag with my debugger when the system
is in the endless interrupt loop. The CISR Flag of the hanging channel
seems to be kind of locked.

Note:
I reset the CISR Flag by doing  AND.W  #$FFFE,CISR  (for example)
It works half an hour ok, but at some point it hangs.

Please help me, why can't I clear the CISR Flag?

Ivo


-----------------------------------------------------
Ivo Strebel
SCHILLER AG, Altgasse 68, CH-6341 Baar
Phone +41 41 766 42 42 / Fax +41 41 761 08 80
Direct Phone / Voice Box +41 41 766 43 55
Ivo.Strebel@...  / www.schiller.ch

Re: [68300] Not able to clear pending CISR Flag in interrupt routine *>Help please

2006-07-13 by Andrei Chichak

Hi Ivo,

>I have no clue what's going on. I use six TPU-Channels as UART (3*Rx,3*Tx).
>At some point one of those channels * not always the same * is not 
>able to delete
>his own CISR flag. This leads to an endless interrupt loop -> system crash.

Did you ever get a response to this?

In a previous life, I used a 68332 do make 8 half uarts (4 
transmitters and 4 receivers). I set up the interrupt routines as 
macros to make sure that they all worked the same except for which 
parameter bank was used.

Below is the code for a receiver channel ISR. It is set up as a macro 
that took the channel number as a parameter. So the code 
RECEIVE_ISR(4) would generate an interrupt routine  void 
Tpu_uart_receive_4(void). This routine would then call 
TPUClearChannelIntStatus(4). As you can see below, this would do a 
tpu.CISR &= ~(1 << 4).

The transmit ISR was very similar.

My first hunch to your problem is that you are clearing the wrong bit 
in the CISR. The question is "how"?

If you are using a static variable for calculating the mask for 
clearing the CISR, it could be getting stompped on by another thread 
or interrupt routine.  One thread would calculate its mask then get 
interrupted, the other thread would calculate its mask and clear the 
bit then return, the original thread then clears the bit. Since the 
mask is static, the same mask is used by both threads. This can also 
happen if the mask is a global variable, but that is very bad style 
(for just this reason). A real computer geek would never use global 
variables, global variables are considered harmful.

It could be that you have a typeo in one of your routines and you are 
clearing the bit for the wrong channel. This sort of error is common 
when one is not a real computer geek. Real computer geeks know that 
numbers start at 0 and not 1. So the flag for channel 4 is the 5th bit.

I hope you found a solution.

Andrei


#define RECEIVE_ISR(chan) \
void Tpu_uart_receive_ ## chan(void) \
{\
         register INT16U reg;\
         TPUClearChannelIntStatus( (INT8U)(chan)); \
         reg = TPUGetChannelParam( (INT8U)(chan), PARAM_DATA_REG); \
         reg = reg & 0x00FF; \
         if ((INT16U) ((INT16U) tpu_rx_in_ptr[(INT16U)(chan)] + 1) != 
((INT16U) tpu_rx_out_ptr[(INT16U)(chan)]))                 /* See if 
there's still room in the buffer */ \
         { \
                 tpu_uart_input_buffer[(INT16U)(chan)][(INT16U)tpu_rx_in_ptr[(INT16U)(chan)]] 
= (INT8U) reg;             /* Put the character into the buffer, and ... */ \
                 tpu_rx_in_ptr[(INT16U)(chan)] = (volatile INT8U) 
((tpu_rx_in_ptr[(INT16U)(chan)] + 1) % TPU_BUFFER_SIZE); \
         } \
}

void TPUClearChannelIntStatus( TPU_CHANNEL channel)
{
#ifdef RAM
         if ( (INT16U) channel > 15) {
                 LogError(EL_APP_575);
         }
#endif
         tpu.CISR &= (INT16U) ~(1U << channel);
}

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.