Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 06:58 22 Jan 2022 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : A PicoMite CSUB to  timestamp pin changes (Manchester code?)

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 5688
Posted: 04:15pm 14 Jan 2022
Copy link to clipboard 
Print this post

As part of the work I've been doing to shakedown the CSUB functionality in the PicoMite I thought I'd write a logger that can timestamp changes to an input pin very accurately (nearest micro-second).

This also shows the power of the CSUB on the PicoMite. You need V5.07.03RC14 or greater to run this code

Hopefully the comments in the code will be self-explanatory

Option explicit
Option default none
'
Interrupt myint 'set up an interrupt that can be triggered by the CSUB
'
SetPin gp6,cin,3 'set pin 9 (GP6) to cause a H/W interrupt on both edges
'
Dim a%(100) 'array to receive the timestamps
Dim b%=100 'maximum number of transitions to receive
Dim c%=20000000 'timeout of the CSUB in microseconds
'
log a%(),b%,c% 'initialise the logging
'
Do :Loop  'loop continuously
'
Sub myint 'subroutine that is triggered when the non-blocking CSUB terminates
'
 local integer i
 Do While a%(i) 'read all valid data
   Print i,a%(i) 'print it out
   Inc i 'increment the loop counter
 Loop
 Print "end"
 Pause 200
 End  'terminate the program
End Sub
'
' This CSUB logs activity on GP6, each transition of the pin is
' logged to the nearest microsecond. The timestamp is positive for positive
' going transitions and negated for negative going ones
' The parameters are:
' an integer array to hold the timestamps
' an integer with the number of samples to take (the array must be at least this big)
' an integer giving a timeout in microseconds for the CSUB to terminate
' if the number of sample requested is not reached
' when either the timeout occurs or the number of samples is reached the
' CSUB triggers an interrupt to let the Basic program know

CSub log
0000002F
'timout
4B0CB570 4B0C681D 4798681B 428B6A6B D10DD303 42836A2B 4B08D20A 2300681A
4A076013 60136812 681B4B06 601A2201 46C0BD70 10000388 100003A8 10000384
100003C4 100003CC
'intprog
4B16B570 6825681C 3B016923 2B006123 4B13DD0E 2009681B 28004798 4B11D014
4798681B 60696028 33086823 BD706023 681A4B0D 60132300 68124A0C 4B0C6013
2201681B E7E4601A 681B4B06 23004798 418B4242 606B602A 46C0E7E6 10000388
10000328 100003A8 10000384 100003C4 100003CC
'main
0015B570 681B4B0C 447A4A0C 4B0C601A 4A0C681B 601A447A 681C4B0B 680B6020
4B0A6123 4798681B 686B682A 414B1812 62636222 46C0BD70 100003C4 FFFFFF7F
10000384 FFFFFF2D 10000388 100003A8
End CSub


#include "PicoCFunctions.h"
// uSecTimer returns a 64-bit integer giving the number of microseconds since system boot
// CFuncRam is 256 bytes of RAM that aren't touched by Basic
// PinRead gives the status of a pin specified by the number (pin9 = GP6)
// CFuncInt1 is the address of a function to be called when a H/W interrupt occurs on COUNT pin 1
// CFuncmSec is the address of a function to be called every millisecond by trhe main clock interrupt
// Interrupt is a variable that tells Basic that the INTERRUPT specified in the Basic code has been triggered
//
static void timout(void){ //routine called every millisecond
unsigned long long int *endtime=(unsigned long long int *)&CFuncRam[8];
if(uSecTimer()>*endtime){ //  timeout triggered
CFuncmSec=0; //disable the millisecond interrupt
CFuncInt1=0; //disable the H/W pin change interrupt
Interrupt=1; //trigger the Basic ionterrupt
}
}
static void intprog(void){ //routine called every change on GP6
unsigned int *array=(unsigned int *)&CFuncRam[0];
int *count=(int *)&CFuncRam[4];
unsigned int d=*array;
*count=*count-1; //decrement the event counter
if(*count<=0){ //count satisfied
CFuncmSec=0; //disable the millisecond interrupt
CFuncInt1=0; //disable the H/W pin change interrupt
Interrupt=1; //trigger the Basic interrupt
}
if(PinRead(9))*(long long int *)d=uSecTimer();
else *(long long int *)d=-uSecTimer();
*array=*array+sizeof(long long int);
}
void main(long long int *basicarray, long long int *samplecount, long long int *timout){
CFuncInt1=(unsigned int)&intprog; //set up the address for the H/W interrupt
CFuncmSec=(unsigned int)&timout; //Set up the address for the millisecond timer
unsigned int *array=(unsigned int *)&CFuncRam[0]; //get a pointer to a permanent location to store a global pointer to the array
int *count=(int *)&CFuncRam[4]; //get a pointer to a permanent location to store the count of the samples required
unsigned long long int *endtime=(unsigned long long int *)&CFuncRam[8]; //get a pointer to a permanent location to store the timeout value
*array=(unsigned int)basicarray;
*count=(int)*samplecount;
*endtime=uSecTimer()+ *timout;
}

