On Fri, 23 Jan 2009 09:24:44 -0600, "Hagar"
<mm283729@spamcorptastic.com> wrote:
>It worked!
>
>extern "C" __irq __arm void IRQ_Handler();
>
>Thank you so much!
>It was driving me crazy since yesterday!
I see Leo beat me to it. I'm glad the solution was simple. I was
worried that the C code was doing something that breaks in C++.
Most people forget (or never knew) that C++ isn't a superset of C.
The functional overlap is better than 99% but not all C code is legal
C++ and some which is legal doesn't work the same.
George
It worked!
extern "C" __irq __arm void IRQ_Handler();
Thank you so much!
It was driving me crazy since yesterday!
Reply by ●January 23, 20092009-01-23
> __irq __arm void IRQ_Handler()
Check in your map file that this function is actually linked in.
If not, try:
extern "C" __irq __arm void IRQ_Handler()
Leo Havm�ller.
Reply by Hagar●January 23, 20092009-01-23
================ C++ ===============================
//IDE libraries
#include "QuantumCanStack.h"
#include "Can.h"
#include "Clock.h"
//################### Functions Prototypes ##################
void systemInit(void);
//###########################################################
Clock clock;
Can can;
int main()
{
systemInit();
__enable_interrupt();
HETDIR = 0xFFFFFFFF; // HETx Output direction
HETDOUT = 0xFFFFFFFF;
HETDOUT = 0x01;
while(1)
{
if (!(GIODINA & 0x04))
HETDOUT = 0x00;
if (!(GIODINA & 0x08))
HETDOUT = 0x01;
}
}
/**
Initializes the hardware
**/
void systemInit(void)
{
clock.init();
can.init();
//can.enableInterrupt(true);
}
__irq __arm void IRQ_Handler()
{
switch ((IRQIVEC & 0xff) - 1) // Convert IVEC index to
{ // CIM interrupt channel
case CIM_SCCB: // SCC interrupt B
HETDOUT = 0x00;
SCC1CANRMP = RMP0;
break;
}
}
========================== CAN Class =========================
#include "Can.h"
void Can::init(void)
{
//Function pins
SCC1CANTIOC = TXFUNC; //CANTX pin for CAN transmit functions
SCC1CANRIOC = RXFUNC; //CANRX pin for CAN receive functions
//Interrupt Configuration
SCC1CANMIL = MIL0; //Interrupt generated in Line 1
SCC1CANMIM = MIM0; //Enable interrupt for mailbox 0
SCC1CANGIM = I1EN; //Enable interrupt in Line 1
//Enable configuration mode. Activate auto bus on after bus off
condition
SCC1CANMC = CCR + ABO; //CCR = write access requested, set bus off
state.
//ABO = after bus off state automatically returns to bus on state
// Wait until CPU has access to CAN configuration registers
while(!SCC1CANES & CCE);
// Setup CAN bit timing for 125kbit/s according to CiA specifications:
// 8us nominal bit time w/ 16TQs/bit, sample point is located at 7us
(14TQ)
// BRP = 5 (Prescaler 6, w/ ICLK = 12MHz)
// Sample 3x, TSEG1 = 13, TSEG2 = 2, SJW = 1
SCC1CANBTC = (5 << 16) + SAM + TSEG1_13 + TSEG2_2 + SJW_1;
//Set local acceptance mask for mailbox 0
SCC1CANLAM0 = LAMI + 0x1FFFFFFF; //LAMI = extended and standard frames
can be received
//0x1FFFFFFF = receive any package
//Configure mailbox 0 for receive
SCC1CANMID0 = AME; //aceptance mask is used
//Can data register
SCC1CANMCF0 = 0x00;
SCC1CANMDL0 = 0x00;
SCC1CANMDH0 = 0x00;
//Configure maibox 0 for receive
SCC1CANMD = MD0; //receive mailbox
SCC1CANOPC = OPC0; //Protect against overwrite
SCC1CANME = ME0; //Enable mailbox 0
// Start CAN module
SCC1CANMC &= ~CCR;
while (SCC1CANES & CCE); //Wait until CAN module is started
REQMASK = (1 << CIM_SCCB);
}
void Can::enableInterrupt(bool b)
{
if(b)
REQMASK = (1 << CIM_SCCB);
else
REQMASK = (0 << CIM_SCCB);
}
Reply by Hagar●January 23, 20092009-01-23
Here the codes:
================== C Working Code =========================
//IDE libraries
#include "QuantumCanStack.h"
//################### Functions Prototypes ##################
void systemInit(void);
//###########################################################
int main()
{
systemInit();
__enable_interrupt();
HETDIR = 0xFFFFFFFF; // HETx Output direction
HETDOUT = 0xFFFFFFFF;
HETDOUT = 0x01;
while(1)
{
if (!(GIODINA & 0x04))
HETDOUT = 0x00;
if (!(GIODINA & 0x08))
HETDOUT = 0x01;
}
}
/**
Initializes the hardware
**/
void systemInit(void)
{
//Clock Init
GCR = 0x00000008;
PCR = 0x00000006|PENABLE;
// Use CANTX pin for the CAN transmit functions
SCC1CANTIOC = TXFUNC;
// Use CANRX pin for the CAN receive functions
SCC1CANRIOC = RXFUNC;
// Set SCC interrupt configuration. Mailbox 0 (receive mailbox) generates
// low-priority interrupts (int line 1 --> CIM_SCCB).
SCC1CANMIL = MIL0; // Use int line 1 for mbox 0
SCC1CANMIM = MIM0; // Enable int for mbox 0
SCC1CANGIM = I1EN; // Enable int line 1
// Setup master control register
// Enable configuration mode, activate auto bus on after bus off
condition
SCC1CANMC = CCR + ABO;
// Wait until CPU has access to CAN configuration registers
while (!(SCC1CANES & CCE));
// Setup CAN bit timing for 125kbit/s according to CiA specifications:
// 8us nominal bit time w/ 16TQs/bit, sample point is located at 7us
(14TQ)
// BRP = 5 (Prescaler 6, w/ ICLK = 12MHz)
// Sample 3x, TSEG1 = 13, TSEG2 = 2, SJW = 1
SCC1CANBTC = (5 << 16) + SAM + TSEG1_13 + TSEG2_2 + SJW_1;
// Setup local acceptance mask LAM0
// Receive any incoming standard/extended ID message
SCC1CANLAM0 = LAMI + 0x1fffffff;
// Configure mailbox 0 for receive
SCC1CANMID0 = AME; // Use acceptance mask LAM0
SCC1CANMCF0 = 0x00;
SCC1CANMDL0 = 0x00;
SCC1CANMDH0 = 0x00;
SCC1CANMD = MD0; // Use mbox 0 for RX
SCC1CANOPC = OPC0; // Protect against overwrite
SCC1CANME = ME0; // Enable mailbox 0
// Start CAN module
SCC1CANMC &= ~CCR;
// Wait until CAN module is started
while (SCC1CANES & CCE);
REQMASK = (1 << CIM_SCCB);
}
__irq __arm void IRQ_Handler()
{
switch ((IRQIVEC & 0xff) - 1) // Convert IVEC index to
{ // CIM interrupt channel
case CIM_SCCB: // SCC interrupt B
HETDOUT = 0x00;
SCC1CANRMP = RMP0;
break;
}
}
Reply by Hagar●January 22, 20092009-01-22
Hi George! Thanks for the fast response!
I know C and C++ aren't interchangeable. Sorry for bad explanation. I was
at work trying to solve this problems and didn't explained well.
I have got simple code from TI website which configures CAN module (SCC)
to receive any CAN message. This code works well if I use IAR C Compiler
Version 5.1, but if I create another project using IAR C++ Compiler it
doesn't recognizes CAN interruption. In fact, when the message is received
the software stops working, like if there wasn´t an IRQ routine!
In C project all the configurations and register's setups are made in only
one source file (main.c). In C++ project registers setup and configurations
are the same, the difference are, of course, the compiler and a "Can"
class. I'm sure the logic is the same (I've compared all the registers in
both projects and they are identical).
After many attempts to solve this (web researches, reference guide,
datasheets, help files...) I decided to test both codes in IAR Version 4,
which I have installed in an old machine, and both projects (C and C++)
worked well!
Reading IAR documents about the two versions (IAR V4 and V5) I didn't find
any huge difference that could interfere in V5 C++ Compiler. I suspect of
different startup operation (cstartup.s file) between this versions but
didn't find more explanations about it! Does anyone have some material
about startup code?
Summarizing:
- IAR Embedded Workbench V4: C and C++ projects working fine!
- IAR Embedded Workbench V5: Only C version works.
- The source codes used to test the different versions are the same!
- No errors or warnings are shown in either version.
- Code optimization is turned off.
- With IAR Version 5 and C++ project the Interruption Routine seems to be
"ignored" by the compiler (but it don't generate warning or errors).
- I'm using the same IAR Development Board to test both projects.
I'm at home now and don't have the code with me, but tomorrow I'll post
it.
Any idea that could show a new way?
Sorry for huge email and thanks a lot for your attention and time!
>On Thu, 22 Jan 2009 10:32:38 -0600, "Hagar"
><mm283729@spamcorptastic.com> wrote:
>
>>Hi all.
>>
>>I'm trying to use C++ and IAR for TMS470 uC's but I'm getting some
weird
>>troubles with C++.
>>
>>For example: I have a simple test code to receive CAN frames using
>>interrupts. It compiles ok but when the frame arrives the application
>>blows!
>>If I use the same logic and configurations with C compiler everything
>>works perfectly.
>>
>>I did a research for C++ Projects with TMS470 but didn't find
anything...
>>Do you have a link or a simple C++ IAR project using interrupts?
>>
>>
>>Any help will be appreciated!
>>
>>Thanks a lot!
>
>C and C++ aren't interchangeable. Can you post the code?
>
>George
>
Reply by George Neuner●January 22, 20092009-01-22
On Thu, 22 Jan 2009 10:32:38 -0600, "Hagar"
<mm283729@spamcorptastic.com> wrote:
>Hi all.
>
>I'm trying to use C++ and IAR for TMS470 uC's but I'm getting some weird
>troubles with C++.
>
>For example: I have a simple test code to receive CAN frames using
>interrupts. It compiles ok but when the frame arrives the application
>blows!
>If I use the same logic and configurations with C compiler everything
>works perfectly.
>
>I did a research for C++ Projects with TMS470 but didn't find anything...
>Do you have a link or a simple C++ IAR project using interrupts?
>
>
>Any help will be appreciated!
>
>Thanks a lot!
C and C++ aren't interchangeable. Can you post the code?
George
Reply by Hagar●January 22, 20092009-01-22
Hi all.
I'm trying to use C++ and IAR for TMS470 uC's but I'm getting some weird
troubles with C++.
For example: I have a simple test code to receive CAN frames using
interrupts. It compiles ok but when the frame arrives the application
blows!
If I use the same logic and configurations with C compiler everything
works perfectly.
I did a research for C++ Projects with TMS470 but didn't find anything...
Do you have a link or a simple C++ IAR project using interrupts?
Any help will be appreciated!
Thanks a lot!