IIC ACK?
Rick Murray (539) 13840 posts |
I received my little OLED module this morning. The first task was to short pins 19 & 20 on the ribbon cable to the controller chip as apparently these are SDA_IN and SDA_OUT and only SDA_IN was wired up. Aimed at microcontrollers, it would be quite easy for them to write a broken IIC protocol that spat out data without expecting an ACK. Unfortunately, we need an ACK to co-exist as this is a real IIC bus. The horrible torn-up-track is because Heltech grounded pin 20 (should have been left floating, surely?) which meant that joining the two with a blob of solder would force SDA low and kill all IIC communications. I can read from the device. Any read will return the contents of the status register, in which ‘64’ (bit 6) is set when the display is off. This is the power-up default. If you look closely at the orange ribbon, you’ll see tiny scraped-away places. This is to confirm that the electrical connection is good, and that SDA_IN and SDA_OUT are both connected to SDA … would have been simpler if the <beep>ing Chinese outfit that made this thing did it properly in the first place! The SSD1306 is not exactly an unknown part, is it now? But, there’s what should happen and then there’s reality. Hmmm… Does anybody have any ideas? If not, I suspect I might (some day, when I can be bothered) hijack some GPIO lines and try bit-banging IIC to see if I can determine what exactly is going on. |
Dave Higton (1515) 3526 posts |
When writing to an IIC EEPROM, the EEPROM doesn’t ACK until it has completed the write. You write the stuff, get NACK, then keep addressing the thing repeatedly until you get ACK. When you do get ACK, it’s ready for you to have another go. Perhaps there’s something similar going on in your display module, and perhaps similar treatment is appropriate. |
Rick Murray (539) 13840 posts |
I was thinking last night – reading works, so data in (address) and data out (status) work. |
Rick Murray (539) 13840 posts |
Nice to know it bothers to implement tugging on SCL to mean “hang on, I’m busy”.
What do you mean by “addressing the thing”? You only get an ACK for bytes written, don’t you?
The datasheet doesn’t indicate that writing is slow. Indeed, you are supposed to be able to write the data for the display at least every refresh (15fps?) to avoid ‘tearing’ as the screen updates itself from the stored bit pattern in its memory. |
Rick Murray (539) 13840 posts |
Okay. Sussed it. It needs two things. The first is a prefix byte to specify “command” or “data” (this was buried deep in the datasheet) and it will also choke and give up if it thinks there is anything wrong with the data it has been fed. But, no matter. I’m getting somewhere. Took forever before the penny dropped that each byte is eight pixels down with column increment, and eight ‘pages’ (eight pages of 8 rows of pixels = all 64 pixels).1 Once I’d sussed that one, the rest was just bit ops in BASIC. ;-) Oh, and ChangeFSI thinks dithering to a b/w image of 64×64 is “too complicated”. This is the ‘d’ special pattern as ‘c’ looked awful and error diffused didn’t want to know. 1 Horrible ASCII art: [page 0] 0 0 0 ... 0 1b 1b 1b ... 1b 2y 2y 2y ... 2y 3t 3t 3t ... 3t 4e 4e 4e ... 4e 51 52 53 ... 51 6 6 6 ... 62 7 7 7 ... 78 [page 1] 0 0 0 ... 1 1 1 ... [etc] |
Rick Murray (539) 13840 posts |
Final test of the night – a custom ‘font’ with the smallest characters I think will still be legible (mostly). I will probably go with a 7×5 ‘font’. Less on-screen at one time, but also less naff looking (look at the lowercase versions for examples of naffness!). |
Rick Murray (539) 13840 posts |
I lied. One last little thing. The display memory, of a 1280×1024 screen, integer-averaged down to 128×64 on-or-off. What you can see is a textured background, two filer windows, and a Zap taskwindow. The result is only slightly worse than ChangeFSI, and this is done on the fly ripping directly from screen memory. I wrote a little Obey file to run the screen grabber (written in C, as BASIC is way too slow) and then call the program to push the image data to the OLED, and then call itself to repeat the process. It was managing around 2-3fps1 in a taskwindow, which was amusing. To save spamming the forum with pictures, click this → http://www.heyrick.co.uk/random/pics/oleddesktop.jpeg (1280×720, 183K). 1 This could be optimised greatly. The screen grabber builds a byte array and translates that into a sprite, and the plotter loads a sprite and translates that into byte data. Oh, and that part is in BASIC. So it could run faster. It is, however, practically zero use whatsoever except just to say… I did it. Which is good enough. [That’ll do, pig. That’ll do.] |
Jeffrey Lee (213) 6048 posts |
Which version of ChangeFSI? With 1.40 I believe I fixed all of the silly cases where it was complaining things were too complicated (for images <8bpp it was shifting the address left by 1-3 bits so that it could use the value to address the image on a per-pixel basis. Which doesn’t work so great on RISC OS 5 where it has to deal with dynamic area addresses with the top three/four bits non-zero) |
Dave Higton (1515) 3526 posts |
You need to look at the data sheets of a few IIC devices so you understand how IIC works. Particularly if you’re talking about bi-banging it. |
Rick Murray (539) 13840 posts |
I bit banged IIC on RISC OS, DOS, and Windows (parallel port), but that was over a decade ago. My memory is fuzzy. |
Rick Murray (539) 13840 posts |
Today’s work (lowish quality image to keep filesize down): If you want to see it in action: http://www.youtube.com/watch?v=4Uj0rAW_XAI (720P) I was wondering about the font to use, but it turns out that redirecting VDU→sprite means I can use everything that RISC OS places at my disposal. That which you see above is the standard RISC OS VDU font, and I can fit 16×7 on the display, with a full character set already made. I have played around a little and tested it using 8pt Corpus, which gives me 21×7, and (starting to get unreadable!), 6pt Corpus would offer an astonishing 28×9 (but only in capitals/digits as other stuff gets garbled in 1bpp!). It’s just a test. I’ll probably stick to the VDU font. It is nice and clear, which is arguably the entire point of the exercise. |
Rick Murray (539) 13840 posts |
Just noticed… My clock seems to think it is tomorrow. Did I mess up in switching to summer time? Pro’lly. |
David Pitt (102) 743 posts |
My Pi clock went a bit adrift from reality recently, it seemed to have automatically picked a server that did not actually know what the time really was! It is now configured to PlusNet’s server. *nettime_status Current time: Thursday, 3 April 2014 19:35:43.85 Status: Sleeping Last server: samarium.admin.cloudfabriq.com Poll interval: 30 minutes Timer latch: 10000 *nettime_kick *nettime_status Current time: Thursday, 3 April 2014 22:16:45.86 Status: Sleeping Last adjustment: 10 seconds ago Last delta: 0.010093 seconds fast Last server: uk.pool.ntp.org Last protocol: SNTP Poll interval: 30 minutes Timer latch: 10002 (-200ppm) * |
WPB (1391) 352 posts |
Great stuff, Rick! How much current does that display module draw? Very little, I’d expect, but have you tried to measure it? |
Rick Murray (539) 13840 posts |
Not tried to measure it. A Google search says it is around 1.2mA in sleep mode, and a fully lit 0.96" display is 22.75mA. As this is a 1.3" display, add half as much again just to cover differences, we’re looking at something in the region of 30mA….in theory. Leaving it running for hours last night, no part of it so much as warmed up. |
Rick Murray (539) 13840 posts |
Just measured it at four settings. The display has 256 discrete “Contrast” settings (for our purposes, contrast = brightness) though it seems that the larger the value, the less difference it makes. The default setting is halfway, and there isn’t much between that and full brightness. Readings taken from the OLED connected to a RaspberryPi, powered from 3.3V, with all pixels lit. Minimum brightness (0x00) - 13.7mA Low brightness (0x3F) - 29mA Middle/default brightness - 33.3mA Higher brightness - 35.2mA Maximum brightness - 36.2mA Because the display is self-illuminating, I find the defalt medium brightness to be quite sufficient. Especially when you consider that the ‘on’ pixels glow and the ‘off’ pixels barely reflect. I just held my phone’s bright LED torch right up to the display and it was still perfectly readable. |
Dave Higton (1515) 3526 posts |
Rather belated reply…
No, it doesn’t; it simply doesn’t pull SDA low.
You should get an ACK when sending every byte, including the address right from the first byte. No ACK (i.e. SDA not pulled low) means there’s nothing responding, which would include any device that’s busy, e.g. doing the write you just asked it to do a few tens of microseconds ago. |