This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I have one issue regarding the CAN “Receive” Interrupt service routine for TMS320F2812. Actually my customer is unable to invoke CAN ISR for Receiving the data.
The example program Ecanback2back is on polling and they have implemented that. The polling CAN reception is working absolutely fine thus conforming that hardware is alright.
But they are unable to invoke the reception interrupt for CAN. It actually is unable to come out of initialization mode and go to normal mode. It hangs in the InitECan routine’s on this set of code lines:
// Wait until the CPU no longer has permission to change the configuration registers
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while(ECanaShadow.CANES.bit.CCE != 0 ); // Wait for CCE bit to be cleared..
The response from TI help-desk is to use polling for reception because there seems some issue with CAN reception ISR. They have given sample example for CAN transmission ISR which they are trying to invoke but their application needs as of now only the receive interrupt.
Awaiting your response.
If the code hangs in this loop, the CAN initalization has failed. There is no issue with CAN reception ISR whatsoever; it is working perfect in hundreds of customer projects. Where did you get this information from?
I have attached an example for a 2812 duplex CAN transmit and receive interrupt. This example is taken from my lessons about C2000 CAN.
Regards
Frank Bormann
// // Lab CAN_5 : TMS320F2812 // (C) Frank Bormann // //########################################################################### // // FILE: Lab_CAN_5.c // // TITLE: DSP28 CAN Transmit and Receive with mailbox-interrupt // - mailbox-interrupts with low priority ECAN1INTA // Receive-MBX1 and Transmit-MBX5 -> I1EN // Extended CAN-Frame transmit @ 100kbps // // CAN-Transmit (MBX5): identifier 0x1000 0000 // incremental 8-bit-pattern; rate 1 per second // // CAN-Receive (MBx1): identifier 0x1100 0000 // - mailbox interrupt request to read out the mailbox // - Byte 0 displayed at GPIO-B7 to B0 (LED�s) // - local acceptance mask // 1. enable only messages with identifier 0x1100 0000 // 2. enable messages with identifier 0x1100 0000, // 0x1100 0001, // 0x1100 0004 // LAMI = 1: Local-acceptance-mask identifier extension bit // // DLC = 1 // // Frequency Osscillator : 30MHz // PLLCR = 0xA : multiply by 5 // SYSCLKOUT = CLKIN = 150MHz // Highspeed - Prescaler (HISPCP = 0x0001; div by 2 ) : 75 Mhz // Lowspeed - Prescaler (LOSPCP = 0x0002; div by 4 ) : 37.5 Mhz //########################################################################### // // Ver | dd mmm yyyy | Who | Description of changes // =====|=============|======|=============================================== // 1.0 | 09 May 2003 | F.B. | Startup Version for Lab_CAN_1 // 2.0 | 27 Nov 2003 | F.B. | adapted to header-files Version 1.00 // 2.1 | 21 Oct 2007 | F.B. | incremental pattern // | | | //########################################################################### #include "DSP281x_Device.h" #define TRANSMIT_IDENTIFIER 0x10000000 #define RECEIVE_IDENTIFIER 0x11000000 // external prototypes void InitSysCtrl(void); void InitPieCtrl(void); void InitPieVectTable(void); // local prototypes. void Gpio_select(void); void MyInitCan(void); void MyPrepareMailboxes(void); interrupt void cpu_timer0_isr(void); interrupt void ecan1intA_isr(void); // Global Variables struct ECAN_REGS ECanaShadow; int CanMBox5Quit=1; main() { int send_data = 0; // Payload for Mailbox 5 // Initialize System Control registers, PLL, WatchDog, Clocks to default state: // This function is found in the DSP28_SysCtrl.c file. InitSysCtrl(); // Enable Watchdog EALLOW; SysCtrlRegs.WDCR= 0x00AE; EDIS; // Initialise the physical pins of the DSP Gpio_select(); // Initialize Interrupt System PIE InitPieCtrl(); InitPieVectTable(); // Overload CPU Timer 0 and CAN1 ISR - entry EALLOW; PieVectTable.TINT0 = &cpu_timer0_isr; PieVectTable.ECAN1INTA = &ecan1intA_isr; EDIS; // Iitialize CPU - Timer system InitCpuTimers(); // Initialize the CAN module MyInitCan(); // Prepare mailboxes in use MyPrepareMailboxes(); // enable interrupt lines PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // TINT0 PieCtrlRegs.PIEIER9.bit.INTx6 = 1; // ECAN1INTA IER |= 0x0101; EINT; // setup CPU-Timer 0 to 50 ms ConfigCpuTimer(&CpuTimer0,150,50000); CpuTimer0.InterruptCount =0; CpuTimer0Regs.TCR.bit.TSS = 0; while(1) { if(CpuTimer0.InterruptCount >= 20) { CpuTimer0.InterruptCount = 0; if(CanMBox5Quit == 1) // prev. transmission completed { CanMBox5Quit=0; ECanaMboxes.MBOX5.MDL.byte.BYTE0 = send_data & 0x00FF; ECanaShadow.CANTRS.bit.TRS5 = 1; ECanaRegs.CANTRS = ECanaShadow.CANTRS; send_data++; // next payload send_data %= 256; // limit to 8 bit GpioDataRegs.GPBTOGGLE.bit.GPIOB0 = 1; } } EALLOW; SysCtrlRegs.WDKEY = 0x55; // service half of WD EDIS; } } void Gpio_select(void) { EALLOW; GpioMuxRegs.GPAMUX.all=0; GpioMuxRegs.GPBMUX.all=0; GpioMuxRegs.GPDMUX.all=0; GpioMuxRegs.GPEMUX.all=0; GpioMuxRegs.GPFMUX.all=0; // Port F is the CAN-Port GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1; GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1; GpioMuxRegs.GPGMUX.all=0; GpioMuxRegs.GPADIR.all=0; // GPIO PORTs as input GpioMuxRegs.GPBDIR.all=0x00ff; // GPIO Port B15-B8 input , B7-B0 output GpioMuxRegs.GPDDIR.all=0; GpioMuxRegs.GPEDIR.all=0; GpioMuxRegs.GPFDIR.all=0; GpioMuxRegs.GPGDIR.all=0; GpioMuxRegs.GPAQUAL.all=0; // Set GPIO input qualifier values GpioMuxRegs.GPBQUAL.all=0; GpioMuxRegs.GPDQUAL.all=0; GpioMuxRegs.GPEQUAL.all=0; GpioDataRegs.GPBDAT.all = 0x0000; // Switch off LED's ( B7...B0) EDIS; } void MyInitCan(void) { EALLOW; ECanaRegs.CANTIOC.bit.TXFUNC = 1; ECanaRegs.CANRIOC.bit.RXFUNC = 1; ECanaRegs.CANMC.bit.SCB = 1; // HECC mode ECanaRegs.CANMC.bit.CCR = 1; while(ECanaRegs.CANES.bit.CCE == 0); ECanaRegs.CANBTC.bit.BRPREG = 99; ECanaRegs.CANBTC.bit.TSEG1REG = 10; ECanaRegs.CANBTC.bit.TSEG2REG = 2; ECanaRegs.CANBTC.bit.SJWREG = 1; // SJW = 2*Tq ECanaRegs.CANBTC.bit.SAM = 0; // one sample at sample point ECanaRegs.CANMC.bit.CCR = 0; while(ECanaRegs.CANES.bit.CCE == 1); ECanaRegs.CANME.all = 0; //disable all mailboxes // Mailbox-Interrupt ECanaShadow.CANMIM.all = 0; ECanaShadow.CANMIM.bit.MIM1 = 1; // MB#1 Mailbox interrupt is enabled ECanaShadow.CANMIM.bit.MIM5 = 1; // MB#5 Mailbox interrupt is enabled ECanaRegs.CANMIM.all = ECanaShadow.CANMIM.all; ECanaShadow.CANMIL.all = 0; ECanaShadow.CANMIL.bit.MIL1 = 1; // Int.-Level MB#1 -> I1EN ECanaShadow.CANMIL.bit.MIL5 = 1; // Int.-Level MB#5 -> I1EN ECanaRegs.CANMIL.all = ECanaShadow.CANMIL.all; ECanaShadow.CANGIM.all = 0; ECanaShadow.CANGIM.bit.I1EN = 1; // enable I1EN ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all; EDIS; } void MyPrepareMailboxes(void) { // ----------- use shadow-register ------------------------------- ECanaShadow.CANMD.all = ECanaRegs.CANMD.all; ECanaShadow.CANME.all = ECanaRegs.CANME.all; // MBX5 ECanaMboxes.MBOX5.MSGID.all = TRANSMIT_IDENTIFIER; ECanaMboxes.MBOX5.MSGID.bit.IDE = 1; // Extended Identifier ECanaMboxes.MBOX5.MSGCTRL.all = 0; ECanaMboxes.MBOX5.MSGCTRL.bit.DLC = 1; ECanaShadow.CANMD.bit.MD5 = 0; // transmit ECanaShadow.CANME.bit.ME5 = 1; // enable Mailbox #5 // MBX1 ECanaMboxes.MBOX1.MSGID.all = RECEIVE_IDENTIFIER; ECanaMboxes.MBOX1.MSGID.bit.IDE = 1; // Extended Identifier ECanaMboxes.MBOX1.MSGID.bit.AME = 1; // Acceptance Mask enable ECanaLAMRegs.LAM1.all = 0x00000005; // 0x1100 0000, // 0x1100 0001 // 0x1100 0004 // 0x1100 0005 ECanaLAMRegs.LAM1.bit.LAMI = 1; ECanaShadow.CANMD.bit.MD1 = 1; // receive ECanaShadow.CANME.bit.ME1 = 1; // enable Mailbox #1 // replace shadows in original Regs ECanaRegs.CANMD.all = ECanaShadow.CANMD.all; ECanaRegs.CANME.all = ECanaShadow.CANME.all; } //++++++++++++++++++++++++++++++++++++++++++++++++ // Interrupt Service Routines //++++++++++++++++++++++++++++++++++++++++++++++++ interrupt void cpu_timer0_isr(void) { EALLOW; SysCtrlRegs.WDKEY = 0xAA; EDIS; CpuTimer0.InterruptCount++; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } interrupt void ecan1intA_isr(void) { unsigned int mailbox_nr; mailbox_nr = ECanaRegs.CANGIF1.bit.MIV1; if(mailbox_nr == 1) // mailbox #1 receive message { GpioDataRegs.GPBDAT.all = ECanaMboxes.MBOX1.MDL.byte.BYTE0 & 0x000000FF; ECanaShadow.CANRMP.bit.RMP1 = 1; ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all; } if(mailbox_nr == 5) // mailbox #5 transmit-message { ECanaShadow.CANTA.all = 0; ECanaShadow.CANTA.bit.TA5 = 1; ECanaRegs.CANTA.all = ECanaShadow.CANTA.all; CanMBox5Quit = 1; } PieCtrlRegs.PIEACK.bit.ACK9 = 1; } //=========================================================================== // End of SourceCode. //===========================================================================
I purchased an F2812 Zwickau board last year to help start a
design project, and received a CD ROM with a seminar
authored by you, including a lot of source files.
But I can't find that file anywhere. The CAN examples all
use polling. Is it from a different seminar?
Yes, the files from the Teaching-CDROM are just simple examples and use CAN polling. You can use my attachment file from the previous reply above as an example for an interrupt driven CAN communcation. All the enhanced CAN examples are part of a separate seminar series.