HCS12 banked model &  "near" function pointers

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HCS12 banked model &  "near" function pointers

Jump to solution
2,723 Views
Lundin
Senior Contributor IV
Environment: CW3.1 and/or CW4.7 for HCS12 (DG128).

I have a project where I am trying to make the entire code portable, as well as MISRA-C compliant. For this, I want to avoid as much non-standard C as possible. Codewarrior has plenty of smart solutions for this through the #pragma keyword. For example I can avoid the interrupt keyword entirely.

One thing I can't figure out however, is how to make function pointers portable. I have an interrupt vector table written in C with "near" function pointers. As I am using the banked memory model, I must explicitly declare them as near or the compiler will try to stuff a PPAGE address into them as well. Though for standard compliance, I don't want this "near" keyword.

I can place functions in non-banked segments by explicitly writing #pragma CODE_SEG NEAR. The actual ISR routines are located in CODE_SEG NEAR, for example. And the vectortable is allocated in CONST_SEG NEAR.

Is there an equivalent for this when it comes to function pointers?

Acceptable solutions would be #pragma or compiler/linker options. I realize it doesn't make sense to make a vectortable code portable, but it would save me a lot of fuss with static analyzers and such tools if the code was pure ISO C.
Labels (1)
Tags (1)
0 Kudos
1 Solution
645 Views
Lundin
Senior Contributor IV
Simply making an array of 16-bit integers solved the problem. Casts between function pointers and integers are well-defined in ISO C, and even if the function pointer happens to be a 24 bit one, it will be truncated into 16 bits. Though of course you will still need to allocate all ISR in non-banked memory.

So for the record, this is how you write a fully ISO C compliant vector table for HCS12 (D family) Codewarrior. The only thing I couldn't do in standard C was to set the stack pointer. Feel free to use the code in your own projects, and please let me know if you find any errors.

It comes with some useful practice for how to handle unused interrupts. It also allows you to replace the horrid "start12.c", assuming you aren't using any static initalization in your project.


/* .prm file */
SEGMENTS

    VECTOR_RESERVED
             = NO_INIT      0xFF80  TO    0xFF8B;
            
    VECTOR_TABLE
             = READ_ONLY    0xFF8C  TO    0xFFFF;

    ROM_4000 = READ_ONLY    0x4000  TO    0x7FFF;

    ROM_C000 = READ_ONLY    0xC000  TO    0xFEFF;

END


PLACEMENT

    INTERRUPT_ROM          INTO  ROM_C000;
    VECTORS                INTO  VECTOR_TABLE;

END



ENTRIES

    vector_table

END



/* vectortable_hcs12.h */

#ifndef _VECTORTABLE_HCS12_H
#define _VECTORTABLE_HCS12_H

/*** Include files ***/

#include "s12reg.h" /* your register map goes here */
#include "types.h" /* your uint16 etc typedef header goes here */


/*** Macros and numeric constants ***/

#define DEFAULT_VECTOR interrupt_unused


/*** Function prototypes ***/

#pragma CODE_SEG NEAR INTERRUPT_ROM

extern void interrupt_unused       (void);
 
extern void interrupt_reset        (void);
extern void interrupt_clock_fail   (void);
extern void interrupt_cop_reset    (void);
extern void interrupt_SWI          (void);
extern void interrupt_RTI          (void);
extern void interrupt_ECT_timer0   (void);
extern void interrupt_ECT_timer1   (void);
extern void interrupt_ECT_timer2   (void);
extern void interrupt_ECT_timer3   (void);
extern void interrupt_ECT_timer4   (void);
extern void interrupt_ECT_timer5   (void);
extern void interrupt_ECT_timer6   (void);
extern void interrupt_ECT_timer7   (void);
extern void interrupt_ECT_overflow (void);
extern void interrupt_ECT_PACA     (void);
extern void interrupt_ECT_PACIE    (void);
extern void interrupt_SPI0         (void);
extern void interrupt_SCI0         (void);
extern void interrupt_SCI1         (void);
extern void interrupt_PortJ        (void);
extern void interrupt_PortH        (void);
extern void interrupt_ECT_PACB     (void);
extern void interrupt_PLL_lock     (void);
extern void interrupt_SPI1         (void);
extern void interrupt_PortP        (void);

