![]() |
Forum Index : Microcontroller and PC projects : Fast Counter Cfunction (10MHz+): MM2, MM+
Author | Message | ||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
This Cfunction sets up a pin on a MM2 or MM+ as a fast counter. It is tested to 10MHz on both the MM2 and MM+ but will run higher. Note on MM2 accuracy will be determined by accuracy of the MM2 internal oscillator. Pins are 25 on 28pin, 14 on 44-pin, 13 on 64-pin, and 22 on 100pin Calls are: a%=FASTCOUNT(1, n) ' sets up the counter with window of n milliseconds a%=FASTCOUNT(0) 'turns off the counter a%= FASTCOUNT(2) ' returns the count for the last period The code includes the C source as comments at the bottom ' ' ' Fast counter CFunction for MM2/MM+ ' Tested to 10,000,000Hz on MM2 ' Note on MM2 accuracy will be determined by accuracy of the MM2 internal oscillator ' ' Pins are 25 on 28pin, 14 on 44-pin, 13 on 64-pin, and 22 on 100pin ' CONST stopcounter = 0 const startcounter = 1 const readcounter = 2 pwm 1,10000,50 'connect pin 4 to pin 25 for test purposes on MM2 a%=FASTCOUNT(startcounter,1000) 'start counter and set up 1000mSec period do pause 1000 ? FASTCOUNT(readcounter) b=b+1 loop while b<10 a%=FASTCOUNT(stopcounter) end ' ' Calls are: ' a%=FASTCOUNT(1, n) ' sets up the counter with window of n milliseconds ' a%=FASTCOUNT(0) 'turns off the counter ' a%= FASTCOUNT(2) ' returns the count for the last period ' CFUNCTION FASTCOUNT (integer, integer) INTEGER 00000022 'countint 3C029D00 8C43008C 8C640008 24840001 AC640008 8C44008C 3C03BF80 8C650E10 8C86000C 00C52821 AC85000C AC600E10 8C42008C 8C440008 8C430000 14830008 00000000 8C43000C AC430004 3C029D00 8C43008C AC60000C 8C42008C AC400008 03E00008 00000000 'getFPC 27BDFFF8 AFBF0004 00852023 03E42021 ACC40000 8FBF0004 03E00008 27BD0008 'main 27BDFFD8 AFBF0024 AFB10020 AFB0001C 00808021 00A08821 00002021 3C059D00 24A500B8 27A60010 0411FFED 00000000 8E020000 8E030004 00432025 54800039 24040001 3C029D00 8C420084 AC400000 3C02BF81 8C43F220 7C63D800 3C020661 24420053 10620007 3C02BF81 8C43F220 7C63D800 3C020660 24420053 14620007 3C02BF81 3C029D00 8C420088 AC400064 00002021 10000084 00002821 8C43F220 7C63D800 3C020661 3442A053 10620007 3C02BF81 8C43F220 7C63D800 3C020660 3442A053 14620007 3C02BF81 3C029D00 8C420088 AC400038 00002021 10000072 00002821 8C43F220 7C63D800 3C020580 3442A053 14620006 3C029D00 8C420088 AC400034 00002021 10000067 00002821 8C420088 AC400058 00002021 10000062 00002821 54440058 24040002 54600056 24040002 3C02BF81 8C43F220 7C63D800 3C020661 24420053 10620007 3C02BF81 8C43F220 7C63D800 3C020660 24420053 1462000A 3C02BF81 3C029D00 8C420088 24030064 AC430064 24030001 3C02BF81 AC43FA24 1000002B 34038002 8C43F220 7C63D800 3C020661 3442A053 10620007 3C02BF81 8C43F220 7C63D800 3C020660 3442A053 1462000A 3C02BF81 3C029D00 8C420088 24030064 AC430038 24030001 3C02BF81 AC43FA24 10000016 34038002 8C43F220 7C63D800 3C020580 3442A053 14620009 3C029D00 8C420088 24030064 AC430034 24030008 3C02BF81 AC43FA24 10000008 34038002 8C420088 24030064 AC430058 24030008 3C02BF81 AC43FA24 34038002 3C02BF80 AC430E00 8FA50010 3C029D00 8C430084 3C049D00 24840000 00852021 AC640000 8C43008C 8E240000 AC640000 8C43008C AC600008 8C43008C AC60000C 8C42008C AC400004 00002021 10000009 00002821 1444000A 8FBF0024 14600009 8FB10020 3C029D00 8C42008C 8C440004 00042FC3 00801021 00A01821 8FBF0024 8FB10020 8FB0001C 03E00008 27BD0028 End CFUNCTION '#define Version 100 //Version 1.00 '#define _SUPPRESS_PLIB_WARNING // required for XC1.33 Later compiler versions will need PLIB to be installed '#include <plib.h> // the pre Harmony peripheral libraries '#include "../cfunctions.h" '//#define MX470 '#define timeperiod 0 '#define count 1 '#define counter 2 '#define current 3 ' '// 'void countint(void){ ' CFuncRam[counter]++; ' CFuncRam[current]+=TMR5; ' TMR5=0; ' if(CFuncRam[counter]==CFuncRam[timeperiod]){ ' CFuncRam[count]=CFuncRam[current]; ' CFuncRam[current]=0; ' CFuncRam[counter]=0; ' } '} '__attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c) ' { ' *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ; ' } ' 'long long main(long long *mode, long long *duration){ ' volatile unsigned int libAddr ; ' getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor ' getFPCLab: { } ' if(*mode==0){ ' CFuncmSec=NULL; ' if(HAS_28PINS){ ' ExtCurrentConfig[25]=EXT_NOT_CONFIG; ' } else if(HAS_44PINS) { ' ExtCurrentConfig[14]=EXT_NOT_CONFIG; ' } else if(HAS_64PINS){ ' ExtCurrentConfig[13]=EXT_NOT_CONFIG; ' } else { ' ExtCurrentConfig[22]=EXT_NOT_CONFIG; ' } ' return 0; ' } else if(*mode==1){ ' if(HAS_28PINS){ ' ExtCurrentConfig[25]=EXT_RESERVED; ' T5CKR=1; ' } else if(HAS_44PINS){ ' ExtCurrentConfig[14]=EXT_RESERVED; ' T5CKR=1; ' } else if(HAS_64PINS){ ' ExtCurrentConfig[13]=EXT_RESERVED; ' T5CKR=8; ' } else { ' ExtCurrentConfig[22]=EXT_RESERVED; ' T5CKR=8; ' } ' T5CON=0x8002; ' CFuncmSec=(unsigned int)&countint + libAddr; ' CFuncRam[timeperiod]=*duration; ' CFuncRam[counter]=0; ' CFuncRam[current]=0; ' CFuncRam[count]=0; ' return 0; ' } else if(*mode==2){ ' return CFuncRam[count]; ' } ' } |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
excellent. Thanks loads! |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
I've now tested both the MM+ and MM2 up to 20MHz and both work perfectly (the MM2 needs to be at CPU 48 to work at this speed). I suspect the limiting speed is 50% of the chip's peripheral clock speed. Peripheral clocks speeds are: MM2 = CPU speed MM+ = CPU speed / 2 above 80MHz, CPU speed at or below 80MHz NB there is virtually no processing overhead using this CFunction and certainly less than using a normal COUNT input |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
Thanks again, Peter. 20MHz is way beyond what I need but this is a great addition to the embedded modules in the Firmware I reckon. |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
Hello Geoff/Peter. There seems to be a bug in the way the inbuilt editor crunches an edited program back into memory after editing, perhaps around CSub "compiling". I have Peter's example code above loaded on a 44pin '170 and it runs fine. Using the inbuilt editor, I change '1000' in the two line: a%=FASTCOUNT(startcounter,1000) to 100 (but probably any value), hit Ctrl-Q (finish editing) and immediately get a processor exception (I didn't even get a prompt back): [code] CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ CPU exc▒ etc... [/code] Reset doesn't help (you get that same loop again) and when I drop the power, I get another loop: [code] Option error - Cleared OPTION TOUCH Processor rest Option error - Cleared OPTION TOUCH Processor rest Option error - Cleared OPTION TOUCH Processor rest Option error - Cleared OPTION TOUCH Processor rest Option error - Cleared OPTION TOUCH Processor rest Option error - Cleared OPTION TOUCH Processor rest etc... [/code] only way to break the loop is to blast MMBasic with !'s on reset - which pulls it back to "just flashed" mode. HOWEVER... if I edit the code in an editor (NotePad++) on my PC so it reads the same (with the 100) and using AUTOSAVE transfer the program (this is my usual method), it runs perfectly. It seems to be exclusively with the inbuilt editor - for me I rarely use it but on this occasion just mucking about with that example code it was easy. It isn't a show-stopper for me but I thought you ought to know. All the best h |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
Hmm, this is a difficult one. I will try and reproduce it. Geoff Graham - http://geoffg.net |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
did you Ctrl-C the program? If you don't call FASTCOUNT(0) to unlink the interrupt routine before editing then it is almost certain that very bad things would happen as the MMBasic firmware would try and execute a subroutine call to a non-existent bit of code and given that the editor has the Flash memory open for write........ ![]() |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
![]() You got it Peter. I did the same tests but after Ctrl-C into the program. before EDITing I type a%=fastcount(0) at the prompt, then EDITed the line and changed the time period and after CTRL-Q it came back to the prompt. I did try it the "old" way [without fastcount(0)] just to check and it still throws a wobbly Does this mean that Geoff is potentially chasing a wild goose with any investigation on the CPU Exception at start-up thread? I really don't want to waste anyone's time. As an aside, is this a sort of general caution for all CSubs/CFunctions? They do stuff behind MMBasic's back so I guessing so. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
Yes, I think so. Only those which link to firmware interrupt routines or other firmware calls. |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
Noted - many thanks |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |