Xgate - not processing interrupts

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

Xgate - not processing interrupts

Jump to solution
1,666 Views
jimmymitt
Contributor I

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 */

Labels (1)
Tags (2)
0 Kudos
Reply
1 Solution
1,347 Views
RadekS
NXP Employee
NXP Employee

Hi jimmymitt,

Just detail, command XGMCTL = 0xFFE1; will set XGDBG bit and this way Enter into Debug Mode.

In debug mode the RISC core will be halted (and the debug features will be enabled).

Please use command XGMCTL= 0xFBC1; /* XGE | XGFRZ | XGIE */ for enabling XGATE.

I would like to also recommend enable XGATE after setting interrupt routing and priorities.

I would like to recommend also initialize stacks (valid for S12XE, missing on S12XD). For example:

  XGISPSEL= 1;

  XGISP31= (unsigned int)(void*__far)(XGATE_STACK_L + 1);

  XGISPSEL= 2;

  XGISP74= (unsigned int)(void*__far)(XGATE_STACK_H + 1);

  XGISPSEL= 0;

In prm file:

    RAM_XGATE_STK_L_ = NO_INIT DATA_FAR            0xF81000 TO 0xF8107D;

      RAM_XGATE_STK_L = NO_INIT DATA_FAR            0xF8107E TO 0xF8107F;

      RAM_XGATE_STK_H_ = NO_INIT DATA_FAR            0xF81080 TO 0xF810FD;

      RAM_XGATE_STK_H = NO_INIT DATA_FAR            0xF810FE TO 0xF810FF;

      XGATE_STK_L      INTO RAM_XGATE_STK_L;

      XGATE_STK_H      INTO RAM_XGATE_STK_H;

This default initialization is missing in older CW versions. It doesn’t problem until we want use interrupt nesting.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
Reply
5 Replies
1,348 Views
RadekS
NXP Employee
NXP Employee

Hi jimmymitt,

Just detail, command XGMCTL = 0xFFE1; will set XGDBG bit and this way Enter into Debug Mode.

In debug mode the RISC core will be halted (and the debug features will be enabled).

Please use command XGMCTL= 0xFBC1; /* XGE | XGFRZ | XGIE */ for enabling XGATE.

I would like to also recommend enable XGATE after setting interrupt routing and priorities.

I would like to recommend also initialize stacks (valid for S12XE, missing on S12XD). For example:

  XGISPSEL= 1;

  XGISP31= (unsigned int)(void*__far)(XGATE_STACK_L + 1);

  XGISPSEL= 2;

  XGISP74= (unsigned int)(void*__far)(XGATE_STACK_H + 1);

  XGISPSEL= 0;

In prm file:

    RAM_XGATE_STK_L_ = NO_INIT DATA_FAR            0xF81000 TO 0xF8107D;

      RAM_XGATE_STK_L = NO_INIT DATA_FAR            0xF8107E TO 0xF8107F;

      RAM_XGATE_STK_H_ = NO_INIT DATA_FAR            0xF81080 TO 0xF810FD;

      RAM_XGATE_STK_H = NO_INIT DATA_FAR            0xF810FE TO 0xF810FF;

      XGATE_STK_L      INTO RAM_XGATE_STK_L;

      XGATE_STK_H      INTO RAM_XGATE_STK_H;

This default initialization is missing in older CW versions. It doesn’t problem until we want use interrupt nesting.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
1,347 Views
jimmymitt
Contributor I

Ok, its now working. Thanks to both of you!

I ended up adding setting up a new project using the project wizard and porting some of the content to my existing project. Mostly better management of the memory segments. Also initializing the stacks which was also suggested by Radek.

I also made all other changes recommended by Radek.

I am not 100% sure but suspect that changing to XGMCTL= 0xFBC1 made the difference. I made a number of changes at once. I made a number of changes at once and am in a bit of a rush now so did not go back and confirm the exact change that fixed it.

A couple follow up questions on the linker file:

  1. I could not find a detailed description of syntax for the prm. Is there a manual that describes keywords etc...
  2. In particular, I am not sure what the IBCC_FAR of this line does:
    ROM_XGATE       = READ_ONLY   DATA_FAR IBCC_FAR  0xE18000 TO 0xE1BFFF ALIGN 2[1:1];
  3. I noticed in some examples that the RELOCATE action was used - I'd like to know what exactly this does. I may end up needing to run this from RAM in the end and I think I'll need to know more about the prm file.

thanks,

0 Kudos
Reply
1,347 Views
RadekS
NXP Employee
NXP Employee

Hi jimmymitt,

Some details about prm file and linker could be found here:

"c:\Program Files (x86)\Freescale\CWS12v5.1\Help\PDF\Build_Tools_Utilities.pdf"

IBCC_FAR keyword is related mainly to MemoryBanker feature. Please look at TN262 for more details about this tool:

"c:\Program Files (x86)\Freescale\CWS12v5.1\Help\PDF\TN262.pdf"

RELOCATE_TO to keyword is described in Build_Tools_Utilities.pdf. This feature is used for example in AN4258 Serial Bootloader for S12(X) Microcontrollers Based on 180 nm Technology

http://www.freescale.com/files/microcontrollers/doc/app_note/AN4258.pdf

http://www.freescale.com/files/microcontrollers/doc/app_note/AN4258SW.zip

for copy flash routines into RAM, that we could load application code into the same flash block where bootloader code is placed.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
1,347 Views
kef2
Senior Contributor V

Regarding L1827. Is XGATE vector table declared in *.h file like you wrote, with unknown array size []? If so, then main.c.o shouldn't know its size.

Did you try creating new multicore project using project wizard? It should give you some hits.

It is wrong to put XGATE_DATA in ROM segment. CONST_SEG and XGATE_CONST should be placed to ROM.

0 Kudos
Reply
1,347 Views
jimmymitt
Contributor I

The XGATE vecor is declared in the *.h file as I wrote previously:

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

The *.c file defines it as

const xgate_vector XGATEVectorTable[] = {

                          // Channel # = Vector address / 2

  {ErrorHandler, U_XDP},  // Channel 00 - Reserved

  {ErrorHandler, U_XDP},  // Channel 01 - Reserved

  {ErrorHandler, U_XDP},  // Channel 02 - Reserved

etc. etc.

I agree that main.c.o should not know or be concerned about the size of the XGate vector table. I'm a bit puzzled by this.

I have not created a new project with the wizard - I'll give this a try and use what is generated as a reference.

I fixed the mistake of putting the XGATE_DATA in ROM. The only thing my handler does at this point is turn on a digital output so there is no Xgate data at this point, but will be once this is up and running. I adjusted the the pragma to be as follows:

#pragma CONST_SEG XGATE_CONST

and placed this in ROM in the linker file. In the map file I confirmed that the linker put the Xgate vector table in this section.

If it helps, here are the key registers at runtime:

pastedImage_3.pngpastedImage_4.pngpastedImage_2.pngpastedImage_6.png

pastedImage_7.png

As far as I can tell, the interrupt is firing, the Xgate is on and should be accepting interrupts, the Xgate vector register is pointing to the vector address, and the vector corresponding to PIT0 is pointing to the handler.

thanks,

0 Kudos
Reply