Hi
I am running a 1MHz CAN network with 9 nodes consisting of 28335 and 2809 micros. The bus time usage is around 60%. All messages use std 11 bit identifiers and 8 byte data fields
The master node does not use any CAN interrupts
The slave nodes (3 of) each have an ECAN0INTA interrupt which immediately grabs and uses the data
The master node has to transmit very time sensitive data for reception by 3 nodes (sent at 1kHz rate). This uses the lowest active CAN ID 64 so it should always be the next one to transmit if the bus is busy when it needs it. This tx mail box also has the TPL set to the maximum value.
All bus packet lengths are around 125uS (depending on bit stuffing) so in theory the max delay for ID64 should be around 125uS
The master node (blue/green trace) sets/clears a port pin each time the data is sent
Each slave node (orange trace) sets/clears a port pin when the data is received
Most of the time it works correctly. However, every few minutes the ID64 message will be delayed by up to 500uS
The attached scope shots show normal behaviour
7510.Simple tx method - Ideal timing.TIF
1680.Ref tx method - Ideal timing.TIF
Also attached is another shot where ID64 is delayed
2804.Simple tx method - ID64 delayed.TIF
7411.Ref method - ID64 delayed.TIF
In this example ID 131 starts transmitting on the bus just before ID64 is sent to the peripheral
When ID131 finishes, ID65 and ID227 are sent before ID64 is sent. My understanding is that ID65 and ID227 should yield and let ID64 go first.
It seems clear that the master node is delaying sending the ID64 packet.
The slave is ISR is responding correctly
The bus physical layer seems to be working correctly, because if I stop most of the other nodes from transmitting the then system works perfectly with a correct delay for ID64
#define CAN_PRIORITY_1 31
#define CAN_PRIORITY_2 30
#define CAN_PRIORITY_3 29
#define CAN_PRIORITY_4 28
#define CAN_PRIORITY_LO 0
#define BRAIN_INNER_VOL 64 //Lowest active CAN address
#define IAZ_BRAIN_ENC 65
void init_mailbox(void)
{
mailboxCana(CAN_MAILBOX_4, CAN_DIR_RX, IAZ_BRAIN_ENC, CAN_8BYTE, CAN_NO_MASK, CAN_PRIORITY_LO);
// And others
mailboxCana(CAN_MAILBOX_21, CAN_DIR_TX, BRAIN_INNER_VOL, CAN_8BYTE, CAN_NO_MASK, CAN_PRIORITY_1);
// And others
}
void init_cana(void)
{
InitECanaGpio(); // Init IO for CAN_A module
InitECana(); // Initialize eCAN-A module
ECanaRegs.CANRMP.all = 0xFFFFFFFF; // Clear the received message pending bits
ECanaRegs.CANTA.all = 0xFFFFFFFF; // Clear all transmit Ack (TAn) bits
// DSP CAN port_a MailBox and Bus Error Interrupt Initialisation
EALLOW;
ECanaRegs.CANOPC.all = 0xFFFFFFFF; // Set over write protect.
ECanaRegs.CANGIM.all = 0x00000000; // No interrupts enabled.
ECanaRegs.CANMIM.all = 0x00000000; // Disable Mailbox Interrupt for all 32 Mailboxes.
ECanaRegs.CANMIL.all = 0x00000000; // Enable Mailbox interrupt on INT0 line when set to 0
// Enable Mailbox interrupt on INT1 line when set to 1
EDIS;
}
main()
{
//extract from 1kHz loop
ClearDebugOutput(); // port pin
cana_tx(BRAIN_INNER_VOL, &data);
SetDebugOutput(); // port pin
}
void cana_tx(Uint16 message_id, CAN_DATA *tx_data)
{
union CANTA_REG can_ta_shadow;
union CANTRS_REG can_trs_shadow;
switch(message_id)
{
// ******* Simple tx method version
case BRAIN_INNER_VOL:
if(ECanaRegs.CANTRS.bit.TRS21 == 0){ // Check mailbox is empty
ECanaMboxes.MBOX21.MDL.all = tx_data->can.longs.value1; // Load first Long value
ECanaMboxes.MBOX21.MDH.all = tx_data->can.longs.value2; // Load second Long value
ECanaRegs.CANTRS.bit.TRS21 = 1;
}
break;
// ******* Ref tx method as per TI examples
case BRAIN_INNER_VOL:
if(ECanaRegs.CANTRS.bit.TRS21 == 0){ // Check mailbox is empty
ECanaMboxes.MBOX21.MDL.all = tx_data->can.longs.value1; // Load first Long value
ECanaMboxes.MBOX21.MDH.all = tx_data->can.longs.value2; // Load second Long value
can_trs_shadow.all = ECanaRegs.CANTRS.all;
can_trs_shadow.bit.TRS21 = 1;
ECanaRegs.CANTRS.all = can_trs_shadow.all;
do
{
can_ta_shadow.all = ECanaRegs.CANTA.all;
} while(can_ta_shadow.bit.TA21 == 0 ); // Wait for TAxx bit to be set..
can_ta_shadow.all = 0;
can_ta_shadow.bit.TA21 = 1; // Clear TAxx
ECanaRegs.CANTA.all = can_ta_shadow.all;
}
break;
default:
if(ECanaRegs.CANTRS.bit.TRS31 == 0){ // Check mailbox is empty
ECanaMboxes.MBOX31.MDL.all = tx_data->can.longs.value1; // Load first float value
ECanaMboxes.MBOX31.MDH.all = tx_data->can.longs.value2; // Load second float value
mailboxCana(CAN_MAILBOX_31, CAN_DIR_TX, message_id, CAN_8BYTE, CAN_NO_MASK, CAN_PRIORITY_LO);
ECanaRegs.CANTRS.bit.TRS31 = 1;
}
break;
}
}
Why is ID64 not always transmitted as soon as it is ready (following the end of the current packet)?
Thanks
Brent