5234 eTPU code for QOM module?

Discussion to talk about software related topics only.
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

5234 eTPU code for QOM module?

Post by Ridgeglider »

If anyone is willing to share code that runs the the eTPU QOM (Queued Output Match) pulse generator, I'd be interested in taking a look.
Thanks
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

Re: 5234 eTPU code for QOM module?

Post by fanat9 »

QOM very easy to use.

Single pulse with "on_time_t" length (Active High) and return to Low/Default state:

Code: Select all


uint32 on_time_t = (pulse_length_uS * etpu_a_tcr1_freq) / 1000000;

union etpu_events_array sparkSource_QOM_array[2] =
{
	{(0x00000 << 1) + FS_ETPU_PIN_HIGH},
	{(on_time_t << 1) + FS_ETPU_PIN_LOW}
};

int result = fs_etpu_qom_init(CHANNEL01, FS_ETPU_PRIORITY_HIGH, FS_ETPU_QOM_SINGLE_SHOT, FS_ETPU_TCR1, FS_ETPU_QOM_INIT_PIN_LOW, FS_ETPU_QOM_IMMEDIATE, (uint32_t *) 0, 0, array_size, sparkSource_QOM_array);

Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: 5234 eTPU code for QOM module?

Post by Ridgeglider »

fanat thanks for your code. It looked so simple! I must be missing something though. Any suggestions appreciated. Basically, I'm trying to create a pulse on eTPU 5 which I think is J2[9]. For now, I stuck with your oneshot code although in the future I'll be generating continuous pulsetrains. I put your code inside a simple while loop that also toggles J2[7]. When J2[7] goes high, I should see the QOM pulse on J2[9] but the line stays low. Before calling fs_etpu_qom_init(), I call eTPUInit(). I have also tried substituting that call with MOD5234_etpu_init(); followed by MOD5234_etpu_start(); Neither worked.

I can use the eTPU GPIO routines to toggle J2[9] so I know the pin can move if called corrctly. The QOM is just not doing it yet.... The code currently starts by writing J2[9] low, but it didn't work if I just let it float in the initial hiz state either.

Finally, I noticed that your code to produce the on_time_t values works for small microsecond vales, but for millisecond values it breaks s,o for now I just hard coded it. The 1 mSec value is still less that the maximum 22 bit quantity of 3F-FFFF.


Here's the demo code:

Code: Select all

#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <dhcpclient.h>

#include <pins.h>
#include <eTPUinit.h>	// NetBurner eTPU Initialization
#include <eTPU.h>		// NetBurner eTPU API
#include <etpu_qom.h>	// QOM module

#include <sim5234.h>		// sim

extern "C" {
void UserMain(void * pd);
}

const char * AppName="5234_eTPU_QOM-1";

void UserMain(void * pd) {
    InitializeStack();
    if (EthernetIP == 0) GetDHCPAddress();
    OSChangePrio(MAIN_PRIO);
    EnableAutoUpdate();

    iprintf("Application started: %s\n", AppName);

	eTPUInit();		// Standard init for ETPU, puts all channels in hiz (inputs)
	//	MOD5234_etpu_init();
	//	MOD5234_etpu_start();

    int on_time_t = 36864 ; //(1 msec => (1000 usec * etpu_a_tcr1_freq) / 1000000;
    union etpu_events_array event_array[2] =
    {
          {(0x00000   << 1) + FS_ETPU_PIN_HIGH},	// pin goes hi
          {(on_time_t << 1) + FS_ETPU_PIN_LOW},		// len lo after on_time_t
    };

    J2[9] = 0;	// start w/ eTPU5 low.

	while ( 1 ) {
		// Toggle two pins: J2[7] by GPIO calls as a marker.
		//                  J2[9] via eTPU QOM call.
		J2[7] = 1; // Use J2[7] to trigger scope. QOM Pulse on J2[9] should follow it.
		// Every 100 msec QOM should send a pulse hi on J2[9]for 1 msec then lo again.

		//This should work, but the pin never fires...?
		int result = fs_etpu_qom_init(	5,	//J2[9]
									FS_ETPU_PRIORITY_HIGH,
									FS_ETPU_QOM_SINGLE_SHOT,
									FS_ETPU_TCR1,
									FS_ETPU_QOM_INIT_PIN_LOW,
									FS_ETPU_QOM_IMMEDIATE,
									(uint32_t *) 0,
									0,
									2,
									event_array);
		OSTimeDly( 1 );

       iprintf("etpu 5 ret val = %d, ontime = 0x%x, = %d\r", result, on_time_t, on_time_t);
		J2[7] = 0;	// reset J2[7]
		OSTimeDly( 1 );
	}
}
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

Re: 5234 eTPU code for QOM module?

Post by fanat9 »

Well, for slow/long pulses you should switch to FS_ETPU_TCR2 timer.

