Repository navigation
ili9325: add ILI9325 driver for 8-bit parallel displays - #926
Conversation
This adds a driver for the ILI9325 TFT controller on an 8-bit parallel bus, with an example for the ITead ITDB02-2.8 Arduino shield.
This adds an example that draws the Lorenz attractor on the ITead ITDB02-2.8 shield.
The Mega and Zero board files name the analog pins ADC0 and up, and drivers examples such as the ITDB02 shield demo in tinygo-org/drivers#926 use those names. The Due now has the same names as aliases of A0 to A11.
This ports the Lorenz example from the ILI9325 PR (tinygo-org#926) to the Adafruit 2.2" TFT on an Arduino Due, to show a moving drawing on a fast SPI bus. Only the display setup changed. It was tested on a Due, where it is upright and rotates. It uses SPI at 42 MHz, which worked on the test wiring but is above the ILI9341 rating of 10 MHz. The README says to lower the clock if the display shows noise. Like the other Due example, it needs the arduino-due target from davecheney/tinygo, so it is not in smoketest.sh.
deadprogram
left a comment
There was a problem hiding this comment.
Thanks for this. The smoketest builds and go vet pass locally, and the rotation mapping in setWindow looks right to me. A few small things inline.
| cx, cy = x0, y0 | ||
| mode = entryModeIDX | entryModeIDY | ||
| } | ||
| d.writeReg(ENTRY_MODE, entryModeBGR|mode) |
There was a problem hiding this comment.
ENTRY_MODE only depends on rotation, so this could be written once in SetRotation instead of on every setWindow call. SetPixel currently does 8 register writes per pixel, so this would help the lorenz example a bit.
There was a problem hiding this comment.
Done in 74c77c1. SetRotation now writes ENTRY_MODE once, so setWindow does 7 register writes per call, not 8.
Thanks for the review. I’ll check them today. Especially rotation as I simply turned the board til it was the right way up for me :) |
Review of tinygo-org#926 asked for ENTRY_MODE to be written once per rotation, for clearer errors and doc comments, and for a check of the WR pulse width against the ILI9325 AC characteristics. The datasheet V0.43 13.4.1 gives PWLW and PWHW 50 ns min. A DSLogic capture at 400 MS/s on an Arduino M0 at -opt=2 showed WR high of 25 ns between the two bytes of a pixel. WR low was in spec. At the default -opt=z each register store is a call, so the pulses were long only by accident. Inline asm padding gives the same minimum at every opt level. After the change the minimums are 58 ns low and 65 ns high. Traces: https://raw.githubusercontent.com/davecheney/tinygo/pr-assets/drivers926-wr-timing.png
deadprogram
left a comment
There was a problem hiding this comment.
Thank you for the addition @davecheney now squash/merging.
At -opt=z every function has minsize, and LLVM ignores inlinehint in a minsize caller. A register write through a pointer, such as a Register32 held in a driver struct, then becomes a call to Set. The inlined store is also smaller than the call. Measured with the ili9325 Lorenz example from tinygo-org/drivers#926 on an Arduino M0 (SAMD21, 48 MHz). The flash sizes include timing code. The speeds are the mean of three readings. | opt | flash before | flash after | FillScreen before | FillScreen after | Lorenz steps/s before | Lorenz steps/s after | |---|---|---|---|---|---|---| | z | 24104 | 24024 | 137.9 ms | 34.2 ms | 3125 | 3667 | | s | 24196 | 24148 | 29.2 ms | 29.2 ms | 3972 | 3943 | | 1 | 33620 | 33620 | 29.3 ms | 29.3 ms | 4117 | 4134 | | 2 | 33092 | 33092 | 29.2 ms | 29.5 ms | 4156 | 4116 | The z before values are from the same dev commit. The s, 1 and 2 before speeds are from an earlier dev commit. At -opt=z, FillScreen is still 5 ms slower than at -opt=s, with no calls to runtime/volatile left. That difference comes from minsize in other code and is not part of this change. Fixes tinygo-org#6063
At -opt=z every function has minsize, and LLVM ignores inlinehint in a minsize caller. A register write through a pointer, such as a Register32 held in a driver struct, then becomes a call to Set. The inlined store is also smaller than the call. Measured with the ili9325 Lorenz example from tinygo-org/drivers#926 on an Arduino M0 (SAMD21, 48 MHz). The flash sizes include timing code. The speeds are the mean of three readings. -opt=z: flash 24104 to 24024 bytes, FillScreen 137.9 to 34.2 ms, Lorenz 3125 to 3667 steps/s. -opt=s: flash 24196 to 24148 bytes, FillScreen 29.2 to 29.2 ms, Lorenz 3972 to 3943 steps/s. -opt=1: flash 33620 to 33620 bytes, FillScreen 29.3 to 29.3 ms, Lorenz 4117 to 4134 steps/s. -opt=2: flash 33092 to 33092 bytes, FillScreen 29.2 to 29.5 ms, Lorenz 4156 to 4116 steps/s. The z before values are from the same dev commit. The s, 1 and 2 before speeds are from an earlier dev commit. At -opt=z, FillScreen is still 5 ms slower than at -opt=s, with no calls to runtime/volatile left. That difference comes from minsize in other code and is not part of this change. Fixes tinygo-org#6063
At -opt=z every function has minsize, and LLVM ignores inlinehint in a minsize caller. A register write through a pointer, such as a Register32 held in a driver struct, then becomes a call to Set. The inlined store is also smaller than the call. Measured with the ili9325 Lorenz example from tinygo-org/drivers#926 on an Arduino M0 (SAMD21, 48 MHz). The flash sizes include timing code. The speeds are the mean of three readings. | opt | flash before | flash after | FillScreen before | FillScreen after | Lorenz steps/s before | Lorenz steps/s after | |---|---|---|---|---|---|---| | z | 24104 | 24024 | 137.9 ms | 34.2 ms | 3125 | 3667 | | s | 24196 | 24148 | 29.2 ms | 29.2 ms | 3972 | 3943 | | 1 | 33620 | 33620 | 29.3 ms | 29.3 ms | 4117 | 4134 | | 2 | 33092 | 33092 | 29.2 ms | 29.5 ms | 4156 | 4116 | The z before values are from the same dev commit. The s, 1 and 2 before speeds are from an earlier dev commit. At -opt=z, FillScreen is still 5 ms slower than at -opt=s, with no calls to runtime/volatile left. That difference comes from minsize in other code and is not part of this change. Fixes tinygo-org#6063
At -opt=z every function has minsize, and LLVM ignores inlinehint in a minsize caller. A register write through a pointer, such as a Register32 held in a driver struct, then becomes a call to Set. The inlined store is also smaller than the call. Measured with the ili9325 Lorenz example from tinygo-org/drivers#926 on an Arduino M0 (SAMD21, 48 MHz). The flash sizes include timing code. The speeds are the mean of three readings. | opt | flash before | flash after | FillScreen before | FillScreen after | Lorenz steps/s before | Lorenz steps/s after | |---|---|---|---|---|---|---| | z | 24104 | 24024 | 137.9 ms | 34.2 ms | 3125 | 3667 | | s | 24196 | 24148 | 29.2 ms | 29.2 ms | 3972 | 3943 | | 1 | 33620 | 33620 | 29.3 ms | 29.3 ms | 4117 | 4134 | | 2 | 33092 | 33092 | 29.2 ms | 29.5 ms | 4156 | 4116 | The z before values are from the same dev commit. The s, 1 and 2 before speeds are from an earlier dev commit. At -opt=z, FillScreen is still 5 ms slower than at -opt=s, with no calls to runtime/volatile left. That difference comes from minsize in other code and is not part of this change. Fixes tinygo-org#6063
This adds a driver for the ILI9325 TFT controller on an 8-bit parallel bus, with an example for the ITead ITDB02-2.8 Arduino shield.
IMG_2788.MOV