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