I also have to generate mS pulses on few other channels. And I can't remember exact values for frequency/dutycycle, but at some point I was actually forced to change prescaler for TCR2 to get it to work. My current settings:

nburn_folder\MOD5234\system\ETPU\ETPUinit.cpp

Code: Select all

uint32_t etpu_a_tcr1_freq = 36864000;
uint32_t etpu_a_tcr2_freq = 921600;
uint32_t etpu_b_tcr1_freq = 0;
uint32_t etpu_b_tcr2_freq = 0;

struct etpu_config_t MOD5234_etpu_config =
{
  /* etpu_config.mcr */
  FS_ETPU_VIS_OFF	/* SCM not visible (VIS=0) */
  | FS_ETPU_MISC_DISABLE	/* SCM operation disabled (SCMMISEN=0) */,

  /* etpu_config.misc */
  FS_ETPU_MISC,

  /* etpu_config.ecr_a */
  FS_ETPU_ENTRY_TABLE_ADDR	/* entry table base address = shifted FS_ETPU_ENTRY_TABLE */
  | FS_ETPU_CHAN_FILTER_3SAMPLE	/* channel filter mode = three-sample mode  */
  | FS_ETPU_ENGINE_ENABLE	/* engine is enabled (MDIS=0) */
  | FS_ETPU_FILTER_CLOCK_DIV2	/* channel filter clock = etpuclk div 2 (FPSCK=0) */,

  /* etpu_config.tbcr_a */
  FS_ETPU_ANGLE_MODE_DISABLE	/* TCR2 angle mode is disabled (AM=0) */
  | FS_ETPU_TCR2_PRESCALER(10)	/* TCR2 prescaler = 1 (TCR2P='1-1') */
  | FS_ETPU_TCR1_PRESCALER(1)	/* TCR1 prescaler = 1 (TCR1P='1-1') */
  | FS_ETPU_TCRCLK_MODE_INTEGRATION	/* TCRCLK signal is filtered using integration mode (TCRCF=1x) */
  | FS_ETPU_TCR2CTL_DIV8	/* TCR2 source = etpuclk div 8 (TCR2CTL=4) */
  | FS_ETPU_TCRCLK_INPUT_CHANCLOCK	/* TCRCLK signal is filtered with filter clock = channel filter clock (TCRCF=x1) */
  | FS_ETPU_TCR1CTL_DIV2	/* TCR1 source = etpuclk div 2 (TCR1CTL=2) */,

  /* etpu_config.stacr_a */
  FS_ETPU_TCR1_STAC_SERVER	/* TCR1 resource operates as server (RSC1=1) */
  | FS_ETPU_TCR2_STAC_SERVER	/* TCR2 resource operates as server (RSC2=1) */
  | FS_ETPU_TCR1_STAC_DISABLE	/* TCR1 operation on STAC bus disabled (REN1=0) */
  | FS_ETPU_TCR2_STAC_DISABLE	/* TCR2 operation on STAC bus disabled (REN2=0) */
  | FS_ETPU_TCR1_STAC_SRVSLOT(0)	/* TCR1 resource server slot = 0 (SRV1=0) */
  | FS_ETPU_TCR2_STAC_SRVSLOT(0)	/* TCR2 resource server slot = 0 (SRV2=0) */,

  /* etpu_config.ecr_b */
  0,

  /* etpu_config.tbcr_b */
  0,

  /* etpu_config.stacr_b */
  0
};
And it shouldn't matter, but who knows: I'm using etpu_set1. So, in same file:

Code: Select all

/* eTPU function set used */
//#include <NNDK_etpu_set.h>       
#include <etpu_set1.h>
And recompile everything.
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

Re: 5234 eTPU code for QOM module?

Post by rnixon »

I'm not a etpu guy, but I think you need to be careful with the pins class. If you write the pin as gpio, I think that pins function is no longer etpu. I would try to leave it as initialized and assigned as an etpu pin. Is there anything to need to do to assign it to an etpu function with the pins class?
fanat9
Posts: 56
Joined: Thu Apr 24, 2008 4:23 pm
Location: Boston
Contact:

Re: 5234 eTPU code for QOM module?

Post by fanat9 »

Good point Nixon. I forgot to mention it.

And even switching between pure eTPU function doesn't always work. I know switching between PWM and QOM functions works, but between SPWM and QOM doesn't.

And I don't use eTPUInit(), just MOD5234_etpu_init() and MOD5234_etpu_start() instead.

Also, eTPU module is actually independent controller with its own memory.
So, since you trigger QOM events in a loop, you may reset it before it started/or finished previous queue. Try to delay it for let say 2 seconds.

Btw, you can set QOM mode to a single shot mode, loop(up to 256 times) or to continuous and it will run independently of main MCF5234 core.
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: 5234 eTPU code for QOM module?

Post by Ridgeglider »