Edited 2022-01-15 02:45 by matherp
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 964
Posted: 05:01pm 14 Jan 2022
Copy link to clipboard 
Print this post

Pretty cool!  
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 09:16pm 14 Jan 2022
Copy link to clipboard 
Print this post

Thanks Peter this is excellent. All manner of devices with odd serial formats can now be read without need of a unique function or driver. With the stream captured processing can readily be done in basic. Perfect companion to BITBANG BITSTREAM for two way interaction.
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 04:35am 15 Jan 2022
Copy link to clipboard 
Print this post

While playing with RC14 and the above CSub I noticed an odd thing. Using PWM as a signal source the difference between timestamps sometimes seemed wrong - double, expected value. What's wrong isn't the CSub, that is excellent but PWM. A CRO shows that at 3900 Hz and above the frequency divides by 2. It starts out at 3900 then instantly jumps to 1950 Hz. At PWM 100kHz sometimes it is 25kHz actual.
Incase the CSub had upset something I tried turning it off then on, made no difference, nor did changing PW %
Reducing CPU speed also had no effect.

PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a
> pwm 1,1000,25     ok
> pwm 1,3800,25     ok
> pwm 1,3900,25     not ok
> option cpuspeed 126000
> setpin 4,pwm1a
> pwm 1,1000,25     ok
> pwm 1,3900,25     not ok
>


After returning to:-
> option cpuspeed 252000
> setpin 4,pwm1a
> pwm 1,20000,50     ok
> pwm 1,4000,25     ok
> pwm 1,200000,25     ok
> pwm 1,4000,25     ok
>
all speeds work properly.

Spoke too soon, divide by 2 again.



Tried another Pico with RC13

PicoMiteVGA MMBasic Version 5.07.03RC13
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a
> for n=3500 to 4500 step 100 : pause 2000 : pwm 1,n,50 : next
>
And got the same result, at 3800 it divides by 2.


>setpin 4,pwm1a : setpin 9,fin
> for n=3500 to 4100 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3500    3002
3550    3550
3600    3600
3650    3640
3700    3700
3750    3730
3800    3800
3850    1925
3900    1945
3950    1975
4000    1990
4050    2025
4100    2050
>
Edited 2022-01-15 17:32 by phil99
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 5688
Posted: 09:27am 15 Jan 2022
Copy link to clipboard 
Print this post

Please try the attached to confirm if I've fixed it



PicoMite.zip
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 11:32am 15 Jan 2022
Copy link to clipboard 
Print this post

> UPDATE FIRMWARE
PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a : setpin 9,fin
> for n=3500 to 4100 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3500    3500
3550    3539
3600    3600
3650    3628
3700    3699
3750    3750
3800    3788
3850    1925
3900    1939
3950    1974
4000    2000
4050    2019
4100    2050
>

Still something odd. retrying after a CLEAR FLASH seems to have fixed it

> UPDATE FIRMWARE
PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a : setpin 9,fin
> for n=3500 to 4100 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next

Error : Cannot find a matching FOR

