AnsweredAssumed Answered

Xgate - not processing interrupts

Question asked by jimmymitt on Sep 28, 2015
Latest reply on Oct 1, 2015 by Radek Sestak

Hello,

 

I've done a fair bit of reading through past posts and the 9S12 manual but can't seem to get the Xgate to receive interrupts.

 

I am running an HC9S12XET256 and am running low on resources (RAM and CPU loading). I would like to start porting some interrupts to the Xgate module to free resources.

To start with, something as simple as PWMing an LED.

 

I've used AN3225 as a template.

 

I am planning on running the Xgate program from flash. I realize this is slower but am not worried about that at this point.

 

Here is what I've done:

  • Added placement to prm for xgate code, data, and stack

RAM_XGATE_STK = READ_WRITE  0xFC1F00 TO 0xFC1FFF; // The stack is set by the XGATE compiler option -Cstv=D000

ROM_XGATE         = READ_ONLY    0xE18000 TO 0xE1BFFF ALIGN 2[1:1]; /* is also mapped to XGATE:  0x4000..0x7FFF        */

XGATE_CODE, XGATE_DATA          INTO   ROM_XGATE;

 

Also added pragmas to tell linker to put all code and data from the Xgate vector files and PWM module into these segments:

#pragma CODE_SEG XGATE_CODE

#pragma DATA_SEG XGATE_DATA

 

  • Set up vector table and mapped an ISR to PIT0 vector.
  • At startup:
    • Copy Xgate vector base address to register
XGVBR_XGVBR= (int)((void*__far)XGATEVectorTable);
    • Enable Xgate module and interrupts
XGMCTL = 0xFFE1;
    • Routed PIT0 interrupt to Xgate. PIT0 is channel 0x3D, vector 7A.
    INT_CFADDR_INT_CFADDR = 0x7;                    // Set interrupt confiuration address     INT_CFDATA5_PRIOLVL = 0x7;                      // Set priority to 7     INT_CFDATA5_RQST = TRUE;                        // Set to XGate
    • Set up PIT0 timer
    PITCE_PCE0 = 1;             // Enable PIT channel 0     PITMTLD1 = 0;               // Divide by 1 - no pre-scalar needed     PITMUX_PMUX0 = 1;           // Assign PIT channel 0 to microtimer 1     PITLD0 = 2400 - 1;          // 100Hz @ 0.5% -> 50us/20.83ns = 2400     PITCFLMT_PITE = 1;          // Enable PIT0     PITCFLMT_PITFRZ = 1;        // Enable in freeze mode     PITCFLMT_PFLMT1 = 1;        // Force reload of timer     PITFLT_PFLT0 = 1;           // Force reload of counter 0     PITINTE_PINTE0 = 1;         // Enable interrupts from channel 0
    • Enabled interrupts

 

Using a debugger to read from the registers I can confirm that:

  • The timer is counting properly and setting flag PITTF_PTF0 when it times out.
  • The RQST flag and priority have been set for PIT0 interrupt.
  • The XGMCTL register is set correctly (XGE, XGFRZ, XGIE).
  • The value at the Xgate vector address for PIT0 points to the flash location of the ISR (0xE18004 in map file and 0x4004 at vector address)

 

What am I missing here?

Everything seems to be mapped correctly when I cross check the map file to what I see using the debugger.

The interrupt seems to fire and the vector is there pointing to the correct function - why is it not running?

 

Any ideas would be great - I feel like I've been thorough here but can't seem to put my finger on the issue.

 

A few things I noticed that I'm not sure are causing the problem:

  • The XGIF register corresponding to PIT0 is not being set. From the manual it seems like this is only set by the Xgate and not when the interrupt is set so I think this is ok, but maybe I am misunderstanding its purpose.
  • The only other thing that seems a bit off is that if I leave my vector array size undefined, it shows up in the map file as 512 bytes (good). However if I define its size as 128, I get a linker error:

L1827: Symbol XGATEVectorTable has different size in xgatevectors.cxgate.o (512 bytes) and main.c.o (640  bytes)

Is there an alignment issue I've missed? The size difference is 128 bytes which can't be a coincidence. The only place its used in main.c is where the address is copied to the XGVBR register.

 

thanks for all input,

const xgate_vector XGATEVectorTable[]; /* XGATE vector table */

Outcomes