Below is the code I've been using for several years without issues. Makes it easier to see that the initialization is exactly the same for each CAN port.
John
unsigned char *can_periph[5] = {
&CAN0CTL0,
&CAN1CTL0,
&CAN2CTL0,
&CAN3CTL0,
&CAN4CTL0
};
void
MSCANInit(BYTE can_num, BYTE rate) {
unsigned char *can_pt;
can_pt = can_periph[can_num];
ActiveCANDevices |= MASK_TABLE[can_num]; // Set this CANBus as initialized.
// If MSCAN peripheral is not in Initialization Mode, enables the Inizialization Mode Request
if(!(can_pt[CANCTL1]&CANCTL1_INITAK_MASK))
{
can_pt[CANCTL0] = CANCTL0_INITRQ_MASK;
while(!(can_pt[CANCTL1]&CANCTL1_INITAK_MASK))
;
}
// Enables MSCAN peripheral and chooses Oscillator Clock(16MHz), Loop Disabled and Normal Operation
can_pt[CANCTL1] = 0x80;
// Configures SJW = 3Tq and Prescaler = 1 (0x80 for 1Mbps), (= 2 (0x81 for 500kbps)
can_pt[CANBTR0] = rate;
// 1Mbps with 16Mhz clock, 16Tq per bit.
// Configures One Sample, Time Segment 1 = 12Tq and Time Segment 2 = 3Tq
can_pt[CANBTR1] = 0x2B;
// Disables all the Acceptance Filters by setting the masks to DON'T CARE.
can_pt[CANIDMR_1B+0] = 0xFF;
can_pt[CANIDMR_1B+1] = 0xFF;
can_pt[CANIDMR_1B+2] = 0xFF;
can_pt[CANIDMR_1B+3] = 0xFF;
can_pt[CANIDMR_2B+0] = 0xFF;
can_pt[CANIDMR_2B+1] = 0xFF;
can_pt[CANIDMR_2B+2] = 0xFF;
can_pt[CANIDMR_2B+3] = 0xFF;
// Restarts MSCAN peripheral and waits for Initialization Mode exit
can_pt[CANCTL0] = 0x00;
while(can_pt[CANCTL1]&CANCTL1_INITAK_MASK)
;
can_pt[CANRIER] = 0x3C; // Allow status changes to set the CSCIF which signals valid
// data in the CANRFLG
}