MsCAN Tx Interrupt question

Started by apedroso11 June 7, 2006
Hi all,

I've been working on a MsCAN driver for DP256. I am going over it and
I have some questions:

The MSCAN Block Guide V02.15 says that TX interrupt must be
acknowledged by clearing the corresponding flag CANTFLG.

1. Should I ack the tx interrupt doing CANTFLG |= CANTFLG; ?
this way I set the empty buffers ready for tx.

2. I only must clear the bit causing the interrupt, but how can I
recognise it?

the following code shows how I was managing the TX Isr:

//looks for empty buffer for tx
CAN0BSEL = CAN0FLG;

if there's no message in TX user fifo
{
CANTIER = 0x00; // Disable all TX interrupts (***)
// I'm disabling all tx ints. Is it correct????
// Ack interrupt????
}
else // there is a queued message to tx
{
update tx user fifo indexes
CAN0TXFG = user fifo message;
CAN0TFLG = CAN0TBSEL; // Set ready for tx (ACK interrupt)
CAN0TIER |= CAN0TBSEL; // Enable tx interrupt for this buffer
}

3. Should I ack the interrupt instead of disabling it in line ***?

thanks

Hi,

I know how difficult it is to distill the essential bits out of the
Freescale MSCAN doc. It is all there, but Freescale doesn't go the
extra mile to provide decent example code for S12 in any app notes I've
found. This is my ICC12 tx isr for CAN0:

#pragma interrupt_handler can0TxHandler
void can0TxHandler (void)
{
uint8 i, buf_num, can_tx_msg[16];

if (canBufRead (can_dev[CAN0].tx_buf_id, (can_msg_t*)can_tx_msg) =SUCCESS)
{
/* Select CAN transmit buffer */
buf_num = CAN0TFLG;
CAN0TBSEL = buf_num;
buf_num = CAN0TBSEL;

/* Copy message */
if (can_dev[CAN0].id_type == CAN_STD)
{
*CAN0TXFG = can_tx_msg[0];
*(CAN0TXFG + 1) = can_tx_msg[1];
}
else
{
*CAN0TXFG = can_tx_msg[0];
*(CAN0TXFG + 1)= can_tx_msg[1];
*(CAN0TXFG + 2)= can_tx_msg[2];
*(CAN0TXFG + 3)= can_tx_msg[3];
}

for (i = 0; i < can_tx_msg[12]; i++)
{
*(CAN0TXFG + i + 4) = can_tx_msg[i + 4];
}

/* Set pointer to length field */
*(CAN0TXFG + 12) = can_tx_msg[12];

/* set tx priority */
*(CAN0TXFG + 13) = can_tx_msg[13];

/* Send message */
CAN0TFLG = buf_num;
}
else
/* Disable CAN Tx interrupt */
CAN0TIER = 0;
}

CAN0TIER is set at time of successful write to tx buffer. I leave the
buffer implementation details to you.

-rob

apedroso11 wrote:

> Hi all,
>
> I've been working on a MsCAN driver for DP256. I am going over it and
> I have some questions:
>
> The MSCAN Block Guide V02.15 says that TX interrupt must be
> acknowledged by clearing the corresponding flag CANTFLG.
>
> 1. Should I ack the tx interrupt doing CANTFLG |= CANTFLG; ?
> this way I set the empty buffers ready for tx.
>
> 2. I only must clear the bit causing the interrupt, but how can I
> recognise it?
>
> the following code shows how I was managing the TX Isr:
>
> //looks for empty buffer for tx
> CAN0BSEL = CAN0FLG;
>
> if there's no message in TX user fifo
> {
> CANTIER = 0x00; // Disable all TX interrupts (***)
> // I'm disabling all tx ints. Is it correct????
> // Ack interrupt??? ?
> }
> else // there is a queued message to tx
> {
> update tx user fifo indexes
> CAN0TXFG = user fifo message;
> CAN0TFLG = CAN0TBSEL; // Set ready for tx (ACK interrupt)
> CAN0TIER |= CAN0TBSEL; // Enable tx interrupt for this buffer
> }
>
> 3. Should I ack the interrupt instead of disabling it in line ***?
>
> thanks
>
>

> 1. Should I ack the tx interrupt doing CANTFLG |= CANTFLG; ?
> this way I set the empty buffers ready for tx.
>
As a general rule, don't ever acknowledge an interrupt with "X |= X".
Always use the form "X = bit_mask".

> 2. I only must clear the bit causing the interrupt, but how can I
> recognise it?
>
Enable the interrupt by setting a flag in the interrupt enable
register for that peripheral. For the HCS12, it is called CANRIER.
Gary Olmstead
Toucan Technology
Ventura CA