EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Help in streamlining my xgate code

Started by aerowesty2000 May 16, 2006
Thank you Steve and Doron for the great suggestions. Steve, just
placing the function code into the isr netted 1.94 Mhz and combining
Doron's suggestion of using Port AD1 vs PortAB resulted in over 2.67
Mhz. Many thanks to you guys for the fine suggestions. I connected
the simulator up to the ground station and the telemetry decommed
perfectly. Thanks again. When I get a chance I will figure out if
the xgate code has been placed in ram. I did a quick check of the map
file and it seems to be scattered. Thanks again..

George

George ("aerowesty2000") wrote:

> Thank you Steve and Doron for the great suggestions. Steve, just
> placing the function code into the isr netted 1.94 Mhz and combining
> Doron's suggestion of using Port AD1 vs PortAB resulted in over 2.67
> Mhz. Many thanks to you guys for the fine suggestions. I connected
> the simulator up to the ground station and the telemetry decommed
> perfectly. Thanks again. When I get a chance I will figure out if
> the xgate code has been placed in ram. I did a quick check of the map
> file and it seems to be scattered. Thanks again..
>
> George

George, are you sure you saw continuous asinchronous 2.67MHz bitstream on AD
port? Did you really connected osciloscope to AD port and saw ~1.3MHz
meander when shifting 0x5555 or 0xaaaa continuously? Sorry, but I tried to
experiment doing first your code, then optimising it. IMO it's very hard or
even impossible to have all 3 working: 1) shift out bits by XGATE at such
high and 2) _constant_ bit rate and 3) feeding XGATE with useful data from
S12X without underflows or huge jitter on port pins. I'm not saying that
it's impossible to get up to 2MHz or maybe even more but definitely not as
easy as just only replacing PRU regiter by not PRU or removing 2 BRA
instructions
for function call. I really doubt your figures.

In your previous message you wrote:

> handler. My problem lies in the fact I cannot get past 1.5 Mhz
> out. I need to get to about 2.5 Mhz ( with breathing room ). I
> have severely cut out features and streamlined my previous code
> attempts. I top out at a PITLD reg value of 51. I have the PLL set

You said you top out at PITLDQ. At max possible 40MHz bus speed it's
(51+1)*25ns= 1.3 us PIT period or less than 0.77MHz. This is more adequate
for your old code rather than 1.5MHz. Either you didn't try to check it with
scope or you are running your 9s12x at double max speed, 80MHz bus clock or
160MHz core clock (XGATE clock).
Feeding XGATE at 2.5MHz/16 bits rate with _real data_ from S12X is also
challenging. The only possible application for this would be just read data
from flash and send it serially. No breathing room for anything else.
My advices:

1) your XGATE interrupt handler doesn't take arguments. You should utilize
XGATE feature that R1 register value is loaded from XGATE vector table.
XGATE interrupt handler argument is that R1 register. You could pack your X
variables into structure and pass pointer to it through vector table. This
way you could save on reloads of 16bit const address of variable. Code would
get a bit smaller and of course faster.

2) Test counter against zero may be faster than test against nonzero const.
So maybe decrement bit counter and reload it (on new data) to nonzero
constant.

3) Look at diassmbled code and try to understand it. Then think how you
could eliminate instructions you think must be avoided.

4) SPI isn't exactly power of two. 2,4,6,8,10,12,14,16,20,24 dividers are
available. If that's still too big granulity then what about lowering PLL
frequency down from max 80MHz when it's necessary to get into freqs between
available SPI dividers?
Regards,
Edward

Ed,