#pragma CODE_SEG DEFAULT

#endif /* _VECTORTABLE_HCS12_H */


 /* vectortable_hsc12.c */

#include "vectortable_hcs12.h"

/*** Function prototypes ***/

/* external interrupt routines */

#pragma CODE_SEG NEAR INTERRUPT_ROM

extern void main (void);

#pragma CODE_SEG DEFAULT



/*** Global constants ***/

#pragma CONST_SEG NEAR VECTORS

const uint16 vector_table[] =
{
  /*           */      /* $FF00:8B Reserved*/
  (uint16) DEFAULT_VECTOR,  /* $FF8C:8D PWM Emergency Shutdown */
  (uint16) interrupt_PortP, /* $FF8E:8F Port P Interrupt */
  (uint16) DEFAULT_VECTOR,  /* $FF90:91 MSCAN 4 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FF92:93 MSCAN 4 receive */
  (uint16) DEFAULT_VECTOR,  /* $FF94:95 MSCAN 4 errors */
  (uint16) DEFAULT_VECTOR,  /* $FF96:97 MSCAN 4 wake- up */
  (uint16) DEFAULT_VECTOR,  /* $FF98:99 MSCAN 3 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FF9A:9B MSCAN 3 receive */
  (uint16) DEFAULT_VECTOR,  /* $FF9C:9D MSCAN 3 errors */
  (uint16) DEFAULT_VECTOR,  /* $FF9E:9F MSCAN 3 wake- p */
  (uint16) DEFAULT_VECTOR,  /* $FFA0:A1 MSCAN 2 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FFA2:A3 MSCAN 2 receive */
  (uint16) DEFAULT_VECTOR,  /* $FFA4:A5 MSCAN 2 errors */
  (uint16) DEFAULT_VECTOR,  /* $FFA6:A7 MSCAN 2 wake-up */
  (uint16) DEFAULT_VECTOR,  /* $FFA8:A9 MSCAN 1 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FFAA:AB MSCAN 1 receive */
  (uint16) DEFAULT_VECTOR,  /* $FFAC:AD MSCAN 1 errors */
  (uint16) DEFAULT_VECTOR,  /* $FFAE:AF MSCAN 1 wake-up */
  (uint16) DEFAULT_VECTOR,  /* $FFB0:B1 MSCAN 0 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FFB2:B3 MSCAN 0 receive */
  (uint16) DEFAULT_VECTOR,  /* $FFB4:B5 MSCAN 0 errors */
  (uint16) DEFAULT_VECTOR,  /* $FFB6:B7 MSCAN 0 wake-up */
  (uint16) DEFAULT_VECTOR,  /* $FFB8:B9 FLASH */
  (uint16) DEFAULT_VECTOR,  /* $FFBA:BB EEPROM */
  (uint16) DEFAULT_VECTOR,  /* $FFBC:BD SPI2 */
  (uint16) interrupt_SPI1,  /* $FFBE:BF SPI1 */
  (uint16) DEFAULT_VECTOR,  /* $FFC0:C1 IIC Bus */
  (uint16) DEFAULT_VECTOR,  /* $FFC2:C3 DLC */
  (uint16) DEFAULT_VECTOR,  /* $FFC4:C5 SCME */
  (uint16) interrupt_PLL_lock, /* $FFC6:C7 CRG lock */
  (uint16) interrupt_ECT_PACB, /* $FFC8:C9 Pulse Accumulator B Overflow */
  (uint16) DEFAULT_VECTOR,  /* $FFCA:CB Modulus Down Counter underflow */
  (uint16) interrupt_PortH, /* $FFCC:CD Port H*/
  (uint16) interrupt_PortJ, /* $FFCE:CF Port J */
  (uint16) DEFAULT_VECTOR, /* $FFD0:D1 ATD1 */
  (uint16) DEFAULT_VECTOR, /* $FFD2:D3 ATD0 */
  (uint16) interrupt_SCI1, /* $FFD4:D5 SCI1 */
  (uint16) interrupt_SCI0, /* $FFD6:D7 SCI0 */
  (uint16) interrupt_SPI0, /* $FFD8:D9 SPI0 */
  (uint16) interrupt_ECT_PACIE, /* $FFDA:DB Pulse accumulator input edge */
  (uint16) interrupt_ECT_PACA, /* $FFDC:DD Pulse accumulator A overflow */
  (uint16) interrupt_ECT_overflow, /* $FFDE:DF Timer overflow */
  (uint16) interrupt_ECT_timer7, /* $FFE0:E1 Timer channel 7 */
  (uint16) interrupt_ECT_timer6, /* $FFE2:E3 Timer channel 6 */
  (uint16) interrupt_ECT_timer5, /* $FFE4:E5 Timer channel 5 */
  (uint16) interrupt_ECT_timer4, /* $FFE6:E7 Timer channel 4 */
  (uint16) interrupt_ECT_timer3, /* $FFE8:E9 Timer channel 3 */
  (uint16) interrupt_ECT_timer2, /* $FFEA:EB Timer channel 2 */
  (uint16) interrupt_ECT_timer1, /* $FFEC:ED Timer channel 1 */
  (uint16) interrupt_ECT_timer0, /* $FFEE:EF Timer channel 0 */
  (uint16) DEFAULT_VECTOR, /* $FFF0:F1 Real Time Interrupt */
  (uint16) DEFAULT_VECTOR, /* $FFF2:F3 IRQ */
  (uint16) DEFAULT_VECTOR, /* $FFF4:F5 XIRQ */
  (uint16) DEFAULT_VECTOR, /* $FFF6:F7 SWI */
  (uint16) DEFAULT_VECTOR, /* $FFF8:F9 Unimplemented instruction trap */
  (uint16) interrupt_cop_reset, /* $FFFA:FB COP failure reset */
  (uint16) DEFAULT_VECTOR, /* $FFFC:FD Clock Monitor fail reset */
  (uint16) interrupt_reset  /* $FFFE:FF Reset */
};
#pragma CONST_SEG DEFAULT


