PDA

View Full Version : Counters and Background Processing


GATJR
01-07-05, 03:27 PM
Good Morning,

We have a few questions concerning our ServoPodUSB. We need to make the ServoPod do several things in the background and we plan to communicate with the device using the console mode in the foreground. We us a VB front end that basically downloads the entire program to the ServoPod upon boot up and then VB Active objects to control the ServoPod.

Measure Frequency #1 (10hz to 400hz )
Measure Frequency #2 ( 5hz to 900hz )
Count the number of pulses of frequency #2 (32 bit)
Emit a specific number of pulses (Direction and 0-12000 pulses)
Read a quadrature encoder (32 bit)

I looked at the forum and found a reference to Jawahar but the solution looked very complex and not really code for the counting

We have used the following code working for the stepper but would like to do the same in the background:

VARIABLE PWIDTH ( Width of pulses
: STEERING_ENABLE PB2 OFF ; ( Enable stepper drive
: STEERING_STEP PB0 OFF PB1 OFF ; ( Size of step for micro-stepper
: STEERING_INIT STEERING_STEP STEERING_ENABLE ;
: DELAY 0 DO 1 1 + DROP LOOP ;
: PULSES 0 DO PB4 ON PWIDTH @ DELAY PB4 OFF PWIDTH @ DELAY LOOP ;
: FORWARD PB3 ON PULSES ;
: REVERSE PB3 OFF PULSES ;
9 PWIDTH !
5000 FORWARD

This really pretty time consuming and destroys any other foreground processing while running the stepper.

PWM-IN measures a pulse width but we'd prefer to measure the time between pulses.

We use the following code to run the servos in a 0-100% position (1 channel shown), Is this good or is there a better way?:

SCRUB
PWMA0 INDEPENDENT
3337 CONSTANT MINPOS EEWORD ( ~.59 mS for JR
11723 CONSTANT MAXPOS EEWORD ( ~2.38 ms for JR
MAXPOS MINPOS + 2/ CONSTANT MIDPOS EEWORD
MAXPOS MINPOS - CONSTANT RCRANGE EEWORD
100 CONSTANT RCSCALE# EEWORD ( 100 DECIMAL
: Init0 32767 PWMA0 PWM-PERIOD MIDPOS PWMA0 PWMOUT ; EEWORD
: RCOUT0 0 MAX RCSCALE# MIN RCRANGE RCSCALE# */ MINPOS + PWMA0 PWM-OUT ; EEWORD
Init0
0 RCOUT0

Hope it is OK to ask for this level of assistance. Thanks in advance for your consideration. I'm not really a forum kinda guy, I sure hope this works.

RMDumse
01-07-05, 05:39 PM
Originally posted by GATJR
Hope it is OK to ask for this level of assistance. Thanks in advance for your consideration. I'm not really a forum kinda guy, I sure hope this works.

Sure, we prefer to answer questions like this on the forum, because just as you found some answer to another user useful, the same is true. We can answer this once, and hopefully serve many customers at once. There are so many aspects to your question, I think I will break them down and take a few at a time.

First a note, these timers in the 'Pods are some of the "sweetest" timers we've ever seen. The features are many fold and very versatile. I'll see what I can figure out and post in sections shortly.

RMDumse
01-07-05, 05:57 PM
Originally posted by GATJR

Measure Frequency #1 (10hz to 400hz )
Measure Frequency #2 ( 5hz to 900hz )
Count the number of pulses of frequency #2 (32 bit)
Emit a specific number of pulses (Direction and 0-12000 pulses)
Read a quadrature encoder (32 bit)


Starting with quadrature. This is exceedingly easy. There are two quadrature decoders built in in hardware. They share lines with TMRA0,1 and TMRB0,1. If you don't need inputs or outputs on these pins, the timers can still be used independently of the quadrature decoders. Also, the timers themselves can be quadrature decoders! So it is possible to read up two sets of quadrature decoders per timer module, and there are 4 modules (but really only 3 and a half, because TMC2,3 don't have pins, and we are using these as the system timers). So as a maximum, you could read 7 quadrature channels. But! why use timers if you don't need to?

The internal 32-bit quadrature channel have many wonderful features, but you can ignore most of them, and just use them as they power up. So unless you need more, let's make this simple.

To read a 32-bit quadrature channel remotely, you only need to hook up the A and B lines to TMRA0,1. The internal hardware will do the rest. A second channel can be hooked to TMRB0,1. To read the first quad channel simply double fetch the hex location E47. The second encoder can be read at E57.

Example:

HEX
E47 2@ D.
E57 2@ D.

Turn the encoders and test again, you'll see the values have changed.

There's another neat register associated with these registers. If you read E44 (first channel), or E54 (second channel), it will have the difference between this time reading of the count and the last time reading. In other words, if you periodically read the main registers for position, this difference register will give you the velocity (derivative of position wrt time).

RMDumse
01-07-05, 06:18 PM
Originally posted by GATJR

Measure Frequency #1 (10hz to 400hz )
Measure Frequency #2 ( 5hz to 900hz )
Count the number of pulses of frequency #2 (32 bit)
Emit a specific number of pulses (Direction and 0-12000 pulses)
Read a quadrature encoder (32 bit)


Now let's look at measuring frequency. There are two approaches to measuring frequency. One is to measure for a fixed time, and see how many pulses you have, say count for 1 second, if your count in that period is 10, you have 10 Hz. If your count is 900 you have 900 Hz. The other way is to measure the length of the pulse duration, and knowing the time of the pulse, the inverse tells you the frequency. So if your measure a pulse to be 10mS long, you have 10 Hz, if you measure a pulse to be 1.111 mS long, you have 900 Hz.

Which method you use depends on how stable your signal is, and how often you want the answer. Accumulating over a long period gives a slow but stable answer. Measuring over one pulse gives a quick but easily variable answer.

Then there are also issues of accuracy. If you accumulate 5 pulses over 1 second, your answer can only have a little accuracy in the digit. (Your other possibilities would be 4 or 6, so your digit is only about 20% accurate.

Since you mention measuring a frequency, and also accumulating a frequency, I'm guessing you're looking for a pulse width measurement of duration, and will invert that to get frequency.

So what we need to do is pick a time base that will give us enough counts at 900 Hz to be able to resolve the pulse width significantly and, hopefully, not run out of counts when we read a 5 Hz signal. Let's see if that is possible.

At 900 Hz, our pulse width is 1.111 mS. At 5 Hz our pulse width is 200 mS. So our time range is 200:1.

We have ranges we can set the counters to count by prescaler. The system IP clock is 40MHz, and a 16-bit counter can accumulate 65536 ... more later. Have to stop for now.

GATJR
01-07-05, 07:06 PM
Thanks for all of the information. This is all really helpful. I would actually like to measure frequency from same edge to same edge. The PWM-IN word measures from initial edge to opposite edge.

RMDumse
01-08-05, 12:12 PM
Continuing on, so if we could fit the perfect prescaler to the 16 bit timer, we could still only have an accuracy of ~4% on the 900 Hz end, and still read the 5 Hz end below the 65535 count. And we can't have the perfect prescaler.

1 = 0.0016384 (maximum length of pulse measured in seconds)
2 = 0.0032768
4 = 0.0065536
8 = 0.0131072
16= 0.0262144
32= 0.0524288
64= 0.1048576
128= 0.2097152

This last prescaler divider comes very close to fitting your needs. 5Hz is .2 S. So if you set a 16-bit timer to read the IP divided by 128, you can read a pulse width of .209 seconds at the slow end, and 900 Hz with an accuracy of 1 part in ~20 (around 5% accuracy).

Short of going to a 32-bit count, that's the best you can do. On the other hand, there's no reason not to cascase timers and get 32, or even 64 or 128 bits of accuracy. Of course, then you have to deal with the larger math. In the 32-bit count example, I'll get into cascading timers, but for now, I'll assume you want to use a single 16-bit timer and that will be "close enough" for your needs.

Next post, I'll take the same approach as I did with Jawahar and figure out the settings of the timer, starting with a list of all possible combinations of control bits in the CTRL and STATUS register to get the results you want.

RMDumse
01-08-05, 03:04 PM
Following, I started with all possible bit combinations for the timer registers, and then picked only the patterns we were interested int, then converted those bit patterns to bits, then to groups of 4 bits, then to hexidecimal numbers, and finally picked two timers (TMR2, 3) to measure frequencey and made the initialization patters in hex for those timers.

( CTRL
( BASE + 6
( 000 ( COUNT MODE NO COUNT
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 010 ( COUNT RISING AND FALLING EDGES OF PRIMARY SOURCE
( 011 ( COUNT RISING EDGES OF PRIMARY SOURCE WHILE SEC. HIGH
( 100 ( QUADRATURE RISING EDGES OF PRIMARY AND SEC. SOURCE
( 101 ( COUNT PRIMARY SOURCE RISING EDGES, SEC. SPECS. DIRECTION
( 110 ( EDGE OF SEC. SOURCE TRIGGERS PRIMARY COUNT TILL COMPARE
( 111 ( CASCASE COUNTER MODE UP/DOWN
( 0000 ( Counter #0 input pin
( 0001 ( Counter #1 input pin
( 0010 ( Counter #2 input pin
( 0011 ( Counter #3 input pin
( 0100 ( Counter #0 output
( 0101 ( Counter #1 output
( 0110 ( Counter #2 output
( 0111 ( Counter #3 output
( 1000 ( PRIMARY COUNT SOURCE IP/1
( 1001 ( PRIMARY COUNT SOURCE IP/2
( 1010 ( PRIMARY COUNT SOURCE IP/4
( 1011 ( PRIMARY COUNT SOURCE IP/8
( 1100 ( PRIMARY COUNT SOURCE IP/16
( 1101 ( PRIMARY COUNT SOURCE IP/32
( 1110 ( PRIMARY COUNT SOURCE IP/64
( 1111 ( PRIMARY COUNT SOURCE IP/128
( 00 ( SECONDARY COUNT Counter # 0 input
( 01 ( SECONDARY COUNT Counter # 1 input
( 10 ( SECONDARY COUNT Counter # 2 input
( 11 ( SECONDARY COUNT Counter # 3 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 1 ( COUNT ONCE - 1 ONCE AND STOP
( 0 ( COUNT LENGTH ROLL OVER
( 1 ( COUNT LENGTH COUNT UNTIL COMPARE AND REINITIALIZE
( 0 ( DIR COUNT UP
( 1 ( DIR COUNT DN
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 1 ( COINIT FORCE BY OTHER COUNTER WHEN ACTIVE COMPARE
( 000 ( Active while counter is active, OUPUT MODE
( 001 ( CLEAR OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 010 ( SET OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 011 ( TOGGLE OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 100 ( TOGGLE OFLAG USING ALTERNATING COMPARE REG
( 101 ( SET ON COMPARE, CLEAR ON SEC. SOURCE INPUT EDGE
( 110 ( SET ON COMPARE, CLEAR ON COUNTER ROLLOVER
( 111 ( ENABLE GATED CLOCK OUTPUT WHILE COUNTER IS ACTIVE

( STATUS
( BASE + 7
( 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 01 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=0
( 01 CAPTURE REGISTER OPERATION CAP ON FALLING EDGE IF IPS=1
( 10 CAPTURE REGISTER OPERATION CAP ON FALLING EDGE IF IPS=0
( 10 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=1
( 11 CAPTURE REGISTER OPERATION CAP ON BOTH EDGE
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN




( CTRL
( BASE + 6
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 1111 ( PRIMARY COUNT SOURCE IP/128
( 00 ( SECONDARY COUNT Counter # 0 input
( 01 ( SECONDARY COUNT Counter # 1 input
( 10 ( SECONDARY COUNT Counter # 2 input
( 11 ( SECONDARY COUNT Counter # 3 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 0 ( COUNT LENGTH ROLL OVER
( 0 ( DIR COUNT UP
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 000 ( Active while counter is active, OUPUT MODE

( STATUS
( BASE + 7
( 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 01 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=0
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN


( CTRL
( BASE + 6
( 0011111xx0000000
( 0011 111x x000 0000
( 3 E,F 8,0 0

( 3 E 0 0 input pin #0
( 3 E 8 0 input pin #1
( 3 F 0 0 input pin #2
( 3 F 8 0 input pin #3

( STATUS
( BASE + 7
( 0000000001000000
( 0000 0000 0100 0000
( 0 0 4 0



3F00 D16 ! ( TMRA2 CTRL
0040 D17 ! ( TMRA2 STATUS
3F80 D1E ! ( TMRA3 CTRL
0040 D1F ! ( TMRA3 STATUS

With this set up TMRA2 uses its input pin as the secondary count input. When a rising edged occurs, it captures the count. The count it captures is a free running count-up of the system 40MHz clock divided by 128.

There are no timer functions automatically measure a pulse width from edge to same edge. So, this process will take a little software support to function. What the software must do is set up for a capture, take that value, clear the capture, then come back later and take the second captured value. The difference between the first capture and the second will be the period for the frequency. Inversion of the period will yeild the frequency.

The real time burden on the system then is to be able to take a capture and prepare for another, without having an interveining one happen (which would give a falsely long reading).

So I'd suggest a machine chain operating once each millisecond. This should be fast enough to occur at leasst once and maybe even twice during a fast pulse of 900 Hz, so readings should be accurate, taken from one capture before another one can arrive.

So now the issue is to design the software that will do this.

Here's some code (not yet downloaded or tested) that would be my approach.


SCRUB

VARIABLE TMP2 EEWORD
FVARIABLE TMR2FREQ EEWORD

: TMR2EDGE?
D17 @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD

: TMR2CAP&CLR
D12 @ TMP2 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
312500E0 S>F F/ TMR2FREQ F!
0040 D17 ! ( CLR EDGE
D12 @ TMP2 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD

: TMR2FREQ
TMR2EDGE?
IF
TMR2CAP&CLR
THEN
; EEWORD

: TMR2FREQ? TMR2FREQ F@ F. ; EEWORD

VARIABLE TMP3 EEWORD
FVARIABLE TMR3FREQ EEWORD

: TMR3EDGE?
D1F @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD

: TMR2CAP&CLR
D1A @ TMP3 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
312500E0 S>F F/ TMR3FREQ F!
0040 D1F ! ( CLR EDGE
D1A @ TMP3 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD

: TMR3FREQ
TMR3EDGE?
IF
TMR3CAP&CLR
THEN
; EEWORD

: ALL ( CHKFREQ
TMR2FREQ
TMR3FREQ
; EEWORD

: TMR3FREQ? TMR3FREQ F@ F. ; EEWORD

: STARTUP
3F00 D16 ! ( TMRA2 CTRL
0040 D17 ! ( TMRA2 STATUS
D15 @ TMP2 ! ( GET SOME INITIAL VALUE IN TMP2
3F80 D1E ! ( TMRA3 CTRL
0040 D1F ! ( TMRA3 STATUS
D1D @ TMP3 ! ( GET SOME INITIAL VALUE IN TMP3
EVERY 5000 CYCLES SCHEDULE-RUNS ALL ( 1000cps
; EEWORD


DECIMAL
SAVE-RAM
( AUTOSTART STARTUP ( 80x V.7 VERSION
( HEX EC00 AUTOSTART STARTUP DECIMAL ( 807 V.6 VERSION
( HEX 3C00 AUTOSTART STARTUP DECIMAL ( 805 V.6 VERSION

Once STARTUP is executed, or if autostarted, on power up, after the first cycle, the frequency will always be available in the foreground by doing a TMR2FREQ? or TMR3FREQ? word.

RMDumse
01-08-05, 03:32 PM
Now turning attention to using a couple timers for a 32-bit accumulator, this is easily accomplished by just setting the timers up. Then the two timer registers being read will give the results.

( CTRL
( 000 ( COUNT MODE NO COUNT
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 010 ( COUNT RISING AND FALLING EDGES OF PRIMARY SOURCE
( 011 ( COUNT RISING EDGES OF PRIMARY SOURCE WHILE SEC. HIGH
( 100 ( QUADRATURE RISING EDGES OF PRIMARY AND SEC. SOURCE
( 101 ( COUNT PRIMARY SOURCE RISING EDGES, SEC. SPECS. DIRECTION
( 110 ( EDGE OF SEC. SOURCE TRIGGERS PRIMARY COUNT TILL COMPARE
( 111 ( CASCASE COUNTER MODE UP/DOWN
( 0000 ( Counter #0 input pin
( 0001 ( Counter #1 input pin
( 0010 ( Counter #2 input pin
( 0011 ( Counter #3 input pin
( 0100 ( Counter #0 output
( 0101 ( Counter #1 output
( 0110 ( Counter #2 output
( 0111 ( Counter #3 output
( 1000 ( PRIMARY COUNT SOURCE IP/1
( 1001 ( PRIMARY COUNT SOURCE IP/2
( 1010 ( PRIMARY COUNT SOURCE IP/4
( 1011 ( PRIMARY COUNT SOURCE IP/8
( 1100 ( PRIMARY COUNT SOURCE IP/16
( 1101 ( PRIMARY COUNT SOURCE IP/32
( 1110 ( PRIMARY COUNT SOURCE IP/64
( 1111 ( PRIMARY COUNT SOURCE IP/128
( 00 ( SECONDARY COUNT Counter # 0 input
( 01 ( SECONDARY COUNT Counter # 1 input
( 10 ( SECONDARY COUNT Counter # 2 input
( 11 ( SECONDARY COUNT Counter # 3 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 1 ( COUNT ONCE - 1 ONCE AND STOP
( 0 ( COUNT LENGTH ROLL OVER
( 1 ( COUNT LENGTH COUNT UNTIL COMPARE AND REINITIALIZE
( 0 ( DIR COUNT UP
( 1 ( DIR COUNT DN
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 1 ( COINIT FORCE BY OTHER COUNTER WHEN ACTIVE COMPARE
( 000 ( OUPUT MODE, Active while counter is active
( 001 ( CLEAR OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 010 ( SET OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 011 ( TOGGLE OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 100 ( TOGGLE OFLAG USING ALTERNATING COMPARE REG
( 101 ( SET ON COMPARE, CLEAR ON SEC. SOURCE INPUT EDGE
( 110 ( SET ON COMPARE, CLEAR ON COUNTER ROLLOVER
( 111 ( ENABLE GATED CLOCK OUTPUT WHILE COUNTER IS ACTIVE

( STATUS 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 01 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=0
( 01 CAPTURE REGISTER OPERATION CAP ON FALLING EDGE IF IPS=1
( 10 CAPTURE REGISTER OPERATION CAP ON FALLING EDGE IF IPS=0
( 10 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=1
( 11 CAPTURE REGISTER OPERATION CAP ON BOTH EDGE
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN





( TMRB3 - low order for 32 pulse accumulator
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 0011 ( Counter #3 input pin
( 00 ( SECONDARY COUNT Counter # 0 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 0 ( COUNT LENGTH ROLL OVER
( 0 ( DIR COUNT UP
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 000 ( OUPUT MODE, Active while counter is active
( CTRL 0010011000000000 - 0010 0110 0000 0000 - 2600

( 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN
( STATUS 000000000000000 - 0000 0000 0000 0000 - 0000


( TMRB2 - high order for 32 pulse accumulator
( 111 ( CASCASE COUNTER MODE UP/DOWN
( 0111 ( Counter #3 output
( 00 ( SECONDARY COUNT Counter # 0 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 0 ( COUNT LENGTH ROLL OVER
( 0 ( DIR COUNT UP
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 000 ( OUPUT MODE, Active while counter is active
( CTRL 1110111000000000 - 1110 1110 0000 0000 - EE00

( 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN
( STATUS 000000000000000 - 0000 0000 0000 0000 - 0000


;

HEX
: TMR-INIT
( CTRL 0010011000000000 - 0010 0110 0000 0000 - 2600
( STATUS 000000000000000 - 0000 0000 0000 0000 - 0000
2600 D3E ! ( CTRL TMRB3
0000 D3F ! ( STATUS TMRB3

( CTRL 1110111000000000 - 1110 1110 0000 0000 - EE00
( STATUS 000000000000000 - 0000 0000 0000 0000 - 0000
EE00 D36 ! ( CTRL TMRB2
0000 D37 ! ( STATUS TMRB2

0000 D35 ! ( ZERO TMRB2 CNTR REG.
0000 D3D ! ( ZERO TMRB3 CNTR REG.
; EEWORD


A feature of the timers is, that reading any timer counter register in within a module of 4 timers causes the other counter registers in that group to also be captured into a hold register. So to take the 32-bit count without worrying about the carry from the lower timer effecting the upper timer between the time one and the next counter registers are read.

The Counter register for the lower order bits in this example is at D3D. But reading it will cause the upper bits (normally read at D35) to be held at D34. So a 32-bit read would look like this.

: READ32 D3D @ D34 @ ; EEWORD

Which could then be converted into a "printed" value by doing a D.

GATJR
01-08-05, 06:57 PM
RMDumse this is awesome. It is just what we needed to keep us moving forward.

Is there a way to create a set of equates that could be included so that hardnumbers don't need to be used. Does IsoMax have an include function that could read an external file? Redirect the interpreter to a file and then return or something like that?

Again, thanks so much for continuing to work through our questions.

RMDumse
01-09-05, 11:21 AM
Finally, the timers have a mode I've not experimented with much personally, but I think it is perfect for your stepper control. Here's a section from the User Manual.

14.6.10 Pulse-Output Mode

If the counter is setup for count mode (mode = 001), and the OFLAG output mode is set to 111, gated clock output, and the count OnCE bit is set, then the counter will output a pulse stream of pulses with the same frequency of the selected clock source. The number of output pulses is equal to the compare value minus the initialization value. This mode is useful for driving step motor systems.

So, if we use one timer to generate a squarewave of the frequency we want, we can use a second timer to parcel out the pulses. Again, this deserves testing (I don't have the equipment to do it this weekend) so I'll let you try it and see if the results are right.

Starting again with the full range of setup possibilities, and picking the settings we need for the two timers...

( CTRL
( 000 ( COUNT MODE NO COUNT
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 010 ( COUNT RISING AND FALLING EDGES OF PRIMARY SOURCE
( 011 ( COUNT RISING EDGES OF PRIMARY SOURCE WHILE SEC. HIGH
( 100 ( QUADRATURE RISING EDGES OF PRIMARY AND SEC. SOURCE
( 101 ( COUNT PRIMARY SOURCE RISING EDGES, SEC. SPECS. DIRECTION
( 110 ( EDGE OF SEC. SOURCE TRIGGERS PRIMARY COUNT TILL COMPARE
( 111 ( CASCASE COUNTER MODE UP/DOWN
( 0000 ( Counter #0 input pin
( 0001 ( Counter #1 input pin
( 0010 ( Counter #2 input pin
( 0011 ( Counter #3 input pin
( 0100 ( Counter #0 output
( 0101 ( Counter #1 output
( 0110 ( Counter #2 output
( 0111 ( Counter #3 output
( 1000 ( PRIMARY COUNT SOURCE IP/1
( 1001 ( PRIMARY COUNT SOURCE IP/2
( 1010 ( PRIMARY COUNT SOURCE IP/4
( 1011 ( PRIMARY COUNT SOURCE IP/8
( 1100 ( PRIMARY COUNT SOURCE IP/16
( 1101 ( PRIMARY COUNT SOURCE IP/32
( 1110 ( PRIMARY COUNT SOURCE IP/64
( 1111 ( PRIMARY COUNT SOURCE IP/128
( 00 ( SECONDARY COUNT Counter # 0 input
( 01 ( SECONDARY COUNT Counter # 1 input
( 10 ( SECONDARY COUNT Counter # 2 input
( 11 ( SECONDARY COUNT Counter # 3 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 1 ( COUNT ONCE - 1 ONCE AND STOP
( 0 ( COUNT LENGTH ROLL OVER
( 1 ( COUNT LENGTH COUNT UNTIL COMPARE AND REINITIALIZE
( 0 ( DIR COUNT UP
( 1 ( DIR COUNT DN
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 1 ( COINIT FORCE BY OTHER COUNTER WHEN ACTIVE COMPARE
( 000 ( OUPUT MODE, Active while counter is active
( 001 ( CLEAR OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 010 ( SET OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 011 ( TOGGLE OFLAG OUTPUT ON SUCCESSFUL COMPARE
( 100 ( TOGGLE OFLAG USING ALTERNATING COMPARE REG
( 101 ( SET ON COMPARE, CLEAR ON SEC. SOURCE INPUT EDGE
( 110 ( SET ON COMPARE, CLEAR ON COUNTER ROLLOVER
( 111 ( ENABLE GATED CLOCK OUTPUT WHILE COUNTER IS ACTIVE

( STATUS 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 01 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=0
( 01 CAPTURE REGISTER OPERATION CAP ON FALLING EDGE IF IPS=1
( 10 CAPTURE REGISTER OPERATION CAP ON FALLING EDGE IF IPS=0
( 10 CAPTURE REGISTER OPERATION CAP ON RISING EDGE IF IPS=1
( 11 CAPTURE REGISTER OPERATION CAP ON BOTH EDGE
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN


( CTRL TMRD0
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 1100 ( PRIMARY COUNT SOURCE IP/16
( 00 ( SECONDARY COUNT Counter # 0 input
( 0 ( COUNT ONCE - 0 REPEATEDLY
( 1 ( COUNT LENGTH COUNT UNTIL COMPARE AND REINITIALIZE
( 0 ( DIR COUNT UP
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 011 ( TOGGLE OFLAG OUTPUT ON SUCCESSFUL COMPARE

( STATUS 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN


( CTRL TMRD1
( 001 ( COUNT RISING EDGES OF PRIMARY SOURCE
( 0100 ( Counter #0 output
( 00 ( SECONDARY COUNT Counter # 0 input
( 1 ( COUNT ONCE - 1 ONCE AND STOP
( 1 ( COUNT LENGTH COUNT UNTIL COMPARE AND REINITIALIZE
( 0 ( DIR COUNT UP
( 0 ( COINIT NO FORCE BY OTHER CHANNELS
( 111 ( ENABLE GATED CLOCK OUTPUT WHILE COUNTER IS ACTIVE

( STATUS 00 TCF, TCFIE
( 00 TOF, TOFIE
( 00 IEF, IEFIE
( 0 IPS
( 0 INPUT
( 00 CAPTURE DISABLED
( 0 MASTER
( 0 EEOF
( 0 VAL
( 0 FORCE
( 0 OPS
( 0 OEN


( CTRL TMRD0
( 0011100000100011
( 0011 1000 0010 0011
( 3 8 2 3

( STATUS 0000000000000000
( 0000 0000 0000 0000
( 0 0 0 0

( CTRL TMRD1
( 0010100001100111
( 0010 1000 0110 0111
( 2 8 6 7

( STATUS 0000000000000000
( 0000 0000 0000 0000
( 0 0 0 0




: SETPLSRATE
D60 ! ( STORE VALUE IN COMPARE#1
3823 D66 ! ( TMRD0 CTRL
0000 D67 ! ( TMRD0 STATUS
; EEWORD

: SET#PLS
D68 !
2867 D6E ! ( TMRD1 CTRL
0000 D6F ! ( TMRD1 STATUS
; EEWORD

: PLSR-INIT
4000 SETPLSRATE
1000 SET#PLS
; EEWORD

: PLSR-DONE?
D6F @ 8000 AND
; EEWORD

RMDumse
01-09-05, 11:27 AM
Originally posted by GATJR
Is there a way to create a set of equates that could be included so that hardnumbers don't need to be used. Does IsoMax have an include function that could read an external file? Redirect the interpreter to a file and then return or something like that?


Certainly there are ways to use things like equates, but those are simply variables or constants.

The idea of using things in separate include files is rather a concept of a compiler, with access to a hard disk. This language is interactive, and has no "files" on hard disk it can select.

On the other hand, you can write code that is not timer specific, and then create constants needed in the code, then download the code.

Remember too, you have Flash. You can define constants in Flash, then assign them later.

But perhaps just using constants would be enough.

3823 CONSTANT TMRCTRL4PULSEGENERATION
D60 CONSTANT TMRD0CTRL

TMRCTRL4PULSEGENERATION TMRD0CTRL !

GATJR
01-10-05, 07:38 PM
Is it possible that all of these code examples refer to a processor other than that which is used in the ServoPodUSB?

RMDumse
01-10-05, 11:08 PM
Why, yes, actually. [blush] Sorry, those were all for 803 and 805 processors. The ServoPod(TM) uses the 807. My bad.

All the D00 addresses for the timers are off by 400 hex locations in 807's. So D16 should be should be 1116, etc.

See page 3-14 of the DSP Users Manual for base addresses of the various registers.

GATJR
01-11-05, 01:33 AM
No worries, Is everything else the same except for the offset in the base register start location? Functionality, capability, etc?

RMDumse
01-11-05, 04:11 AM
For the timer banks, yes, everything else is the same except offset for base address.

lac54
01-11-05, 03:30 PM
I'm trying to implement the code you have presented in this discussion using the Servopod USB. Here are my results:

1. For the 32 bit accumulator, the first read result is zero. If I connect to J10 Pin34 there is a count. One issue is that the count starts at 65,535 and counts up from there.

2. I am connecting to J11 Pin28 and receive no output pulses when running the code. I have also tried J11 Pin 25.

3. I am connecting a square wave generator at 250Hz to J10 Pin 13, 16 and I do not get a valid result for the frequency (3.2312E-13) and I also get stack empty errors.

Can you let me know why I do not seem to be getting the expected results?

Thank you.

Here's the code I am using:


SCRUB
IsoMax V0.76
HEX OK
OK
VARIABLE TMP2 EEWORD OK
FVARIABLE TMR2FREQ EEWORD OK
OK
: TMR2EDGE?
1117 @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD OK
OK
: TMR2CAP&CLR
1112 @ TMP2 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
312500E0 S>F F/ TMR2FREQ F!
0040 1117 ! ( CLR EDGE
1112 @ TMP2 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD OK
OK
: TMR2FREQ
TMR2FREQ NOT UNIQUE
TMR2EDGE?
IF
TMR2CAP&CLR
THEN
; EEWORD OK
OK
: TMR2FREQ? TMR2FREQ F@ F. ; EEWORD OK
OK
VARIABLE TMP3 EEWORD OK
FVARIABLE TMR3FREQ EEWORD OK
OK
: TMR3EDGE?
111F @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD OK
OK
: TMR3CAP&CLR
111A @ TMP3 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
312500E0 S>F F/ TMR3FREQ F!
0040 111F ! ( CLR EDGE
111A @ TMP3 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD OK
OK
: TMR3FREQ
TMR3FREQ NOT UNIQUE
TMR3EDGE?
IF
TMR3CAP&CLR
THEN
; EEWORD OK
OK
: ALL ( CHKFREQ
TMR2FREQ
TMR3FREQ
; EEWORD OK
OK
: TMR3FREQ? TMR3FREQ F@ F. ; EEWORD OK
OK
: STARTUP
3F00 1116 ! ( TMRA2 CTRL
0040 1117 ! ( TMRA2 STATUS
1115 @ TMP2 ! ( GET SOME INITIAL VALUE IN TMP2
3F80 111E ! ( TMRA3 CTRL
0040 111F ! ( TMRA3 STATUS
111D @ TMP3 ! ( GET SOME INITIAL VALUE IN TMP3
EVERY 5000 CYCLES SCHEDULE-RUNS ALL ( 1000cps
; EEWORD OK
OK
: SETPLSRATE
1160 ! ( STORE VALUE IN COMPARE#1
3823 1166 ! ( TMRD0 CTRL
0000 1167 ! ( TMRD0 STATUS
; EEWORD OK
OK
: SET#PLS
1168 !
2867 116E ! ( TMRD1 CTRL
0000 116F ! ( TMRD1 STATUS
; EEWORD OK
OK
: PLSR-INIT
4000 SETPLSRATE
1000 SET#PLS
; EEWORD OK
OK
: PLSR-DONE?
116F @ 8000 AND
; EEWORD OK
OK
: TMR-INIT
( CTRL 0010011000000000 - 0010 0110 0000 0000 - 2600
( STATUS 000000000000000 - 0000 0000 0000 0000 - 0000
2600 113E ! ( CTRL TMRB3
0000 113F ! ( STATUS TMRB3

( CTRL 1110111000000000 - 1110 1110 0000 0000 - EE00
( STATUS 000000000000000 - 0000 0000 0000 0000 - 0000
EE00 1136 ! ( CTRL TMRB2
0000 1137 ! ( STATUS TMRB2

0000 1135 ! ( ZERO TMRB2 CNTR REG.
0000 113D ! ( ZERO TMRB3 CNTR REG.
; EEWORD OK
OK
: READ32 113D @ 1134 @ ; EEWORD OK
OK
DECIMAL OK
SAVE-RAM OK
AUTOSTART STARTUP ( 80x V.7 VERSION OK
( HEX EC00 AUTOSTART STARTUP DECIMAL ( 807 V.6 VERSION OK
( HEX 3C00 AUTOSTART STARTUP DECIMAL ( 805 V.6 VERSION OK
OK
TMR-INIT OK
READ32 D. 0 OK
READ32 D. 0 OK
READ32 D. 65537 OK
READ32 D. 65538 OK
OK
PLSR-INIT OK
PLSR-INIT OK
PLSR-INIT OK
PLSR-INIT OK
PLSR-DONE? OK
PLSR-INIT OK
PLSR-DONE? OK
PLSR-INIT OK
PLSR-DONE? OK
PA0 ON OK
PA0 OFF OK
PA0 ON OK
PA0 OFF OK
PA0 ON OK
PA0 OFF OK
PA0 OFF OK
PA0 ON OK
PA0 OFF OK
PA0 ON OK
ALL OK
TMR2FREQ? 3.2312E-13 OK
TMR3FREQ? 3.2312E-13 OK
ALL OK
TMR2FREQ? 3.2312E-13 OK
TMR3FREQ? -2.5672E21
TMR3FREQ? ? STACK EMPTY
TMR3FREQ? -2.5672E21
TMR3FREQ? ? STACK EMPTY
ALL OK
TMR3FREQ? -2.5672E21
TMR3FREQ? ? STACK EMPTY

nmitech
01-13-05, 11:18 AM
3. I am connecting a square wave generator at 250Hz to J10 Pin 13, 16 and I do not get a valid result for the frequency (3.2312E-13) and I also get stack empty errors.

Can you let me know why I do not seem to be getting the expected results?



A quick look at your program, you defined the variable & word using the same name. If you did so the previous data will be ignored. In this case, the Variable will be ignored, and the Word will be executed each time the name is called. That caused stack error.

FVARIABLE TMR2FREQ EEWORD

: TMR2FREQ
TMR2EDGE?
IF
TMR2CAP&CLR
THEN
; EEWORD

( ........
( ........

FVARIABLE TMR3FREQ EEWORD

: TMR3FREQ
TMR3EDGE?
IF
TMR3CAP&CLR
THEN
; EEWORD

RMDumse
01-13-05, 11:33 AM
Argh. Another case of "my bad". Well, I did try to make it clear the code was written and not tested.

lac54
02-23-05, 05:24 PM
I have modified the frequency measurement code to work on a servopod usb with 500Hz connected and it seems to work except that it is giving values back randomly that are either 1/2 or 2x the preponderant value being returned. Can you explain why this happens and how you would correct this? Here is the code I am using:

Thank you,
Larry



SCRUB
HEX

( *************** MEASURE FREQ ************************
VARIABLE TMP2 EEWORD
VARIABLE TMR2FREQI EEWORD

: TMR2EDGE?
1117 @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD

: TMR2CAP&CLR
1112 @ TMP2 @ > IF
1112 @ TMP2 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
ELSE
( 0 TMP2 @ - 1112 @ +
TMR2FREQI @
THEN
TMR2FREQI !
0040 1117 ! ( CLR EDGE
1112 @ TMP2 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD

: CTMR2FREQ
TMR2EDGE?
IF
TMR2CAP&CLR
THEN
; EEWORD

: TMR2FREQI? TMR2FREQI @ . ; EEWORD

: ALL ( CHKFREQ
CTMR2FREQ
; EEWORD

: INIT_FREQ
0040 1117 ! ( TMRA2 STATUS
3F00 1116 ! ( TMRA2 CTRL
1115 @ TMP2 ! ( GET SOME INITIAL VALUE IN TMP2
EVERY 5000 CYCLES SCHEDULE-RUNS ALL ( 1000cps
; EEWORD
( *************** END MEASURE FREQ *********************

DECIMAL
: DELAY 1000 0 DO 1 1 * DROP LOOP ; EEWORD
HEX
: TEST
BEGIN
TMR2FREQI?
?KEY IF EXIT THEN
DELAY
AGAIN ; EEWORD

I just run INIT_FREQ and then TEST.

lac54
02-24-05, 01:32 PM
Any ideas?

RMDumse
02-24-05, 02:25 PM
Originally posted by lac54
Any ideas?

Yes, but so far, only ideas. I downloaded and tried the program last night, but of course, without an input frequency, I got only 0's out. What is the usual amount you get from TMR2FREQI?

Here is my suspiction. In TMR2CAP&CLR you check

1112 @ TMP2 @ >

and only if it is greater you then subtract. If it is not greater, you just take the previous value and replace.

IF
1112 @ TMP2 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
ELSE
( 0 TMP2 @ - 1112 @ +
TMR2FREQI @
THEN
TMR2FREQI !

So why throw away all case where TMP2 is greater than the captured value? A subtraction still should get the right number.

For instance, let's say you normally get a reading of 30000. Let's say your first compare is at a counter value of 2000, your next timer capture will be at 32000. So you check 32000 and it is greater than 2000. Great, you subtract and get 30000.

Now run again. so you capture at 62000, and have 32000 from the previous time. But when you check with > the 62000 appears smaller than 32000 (62000 is treated as a negative number), so you don't calculate this time, (even though 62000 - 32000 = 30000 which would have been correct).

Now run again. so you capture at 26464, and have 62000 from the previous time. When you check with > the 62000 appears smaller than 26464 (62000 is treated as a negative number), so you do calculate this time.

RMDumse
02-24-05, 02:31 PM
Here is another idea. Where is this signal coming from? Sometimes signals are noisy. So if there was a bounce on the edge (remember the 'Pod can see a 40MHz pulse that is difficult to even catch with most scopes) it will read half frequency. That may not explain the long reading, but I've seen signal sources with bad grounds, or grounds that float a bit, give problems too.

So here's an idea. Make one of the timers generate 500 Hz, and jumper it to this timer's inputs. If it reads its own single without problems, its likely the incoming signal. If it still has double or half times with its own timer, then its likely a software issue.

lac54
02-24-05, 03:02 PM
The compare was my attempt at detecting and handling a zero crossing situation. Is this what could be happening?

I can also try to connect a timer to the input, but I am currently using a function generator and I have checked the output signal with an oscilloscope to be sure the edges are clean.

lac54
02-24-05, 03:20 PM
Just FYI...
I took out the if statement I was using to check for the timer overflowing (zero crossing) and it does the same thing: 0, 1/2, 2x

GATJR
02-24-05, 09:39 PM
Sorry to horn in on this but we need to find a solution pretty soon. So I thought I'd try another tact.

I am using the code previously discussed feeding it with a BNC coax line to the ServoPodUSB at 471hz. Noise ain't the issue.

This is the capture from NMITerm

Start of Capture
Start ?
FREQLOOP 1326 0
661 0
1327 0
1326 0
1328 0
1327 0
1327 0
1325 0
1327 0
1327 0
1327 0
1327 0
1326 0
1327 0
1326 0
1327 0
1326 0
1326 0
1327 0
1327 0
1326 0
1326 0
1326 0
1327 0
1327 0
1327 0
1327 0
1327 0
1327 0
1326 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1327 0
1326 0
1327 0
1327 0
1327 0
1327 0
1326 0
1327 0
1327 0
1326 0
663 0
1326 0
1327 0
1315 0
1326 0
1326 0
663 0
1328 0
663 0
1326 0
1326 0
1327 0
663 0
1327 0
1325 0
1326 0
663 0
1327 0
1327 0
1326 0
663 0
1327 0
1327 0
1326 0
1326 0
1326 0
1326 0
1327 0
1327 0
1326 0
1326 0
1326 0
1327 0
1326 0
1326 0
1326 0
1327 0
1327 0
1326 0
1323 0
1327 0
1327 0
1327 0
1326 0
1327 0
1327 0
1327 0
1327 0
1326 0
1324 0
1327 0
1327 0
1326 0
1326 0
1326 0
1326 0
1326 0
1326 0
1326 0
1327 0
1327 0
1326 0
1327 0
1324 0
1326 0
1327 0
1327 0
1327 0
1325 0
1328 0
1326 0
1326 0
1326 0
1326 0
1327 0
663 0
1326 0
1326 0
1327 0
663 0
1327 0
1327 0
1326 0
664 0
1327 0
1326 0
1327 0
1325 0
1326 0
1326 0
1326 0
1325 0
1327 0
1327 0
1327 0
1327 0
1327 0
1327 0
1326 0
1327 0
1328 0
1326 0
1326 0
1317 0
1326 0
1323 0
1326 0
1326 0
1327 0
1327 0
1326 0
1316 0
1327 0
1327 0
1328 0
1326 0
1324 0
1327 0
1327 0
1326 0
1326 0
1326 0
1327 0
1327 0
1326 0
1327 0
1327 0
1326 0
1327 0
1328 0
1326 0
1327 0
1326 0
1326 0
1327 0
1326 0
1326 0
1327 0
664 0
1327 0
1325 0
1326 0
663 0
1327 0
1326 0
1327 0
664 0
1327 0
663 0
1325 0
663 0
1327 0
1318 0
1326 0
1326 0
1327 0
1320 0
1327 0
1326 0
1327 0
1327 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1327 0
1326 0
1326 0
1326 0
1326 0
1326 0
1327 0
1326 0
1327 0
1327 0
1327 0
1325 0
1326 0
1327 0
1327 0
1326 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1326 0
1326 0
1324 0
1326 0
1315 0
1328 0
1327 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1326 0
1323 0
1327 0
1326 0
1326 0
1326 0
1319 0
1327 0
1327 0
1327 0
1326 0
663 0
1327 0
1327 0
1327 0
663 0
1327 0
664 0
1325 0
663 0
1326 0
1327 0
1320 0
664 0
1326 0
1326 0
1327 0
663 0
1327 0
1326 0
1324 0
664 0
1327 0
1327 0
1326 0
1327 0
1324 0
1327 0
1324 0
1326 0
1327 0
1326 0
1327 0
1326 0
1326 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1327 0
1327 0
1324 0
1326 0
1327 0
1327 0
1326 0
1325 0
1327 0
1327 0
1326 0
1327 0
1324 0
1327 0
1326 0
1326 0
1326 0
1326 0
1327 0
1327 0
1327 0
1328 0
1326 0
1327 0
1327 0
1327 0
1324 0
1327 0
1327 0
1327 0
1327 0
1326 0
1326 0
1326 0
1325 0
1327 0
1323 0
1326 0
1327 0
0 0
1326 0
663 0
1327 0
663 0
1327 0
663 0
1326 0
663 0
1327 0
1327 0
1326 0
664 0
1326 0
1326 0
1326 0
663 0
1325 0
1327 0
1326 0
1326 0
1326 0
1327 0
1326 0
1318 0
1326 0
1326 0
1326 0
1327 0
1327 0
1324 0
1325 0
1319 0
1326 0
1326 0
1326 0
1326 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1327 0
1325 0
1325 0
1327 0
1326 0
1326 0
1326 0
1324 0
1327 0
1325 0
1327 0
1322 0
1326 0
1325 0
1326 0
1326 0
1326 0
1317 0
1326 0
1327 0
1325 0
1326 0
1326 0
1326 0
1328 0
1327 0
1325 0
1327 0
1326 0
1327 0
1327 0
1327 0
1327 0
1327 0
663 0
1327 0
1324 0
1325 0
656 0
1327 0
663 0
1326 0
664 0
1327 0
663 0
1328 0
1327 0
1326 0
1324 0
1327 0
1327 0
1327 0
1327 0
1326 0
1327 0
1326 0
1323 0
1326 0
1327 0
1326 0
1326 0
1321 0
1327 0
1327 0
1326 0
1326 0
1327 0
1326 0
1327 0
1326 0
1327 0
1327 0
1327 0
1323 0
1326 0
1327 0
1326 0
1326 0
1327 0
1326 0
1327 0
1327 0
1328 0
1327 0
1326 0
1326 0
1326 0
1327 0
1322 0
1326 0
1326 0
1327 0
1327 0
1326 0
1325 0
1327 0
1327 0
1327 0
1327 0
1326 0
1327 0
1327 0
1327 0
1326 0
1326 0
1326 0
1327 0
1326 0
1326 0
1326 0
1326 0
1327 0
1327 0
1326 0
1327 0
664 0
1327 0
1327 0
1326 0
663 0
1327 0
1325 0
1326 0
663 0
1327 0
1327 0
1327 0
663 0
1326 0
1327 0
1329 0
664 0
1326 0
1326 0
1327 0
664 0
1326 0
1326 0
1327 0
1326 0
1326 0
1325 0
1326 0
1326 0
1327 0
1326 0
1328 0
1326 0
1327 0
1327 0
1326 0
1326 0
1327 0
1326 0
1326 0
1326 0
1327 0
1326 0
1322 0
1327 0
1328 0
1326 0
1326 0
1326 0
1328 0
1327 0
1327 0
1326 0
1327 0
1326 0
1327 0
1326 0
1327 0
1326 0
1327 0
1326 0
1326 0
1326 0
1327 0
1323 0
1327 0
1327 0
1328 0
1327 0
1327 0
1326 0
1326 0
1326 0
1326 0
1326 0
1326 0
1326 0
1326 0
1327 0
1327 0
1327 0
1326 0
1326 0
1327 0
1327 0
663 0
1327 0
1327 0
1326 0
662 0
1326 0
663 0
1326 0
663 0
1326 0
1326 0
1327 0
663 0
1327 0
1324 0
1327 0
1328 0
1327 0
1327 0
1327 0
1326 0
1326 0
1324 0
1326 0
1325 0
1327 0
1326 0
1327 0
1326 0
OK
END OF LOOP
END ? MSG# 17
OK
And the other channel
And ?
FREQLOOP 1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1321
1325 1325
1325 1325
1325 1325
1325 1325
1325 1326
1325 1323
1325 1325
1325 1325
1325 1322
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1322
1325 1324
1325 1326
1325 1326
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1324
1325 1326
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1324
1325 1324
1325 1324
1325 1325
1325 1326
1325 1326
1325 1324
1325 1324
1325 1325
1325 1325
1325 1326
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1326
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1323
1325 1326
1325 1324
1325 1324
1325 1326
1325 1325
1325 1325
1325 1325
1325 1325
1325 1322
1325 1325
1325 1325
1325 1324
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1324
1325 1326
1325 1325
1325 1323
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1325
1325 1323
1325 1325
1325 1325
1325 1324
1325 1325
1325 1324
1325 1325
1325 1326
1325 1325
1325 1323
1325 1325
1325 1325
1325 1323
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1323
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1326
1325 1326
1325 1325
1325 1325
1325 1325
1325 1322
1325 1324
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1325
1325 1326
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1326
1325 1324
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1318
1325 1326
1325 1325
1325 1325
1325 1325
1325 1325
1325 1322
1325 1325
1325 1325
1325 1324
1325 1323
1325 1325
1325 1324
1325 1324
1325 1324
1325 1322
1325 1325
1325 1325
1325 1326
1325 1324
1325 1324
1325 1325
1325 1322
1325 1324
1325 1325
1325 1324
1325 1325
1325 1326
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1326
1325 1325
1325 1326
1325 1324
1325 1325
1325 1326
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1320
1325 1325
1325 1325
1325 1323
1325 1325
1325 1324
1325 1323
1325 1326
1325 1326
1325 1322
1325 1325
1325 1324
1325 1321
1325 1324
1325 1326
1325 1324
1325 1324
1325 1325
1325 1323
1325 1323
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1326
1325 1326
1325 1324
1325 1323
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1326
1325 1321
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1326
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1326
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1324
1325 1326
1325 1325
1325 1323
1325 1325
1325 1325
1325 1324
1325 1325
1325 1324
1325 1325
1325 1324
1325 1326
1325 1325
1325 1324
1325 1325
1325 1321
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1326
1325 1323
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1324
1325 1325
1325 1325
1325 1326
1325 662
1325 1324
1325 1325
1325 1325
1325 1325
1325 1326
1325 1326
1325 1324
1325 1325
1325 1324
1325 1325
1325 1325
1325 1324
1325 1324
1325 663
1325 1325
1325 663
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 0
1325 1325
1325 663
1325 1325
1325 663
1325 1325
1325 663
1325 1325
1325 1325
1325 1325
1325 1323
1325 1324
1325 1325
1325 1323
1325 1325
1325 1325
1325 1322
1325 1325
1325 662
1325 1323
1325 662
1325 1324
1325 662
1325 1325
1325 1325
1325 1324
1325 1324
1325 1324
1325 1320
1325 1319
1325 1326
1325 1325
1325 1323
1325 1326
1325 1324
1325 1325
1325 1325
1325 1325
1325 663
1325 1325
1325 662
1325 1326
1325 1326
1325 1324
1325 1324
1325 1323
1325 1325
1325 1325
1325 1326
1325 1325
1325 1325
1325 1324
1325 1324
1325 1324
1325 663
1325 1324
1325 663
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 663
1325 1324
1325 1326
1325 1325
1325 662
1325 1324
1325 1325
1325 1325
1325 1323
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1324
1325 1324
1325 1324
1325 1322
1325 1325
1325 1325
1325 1325
1325 1325
1325 662
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1325
1325 1326
1325 1326
1325 663
1325 1325
1325 662
1325 1324
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1324
1325 1324
1325 1325
1325 1325
1325 1324
1325 662
1325 1325
1325 662
1325 1324
1325 662
1325 1324
1325 662
1325 1325
1325 1325
1325 1325
1325 1325
1325 1324
1325 1324
1325 1325
1325 1325
1325 1324
1325 662
1325 1325
1325 663
1325 1326
1325 662
1325 1324
1325 1324
1325 1324
1325 1325
1325 1325
1325 1326
1325 1325
1325 0
1325 1326
1325 662
1325 1321
1325 663
1325 1324
1325 662
1325 1326
1325 1325
1325 1323
1325 1324
1325 1324
1325 1321
1325 1325
1325 1325
1325 1325
1325 0
1325 1325
1325 662
1325 1325
1325 662
1325 1324
1325 663
1325 1325
1325 1325
1325 1323
1325 1326
1325 1325
1325 1323
1325 1325
1325 1325
1325 1326
OK

I can provide more data if it is needed.

Look how weird this is. Periodically it gives the wrong rythmic data. Even the incorrect result dithers as expected with a digital measurement. Note the mathematical coorelation to the correct responses.

Also note how long it took for the error to start on the second channel, scared me, thought I might be an idiot.

For review here is the code.

( *************** MEASURE FREQ ************************
VARIABLE TMP2 EEWORD
( FVARIABLE TMR2FREQ EEWORD
VARIABLE TMR2FREQI EEWORD
VARIABLE TMR3FREQI EEWORD

: TMR2EDGE?
1117 @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD

: TMR2CAP&CLR
1112 @ TMP2 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
( 312500E0 S>F F/ TMR2FREQ F!

TMR2FREQI !
0040 1117 ! ( CLR EDGE
1112 @ TMP2 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD

: CTMR2FREQ
TMR2EDGE?
IF
TMR2CAP&CLR
THEN
; EEWORD

( : TMR2FREQ? TMR2FREQ F@ F. ; EEWORD
: TMR2FREQI? TMR2FREQI @ . ; EEWORD

VARIABLE TMP3 EEWORD
( FVARIABLE TMR3FREQ EEWORD

: TMR3EDGE?
111F @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD

: TMR3CAP&CLR
111A @ TMP3 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
( 312500E0 S>F F/ TMR3FREQ F!
TMR3FREQI !
0040 111F ! ( CLR EDGE
111A @ TMP3 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
; EEWORD

: CTMR3FREQ
TMR3EDGE?
IF
TMR3CAP&CLR
THEN
; EEWORD

: ALL ( CHKFREQ
CTMR2FREQ
CTMR3FREQ
; EEWORD

( : TMR3FREQ? TMR3FREQ F@ F. ; EEWORD
: TMR3FREQI? TMR3FREQI @ . ; EEWORD

: INIT_FREQ
0040 1117 ! ( TMRA2 STATUS
3F00 1116 ! ( TMRA2 CTRL
1115 @ TMP2 ! ( GET SOME INITIAL VALUE IN TMP2
0040 111F ! ( TMRA3 STATUS
3F80 111E ! ( TMRA3 CTRL
111D @ TMP3 ! ( GET SOME INITIAL VALUE IN TMP3
EVERY 5000 CYCLES SCHEDULE-RUNS ALL ( 1000cps
; EEWORD
( *************** END MEASURE FREQ *********************

: FREQ. TMR2FREQI? TMR3FREQI? ;
: FREQLOOP BEGIN FREQ. DELAY DELAY DELAY CR ?KEY UNTIL KEY DROP ;

It appears to be something funky with hardware or maybe a bit of poor software interaction, lousy FORTH coding on our part , not sure

Way simple to set up and reproduce. Copy this code out, place it in the ServoPOD USB, pump a function generator into TA2, you'll get the same results. Any ideas?

Additional info. We also find that the PWM measurement is not so stable either, does it use the same program or method for pulse width measurement.

Stuck in Utah, looking to Texas for help. Can you pull my Chevy out of the mud?

RMDumse
02-26-05, 03:39 PM
I'm getting another idea. A very careful read of the DSP56F801-7UM goes like this:

14.1 Introduction Each timer module contains four identical counter/timer groups.

14.6.14 Usage of Capture Register
The capture register stores a copy of the counter’s value, an input transition is detected. The register depends on the capture mode and IPS settings. Once a capture event occurs, no further updating of the capture register will occur until the input edge flag (IEF) is cleared by writing a zero to the IEF bit of the SCR. Please refer to Section 14.7.2.9.

14.7.2.5 Input Edge Flag (IEF)—Bit 11
This bit is set when a capture occurs. The bit is cleared by writing a zero to the bit position.

Note: The timer group will not asset another input edge interrupt until this bit has been cleared.


Now what worries me is it doesn't say that "this timer" won't assert another input edge interrupt until this is cleared, it says "this timer group" won't assert another input edge interrupt until this is cleared.

I'm wondering if TMR2 and TMR3 are interacting with each other undesireably.

RMDumse
02-26-05, 05:44 PM
Well, my concerns for the wording has been tested and it isn't a problem. Here you can see I have two edge flags set in this dump:

0 1 2 3 4 5 6 7
1100: 0000 0000 0000 0000 0000 0000 0000 0109 ........
1108: 0000 0000 0000 0000 0000 0000 0000 0109 ........
1110: 0000 0000 DAC6 0000 3F8E 462E 3F00 A940 ........
1118: 0000 0000 ADA9 0000 D41F DABF 3F80 A940 ........ OK

So the second flag will set while one is already on in the timer group.

RMDumse
02-26-05, 06:51 PM
Well, it had me going a while. Turns out I mixed DECIMAL with HEX back in the example and got confused on the timing. Here's what I finally got working. I hooked TA0 to TA2 and TA1 to TA3. I made TA0 & TA1 generate rates. The key difference is in the INIT_FREQ definition I entered 1388 vs. 5000.

SCRUB
IsoMax V0.77
OK
OK
HEX OK
OK
( *************** MEASURE FREQ ************************ OK
VARIABLE TMP2 EEWORD OK
VARIABLE TMR2FREQI EEWORD OK
OK
VARIABLE TMP3 EEWORD OK
VARIABLE TMR3FREQI EEWORD OK
OK
: TMR2EDGE?
1117 @ 0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD OK
OK
: TMR2CAP&CLR
1112 @ DUP
TMP2 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
( 312500E0 S>F F/ TMR2FREQ F!
TMR2FREQI !
TMP2 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
0040 1117 ! ( CLR EDGE
; EEWORD OK
OK
: CTMR2FREQ
TMR2EDGE?
IF
TMR2CAP&CLR
THEN
; EEWORD OK
OK
( : TMR2FREQ? TMR2FREQ F@ F. ; EEWORD OK
: TMR2FREQI? TMR2FREQI @ . ; EEWORD OK
OK
OK
: TMR3EDGE?
111F @
0800 AND ( LOOK FOR INPUT EDGE FLAG IN STATUS
; EEWORD OK
OK
: TMR3CAP&CLR
111A @ DUP
TMP3 @ - ( GET CAPTURED VALUE DIFFERENCE LAST TIME
( 312500E0 S>F F/ TMR3FREQ F!
TMR3FREQI !
TMP3 ! ( SAVE CAPTURED VALUE FOR NEXT EDGE
0040 111F ! ( CLR EDGE
; EEWORD OK
OK
: CTMR3FREQ
TMR3EDGE?
IF
TMR3CAP&CLR
THEN
; EEWORD OK
OK
: ALL ( CHKFREQ
CTMR2FREQ
CTMR3FREQ
; EEWORD OK
OK
OK
OK
( : TMR3FREQ? TMR3FREQ F@ F. ; EEWORD OK
: TMR3FREQI? TMR3FREQI @ . ; EEWORD OK
OK
OK
: INIT_FREQ
0040 1117 ! ( TMRA2 STATUS
3F00 1116 ! ( TMRA2 CTRL
1115 @ TMP2 ! ( GET SOME INITIAL VALUE IN TMP2
0040 111F ! ( TMRA3 STATUS
3F80 111E ! ( TMRA3 CTRL
111D @ TMP3 ! ( GET SOME INITIAL VALUE IN TMP3
EVERY 1388 CYCLES SCHEDULE-RUNS ALL ( 5000 DEC FOR 1000cps
; EEWORD OK
( *************** END MEASURE FREQ ********************* OK
OK
OK
: DELAY 1000 0 DO 1 1 * DROP LOOP ; EEWORD OK
OK
: FREQ. TMR2FREQI? TMR3FREQI? ; EEWORD OK
: FREQLOOP BEGIN FREQ. DELAY DELAY DELAY CR ?KEY UNTIL KEY DROP ; EEWORD OK
OK
: L 1100 20 DUMP ; EEWORD OK
OK
0001 1107 ! ( TMRA2 STATUS OK
3823 1106 ! ( TMRA2 CTRL OK
1350 1100 ! ( TMRA2 STATUS OK
OK
0001 110F ! ( TMRA3 STATUS OK
3823 110E ! ( TMRA3 CTRL OK
1350 1108 ! ( TMRA2 STATUS OK
OK
INIT_FREQ OK
OK
OK
OK
OK
DECIMAL OK
FREQLOOP 1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1237
1237 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1237
1237 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1236
1237 1236
1237 1236
1236 1236
1236 1237
1236 1237
1236 1236
1237 1236
1236 1236
1236 1236
1236 1237
1236 1237
OK