ST7796 Teensyduino support

I downloaded your latest library changes and also updated the DMA cores with your zip file per post #108.

Running your torture test on the Mini Platform, all of the update modes 0-11 work OK except for 2, 4 and 5 where the audio is broken as expected per your auok[] table. #3 (async frame buffer, continuous) also seemed to work OK @ 16MHz SPI though your table indicated otherwise.

Also recompiled my 2 test cases without using any of the new update modes and they still work OK.

When the 3.x went EOL and parts were scarce, I sold all remaining inventory so I don't have a test case here to work with unfortunately. I will bring in an ST7735 display to do some testing with though.
 
Thanks @KenHahn. I'll look into the mode 3 update behaviour, it ought to break audio if it's working as intended...

I've got some ST7735 and ST7789 displays on the way from AliExpress, but as ever it's good to have corroboration - plus there's no guarantee mine will be from a good batch!
 
Note: on doing interrupt at half frame. Not really sure how meaningful that might be... Maybe it is, if it is for a fixed size update frame,
and not one that depends on what changed since the last update.

That is still maybe useful, if for example, your app is displaying a video in lets say 3/4 of the screen, .. then same usage pattern as I mentioned.
But if changes the rectangle from frame to frame, then maybe not overly useful.
 
You make good points - I'm not sure myself how useful this will be! Then again, I'm always wary of removing features just because I happen to think the upgrades are better ... feels like not a great attitude :)

I'm coming to the conclusion that attempts to change the update area silently are doomed to failure, in any case. If the frame buffer drawing is half-done when a new update starts then mayhem is likely to ensue, plus if no changes have been made then Bad Things happen. Hence I'm planning on adding an API call to trigger an area change as needed, which will then become the new area until async updates are stopped or the area is changed again.
 
OK, so I think I've implemented the final few features, and updated the ReadMe to suit. I may well have missed documenting some important methods, so do let me know if you spot one. There are a few undocumented ones which are still in there solely for development purposes; they shouldn't be needed for real-world applications, and are liable to be removed at any moment!
  • half-frame(-ish) callbacks are implemented; the subFrameCount() method returns true if the callback has been made halfway through the frame update. I say it's "-ish" because it's essentially impossible to get it exact for all cases, and as @KurtE pointed out, it's of dubious utility anyway. It should turn out to be reliably after the halfway point.
  • the changeAsyncClipArea() method re-computes the continuous aysnc clipped area boundary on the next full update, i.e. after the current frame output is complete. If you do not call this, the clipped area is only changed if the continuous update is stopped and re-started.
  • the clearChangedArea() method resets the boundary used if the updateChangedAreasOnly option is in force. You must then ensure that something has been written to the frame buffer before calling changeAsyncClipArea() to start updating the new area - see the ReadMe
The slight delay in getting to this point was because stopping an ongoing continous asynchronous update occasionally locked up the test. I think it's sorted out, but I'd welcome others' opinions, especially if they're using their own code.
 
I'm not considering it until my previous DMA PR is processed (which is sooo much easier to demonstrate and fix, but has still been completely ignored).
 
I hear you! Might be worth another plug on the beta 4 thread, since Paul is more visibly engaged at the moment, and it’s a definite, reproducible bug.
 
I'm not considering it until my previous DMA PR is processed (which is sooo much easier to demonstrate and fix, but has still been completely ignored).
When I got the DMA update from @h4yn0nnym0u5e did it also have the pending <PR> changes @jmarsh ?

If so, it is on my machine and caused no trouble - though I'm not sure if it was tested in using the display changes.
 
“other things” are all good!
Going well so far. Late start in HAM radio and this weekend is "Field Day is the biggest on-air event of the year" so I'm helping setup today and then 24 hr on the air event starting tomorrow.

I got over a few hours and helped get at least 4 antennas in the air and one tent on the ground.

That I could do and no shoulder pain - sitting here typing is risky ...
 
When I got the DMA update from @h4yn0nnym0u5e did it also have the pending <PR> changes @jmarsh ?

If so, it is on my machine and caused no trouble - though I'm not sure if it was tested in using the display changes.
I probably based that PR on the same branch as the older one, it wouldn't make a difference unless a DMASetting was being used with the START bit set (so that it autostarts when assigned to a channel).
The older issue is described here and I'm not sure how I could make it clearer that it's a basic omission, considering I wrote a full test program and included annotated assembly code to explain it all.
 
Yes, it has the existing PR changes; inspection suggests they can only be benign, though I don’t think my code exercises the change.

