<simpletools.h> long count ( int pin, long duration) doubles expected result?
When I use count(0,1000) to measure the 1000 baud square wave that my oscilloscope puts out, I get a return value which not only varies ~10%, but is double the value I expected. i.e. I get ~2000 when I expect ~1000.
Is this a bug? What is the maximum pulse rate I can measure this way?
Reference:
https://propsideworkspace.googlecode.com/hg-history/029efb9bf270758003c0a67571d1cbe4cc9986b5/Learn/Simple%20Libraries/Utility/libsimpletools/html/simpletools_8h.html#a20a9d97de9777b12cfd9353a83ac21cb
I have a really hard time interpreting the .asm rendition of the code:
The C code:
Is this a bug? What is the maximum pulse rate I can measure this way?
Reference:
https://propsideworkspace.googlecode.com/hg-history/029efb9bf270758003c0a67571d1cbe4cc9986b5/Learn/Simple%20Libraries/Utility/libsimpletools/html/simpletools_8h.html#a20a9d97de9777b12cfd9353a83ac21cb
I have a really hard time interpreting the .asm rendition of the code:
GNU assembler version 2.21 (propeller-elf)
using BFD version (propellergcc_v1_0_0_2408) 2.21.
options passed : -lmm -ahdlnsg=lmm/PulseMonitor.asm
input file : C:\Users\n\AppData\Local\Temp\ccIBm3CJ.s
output file : lmm/PulseMonitor.o
target : propeller-parallax-elf
time stamp :
1 .text
2 .Ltext0
3 .data
4 .balign 4
5 .LC0
6 0000 25640A00 .ascii "%d\12\0"
7 .text
8 .balign 4
9 .global _main
10 _main
11 .LFB1
12 .file 1 "PulseMonitor.c"
1:PulseMonitor.c **** /*
2:PulseMonitor.c **** PulseMonitor.c
3:PulseMonitor.c **** */
4:PulseMonitor.c ****
5:PulseMonitor.c **** #include "simpletools.h"
6:PulseMonitor.c ****
7:PulseMonitor.c **** long clocks = 0;
8:PulseMonitor.c ****
9:PulseMonitor.c **** int main()
10:PulseMonitor.c **** {
13 .loc 1 10 0
14 0000 0400FC84 sub sp, #4
15 .LCFI0
16 0004 00003C08 wrlong lr, sp
17 .LCFI1
18 0008 0800FC84 sub sp, #8
19 .LCFI2
11:PulseMonitor.c **** clocks = count(0, 1000);
20 .loc 1 11 0
21 000c 00007C5C mvi r1,#1000
21 E8030000
22 0014 0000FCA0 mov r0, #0
23 0018 00007C5C lcall #_count
23 00000000
24 0020 00007C5C mvi r7,#_clocks
24 00000000
25 0028 00003C08 wrlong r0, r7
12:PulseMonitor.c **** print("%d\n",clocks);
26 .loc 1 12 0
27 002c 00007C5C mvi r7,#.LC0
27 00000000
28 0034 00003C08 wrlong r7, sp
29 0038 0000BCA0 mov r7, sp
30 003c 0400FC80 add r7, #4
31 0040 00003C08 wrlong r0, r7
32 0044 00007C5C lcall #_print
32 00000000
13:PulseMonitor.c **** }...
33 .loc 1 13 0
34 004c 0000FCA0 mov r0, #0
35 0050 0800FC80 add sp, #8
36 0054 0000BC08 rdlong lr, sp
37 0058 0400FC80 add sp, #4
38 005c 0000BCA0 mov pc,lr
39 .LFE1
40 .global _clocks
41 .section .bss
42 .balign 4
43 _clocks
44 0000 00000000 .zero 4
82 .Letext0
83 .file 2 "C:/Users/n/Documents/SimpleIDE/Learn/Simple Libraries/TextDevices/libsimpletext/simpletex
DEFINED SYMBOLS
C:\Users\n\AppData\Local\Temp\ccIBm3CJ.s:10 .text:00000000 _main
C:\Users\n\AppData\Local\Temp\ccIBm3CJ.s:14 .text:00000000 L0
C:\Users\n\AppData\Local\Temp\ccIBm3CJ.s:43 .bss:00000000 _clocks
.data:00000000 .LC0
.debug_frame:00000000 .Lframe0
.text:00000000 .LFB1
.debug_abbrev:00000000 .Ldebug_abbrev0
.text:00000000 .Ltext0
.text:00000060 .Letext0
.debug_line:00000000 .Ldebug_line0
.text:00000060 .LFE1
.debug_loc:00000000 .LLST0
.debug_info:00000000 .Ldebug_info0
UNDEFINED SYMBOLS
sp
lr
__LMM_MVI_r1
r0
__LMM_CALL
_count
__LMM_MVI_r7
r7
_print
pc
The C code:
/*
PulseMonitor.c
*/
#include "simpletools.h"
long clocks = 0;
int main()
{
clocks = count(0, 1000);
print("%d\n",clocks);
}