/*** Function definitions ***/

/* Unused interrupt implementations */

#pragma CODE_SEG NEAR INTERRUPT_ROM

#pragma TRAP_PROC
void interrupt_unused (void)
{}

#pragma TRAP_PROC
void interrupt_reset(void)
{
  #pragma MESSAGE DISABLE C12053
  asm LDS   #$2500;

 
  INITRM = 0x21;
  INITEE = 0x09;
 
  main();
}

#pragma TRAP_PROC
void interrupt_cop_reset(void)
{
  #pragma MESSAGE DISABLE C12053
  asm LDS   #$2500;
 
  INITRM = 0x21;
  INITEE = 0x09;
 
  main();
}

#pragma TRAP_PROC
void interrupt_SWI (void)
{}

#pragma TRAP_PROC
void interrupt_RTI (void)
{
  CRGINT &= ~RTIE;
}

#pragma TRAP_PROC
void interrupt_ECT_timer0 (void)
{
  TIE &= ~0x01;
}

#pragma TRAP_PROC
void interrupt_ECT_timer1 (void)
{
  TIE &= ~0x02;
}

#pragma TRAP_PROC
void interrupt_ECT_timer2 (void)
{
  TIE &= ~0x04;
}

#pragma TRAP_PROC
void interrupt_ECT_timer3 (void)
{
  TIE &= ~0x08;
}

#pragma TRAP_PROC
void interrupt_ECT_timer4 (void)
{
  TIE &= ~0x10;
}

#pragma TRAP_PROC
void interrupt_ECT_timer5 (void)
{
  TIE &= ~0x20;
}

#pragma TRAP_PROC
void interrupt_ECT_timer6 (void)
{
  TIE &= ~0x40;
}