Thanks guys...
I agree with your recommendation to avoid the pins class (even though it's implemented by the gpio etpu module). However, Section 6.1 of the NB etpu Appnote states:
"The standard NetBurner initialization function is int eTPUInit(). This function will initialize all eTPU settings, RAM and start the timers on the eTPU. Once the eTPU is started, this function will configure all of the channels to be GPIO inputs to put the system in a safe state. Channels can switch between function while the eTPU is running so it is OK to first initialize them all to be high impedance." In any case, I've tried my code with the following variations, all w/o any output:

1) eTPUInit() followed by the fs_etpu_qom_init() call.
2) eTPUInit() followed by J[x] = 0, followed by the the fs_etpu_qom_init() call for pin x.
3) Instead of eTPUInit(), I've tried MOD5234_etpu_init() followed by MOD5234_etpu_start().
4) After calling MOD5234_etpu_init() followed by MOD5234_etpu_start(), I've added calls to eTPUEventPoll(PinX, Delay), then eTPUEventClear(pinX). This is done in the SPI etpu example.

Finally, I do understand that lop mode would definitely be the way to go instead of putting the single shot call into the while loop. However, I figured that I might have the wrong values for the values of the event counts, and consequently, I thought I might somehow be missing them on my scope. Because of this, I put them in the while loop and called them just after setting another pin hi so that I could use that edge as a trigger to mark the start of the etpu output. That trigger line uses one of the etpu lines, so I just tried commenting it out in case, as a pins call, it perturbs the fs_etpu_qom_init() call. Did't work.

The last thing I tried is to move the fs_etpu_qom_init() call to before the while loop. I've tried CONTINUOUS, CONTINUOUS_A, and SINGLE_SHOT mode -- all w/o any output: the pin stays hiz.

By the way, any idea what the difference between continuous, and continuous_a mode might be?
roland.ames

Re: 5234 eTPU code for QOM module?

Post by roland.ames »

eTPUInit() does initialise all eTPU channels into GPIO mode. So don't use it if you are going to use anything other than GPIO

I have not used QOM, but I had the same problem with trying to use some eTPU pins for SPI functions. There is a problem with changing pins from one mode to another, so it is best to set the function of each pin just once to the required function.

I would suggest looking at the source code in nburn\MOD5234\system\ETPU, to see what the standard initialisation does. Then make your own version of it to make sure your QOM pins are not initialised as GPIO but as QOM instead.

Pins classes work fine for eTPU pins initialised as GPIO, have a look at the source code for pins in nburn\MOD5234\system\pins.cpp for the eTPU pins, J2[5] - J2[20].
The default initialisation eTPUInit() will allow you to use pins class for all eTPU pins.
roland.ames

Re: 5234 eTPU code for QOM module?

Post by roland.ames »

Ridgeglider wrote: However, Section 6.1 of the NB etpu Appnote states:
"The standard NetBurner initialization function is int eTPUInit(). This function will initialize all eTPU settings, RAM and start the timers on the eTPU. Once the eTPU is started, this function will configure all of the channels to be GPIO inputs to put the system in a safe state. Channels can switch between function while the eTPU is running so it is OK to first initialize them all to be high impedance."
At the end of section 6.2 it also says:
"Note: The eTPU has a RAM malloc issue that can affect the switching of functions but this should be corrected by Freescale in the near future. If you cannot get a function to run properly on a channel, then use this method to initialize and start the eTPU. The SPI example demonstrated this work around initialization."

And I think this is relevant to your problem.

I know I had exactly this problem when trying to get the SPI functions to work, I had to use the manual initialisation method and set each pin to its required function once only on initialisation.
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: 5234 eTPU code for QOM module?

Post by Ridgeglider »

Continuing the saga, I took everyone's advice and modified a new version of the eTPUinit() function so that it specifically did not init the pins I'll use as QOM channels as GPIO first. Now, the QOM init is the only one that happens for the targeted pins. No luck. Just to be sure I was on the right pins, I edited some of the eTPU PWM code examples so it only ran the pins I was interested in for QOM, and sure enough the pins worked fine as PWM, so at least I'm on the right pins, eg eTPU 5 = J2[9].

Last attempt is the following:
Init etpu pins 0, 1, 2 as GPIO (normal init)
Init etpu pins 3, 4, 5 as continuous sq wave (1ms) QOM outputs
Init etpu pins 6, 7 (skipping 8) as GPIO (normal init)

This code uses the MOD5234_etpu_init(), MOD5234_etpu_start(), followed by the eTPUEventPoll(), and eTPUEventClear() process demonstrated in the SPI example.

Result: No QOM outputs visible, GPIO works. Finally, after a 10 sec delay after the original inits, I rewrite one of the previously inited QOM pins (ch3) as PWM. PWM output appears, suggesting that the eTPU is still running and not crashed.

The take away is that the QOM module is non-functional. I'm on Rel2.5.3. I've opened a support ticket. Will keep you all posted. Thanks for your help.
Post Reply