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);
}