#pragma TRAP_PROC
void interrupt_ECT_timer7 (void)
{
  TIE &= ~0x80;
}

#pragma TRAP_PROC
void interrupt_ECT_overflow (void)
{
  TSCR2 &= ~TOI;
}

#pragma TRAP_PROC
void interrupt_ECT_PACA (void)
{
  PACTL &= ~PAOVI;
}

#pragma TRAP_PROC
void interrupt_ECT_PACIE (void)
{
  PACTL &= ~PAI;
}

#pragma TRAP_PROC
void interrupt_SPI0 (void)
{
  SPI0CR1 &= ~(SPIE | SPTIE);
}

#pragma TRAP_PROC
void interrupt_SCI0 (void)
{
  SCI0CR2 &= ~(0x80|TCIE|RIE|ILIE); /* 0x80 == TIE */
}

#pragma TRAP_PROC
void interrupt_SCI1 (void)
{
  SCI1CR2 &= ~(0x80|TCIE|RIE|ILIE); /* 0x80 == TIE */
}

#pragma TRAP_PROC
void interrupt_PortJ (void)
{
  PIEJ = 0x00;
}

#pragma TRAP_PROC
void interrupt_PortH (void)
{
  PIEH = 0x00;
}

#pragma TRAP_PROC
void interrupt_ECT_PACB (void)
{
  PBCTL &= ~PBOVI;
}

#pragma TRAP_PROC
void interrupt_PLL_lock (void)
{
  CRGINT &= ~LOCKIE;
}

#pragma TRAP_PROC
void interrupt_SPI1 (void)
{
  SPI1CR1 &= ~(SPIE | SPTIE);
}

#pragma TRAP_PROC
void interrupt_PortP (void)
{
  PIEP = 0x00;
}

#pragma CODE_SEG DEFAULT

View solution in original post

0 Kudos
5 Replies
646 Views
Lundin
Senior Contributor IV
Simply making an array of 16-bit integers solved the problem. Casts between function pointers and integers are well-defined in ISO C, and even if the function pointer happens to be a 24 bit one, it will be truncated into 16 bits. Though of course you will still need to allocate all ISR in non-banked memory.

So for the record, this is how you write a fully ISO C compliant vector table for HCS12 (D family) Codewarrior. The only thing I couldn't do in standard C was to set the stack pointer. Feel free to use the code in your own projects, and please let me know if you find any errors.

It comes with some useful practice for how to handle unused interrupts. It also allows you to replace the horrid "start12.c", assuming you aren't using any static initalization in your project.


/* .prm file */
SEGMENTS

    VECTOR_RESERVED
             = NO_INIT      0xFF80  TO    0xFF8B;
            
    VECTOR_TABLE
             = READ_ONLY    0xFF8C  TO    0xFFFF;

    ROM_4000 = READ_ONLY    0x4000  TO    0x7FFF;

    ROM_C000 = READ_ONLY    0xC000  TO    0xFEFF;

END


PLACEMENT

    INTERRUPT_ROM          INTO  ROM_C000;
    VECTORS                INTO  VECTOR_TABLE;

END



ENTRIES

    vector_table

END



/* vectortable_hcs12.h */

#ifndef _VECTORTABLE_HCS12_H
#define _VECTORTABLE_HCS12_H

/*** Include files ***/

#include "s12reg.h" /* your register map goes here */
#include "types.h" /* your uint16 etc typedef header goes here */


/*** Macros and numeric constants ***/

#define DEFAULT_VECTOR interrupt_unused


/*** Function prototypes ***/

#pragma CODE_SEG NEAR INTERRUPT_ROM

extern void interrupt_unused       (void);
 
