Drive for inexpensive 128x64 OLED displays
Rick Murray (539) 13806 posts |
[gah! title typo!] The driver module, documentation, and the demo program featured in the video: http://www.heyrick.co.uk/software/oled/oled_0-01.zip Blog article on getting the hardware set up: http://www.heyrick.co.uk/blog/index.php?diary=20140421 Blog article on using/programming the OLED: http://www.heyrick.co.uk/blog/index.php?diary=20140426 API/documentation (if anybody wants to read it): http://www.heyrick.co.uk/software/oled/!help.txt The OLED that I purchased: http://cgi.ebay.fr/ws/eBayISAPI.dll?ViewItem&item=221376624285 – FR ~€8,54 To remind yourself why – the YouTube video of the OLED in action (no sound, up to 1080P): http://www.youtube.com/watch?v=1pWXNa8mdiw Anybody who does cool stuff with this – let me know! |
Rick Murray (539) 13806 posts |
Clarification note – this is only for the Pi. If you’re a hardware hacker and you get it to work, the module ought to be reasonably hardware agnostic, so long as your IIC bus is what RISC OS considers to be the primary one. |
David Feugey (2125) 2709 posts |
Pi + battery + Oled + three buttons + usb dac = high end mp3 player :) |
WPB (1391) 352 posts |
Rick, this is really great. おめでとう! |
Raik (463) 2059 posts |
All what David wrote an more do my HandPi but only with Wheezy :-( |
jim lesurf (2082) 1438 posts |
Possibly even better if someone sorts out using the Wolfson card for the RPi when running RO. ;→ Jim |
Rick Murray (539) 13806 posts |
Raik – can you try the following:
From power-up with nothing touching the OLED, it should reply either 64 or 96 (but any response is good). The R/!W line is used, in IIC mode, to select an alternative device address. That’s what we’re testing. If your display responds, I can add in support for the alternative address. If it doesn’t reply to either the module default or this test, it isn’t a compatible device.1 So – fingers crossed! 1 If you can tell me the device ID, I can bake you a special version of the module to “try it anyway” if you like. |
Rick Murray (539) 13806 posts |
Unfortunately this doesn’t work with the DiskSample player. Any ideas how to make DiskSample more resilient? Is there something else that can be tweaked? |
Chris Johnson (125) 825 posts |
This isn’t similar to the problems with sound on the PandaBoard ES https://www.riscosopen.org/forum/forums/5/topics/2482 or the previous thread on the Raspberry Pi |
Raik (463) 2059 posts |
Helps not Edit: Second look in the technical doc… My display use additional the MOSI and MISO PINs of the GPIO… the rose glasses |
Rick Murray (539) 13806 posts |
Thanks for the sound problem pointers. I’ll update the OS this evening and see if that fixes things. As for your OLED… Um… Yeah… Not exactly a 128×64 1bpp is it? :-) :-) |
Raik (463) 2059 posts |
I was a little bit optimistic and so I hope my display “understand” your mode |
Steve Revill (20) 1361 posts |
It may perhaps have been useful to Rick, given the subject of this topic, to have pointed out that fact when you first said your display didn’t work… :) |
Raik (463) 2059 posts |
Rick “knows” my display ;-) |
Rick Murray (539) 13806 posts |
You’re assuming that I have a memory worth a damn… ;-) |
Raik (463) 2059 posts |
You must important things keep in mind, understand. ;-) |
Rick Murray (539) 13806 posts |
’tis okay. Gedächtnis wie ein Goldfisch. ;-) |
Rick Murray (539) 13806 posts |
Okay. The latest version does not fix things. Doesn’t seem to make any difference here (sorry Willi!). With AudioMPEG buffers set to I=128K, O=1024K and DiskSample buffers set to I=256K, O=1024K; I set my OLED update to send a screenful (8 × 131 bytes) every 2.5 seconds, I can actually hear the MP3 playback stutter as the data is sent. After maybe 10-12 seconds of this, it gives up and playback ceases. I can only imagine that the sound system is sending a “refill buffer” interrupt which isn’t getting picked up in reasonable time because the IRQs are disabled; and something (DiskSample? SoundScheduler?) throws in the towel at that point. I don’t want to jinx anything yet, but it appears to be working with the IIC hacked to run at 400kHz. I just can’t believe this is so flaky – I mean, what’s the point of a megabyte sized buffer if the sound system can’t handle something taking longer than about 15cs? Next test – fails at 400kHz IIC rate with update every 1.5s. Fails also at 2.0s. Appears to work at 2.5s. Appears to work at 2.0s if I only send the first 16 pixels of each line (instead of 128). Fails at 1.5s. Definitely some bizarre timing-related thing going on here. Jeffrey – the IIC stuff in the Pi is quite high level (not IOC pin wiggling). Is it possible to run IIC without disabling interrupts (on the Pi)? |
Rick Murray (539) 13806 posts |
…and every valid value to |
Raik (463) 2059 posts |
Sorry for my stupid question… |
Jeffrey Lee (213) 6048 posts |
In terms of interrupts being disabled during IIC transfers, the Pi is the exception, not the norm. You’d have to check with Dave Higton for the exact reason why, but the Pi implementation of HAL_IICTransfer blocks and performs the entire transfer. What it’s meant to do instead is start the transfer running and then process the rest within HAL_IICMonitorTransfer each time the IRQ fires (or each time the kernel polls it if IRQs aren’t supported). And although HAL_IICTransfer doesn’t disable interrupts itself, the kernel does call it with interrupts disabled (to cope with the slightly funny threaded/re-entrant IIC implementation), and so interrupts end up getting blocked for the entire transfer.
Negative. Audio needs VCHIQ (far too high-level to run from FIQ), and the FIQ interrupt (of which there can be only one due to limitations in the Pi interrupt controller) will soon be being used for the fabled USB FIQ fix. |
Rick Murray (539) 13806 posts |
Not stupid, just wasn’t clear. I’ll forgive you, though, that wall-banging penguin is great. I feel like that a lot at work.
My module won’t support your display. It is 1bpp at 128×64 – pretty much hardwired to the little OLED modules referred to on my blog (link at top). Your interface is SPI. This allows much higher speeds than IIC. To give an example, 320×240×18bit is ~170K per screen. If I’m experiencing audio problems sending one kilobyte to my OLED… yeah, you don’t want to think about passing 170K by IIC. I’m not ever sure it is feasible unless you don’t mind your display updates taking around 10 seconds each! ;-) Your display seems like it will be controlled by a IILI9341 or something similar. Somebody made a Linux framebuffer driver for it (and other similar displays) – https://github.com/notro/fbtft – though the Adafruit one looks like it is their own modification. |
Rick Murray (539) 13806 posts |
Fair enough. :-)
Right. I’ll give up on making an MP3 player in that case.
As you have WAY more experience with the kernel than I… I’m assuming an IIC_Control1 SWI call won’t return until the job is done (so shouldn’t have issues of IIC re-entrancy). 1 My default setting is to use IIC_Control over OS_IICOp, primarily because I remember the syntax for the former, but not the latter. 2 Unpacking last night’s tarball as I write this. |
Jeffrey Lee (213) 6048 posts |
Correct. OS_IICOp also only returns once the transfer is complete. The re-entrancy comes into effect if you have an interrupt fire in the middle of the IIC transfer, and the interrupt handler decides it wants to send its own transfer. Old versions of the kernel (pre-RISC OS 5? pre-RISC OS 4?) used to just throw an error in this situation, but the current kernel supports it. It waits for the current transfer to complete, makes a note of its error code (for return to the original caller) and then performs the new transfer.
With the current implementation, yes. The code runs in IRQ mode (I think so that it can take advantage of the way IRQsema forms a linked-list of currently active IRQ handlers), so the bits which run with IRQs enabled have to do so without using R14 – because it’ll get clobbered whenever the next interrupt happens. Which is why it ends up disabling IRQs during the HAL_IICTransfer call (plus it’s calling non-kernel code, and so doesn’t really know how to deal with re-entrancy in that case – i.e. it doesn’t know how to jump into the middle of HAL_IICTransfer and resume execution if it needs to perform a nested IIC operation). See Kernel.s.PMF.IIC for the full code! |
Rick Murray (539) 13806 posts |