> OPTION DISPLAY 50, 240

> setpin 4,pwm1a : setpin 9,fin
> for n=3500 to 4100 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3500    2722
3550    3550
3600    3579
3650    3648
3700    3700
3750    3738
3800    3800
3850    3828
3900    3898
3950    3951
4000    3987
4050    4050
4100    4078
>

Thanks for your help.
I will see if it stays that way when I restore the other Options.

Edit
> OPTION SYSTEM SPI GP18,GP19,GP16
> OPTION SYSTEM I2C GP0,GP1
> OPTION CPUSPEED 252000
> OPTION LCDPANEL ILI9341, LANDSCAPE,GP15,GP14,GP13
> OPTION TOUCH GP12,GP11
> GUI CALIBRATE 0, 3912, 3831, -897, -650
> OPTION SDCARD GP22
> OPTION RTC AUTO ENABLE
PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a : setpin 9,fin
> for n=3500 to 4100 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3500    3500
3550    3534
3600    3600
3650    3650
3700    3693
3750    3750
3800    3784
3850    1925
3900    1950
3950    1972
4000    2000
4050    2017
4100    2050
>

Its back to the same /2 above 3800.
I will remove Options to find which one dos it.
Edited 2022-01-15 21:50 by phil99
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 5688
Posted: 11:45am 15 Jan 2022
Copy link to clipboard 
Print this post

How are you measuring? I'm using a counter/timer and getting correct results now independent of CPU speed. Was certainly wrong in original RC14
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 12:11pm 15 Jan 2022
Copy link to clipboard 
Print this post

I was using a scope which gave the same results as FIN and your new CSub.
Removing all the options one at a time ( cpu restart each time) made no difference, but now CPU SPEED does.

OPTION CPUSPEED 126000
> cpu restart
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    2284
3750    3750
3800    3800
3850    3841
3900    3900
3950    3931
4000    4000
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3788
3750    3750
3800    3775
3850    3845
3900    3900
3950    3935
4000    4000
> OPTION CPUSPEED 252000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    2558
3750    3750
3800    3800
3850    2138
3900    1950
3950    1967
4000    2000
> OPTION CPUSPEED 126000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3700
3750    3742
3800    3800
3850    3832
3900    3900
3950    3950
4000    3992
>
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 12:45pm 15 Jan 2022
Copy link to clipboard 
Print this post

Re did clear flash and updated again then tried a few different CPU speeds. All ok up to 233000 at which point it died. No USB connection showing in Device Manager.

> UPDATE FIRMWARE
PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a : setpin 9,fin
> OPTION DISPLAY 50, 240

> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3700
3750    3750
3800    3792
3850    3850
3900    3882
3950    3950
4000    4000
> option cpuspeed 200000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    2587
3750    3750
3800    3800
3850    3845
3900    3900
3950    3934
4000    4000
> option cpuspeed 210000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3700
3750    3750
3800    3792
3850    3850
3900    3882
3950    3950
4000    4000
> option cpuspeed 233000
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 5688
Posted: 01:52pm 15 Jan 2022
Copy link to clipboard 
Print this post

  Quote  All ok up to 233000 at which point it died.


I would suspect power supply to the Pico or similar. All my Picos run happily at 252MHz and PWM is now correct in all cases
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 08:29pm 15 Jan 2022
Copy link to clipboard 
Print this post

Got it going again with a couple of hold button - plug in USB - clear flash - re-flash cycles.
At 133000
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3219
3750    3750
3800    3783
3850    3850
3900    3900
3950    3943
4000    4000
> option cpuspeed 252000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3442
3750    3750
3800    3787
3850    1925
3900    1938
3950    1974
4000    2000
>
Edit
240000 seems ok

> option cpuspeed 250000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    2109
3750    3749
3800    3800
3850    2365
3900    1950
3950    1964
4000    1999
> option cpuspeed 240000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    2761
3750    3750
3800    3777
3850    3847
3900    3900
3950    3937
4000    4000
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    3700
3750    3731
3800    3800
3850    3850
3900    3891
3950    3950
4000    3982
>
Edited 2022-01-16 06:40 by phil99
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 4537
Posted: 09:08pm 15 Jan 2022
Copy link to clipboard 
Print this post

