PulseOut issue

Discussion specific to the ZX-1281 and ZX-1280 microcontrollers as well as the ZX-1281 and ZX-1280 Dev Boards.
Post Reply
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

PulseOut issue

Post by pjc30943 »

The following fails to produce pulses on a 1280n. However, alternate calls putpin with 0 and 1 states yield a toggling pin, so the detection is correct.

Code: Select all

const debugPin as byte = J.1
putpin debugPin, 0
do
	pulseout debugPin,  1E-5, 1
	sleep 0.001
loop

Anyone have thoughts? Most likely this is something silly I'm doing wrong...
Paul
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: PulseOut issue

Post by dkinzer »

pjc30943 wrote:The following fails to produce pulses on a 1280n.
I copied your code verbatim and placed in inside Sub Main() ... End Sub. Running it produces a pulse 10.2uS long beginning approximately every 46 uS.

Can you duplicate that as a simple test case?
- Don Kinzer
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Re: PulseOut issue

Post by pjc30943 »

dkinzer wrote:
pjc30943 wrote:The following fails to produce pulses on a 1280n.
I copied your code verbatim and placed in inside Sub Main() ... End Sub. Running it produces a pulse 10.2uS long beginning approximately every 46 uS.

Can you duplicate that as a simple test case?

It does work as written above.

It turns out the problem arises from a part of the initialization routine, where I alter TMR4 (see below). Or at least I *think* I'm only using TMR4. If this section is commented out, pulseOut() works. Otherwise, if it's called after the following code, nothing is outputted.
Doesn't pulseOut() use TMR2?

Code: Select all

   '~~~~~~~~~~~~ PWM ~~~~~~~~~~~~~~
	'based on TMR4 (PWM)
	OpenPWM motor1PWMCh, SERVO_REFRESH_RATE, zxCorrectPWM				'set up for RC control
	PWM motor1PWMch, SERVO_PWM_CENTER_PERCENT
	PWM servo1PWMch, SERVO_PWM_CENTER_PERCENT	'0.0625
	'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
with

Code: Select all

public const motor1PWMch 		as byte = 7		'ch8 PWM, L.4, based on timer 4
public const servo1PWMch	 	as byte = 8		'ch7 PWM, L.3

EDIT:

Additionally, the following does not work inside the loop:

Code: Select all

dim testVar as single
testVar = 1.0 / 1E5
pulseout debugPin,  testVar, 1 
'pulseout debugPin,  1.0 / 1E5, 1 
but if the comments are swapped then it does:

Code: Select all

'dim testVar as single
'testVar = 1.0 / 1E5
'pulseout debugPin,  testVar, 1 
pulseout debugPin,  1.0 / 1E5, 1 
The literal appears to give the expected result.
Paul
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: PulseOut issue

Post by dkinzer »

pjc30943 wrote:Doesn't pulseOut() use TMR2?
No. On a ZX-1280 or ZX-1280n the timer used for I/O functions like PulseOut() is Timer4. This information is found in the Resource Usage section of the System Library Reference. The I/O timer is indicated in the column of the table with the heading I/O.
- Don Kinzer
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Post by pjc30943 »

Ah, okay. Thanks for clarifying.

What is still unclear, then, is the varied outcome for a literal vs. variable parameter. I'll verify the code, as it's probably a simple mistake that I'm doing.
Paul
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Post by pjc30943 »

I verified the code. This example does not produce pulses:

Code: Select all

Option TargetCPU zx1280n
public const debugPin 		as byte = J.1 
public bvars as single
Sub Main()
	putpin debugPin, zxOutputLow
	bvars = 2E-5
	do 
	   'pulseout debugPin,  2E-5, 1 
	   pulseout debugPin,  bvars, 1 
	   sleep 0.002
	loop
End Sub
but this does:

Code: Select all

Option TargetCPU zx1280n
public const debugPin 		as byte = J.1 
public bvars as single
Sub Main()
	putpin debugPin, zxOutputLow
	bvars = 2E-5
	do 
	   pulseout debugPin,  2E-5, 1 
	   'pulseout debugPin,  bvars, 1 
	   sleep 0.002
	loop
End Sub
Paul
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

pjc30943 wrote:This example does not produce pulses
We were able to reproduce the problem and have identified both the cause and the solution. It is an issue with native mode code generation for PulseOut() when it has type Single, non-constant value for the duration parameter. The compiler correctly deduces that in this particular case the value of bvars might change over the iterations of the loop since it is a public variable and could be modified by another task.

A workaround is to either make bvars local to Main() or introduce a local variable to hold the value as shown in the code below. Using the local variable allows the compiler to see that the value of the duration won't change over the iterations of the loop and, hence, it can compute the duration in IO_Timer ticks at compile time. With a non-constant value, code is generated to convert the Single value to IO_Timer ticks at run time and it was this code that was incorrect.

Code: Select all

Option TargetCPU zx1280n
public const debugPin 		as byte = J.1 
public bvars as single
Sub Main()
  putpin debugPin, zxOutputLow
  bvars = 2E-5
  Dim duration as Single
  duration = bvars
  do 
    pulseout debugPin, duration, 1 
    sleep 0.002
  loop
End Sub
- Don Kinzer
Post Reply