extern void interrupt_reset        (void);
extern void interrupt_clock_fail   (void);
extern void interrupt_cop_reset    (void);
extern void interrupt_SWI          (void);
extern void interrupt_RTI          (void);
extern void interrupt_ECT_timer0   (void);
extern void interrupt_ECT_timer1   (void);
extern void interrupt_ECT_timer2   (void);
extern void interrupt_ECT_timer3   (void);
extern void interrupt_ECT_timer4   (void);
extern void interrupt_ECT_timer5   (void);
extern void interrupt_ECT_timer6   (void);
extern void interrupt_ECT_timer7   (void);
extern void interrupt_ECT_overflow (void);
extern void interrupt_ECT_PACA     (void);
extern void interrupt_ECT_PACIE    (void);
extern void interrupt_SPI0         (void);
extern void interrupt_SCI0         (void);
extern void interrupt_SCI1         (void);
extern void interrupt_PortJ        (void);
extern void interrupt_PortH        (void);
extern void interrupt_ECT_PACB     (void);
extern void interrupt_PLL_lock     (void);
extern void interrupt_SPI1         (void);
extern void interrupt_PortP        (void);

#pragma CODE_SEG DEFAULT

#endif /* _VECTORTABLE_HCS12_H */


 /* vectortable_hsc12.c */

#include "vectortable_hcs12.h"

/*** Function prototypes ***/

/* external interrupt routines */

#pragma CODE_SEG NEAR INTERRUPT_ROM

extern void main (void);

#pragma CODE_SEG DEFAULT



/*** Global constants ***/

#pragma CONST_SEG NEAR VECTORS