I can confirm Phil's observation
> option list
OPTION SYSTEM SPI GP10,GP11,GP12
OPTION CPUSPEED (KHz) 200000
OPTION LCDPANEL ILI9341, LANDSCAPE,GP7,GP8,GP9
OPTION TOUCH GP14,GP15
GUI CALIBRATE 0, 250, 504, 925, 747
OPTION SDCARD GP13


speed 200000 is OK
speed 250000 gives the half speed PWM.
Definitively PWM, not frequency measurement.

using firmware post earlier in this thread.

PicoMite.uf2 15/01/2022 0925

Jim
VK7JH
MMedit   MMBasic Help
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 341
Posted: 09:25pm 15 Jan 2022
Copy link to clipboard 
Print this post

** Jump to Edit 4
Now it has infected FIN. FIN now shows double the frequency that I get on the CRO.

PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> option cpuspeed 252000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    5817   <--3700 actual
3750    7500
3800    7558
3850    3920   <--1925 actual
3900    3900
3950    3939
4000    4000   <--2000 actual
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    6149
3750    7500
3800    7600
3850    4495   <--1925 actual
3900    3900
3950    3931
4000    4000   <--2000 actual

Edit
After power off

> ? mm.info(cpuspeed)
252000000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    7400   <--3700 actual
3750    7468
3800    7600
3850    3850
3900    3894
3950    3950
4000    3983   <--2000 actual
> option cpuspeed 240000
> ? mm.info(cpuspeed)
240000000
> setpin 4,pwm1a : setpin 9,fin
> for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    7400   <--3700 actual
3750    7500
3800    7589
3850    7700
3900    7768
3950    7900
4000    8000   <--4000 actual
>

Edit 2 FIN showing double measured freq. at all CPU speeds, despite re-flashing.

> update firmware
PicoMite MMBasic Version 5.07.03RC14
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> setpin 4,pwm1a : setpin 9,fin:for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    6646
3750    7500
3800    7569
3850    7700
3900    7800
3950    7889
4000    8000
> option cpuspeed 125000
> setpin 4,pwm1a : setpin 9,fin:for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    6649
3750    7501
3800    7569
3850    7701
3900    7800
3950    7889
4000    8000
> option cpuspeed 48000
> setpin 4,pwm1a : setpin 9,fin:for n=3700 to 4000 step 50 : pause 100 : pwm 1,n,50 : pause 1500 : :? n,pin(9) : next
3700    6643
3750    7500
3800    7569
3850    7700
3900    7801
3950    7888
4000    8000
>

Edit 3 Further observations.
Returned to this Pico after some time testing another (same PWM symptoms) and found FIN back to normal. It seems a brief power off / on is insufficient for a proper reset. If others also find this it may be worth a mention in the manual.
> With OPTION CPUSPEED 240000 PWM is fine up to 100kHz. Not sure what the upper limit is.
If PWM is set too high, relative to CPU speed MMBasic freezes though the heartbeat LED continues to blink. Only power off / on restores it.

Edit 4 Supply filtering
Added 10uF to +5v and 47uF to +3.3V and now PWM works to 200kHz at top CPU speed.

> option cpuspeed 252000
> setpin 4,pwm1a : setpin 9,fin
> pwm 1,200000,50 : pause 1500 : ? pin(9)
200659
> ? pin(9)
200712
> ? pin(9)
200777

CRO shows 200.3kHz, multimeter shows 199.9kHz.

Edit 5 It has reverted to the original problem, so the capacitors aren't the answer.

Edit 6
"V5.07.03RC15"
Many thanks Peter so far it is working perfectly.

> pwm 1,200000,50 : pause 2500 : ? pin (9)
199987
> ? pin (9)
199984                          measured 199.9kHz
> ? pin (9)
199976
> pwm 1,250000,50 : pause 2500 : ? pin (9)
248987                          measured 249.9kHz
>
Edited 2022-01-17 07:46 by phil99
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2022