Additional device for Espruino to support 8 pins in parallel (for discussion) #1253
Replies: 25 comments
-
Posted at 2018-11-07 by @gfwilliams Do you have an example of how you used this in JS? Like your P3 driver code? As far as I can see this doesn't add anything that you couldn't do with shiftOut (http://www.espruino.com/Reference#l__global_shiftOut) in fact it actually does less stuff? Couldn't we just work on making shiftOut faster, even if that was special-casing it for ESP32 when sending 8 bits at a time? I believe we may already special-case for STM32. Basically I'm now at the point where I'm having to pull features OUT of the Original Espruino board in order to do new releases, so I don't want to have to remove features in order to add things that don't actually add any new functionality. I know you think that parsing the 8 pins each time would slow the call down, but if they're pre-bound with |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-07 by @gfwilliams Just looking at your code, you use There's a function called While this only deals with one address for a pin (which only seems to work on STM32) we could extend that to return:
That would work on nRF52/ESP32 and STM32, and then we could have a fast |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-07 by @gfwilliams Check this branch out: https://github.com/espruino/Espruino/compare/direct_io Not tested on anything yet, but hopefully that'll make I was wrong about software SPI being improved, but that could be improved in the same way now without having to add anything platform specific. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-07 by JumJum Fully agree to "it does less staff compared to shiftOut". Simple reason is, I stopped implementing all options, and use existing code, to get first feedback. If this idea will not make it to Espruino, at least I didn't waste too much time. Main target was to arrive at about 20msecs for each refresh. Please see attached file for JS code, its also in an early state. There are some additional time saver, in predefining arrays instead of creating new arrays all the time. Thats all I could find. Lets show, what I did: Next came up with use of GPIO.outw1tc, first version added up all bits and at the end sent it to GPIO.out_w1.... Similiar to your JshPinAddress. Once again there was an end of optimization for speed. Helpful step was to create a translation table from byte to pins in GPIO.out_w1.... Let me try your changes tomorrow. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-07 by JumJum Couldn't resist and tested today ;-) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-08 by @gfwilliams Interesting - so even with Are you sure you're compiling with It may be there's a bug in shiftout_fast that causes the corruption - could just be the way I implemented
It's slow for allocation, but shouldn't be slow for access. If you can get a good test example that is also slow on Espruino boards I'm very happy to look at it.
That's an interesting slowdown - I guess it could just be my use of jsvIterateCallback vs your direct iteration from the pointer? It may be something I could special-case in jsvIterateCallback for byte arrays, which would improve a whole lot of stuff |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-08 by JumJum I'm not absolutely sure about 500 usecs. It's some time ago, and I tested a lot of different options, at least it was remarkable. One major point, why I like the bytePort class, is the option to have a default solution for all boards, and still the option to use the strength of other boards. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-08 by Wilberforce Is the Esp32 code setting up the pinmode on output every time even when it is already setup? Setting the gpio matrix via the ESP-idf might be the delay here. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-08 by @allObjects @gfwilliams, let me understand - first - who
is used and - second - it then still on - invocation -
Is the bind used to partially apply the function and 'store' it in a variable / keep it handy with a variable reference, for example, I'd be surprised if 'invocation / stack-handling' takes takes that much time, except fully apply a partially applied function is the time sink. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-09 by JumJum To avoid misunderstandings because of the 500usecs.
Tests have been done on ESP32 only, and duration has not been stable. In my understanding bind optimizes interpreting source code. I hope this is reasonably correct, and I'm not embarrassing myself ;-) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-09 by @gfwilliams
Yes - exactly as @jumjum says - you're basically eliminating the parsing step, which is the slow bit in Espruino.
I'm totally happy to have something like this at the top of
The thing I don't like is creating a duplicate API for the same thing if there isn't a good reason. Having two similar APIs just confuses people, gives us more stuff to maintain, and ultimately means that instead of one, optimised solution we have two partially optimised solutions. If we can make the existing If there really is something in
So if we can merge my tweaks and fix jsvIterateCallback we should be within a few percent of @jumjum's implementation, and then maybe we can add the special case for I2S to really speed things up for ESP32 in the right cases? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-09 by @gfwilliams Actually I should add that because of So with a tiny tweak to
This would be way faster, since it's not actually executing any JS in order to do the entire scan - including toggling the data lines. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-12 by JumJum First of all, duplicating a function under a different name was not my intention.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-12 by @gfwilliams Thanks, that's really interesting! What is I just committed those changes I mentioned above - it should be useful in a bunch of cases since it applies even to SPI/I2C/etc. Basically this should mean that the setup is done only once - even in I don't have a P3 matrix here so this is what I did for the LPD6416 - hopefully the change is pretty straightforward.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-12 by JumJum push data out is jsvIterateCallback(data, allFast..... I'll check it soon. even in BytePort you had to grab the binary data out of a variable each call |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-12 by @gfwilliams
Ideally to do your method you'd allocate a Flat String, and put the data in there. You could then get a pointer to it when executing the code. It's what I should do for most stuff like Graphics/etc (but I don't). |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-13 by JumJum I tested with latest direct_io branch, see my code
Next tried to work with graphics and whatever I did, panel displays something different. :-(
Checking jsvIterateCallback was next step, some more printf like this in
See log, Sum of all byteLength gives exactly 8704, which is the number how often callbackFast is called. tst() |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-13 by @gfwilliams Argh - thanks for checking into this! It was because my 'fast path' for execution wasn't checking when it should stop correctly. If you pull now and try, it should at least call iteration the correct number of times. And on the plus side if it's 18ms while doing 8x as much work as is needed, it should be substantially faster now! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-14 by JumJum Believe me, the world is absolutely crazy. After a lot of frustration, I went back to setting pins with jshPinSetValue, and surprise surprise, now it works. Anyway, my next step will be to create a graphics driver, using Graphics.createCallback to get rid of prep step. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-14 by @gfwilliams Great! So you're not really using the direct_io branch now, but just standard Espruino? It's a shame - can you see the pins changing state? The brightness is probably because those rows are left on for slightly longer... I guess I guess the lack of brightness is because now we're actually able to push the data out quickly - flickering might be because something is stopping
I'd have thought that might be quite slow... On Pixl.js/etc we just have |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-14 by JumJum I use the direct_io branch, and love the changes. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-14 by JumJum arr.push({callback:en.set.bind(en)}); |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-14 by JumJum Success, but once again I've only an idea of an idea why, but it works. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-15 by JumJum Last not least, flickering is gone.
Actual status, compared to direct_io branch is:
Latest next week, I'll send a request with all changes to direct_io branch.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-15 by @gfwilliams That's great!
If you switched off fast IO, I believe you could just switch back to the IMO
There's actually already But yes, feel free to add an
Yes, it's still needed. The check is only done when setting pin state. The idea is you might be able to call it with If you wanted to make it faster you could change the test to: In terms of speeding up IO, could you move https://github.com/espruino/Espruino/blob/master/targets/esp32/jshardware.c#L324 |
Beta Was this translation helpful? Give feedback.
-
Posted at 2018-11-07 by JumJum
some weeks ago, a discussion started around P3 RGB pixel panel
Feedback by Gordon and by allObjects brought me to the idea to create a new device for pins.
It should
In a first proof of concept, attached source came up to life. Gave it the name BytePort. It includes
Before spending more time on that, and may be running into a wrong direction, I would like to get feedback. Please see attached zip
Attachments:
Beta Was this translation helpful? Give feedback.
All reactions