const uint16 vector_table[] =
{
  /*           */      /* $FF00:8B Reserved*/
  (uint16) DEFAULT_VECTOR,  /* $FF8C:8D PWM Emergency Shutdown */
  (uint16) interrupt_PortP, /* $FF8E:8F Port P Interrupt */
  (uint16) DEFAULT_VECTOR,  /* $FF90:91 MSCAN 4 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FF92:93 MSCAN 4 receive */
  (uint16) DEFAULT_VECTOR,  /* $FF94:95 MSCAN 4 errors */
  (uint16) DEFAULT_VECTOR,  /* $FF96:97 MSCAN 4 wake- up */
  (uint16) DEFAULT_VECTOR,  /* $FF98:99 MSCAN 3 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FF9A:9B MSCAN 3 receive */
  (uint16) DEFAULT_VECTOR,  /* $FF9C:9D MSCAN 3 errors */
  (uint16) DEFAULT_VECTOR,  /* $FF9E:9F MSCAN 3 wake- p */
  (uint16) DEFAULT_VECTOR,  /* $FFA0:A1 MSCAN 2 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FFA2:A3 MSCAN 2 receive */
  (uint16) DEFAULT_VECTOR,  /* $FFA4:A5 MSCAN 2 errors */
  (uint16) DEFAULT_VECTOR,  /* $FFA6:A7 MSCAN 2 wake-up */
  (uint16) DEFAULT_VECTOR,  /* $FFA8:A9 MSCAN 1 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FFAA:AB MSCAN 1 receive */
  (uint16) DEFAULT_VECTOR,  /* $FFAC:AD MSCAN 1 errors */
  (uint16) DEFAULT_VECTOR,  /* $FFAE:AF MSCAN 1 wake-up */
  (uint16) DEFAULT_VECTOR,  /* $FFB0:B1 MSCAN 0 transmit */
  (uint16) DEFAULT_VECTOR,  /* $FFB2:B3 MSCAN 0 receive */
  (uint16) DEFAULT_VECTOR,  /* $FFB4:B5 MSCAN 0 errors */
  (uint16) DEFAULT_VECTOR,  /* $FFB6:B7 MSCAN 0 wake-up */
  (uint16) DEFAULT_VECTOR,  /* $FFB8:B9 FLASH */
  (uint16) DEFAULT_VECTOR,  /* $FFBA:BB EEPROM */
  (uint16) DEFAULT_VECTOR,  /* $FFBC:BD SPI2 */
  (uint16) interrupt_SPI1,  /* $FFBE:BF SPI1 */
  (uint16) DEFAULT_VECTOR,  /* $FFC0:C1 IIC Bus */
  (uint16) DEFAULT_VECTOR,  /* $FFC2:C3 DLC */
  (uint16) DEFAULT_VECTOR,  /* $FFC4:C5 SCME */
  (uint16) interrupt_PLL_lock, /* $FFC6:C7 CRG lock */
  (uint16) interrupt_ECT_PACB, /* $FFC8:C9 Pulse Accumulator B Overflow */
  (uint16) DEFAULT_VECTOR,  /* $FFCA:CB Modulus Down Counter underflow */
  (uint16) interrupt_PortH, /* $FFCC:CD Port H*/
  (uint16) interrupt_PortJ, /* $FFCE:CF Port J */
  (uint16) DEFAULT_VECTOR, /* $FFD0:D1 ATD1 */
  (uint16) DEFAULT_VECTOR, /* $FFD2:D3 ATD0 */
  (uint16) interrupt_SCI1, /* $FFD4:D5 SCI1 */
  (uint16) interrupt_SCI0, /* $FFD6:D7 SCI0 */
  (uint16) interrupt_SPI0, /* $FFD8:D9 SPI0 */
  (uint16) interrupt_ECT_PACIE, /* $FFDA:DB Pulse accumulator input edge */
  (uint16) interrupt_ECT_PACA, /* $FFDC:DD Pulse accumulator A overflow */
  (uint16) interrupt_ECT_overflow, /* $FFDE:DF Timer overflow */
  (uint16) interrupt_ECT_timer7, /* $FFE0:E1 Timer channel 7 */
  (uint16) interrupt_ECT_timer6, /* $FFE2:E3 Timer channel 6 */
  (uint16) interrupt_ECT_timer5, /* $FFE4:E5 Timer channel 5 */
  (uint16) interrupt_ECT_timer4, /* $FFE6:E7 Timer channel 4 */
  (uint16) interrupt_ECT_timer3, /* $FFE8:E9 Timer channel 3 */
  (uint16) interrupt_ECT_timer2, /* $FFEA:EB Timer channel 2 */
  (uint16) interrupt_ECT_timer1, /* $FFEC:ED Timer channel 1 */
  (uint16) interrupt_ECT_timer0, /* $FFEE:EF Timer channel 0 */
  (uint16) DEFAULT_VECTOR, /* $FFF0:F1 Real Time Interrupt */
  (uint16) DEFAULT_VECTOR, /* $FFF2:F3 IRQ */
  (uint16) DEFAULT_VECTOR, /* $FFF4:F5 XIRQ */
  (uint16) DEFAULT_VECTOR, /* $FFF6:F7 SWI */
  (uint16) DEFAULT_VECTOR, /* $FFF8:F9 Unimplemented instruction trap */
  (uint16) interrupt_cop_reset, /* $FFFA:FB COP failure reset */
  (uint16) DEFAULT_VECTOR, /* $FFFC:FD Clock Monitor fail reset */
  (uint16) interrupt_reset  /* $FFFE:FF Reset */
};
#pragma CONST_SEG DEFAULT


/*** Function definitions ***/

/* Unused interrupt implementations */

#pragma CODE_SEG NEAR INTERRUPT_ROM

#pragma TRAP_PROC
void interrupt_unused (void)
{}

#pragma TRAP_PROC
void interrupt_reset(void)
{
  #pragma MESSAGE DISABLE C12053
  asm LDS   #$2500;

 
  INITRM = 0x21;
  INITEE = 0x09;
 
  main();
}

#pragma TRAP_PROC
void interrupt_cop_reset(void)
{
  #pragma MESSAGE DISABLE C12053
  asm LDS   #$2500;
 
  INITRM = 0x21;
  INITEE = 0x09;
 
  main();
}

#pragma TRAP_PROC
void interrupt_SWI (void)
{}

#pragma TRAP_PROC
void interrupt_RTI (void)
{
  CRGINT &= ~RTIE;
}

#pragma TRAP_PROC
void interrupt_ECT_timer0 (void)
{
  TIE &= ~0x01;
}