Wow, how to take the wind out of someone's sails... Anyhow, you are
absolutely right if the code is used as is. Initially, I used a logic
analyzer to verify the frame data when I was running at slower speeds.
I then used the Ground station to check it until it could not lock onto
the frame. That occurred at about 2.67 Mhz. The GS is happy as a clam
with it. It is not reporting errors on the frame statistics report. The
output graphs of the frame counters ( both major and minor frame ) are
clean ramps with no glitching. However I never looked at the signal
again until today with the LA. And you are right, there is a large
amount of jitter. I slowed the rate to 2.5 Mhz and used a temporary
register to do the load and shifting then at the isr I output the temp
register onto the port ( delayed one count ). This locks the data
transition to the PIT timer better. However even at 2.5 Mhz (400 ns) I
was seeing about 60-100 ns of jitter. The actual application will be
around 2.0 MHz ( req'mt still undefined ). I also clear the interrupt
flag at the top of the isr vs. the end ( this seemed to have an impact
on speed ).

george

-----Original Message-----
From: 6... [mailto:6...] On Behalf
Of Edward Karpicz
Sent: Wednesday, May 17, 2006 5:30 AM
To: 6...
Subject: [68HC12] Re: Help in streamlining my xgate code

George ("aerowesty2000") wrote:

> Thank you Steve and Doron for the great suggestions. Steve, just
> placing the function code into the isr netted 1.94 Mhz and combining
> Doron's suggestion of using Port AD1 vs PortAB resulted in over 2.67
> Mhz. Many thanks to you guys for the fine suggestions. I connected
> the simulator up to the ground station and the telemetry decommed
> perfectly. Thanks again. When I get a chance I will figure out if
> the xgate code has been placed in ram. I did a quick check of the map
> file and it seems to be scattered. Thanks again..
>
> George

George, are you sure you saw continuous asinchronous 2.67MHz bitstream
on AD
port? Did you really connected osciloscope to AD port and saw ~1.3MHz
meander when shifting 0x5555 or 0xaaaa continuously? Sorry, but I tried
to
experiment doing first your code, then optimising it. IMO it's very hard
or
even impossible to have all 3 working: 1) shift out bits by XGATE at
such
high and 2) _constant_ bit rate and 3) feeding XGATE with useful data
from
S12X without underflows or huge jitter on port pins. I'm not saying that
it's impossible to get up to 2MHz or maybe even more but definitely not
as
easy as just only replacing PRU regiter by not PRU or removing 2 BRA
instructions
for function call. I really doubt your figures.

In your previous message you wrote:

> handler. My problem lies in the fact I cannot get past 1.5 Mhz
> out. I need to get to about 2.5 Mhz ( with breathing room ). I
> have severely cut out features and streamlined my previous code
> attempts. I top out at a PITLD reg value of 51. I have the PLL set

You said you top out at PITLDQ. At max possible 40MHz bus speed it's
(51+1)*25ns= 1.3 us PIT period or less than 0.77MHz. This is more
adequate
for your old code rather than 1.5MHz. Either you didn't try to check it
with
scope or you are running your 9s12x at double max speed, 80MHz bus clock
or
160MHz core clock (XGATE clock).
Feeding XGATE at 2.5MHz/16 bits rate with _real data_ from S12X is also
challenging. The only possible application for this would be just read
data
from flash and send it serially. No breathing room for anything else.
My advices:

1) your XGATE interrupt handler doesn't take arguments. You should
utilize
XGATE feature that R1 register value is loaded from XGATE vector table.
XGATE interrupt handler argument is that R1 register. You could pack
your X
variables into structure and pass pointer to it through vector table.
This
way you could save on reloads of 16bit const address of variable. Code
would
get a bit smaller and of course faster.

2) Test counter against zero may be faster than test against nonzero
const.
So maybe decrement bit counter and reload it (on new data) to nonzero
constant.

3) Look at diassmbled code and try to understand it. Then think how you
could eliminate instructions you think must be avoided.

4) SPI isn't exactly power of two. 2,4,6,8,10,12,14,16,20,24 dividers
are
available. If that's still too big granulity then what about lowering
PLL
frequency down from max 80MHz when it's necessary to get into freqs
between
available SPI dividers?
Regards,
Edward
George,

Sorry for taking the wind out of sails. XGATE is what pulled my attention,
also X MHz continuous data bit stream. How long that stream must be
continuous? For up to 16 bit-times, for 100s or 1000s of bit times, or
forever? Short burst of bits should be easy to do even with S12X, but long
and
continuous... challenging. XGATE code must be fast enough to shift out data,
S12X must be fast enough to transfer data to XGATE memory. XGATE has
80MHz/2MHz@ core cycles available. S12X has (40MHz/2MHz)*16bits= 320 bus
cycles. Both figures are too small for breathing room.