Comments
Source
19 long count(int pin, long duration) // count function definition 20 { 21 /* 22 if(!st_pauseTicks) // If global dt not initialized 23 { 24 //set_io_dt(CLKFREQ/1000000); // Initialize dt 25 if(st_pauseTicks == 0) set_pause_dt(CLKFREQ/1000); 26 set_io_timeout(CLKFREQ/4); // Initialize timeout 27 } 28 */ 29 int state = 1; // Initialize state to 1 30 long transitions; // Declare transitions var 31 int ctr = (10 << 26) + pin; // Positive edge ctr config 32 long tf = duration * st_pauseTicks; // Set timeout 33 int t = CNT; // Mark current time 34 // Wait until pin matches state or timeout. 35 while((input(pin) == state) && (CNT - t < tf)); 36 if(CTRA == 0) // If counter A unused 37 { 38 CTRA = ctr; // Start counter module 39 FRQA = 1; // Increment PHSA by 1 per edge 40 t = CNT; // Reset current time 41 PHSA = 0; // Clear phase accumulator 42 while(CNT - t < tf); // Wait for timeout 43 CTRA = 0; // Stop the counter 44 transitions = PHSA; // Record pos edge crossings 45 } 46 else if(CTRB == 0) // If CTRA in use, use CTRB 47 { 48 CTRB = ctr; // Equivalent to CTRA block 49 FRQB = 1; 50 t = CNT; 51 PHSB = 0; 52 while(CNT - t < tf); 53 CTRB = 0; 54 transitions = PHSB; 55 } 56 else // If both counters in use 57 { 58 transitions = -1; // Return -1. 59 } 60 return transitions; // Return transitions 61 }Take a look at line 32. Documentation on `st_pauseTicks` says it defaults to 1/4 second, which would imply that if you call `count(0, 1)`, you should expect to get a return value of 250 for a 1000 baud signal.
0.25 * 1000 = 250 seconds. That will overflow the `tf`.
Are you sure you're not thinking of st_timeout?
st_timeout = 250*st_msTicks; in http://david.zemon.name/PropWare/timeTicks_8c_source.html (Thanks for the link!)
And did I miss something in calculating tf in my head? I don't feel a long should overflow at these values...
/* PulseMonitor.c */ #include "simpletools.h" long count_local(int pin, long duration) { // count function definition [COLOR="#FF8C00"]int state = 1 << pin[/COLOR]; // Initialize state to pin pattern long transitions = -1; // Declare transitions var with default response int ctr = (10 << 26) + pin; // Positive edge ctr config long tf = duration * st_pauseTicks; // Set timeout int t = CNT; // Mark current time while (([COLOR="#FF8C00"]INA & state[/COLOR]) && (CNT - t < tf)); // Wait until pin matches state or timeout. if (!CTRA) { // If counter A unused CTRA = ctr; // Start counter module FRQA = 1; // Increment PHSA by 1 per edge t = CNT; // Reset current time PHSA = 0; // Clear phase accumulator while (CNT - t < tf); // Wait for timeout CTRA = 0; // Stop the counter transitions = PHSA; // Record pos edge crossings } else if (!CTRB) { // If CTRA in use, use CTRB CTRB = ctr; // Equivalent to CTRA block FRQB = 1; t = CNT; PHSB = 0; while (CNT - t < tf); CTRB = 0; transitions = PHSB; } return transitions; // Return transitions } int main(int argc, char **argv) { long clocks = 0; DIRA = 1 << 16; // pin 16 output CTRB = (4 << 26) | 16; // NCO on pin 16 FRQB = 53687; // 1kHz waitcnt(CLKFREQ*3 + CNT); clocks = count_local(16, 1000); // count for 1000 ms print("%d\n", clocks); exit(0); }That being said, are you sure your generated pulse wave has the right frequency?Perhaps it is time I scratch together the money for a real scope. I have been investigating a very cheap USB one called the DDS120, and the signal I'm trying to get from it is its Encode clock sent to the ADC. The device is cheap enough that one might leave it in a permanent installation, or upgrade from an RTL-SDR, but it needs new firmware. Three others have started to work on the same project and by now I'm barely keeping up with them.
Thank you very much for your help! I'll study the code you posted in detail. =D
We've had oscilloscope threads here before. There's lots of praise for both Propalyzer and Saleae's Logic line.