#pragma TRAP_PROC
void interrupt_ECT_timer1 (void)
{
  TIE &= ~0x02;
}

#pragma TRAP_PROC
void interrupt_ECT_timer2 (void)
{
  TIE &= ~0x04;
}

#pragma TRAP_PROC
void interrupt_ECT_timer3 (void)
{
  TIE &= ~0x08;
}

#pragma TRAP_PROC
void interrupt_ECT_timer4 (void)
{
  TIE &= ~0x10;
}

#pragma TRAP_PROC
void interrupt_ECT_timer5 (void)
{
  TIE &= ~0x20;
}

#pragma TRAP_PROC
void interrupt_ECT_timer6 (void)
{
  TIE &= ~0x40;
}

#pragma TRAP_PROC
void interrupt_ECT_timer7 (void)
{
  TIE &= ~0x80;
}

#pragma TRAP_PROC
void interrupt_ECT_overflow (void)
{
  TSCR2 &= ~TOI;
}

#pragma TRAP_PROC
void interrupt_ECT_PACA (void)
{
  PACTL &= ~PAOVI;
}

#pragma TRAP_PROC
void interrupt_ECT_PACIE (void)
{
  PACTL &= ~PAI;
}

#pragma TRAP_PROC
void interrupt_SPI0 (void)
{
  SPI0CR1 &= ~(SPIE | SPTIE);
}

#pragma TRAP_PROC
void interrupt_SCI0 (void)
{
  SCI0CR2 &= ~(0x80|TCIE|RIE|ILIE); /* 0x80 == TIE */
}

#pragma TRAP_PROC
void interrupt_SCI1 (void)
{
  SCI1CR2 &= ~(0x80|TCIE|RIE|ILIE); /* 0x80 == TIE */
}

#pragma TRAP_PROC
void interrupt_PortJ (void)
{
  PIEJ = 0x00;
}

#pragma TRAP_PROC
void interrupt_PortH (void)
{
  PIEH = 0x00;
}

#pragma TRAP_PROC
void interrupt_ECT_PACB (void)
{
  PBCTL &= ~PBOVI;
}

#pragma TRAP_PROC
void interrupt_PLL_lock (void)
{
  CRGINT &= ~LOCKIE;
}

#pragma TRAP_PROC
void interrupt_SPI1 (void)
{
  SPI1CR1 &= ~(SPIE | SPTIE);
}

#pragma TRAP_PROC
void interrupt_PortP (void)
{
  PIEP = 0x00;
}

#pragma CODE_SEG DEFAULT
0 Kudos
645 Views
J2MEJediMaster
Specialist I

Lundin: This is great stuff! As you well know, we get a lot of questions about interrupt vectors tables all the time here, and this code will help a lot of developers.

 

Thanks for sharing.

 

---Tom

Message Edited by J2MEJediMaster on 2009-11-16 09:14 AM
0 Kudos
645 Views
CompilerGuru
NXP Employee
NXP Employee

Hmm, don't think you get around using __near with __near function pointers.

You could for example use object pointers instead (or even unsigned int with some casts). They are 16 bit by default and for the core it does not matter (for 16 bit pointers).

Or you could use the prm file with the VECTOR keyword.

 

BTW: use __near instead of near to be a bit more ANSI C compliant :smileyhappy:.

Daniel

0 Kudos
645 Views
Lundin
Senior Contributor IV
Casting between object pointers and function pointers is undefined behavior in C, so it won't make the code portable, and the static analyzer will surely whine about it. Though perhaps I could allocate the vector table as an integer array. The problem then is to know where all the ISRs are stored in memory.

Perhaps I will have to use the .prm file as you suggest. I don't like that solution, but it would indeed make the code portable.

Why is __near more compliant? It isn't part of ISO C nor ISO C++.
0 Kudos
645 Views
kef
Specialist I

What about using predefined macros like this

 

#ifdef __MWERKS__

  #define NEAR __near

#else

  #define NEAR

#endif

 

and replacing near and __near with NEAR

 

 

0 Kudos