Fastest IO toggle #4946
Replies: 1 comment
-
Posted at 2015-08-21 by alexanderbrevig You should move Posted at 2015-08-21 by cwilt You are correct. I should move start. It will be put on the work bench and tested when time permits. So far I have only been able to pay with the pico on my phone using OTG cable and briefly from my laptop last night. I will update here if there is a significant change from moving the start. Update:
Posted at 2015-08-21 by @gfwilliams Hey, thanks for the post - that looks good! I can't think of any other obvious ways to make it significantly faster. At some point it'd be nice to have a 'fast path' for GPIO in compiled code, but it's not really that high up the priority list. I guess the other (slightly cheaty) options are:
Posted at 2015-08-21 by cwilt I always start with native code and then try to find what works and what doesn't. For example, I learned that having the for-loop outside of the compiled function was significantly slower. May try PWM just to see what the upper limit is, but not SPI. Certainly will give assembler a shot. With nodeMCU and lua I was able to achieve 60Khz with CPU speed at 80Mhz, and 120Khz at 160Mhz but it could not be sustained without it rebooting itself. Posted at 2015-08-22 by DrAzzy Re: SPI, you don't need to send any specific bit pattern, just send whatever and use the clock line ;-) Posted at 2015-08-22 by cwilt @drazzy I am wondering if there is a step between native and assembly. Would it be possible to poke32 the IO address and achieve toggle? Anyone tried it? Its been nearly 30 years since I did assembly and I am not sure I want to go down that rabbit hole again. Posted at 2015-08-24 by @gfwilliams Actually ARM assembler isn't that painful. Most of it is done for you already here under 'Accessing IO' and 'Loops', so it's almost copy+paste. But yes, you could poke the IO address. However at the moment that's still a function call via the JS interpreter which will take quite a bit of time (it should be faster than digitalWrite though) - If I changed the compiler to handle peek and poke with known values as low-level operations it'd be crazy fast though. It's just finding time ;) Another thing to try if you're playing around is
or
I haven't tried, but they could be a smidge faster. Posted at 2015-08-24 by cwilt I figured peek and poke were js calls but it should be the next step with assembly being the fastest but most complicated. I will give bind a test when time permits. Posted at 2015-08-24 by @gfwilliams ... just had a play at adding that peek/poke fast path. Try this now:
And for me it reports 7.7Mhz, which is just a bit faster :) Posted at 2015-08-24 by cwilt Holy crap! Just a little bit faster. Posted at 2015-08-24 by alexanderbrevig Have you looked at it through an oscilloscope yet? :) I'll have a go tomorrow! Posted at 2015-08-24 by cwilt I will tonight when I get home. Should be able to post screen shots as well. Posted at 2015-08-25 by cwilt DSO says 7mhz while the pico calculates it as 8.062mhz Posted at 2015-08-25 by cwilt @gfwilliams Posted at 2015-08-25 by cwilt Trying my hand at assembler but I am getting an error. Trying to toggle B3.
Error is... Posted at 2015-08-25 by @gfwilliams Great! The Pico's timing runs off its internal 32k RC oscillator, and unfortunately it's really not that accurate - probably why the difference is reported. I've been hoping to do something about that, but I'm not 100% sure on the best way around it yet. The assembler issue is a fun problem with Thumb assembler - instructions are 2 bytes, but often immediate values need to be multiples of 4. You just need to add
Posted at 2015-08-25 by cwilt Ok. Will test this when I get home from my day job. Maybe I will do some research and put it in a for loop. Posted at 2015-08-25 by @gfwilliams Ok :) As-is that may not work - You might find out that even with a loop in assembler, the 'compiled JS' is actually faster. GCC is really pretty good at optimising the C code that's generated :) Posted at 2015-08-25 by cwilt You are correct. I was thinking for loop. Its been a looooong time since I did assembly. Posted at 2015-08-25 by DrAzzy Is the RC oscillator really that bad? That's >10% off... Posted at 2015-08-26 by cwilt I tried but I think its triggering so fast that it never comes fully on. Readings are very low and distorted. Probably need to add a delay.
Posted at 2015-08-26 by @gfwilliams I'm not 100% sure about the writes you're doing... You need to write 4 to turn it on, but 4<<16 to turn it off (it's a bit set/reset register). I'm not sure that second store is actually turning it off? @drazzy yes, sadly it really is that bad - but on a device by device basis. If it were calibrated for each board then it'd be Ok, but obviously I can't do that very easily. I was looking into a way to calibrate it on the fly against the high speed oscillator, but I haven't had much luck with that to date. Posted at 2015-08-26 by cwilt I tested those writes individually and they do turn pin B4 on and off. Posted at 2015-08-26 by DrAzzy Does this mean that time-keeping will be off by ~10%? If that's the case, those itty-bitty super-special crystals are a necessity not an option. +/- 10% means it could lose like 2.5 hours a day... Posted at 2015-08-26 by cwilt I guess I only tested the "on" and not the "off". Your description is not making sense to my old brain. Any chance for a snippet code to turn off B4? Posted at 2015-08-27 by @gfwilliams
Sadly yes, at the moment (on the Pico). The original Espruino board is much more accurate for some reason, and the rev 1v4 has a crystal on board anyway. It's something that's been on my list to change, because if done right a firmware update should basically fix it. Posted at 2015-08-27 by @gfwilliams Ahh - just read the assembler page again, and the problem is that the STM32F1 in the original Espruino (what the Assembler page describes) and the STM32F4 in the Pico are different. On the F1, the bit set and bit reset registers are 4 bytes apart, which is great because you can use the Try:
I'll update the docs. Posted at 2015-08-27 by cwilt Thank you for the quick and informative reply. I had tried everything I could think of last night and was never successful and now I know why. ;-) Posted at 2015-08-28 by cwilt 14 Mhz using assembly Attachments: Posted at 2015-08-28 by @gfwilliams Nice! But no way to break out of it? ;) Posted at 2015-08-28 by cwilt I just need to put a for loop into it. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2015-08-21 by cwilt
First I want to say hello and thank the developers for a very cool little board. Post man delivered a Pico to me the day before yesterday. One of the first things I do is figure out the fastest ways to toggle an IO pin.
Most methods produced something between 2.7 and 5.1 Khz.
This is the fastest I could come up with that produces 37.31 Khz. The only other method that I have not tried would be to duplicate the code below with inline assembly.
This may be of no use to anyone else but it satisfies my personal curiosity.
Beta Was this translation helpful? Give feedback.
All reactions