I'm not sure what whole application should look like. I can't think of
useful bitstream have jitter as high as 25-50% of bit time. You can reduce
XGATE jitter but not eliminate it completely without additional hardware.
S12X has priority over XGATE when it comes to access RAM. So unavoidably any
choosen XGATE instruction executes longer when S12X accesses RAM. Your
ucSubmitNewdata flag is in RAM. So S12X must read it often or continuously.
Instead of flag in RAM you may try to use XGATE semafore or available
software triggerable interrupt flag. But eliminating other S12X RAM
accesses... must be something.
Anyway try to understand my version of bit streamer below. Since jitter is
unavoidable as a last resort I made XGATE PIT1 handler running forever.
Forever because I wanted to eliminate the need to reload XGATE registers
with shiftcounter etc. It seems that XGATE registers are reset to 0 every
time XGATE enters any thread. If it wasn't resetting R2-R7 registers I would
try something smart to keep variables in registers. Here asm listing. Fast,
compact and still jitterfull. Look further down for more details and source.

Edward

18:
/////////////////////////////////////////////////////////////////////
19: // Interrupt Service Routine PIT1 Timer
20:
/////////////////////////////////////////////////////////////////////
21: void interrupt PIT1Handler(char * pData)
22: {

0000 ffb1 LDH R7,#177
23: register unsigned int shiftdata=0x5555;
0002 f655 LDL R6,#85
0004 ae55 ORH R6,#85
24: register ucShiftClock;
0006 f510 LDL R5,#16
25:
26: label:
0008 f300 LDL R3,#PART_0_7(_PITTF)
000a ab00 ORH R3,#PART_8_15(_PITTF)
000c f201 LDL R2,#1
000e LE:
27: while(!(PITTF & 2)); // Wait for PIT flag
000e 4460 LDB R4,(R3,#0)
0010 9402 BITL R4,#2
0012 27fd BEQ LE
28: PORTAB = shiftdata; // Write bit to port
0014 5e00 STW R6,(R0,#_PORTAB)
29:
30: PITTF = 0x02; // Clear PIT flag.
0016 f402 LDL R4,#2
0018 5460 STB R4,(R3,#0)
31:
32: if(!(--ucShiftClock)) // decrement counter
001a c501 SUBL R5,#1
001c 2404 BNE CCR, , L26
33: {
34: shiftdata=uiNewData; // new data
001e 4e24 LDW R6,(R1,#4)
35:
36: ucSubmitNewData = 1; // Submit New Data flag to S12X
0020 5226 STB R2,(R1,#6)
37: // S12X has almost 16 bittimes
38: // to write new data
39:
40: ucShiftClock = BITS_PER_WORD;
0022 f510 LDL R5,#16
41: goto label;
0024 3ff4 BRA LE
0026 L26:
42: }
43: shiftdata >>= 1;
0026 0e1d LSR R6,#1
44: goto label;
0028 3ff2 BRA LE
45: }

First one comment about defining shared S12X-XGATE data. It should be struct
in order to be able to pass pointer to that struct via XGATE vector table
and R1 register. It's faster for XGATE to access elements of structure
rather then access many variables directly. Many const pointer reloads will
be eliminated. But XGATE structs must be aligned by 2 byte boundaries so
XGATE compiler adds padding bytes after chars. This makes same structure
declared in XGATE not necessarily compatible to S12X structure. I'm not CW
expert so let me use array of chars for this:
In S12X C:

extern char ShifterData[20];
//#define shiftdata (*(unsigned int*)(pData+0))
//#define ucShiftClock (pData[2])
#define uiNewData (*(unsigned int*)(ShifterData+4))
#define ucSubmitNewData (ShifterData[6])

in XGATE C:

char ShifterData[20];
//#define shiftdata (*(unsigned int*)(pData+0))
//#define ucShiftClock (pData[2])
#define uiNewData (*(unsigned int*)(pData+4))
#define ucSubmitNewData (pData[6])

Note that XGATE ShifterData defines don't refer to ShifterData but to not
yet defined char *pData.

Now having shared data explained S12X code:

########## MAIN.C #########
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>

#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xdt512"
#include
#include "xgate.h"

/* this variable definition is to demonstrate how to share data between
XGATE and S12X */
#pragma DATA_SEG SHARED_DATA
volatile int shared_counter; /* volatile because both cores are accessing
it. */
#pragma DATA_SEG DEFAULT
#define ROUTE_INTERRUPT(vec_adr, cfdata) \
INT_CFADDR= (vec_adr) & 0xF0; \
INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata)

#define SOFTWARETRIGGER0_VEC 0x72 /* vector address= 2 * channel id */
#define PIT1TRIGGER_VEC 0x78

static void SetupXGATE(void) {
/* initialize the XGATE vector block and
set the XGVBR register to its start address */
XGVBR= (unsigned int)(void*__far)(XGATE_VectorTable -
XGATE_VECTOR_OFFSET);

/* switch software trigger 0 interrupt to XGATE */
ROUTE_INTERRUPT(SOFTWARETRIGGER0_VEC, 0x81); /* RQST=1 and PRIO=1 */

ROUTE_INTERRUPT(PIT1TRIGGER_VEC, 0x81); /* RQST=1 and PRIO=1 */

/* enable XGATE mode and interrupts */
XGMCTL= 0xFBC1; /* XGE | XGFRZ | XGIE */

// /* force execution of software trigger 0 handler */
// XGSWT= 0x0101;
}
extern char ShifterData[20];
//#define shiftdata (*(unsigned int*)(pData+0))
//#define ucShiftClock (pData[2])
#define uiNewData (*(unsigned int*)(ShifterData+4))
#define ucSubmitNewData (ShifterData[6])

void main(void) {

//Setup PLL for 40MHz bus clock, 80MHz PLL clock

REFDV=2-1;
SYNR -1; //5-1; // 20-1 for 4MHz osc, 5-1 for 16MHz osc

CRGFLG &= 0x10;
while(!(CRGFLG & 0x8));
CLKSEL |= 0x80;
/* put your own code here */
SetupXGATE();
//EnableInterrupts;

PITCE |= 1<<1; // PIT channel 1
PITCFLMT |= 0x80;

PITMTLD0=0;
PITLD1 -1;//100-1; // number of bus cycles -1
// defines PIT period

PITTF &= 1<<1;
PITINTE |= 1<<1;
// output pin is PRU
// but XGATE may access it doing LDB Rd, (R0,#1)
// while access to nonPRU registers would drag in
// 1 bus cycle to load address of register
DDRB |= 1;
for(;;) {
if(ucSubmitNewData)
{
uiNewData=0x5555; // just const data
ucSubmitNewData=0;
}

} /* wait forever */
/* please make sure that you never leave this function */
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
########## END of MAIN.C #################
Now XGATE part. Part of XGATE vector tables
######## XGATE.CXGATE ####################
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include /* common defines and macros */
#include "xgate.h"
#include

char ShifterData[20];
//#define shiftdata (*(unsigned int*)(pData+0))
//#define ucShiftClock (pData[2])
#define uiNewData (*(unsigned int*)(pData+4))
#define ucSubmitNewData (pData[6])

#define BITS_PER_WORD 16
/////////////////////////////////////////////////////////////////////
// Interrupt Service Routine PIT1 Timer
/////////////////////////////////////////////////////////////////////
void interrupt PIT1Handler(char * pData)
{
register unsigned int shiftdata=0x5555;
register ucShiftClock;

label:
while(!(PITTF & 2)); // Wait for PIT flag
PORTAB = shiftdata; // Write bit to port

PITTF = 0x02; // Clear PIT flag.

if(!(--ucShiftClock)) // decrement counter
{
shiftdata=uiNewData; // new data

ucSubmitNewData = 1; // Submit New Data flag to S12X
// S12X has almost 16 bittimes
// to write new data

ucShiftClock = BITS_PER_WORD;
goto label;
}
shiftdata >>= 1;
goto label;
}

// interrupt handler for all others
interrupt void ErrorHandler(int dataptr) {
int chanNum= dataptr;
asm BRK;
}

#pragma CONST_SEG XGATE_VECTORS /* assign the vector table in separate
segment for dedicated placement in linker parameter file */

const XGATE_TableEntry XGATE_VectorTable[] = {
// Channel # = Vector address / 2
/* channel 0..8 are not used, first used must match macro
XGATE_VECTOR_OFFSET in xgate.h */
{ErrorHandler, 0x09}, // Channel 09 - Reserved
{ErrorHandler, 0x0A}, // Channel 0A - Reserved
{ErrorHandler, 0x0B}, // Channel 0B - Reserved
{ErrorHandler, 0x0C}, // Channel 0C - Reserved
{ErrorHandler, 0x0D}, // Channel 0D - Reserved
{ErrorHandler, 0x0E}, // Channel 0E - Reserved
{ErrorHandler, 0x0F}, // Channel 0F - Reserved
{ErrorHandler, 0x10}, // Channel 10 - Reserved
{ErrorHandler, 0x11}, // Channel 11 - Reserved
{ErrorHandler, 0x12}, // Channel 12 - Reserved
{ErrorHandler, 0x13}, // Channel 13 - Reserved
{ErrorHandler, 0x14}, // Channel 14 - Reserved
{ErrorHandler, 0x15}, // Channel 15 - Reserved
{ErrorHandler, 0x16}, // Channel 16 - Reserved
{ErrorHandler, 0x17}, // Channel 17 - Reserved
{ErrorHandler, 0x18}, // Channel 18 - Reserved
{ErrorHandler, 0x19}, // Channel 19 - Reserved
{ErrorHandler, 0x1A}, // Channel 1A - Reserved
{ErrorHandler, 0x1B}, // Channel 1B - Reserved
{ErrorHandler, 0x1C}, // Channel 1C - Reserved
{ErrorHandler, 0x1D}, // Channel 1D - Reserved
{ErrorHandler, 0x1E}, // Channel 1E - Reserved
{ErrorHandler, 0x1F}, // Channel 1F - Reserved
{ErrorHandler, 0x20}, // Channel 20 - Reserved
{ErrorHandler, 0x21}, // Channel 21 - Reserved
{ErrorHandler, 0x22}, // Channel 22 - Reserved
{ErrorHandler, 0x23}, // Channel 23 - Reserved
{ErrorHandler, 0x24}, // Channel 24 - Reserved
{ErrorHandler, 0x25}, // Channel 25 - Reserved
{ErrorHandler, 0x26}, // Channel 26 - Reserved
{ErrorHandler, 0x27}, // Channel 27 - Reserved
{ErrorHandler, 0x28}, // Channel 28 - Reserved
{ErrorHandler, 0x29}, // Channel 29 - Reserved
{ErrorHandler, 0x2A}, // Channel 2A - Reserved
{ErrorHandler, 0x2B}, // Channel 2B - Reserved
{ErrorHandler, 0x2C}, // Channel 2C - Reserved
{ErrorHandler, 0x2D}, // Channel 2D - Reserved
{ErrorHandler, 0x2E}, // Channel 2E - Reserved
{ErrorHandler, 0x2F}, // Channel 2F - Reserved
{ErrorHandler, 0x30}, // Channel 30 - XSRAM20K Access Violation
{ErrorHandler, 0x31}, // Channel 31 - XGATE Software Error Interrupt
{ErrorHandler, 0x32}, // Channel 32 - XGATE Software Trigger 7
{ErrorHandler, 0x33}, // Channel 33 - XGATE Software Trigger 6
{ErrorHandler, 0x34}, // Channel 34 - XGATE Software Trigger 5
{ErrorHandler, 0x35}, // Channel 35 - XGATE Software Trigger 4
{ErrorHandler, 0x36}, // Channel 36 - XGATE Software Trigger 3
{ErrorHandler, 0x37}, // Channel 37 - XGATE Software Trigger 2
{ErrorHandler, 0x38}, // Channel 38 - XGATE Software Trigger 1
{ErrorHandler, 0x38}, // Channel 39 - XGATE Software Trigger 0
{ErrorHandler, 0x3A}, // Channel 3A - Periodic Interrupt Timer 3
{ErrorHandler, 0x3B}, // Channel 3B - Periodic Interrupt Timer 2
{(XGATE_Function)PIT1Handler, (int)ShifterData}, // Channel 3C - Periodic
Interrupt Timer 1
{ErrorHandler, 0x3D}, // Channel 3D - Periodic Interrupt Timer 0
{ErrorHandler, 0x3E}, // Channel 3E - Reserved
{ErrorHandler, 0x3F}, // Channel 3F - Autonomous Periodical interrupt API
{ErrorHandler, 0x40}, // Channel 40 - Low Voltage interrupt LVI
{ErrorHandler, 0x41}, // Channel 41 - IIC1 Bus
{ErrorHandler, 0x42}, // Channel 42 - SCI5
{ErrorHandler, 0x43}, // Channel 43 - SCI4
{ErrorHandler, 0x44}, // Channel 44 - SCI3
{ErrorHandler, 0x45}, // Channel 45 - SCI2
{ErrorHandler, 0x46}, // Channel 46 - PWM Emergency Shutdown
{ErrorHandler, 0x47}, // Channel 47 - Port P Interrupt
{ErrorHandler, 0x48}, // Channel 48 - CAN4 transmit
{ErrorHandler, 0x49}, // Channel 49 - CAN4 receive
{ErrorHandler, 0x4A}, // Channel 4A - CAN4 errors
{ErrorHandler, 0x4B}, // Channel 4B - CAN4 wake-up
{ErrorHandler, 0x4C}, // Channel 4C - CAN3 transmit
{ErrorHandler, 0x4D}, // Channel 4D - CAN3 receive
{ErrorHandler, 0x4E}, // Channel 4E - CAN3 errors
{ErrorHandler, 0x4F}, // Channel 4F - CAN3 wake-up
{ErrorHandler, 0x50}, // Channel 50 - CAN2 transmit
{ErrorHandler, 0x51}, // Channel 51 - CAN2 receive
{ErrorHandler, 0x52}, // Channel 52 - CAN2 errors
{ErrorHandler, 0x53}, // Channel 53 - CAN2 wake-up
{ErrorHandler, 0x54}, // Channel 54 - CAN1 transmit
{ErrorHandler, 0x55}, // Channel 55 - CAN1 receive
{ErrorHandler, 0x56}, // Channel 56 - CAN1 errors
{ErrorHandler, 0x57}, // Channel 57 - CAN1 wake-up
{ErrorHandler, 0x58}, // Channel 58 - CAN0 transmit
{ErrorHandler, 0x59}, // Channel 59 - CAN0 receive
{ErrorHandler, 0x5A}, // Channel 5A - CAN0 errors
{ErrorHandler, 0x5B}, // Channel 5B - CAN0 wake-up
{ErrorHandler, 0x5C}, // Channel 5C - FLASH
{ErrorHandler, 0x5D}, // Channel 5D - EEPROM
{ErrorHandler, 0x5E}, // Channel 5E - SPI2
{ErrorHandler, 0x5F}, // Channel 5F - SPI1
{ErrorHandler, 0x60}, // Channel 60 - IIC0 Bus
{ErrorHandler, 0x61}, // Channel 61 - Reserved
{ErrorHandler, 0x62}, // Channel 62 - CRG Self Clock Mode
{ErrorHandler, 0x63}, // Channel 63 - CRG PLL lock
{ErrorHandler, 0x64}, // Channel 64 - Pulse Accumulator B Overflow
{ErrorHandler, 0x65}, // Channel 65 - Modulus Down Counter underflow
{ErrorHandler, 0x66}, // Channel 66 - Port H
{ErrorHandler, 0x67}, // Channel 67 - Port J
{ErrorHandler, 0x68}, // Channel 68 - ATD1
{ErrorHandler, 0x69}, // Channel 69 - ATD0
{ErrorHandler, 0x6A}, // Channel 6A - SCI1
{ErrorHandler, 0x6B}, // Channel 6B - SCI0
{ErrorHandler, 0x6C}, // Channel 6C - SPI0
{ErrorHandler, 0x6D}, // Channel 6D - Pulse accumulator input edge
{ErrorHandler, 0x6E}, // Channel 6E - Pulse accumulator A overflow
{ErrorHandler, 0x6F}, // Channel 6F - Enhanced Capture Timer overflow
{ErrorHandler, 0x70}, // Channel 70 - Enhanced Capture Timer channel 7
{ErrorHandler, 0x71}, // Channel 71 - Enhanced Capture Timer channel 6
{ErrorHandler, 0x72}, // Channel 72 - Enhanced Capture Timer channel 5
{ErrorHandler, 0x73}, // Channel 73 - Enhanced Capture Timer channel 4
{ErrorHandler, 0x74}, // Channel 74 - Enhanced Capture Timer channel 3
{ErrorHandler, 0x75}, // Channel 75 - Enhanced Capture Timer channel 2
{ErrorHandler, 0x76}, // Channel 76 - Enhanced Capture Timer channel 1
{ErrorHandler, 0x77}, // Channel 77 - Enhanced Capture Timer channel 0
{ErrorHandler, 0x78}, // Channel 78 - Real Time Interrupt
{ErrorHandler, 0x79}, // Channel 79 - IRQ
};
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
######## END of XGATE.CXGATE ####################

----- Original Message -----
From: "Molnar, George S"
Newsgroups: gmane.comp.hardware.microcontrollers.hc12
Sent: Thursday, May 18, 2006 8:16 PM
Subject: RE: Re: Help in streamlining my xgate code
> Ed,
>
> Wow, how to take the wind out of someone's sails... Anyhow, you are
> absolutely right if the code is used as is. Initially, I used a logic
> analyzer to verify the frame data when I was running at slower speeds.
> I then used the Ground station to check it until it could not lock onto
> the frame. That occurred at about 2.67 Mhz. The GS is happy as a clam
> with it. It is not reporting errors on the frame statistics report. The
> output graphs of the frame counters ( both major and minor frame ) are
> clean ramps with no glitching. However I never looked at the signal
> again until today with the LA. And you are right, there is a large
> amount of jitter. I slowed the rate to 2.5 Mhz and used a temporary
> register to do the load and shifting then at the isr I output the temp
> register onto the port ( delayed one count ). This locks the data
> transition to the PIT timer better. However even at 2.5 Mhz (400 ns) I
> was seeing about 60-100 ns of jitter. The actual application will be
> around 2.0 MHz ( req'mt still undefined ). I also clear the interrupt
> flag at the top of the isr vs. the end ( this seemed to have an impact
> on speed ).
>
> george
>
> -----Original Message-----
> From: 6... [mailto:6...] On Behalf
> Of Edward Karpicz
> Sent: Wednesday, May 17, 2006 5:30 AM
> To: 6...
> Subject: [68HC12] Re: Help in streamlining my xgate code
>
> George ("aerowesty2000") wrote:
>
>> Thank you Steve and Doron for the great suggestions. Steve, just
>> placing the function code into the isr netted 1.94 Mhz and combining
>> Doron's suggestion of using Port AD1 vs PortAB resulted in over 2.67
>> Mhz. Many thanks to you guys for the fine suggestions. I connected
>> the simulator up to the ground station and the telemetry decommed
>> perfectly. Thanks again. When I get a chance I will figure out if
>> the xgate code has been placed in ram. I did a quick check of the map
>> file and it seems to be scattered. Thanks again..
>>
>> George
>
> George, are you sure you saw continuous asinchronous 2.67MHz bitstream
> on AD
> port? Did you really connected osciloscope to AD port and saw ~1.3MHz
> meander when shifting 0x5555 or 0xaaaa continuously? Sorry, but I tried
> to
> experiment doing first your code, then optimising it. IMO it's very hard
> or
> even impossible to have all 3 working: 1) shift out bits by XGATE at
> such
> high and 2) _constant_ bit rate and 3) feeding XGATE with useful data
> from
> S12X without underflows or huge jitter on port pins. I'm not saying that
> it's impossible to get up to 2MHz or maybe even more but definitely not
> as
> easy as just only replacing PRU regiter by not PRU or removing 2 BRA
> instructions
> for function call. I really doubt your figures.
>
> In your previous message you wrote:
>
>> handler. My problem lies in the fact I cannot get past 1.5 Mhz
>> out. I need to get to about 2.5 Mhz ( with breathing room ). I
>> have severely cut out features and streamlined my previous code
>> attempts. I top out at a PITLD reg value of 51. I have the PLL set
>
> You said you top out at PITLDQ. At max possible 40MHz bus speed it's
> (51+1)*25ns= 1.3 us PIT period or less than 0.77MHz. This is more
> adequate
> for your old code rather than 1.5MHz. Either you didn't try to check it
> with
> scope or you are running your 9s12x at double max speed, 80MHz bus clock
> or
> 160MHz core clock (XGATE clock).
> Feeding XGATE at 2.5MHz/16 bits rate with _real data_ from S12X is also
> challenging. The only possible application for this would be just read
> data
> from flash and send it serially. No breathing room for anything else.
> My advices:
>
> 1) your XGATE interrupt handler doesn't take arguments. You should
> utilize
> XGATE feature that R1 register value is loaded from XGATE vector table.
> XGATE interrupt handler argument is that R1 register. You could pack
> your X
> variables into structure and pass pointer to it through vector table.
> This
> way you could save on reloads of 16bit const address of variable. Code
> would
> get a bit smaller and of course faster.
>
> 2) Test counter against zero may be faster than test against nonzero
> const.
> So maybe decrement bit counter and reload it (on new data) to nonzero
> constant.
>
> 3) Look at diassmbled code and try to understand it. Then think how you
> could eliminate instructions you think must be avoided.
>
> 4) SPI isn't exactly power of two. 2,4,6,8,10,12,14,16,20,24 dividers
> are
> available. If that's still too big granulity then what about lowering
> PLL
> frequency down from max 80MHz when it's necessary to get into freqs
> between
> available SPI dividers?
> Regards,
> Edward

Memfault Beyond the Launch