HyperRam & HyperFlash as VGA screen buffer (Now in Spin2!)
Rayman
Posts: 14,646
Use HyperRam or HyperFlash as a screen buffer was previously demonstrated in pure assembly:
https://forums.parallax.com/discussion/169926/
Now, I've converted the code to Spin2 (although still mostly assembly).
It also works with both PNut and FastSpin.
This loads up an embedded bmp file into HyperRam and then reads into a line buffer, coordinated with VGA driver.
Update: The HyperVGA_640_x_480_8bpp_3f.spin2 example can load 2 images from uSD and then flip between them on display.
Update2: The HyperVGA_8bpp_3i.spin2 example can flip back and forth between two images on uSD, up to 1080p.
Update3: The HyperVGA_8bpp_4a.spin2 is much like the above with a fixed timeout issue in FSRW so that several seconds can elapse between images. There's about a 1 second of white between images, while loading.
Update4: 720p@24Hz,16bpp works from Hyperflash onto TV over native HDMI using "Digital Video Out" accessory on P2 Eval board.
But, found bugs in previous codes where addresses were incorrectly calculated...
Update5: Attaching code (HyperHDMI_16bpp_4e.spin2) for digital video out at 720p@24Hz. This also has the correct shift for hyperram address in read and write sections.
Update6: Fixed a bug in the above and added WVGA mode that should work on most monitors and TVs. New version is in HyperHDMI_16bpp_4e.zip.
https://forums.parallax.com/discussion/169926/
Now, I've converted the code to Spin2 (although still mostly assembly).
It also works with both PNut and FastSpin.
This loads up an embedded bmp file into HyperRam and then reads into a line buffer, coordinated with VGA driver.
Update: The HyperVGA_640_x_480_8bpp_3f.spin2 example can load 2 images from uSD and then flip between them on display.
Update2: The HyperVGA_8bpp_3i.spin2 example can flip back and forth between two images on uSD, up to 1080p.
Update3: The HyperVGA_8bpp_4a.spin2 is much like the above with a fixed timeout issue in FSRW so that several seconds can elapse between images. There's about a 1 second of white between images, while loading.
Update4: 720p@24Hz,16bpp works from Hyperflash onto TV over native HDMI using "Digital Video Out" accessory on P2 Eval board.
But, found bugs in previous codes where addresses were incorrectly calculated...
Update5: Attaching code (HyperHDMI_16bpp_4e.spin2) for digital video out at 720p@24Hz. This also has the correct shift for hyperram address in read and write sections.
Update6: Fixed a bug in the above and added WVGA mode that should work on most monitors and TVs. New version is in HyperHDMI_16bpp_4e.zip.
Comments
Here is a version of the files in top post, modified to load image from uSD instead.
Works with both PNut and FastSpin
Some of the image parameters and row settings are now abstracted to make it easier to extend to larger images.
It works. I think before it was violating some spec. But, looks good.
Here's the revamped sdspi low level code with optimised sysclock/8 performance. Note it relies on the latest master build of Fastspin for this to compile correctly: Fastspin Version 4.1.12-beta-05342967 from https://github.com/totalspectrum/spin2cpp
Pnut compiles it okay but gets SD errors. Presumption is Pnut handles inlined assembly differently so timing is out.
EDIT: File updated with extra comments
Once I get the streamer into action then it'll need an adjustable compensation based on sysclock. Or maybe based more on the SPI clock.
Can be 480p, 720p or 1080p mode.
Need to try with faster block reads next.
Also, there is something strange going on with the "bashed" version of sdspi that makes me need to remount between images. Something to do with the timeout I think... Need to investigate that...
Update: Fixed some timeout issues with FSRW in the newly attached.
I.e, it takes 1 second to load a new image from uSD into HyperRam.
Not horrible, but hopefully eMMC will improve things...
Does that mean you can load one HyperRam display pane, whilst viewing another, to change the 1 sec black, to 1 sec update ?
Here's what it looks like in 1080p:
I wish I could load while viewing. Might have that kind of bandwidth in 720p, but probably not at 1080p.
Think that needs sysclock/1 speed
I saw some interesting things in your hyperram thread btw.
There's about 1 second of white screen between images, while it loads from uSD to HyperRam.
This version has the fixed FSRW, where the timeout issues have been addressed.
All better in this one.
It works and load time reduce from ~1000 ms to ~250 ms.
I think it could be reduced even further using only multiblock reads.
This uses a combination of single block reads (currently very slow in my eMMC driver) and mult-block reads.
Still it looks acceptably fast now to actually be used in real life:
Found this out while doing the HDMI @ 720p from HyperRam from this thread: http://forums.parallax.com/discussion/171708/
See below how this shift should be 6 when was 7.
This means I was skipping over rows in my past implementations. Not a big deal, unless you actually need every row...
The really strange part is that my VGA 1080p @60Hz code is broken with this fix. It shows bad reads due to hyperram memory degradation.
It seems as though there's some magic in skipping memory rows when doing long reads... Maybe need to investigate this some more...
But, for some reason, I have yet to understand, It was OK doing 1080p @ 60Hz, 8bpp using a two row read when the next read skipped two rows... Very strange... Must be something to do with the internal refresh mechanism...
One possible way to solve it is using top-down addressing to access the video buffers.
That way, both mechanisms could eventually cross their operations at any region within memory space, but will not remain overlapping each other for long.
Sure, after any crossing event, they'll be stepping over the past footprints of other's recently actions, but this is unnavoidable, unless you are using the newer devices, that enable segregating some areas from receiving self-refresh mechanism attention, because they'll indeed be refreshed by sequentially accessed buffers, like.....video ones.
Since we couldn't exert control over self-refresh counter incrementing/decrementing, then there is the option to control the memory buffer blocks addressing scheme.
P.S. I'd forgot to mention that the above scheme will also make better use of variable-latency-enabled devices, when they become available.