I still think it’s worth raising again. All the signs point to Paul being down another rabbit hole at the start of this year, so even if he did make a mental note to look at it when he came out, it’s entirely possible he’s forgotten. And it isn’t going to get noticed during one of his ”routine trawls through issues and PRs”, because those are very clearly Not A Thing.
 
Hopefully in the next Beta release Paul will see the Audio issue and take that updated ST7796 and the associated DA edit(s)
Is the audio issue actually raised somewhere other than this thread?

In most (not all) cases, it's wishful thinking to expect Paul to see stuff and take action. The best we can do is to submit the necessary PRs, cross-referring as necessary, and then await developments. The last I recall TD1.60 was supposed to address bugfixes, with new features perhaps making it in at a later stage. The volatile DMA thing is a definite bug; the pre-emptible DMA and ST77xx async updates are more features, though I grant you it's nasty that you can't easily draw big level bars!

Once interested users have had a bit more chance to thrash my display code I'll happily put the PR in - without the full DMA fixes there will be elements that don't work, but there are still enough improvements to make it worth having, IMHO.
 
Sorry playing on other things,

but one thing that would be good is to see how the timings compare from old to new...
For example if I am not using an Audio board, is there a performance hit?
Maybe ditto if I am using Audio but SD is not SPI or the same SPI...

Thanks for all the hard work on this!
 
best we can do is to submit the necessary PR
I did a PR for my QUICK fix to the added End/Begin Transaction.
And IIRC updated PR for the Small Rect to not do END/BEGIN on the many small uses of the RECT code that currently happen with that code - and BROKE font drawing.

That makes the newly included ST7796 code usable - though without the feature rich improved version from @h4yn0nnym0u5e
 
Sorry playing on other things,

but one thing that would be good is to see how the timings compare from old to new...
For example if I am not using an Audio board, is there a performance hit?
Maybe ditto if I am using Audio but SD is not SPI or the same SPI...

Thanks for all the hard work on this!
Thanks for engaging at all, given you have other interesting stuff going on!

I haven't done detailed benchmarks, but I'm fairly confident that performance hits vary from minor to none, depending on your use case. The following estimates are based on my 16MHz SPI settings, with the framebuffer in RAM; faster will improve update speeds, but also increase the amount of CPU time spent servicing the display. A framebuffer in PSRAM is usable, but noticeably slower, of course.
  • direct writing to screen with mid-transaction break checks: the checks are very fast because ARM_DWT_CYCCNT is used; if executed the breaks will be a few µs, but you can mitigate against that by setting the required break period to be very large, say 1,000,000µs - even filling the screen doesn't take that long
  • async screen updates can be as fast as the SPI settings allow, if set up for chained DMA transfers. A 480x320 screen requires 5 transfers of 30,720 pixels each, so 5 executions of the ISR to set up the next TCD.
  • if not set up for chained transfers, so as to allow for audio, then I've typically used 2-line transfers every interrupt, resulting in slightly increased overhead. With audio playing it probably takes ~5% longer to copy the 480x320 pixels
  • if updating a clipped area, there's the overhead of a memory-to-memory copy. I've used a 960-pixel intermediate buffer, so the same size per cycle as the 2-line transfers done for the full-screen copy. The M2M copy takes a bit over 50µs, so the overall hit ends up being about 12%
So you'd probably see about 5% CPU use, and 12% slower screen updates, if you have continuous async updates switched on (that's disregarding the time taken to write to the frame buffer). But of course you'd have 100% CPU use if you didn't use async updates, and most of that 100% will be burnt just waiting for the SPI. If you do async updates only as needed, rather than continuously, the CPU would drop, though the update speed won't change - it is what it is.
 
Pushed some more stuff to the branch.
  • shamelessy stole part of an optimisation for setting the output area, though I did fix a problem, and also not implement part of it, as maybe it's an assumption that it'll always be followed by writing to RAM
  • implemented gradient-filled rectangles, based on ILI9341 code but changed to make them output all the colours properly, as discussed on this thread
  • updated the torture test - it's getting stupidly hard to follow, I'm afraid...
 
shamelessy stole part of an optimisation for setting the output area, though I did fix a problem, and also not implement part of it, as maybe it's an assumption that it'll always be followed by writing to RAM
Sounds good. I have put that type optimization in and sometimes removed it. Found there were some displays that
were not happy without both being set. That is they did not properly reset them after you reached the end...
Don't remember which ones they were.
 
Interesting. I have a couple of other display types just arrived, so if they react poorly I’ll soon know. The mid-transaction break does a lot of calls to setAddr(), which will usually only need the row addresses changing…
 
Back
Top