Optimized ILI9341_t3 driver, technical DC questions regarding implementation

honey_the_codewitch

Active member
Background - why I'm even asking:
I wrote the htcw_gfx library which is a cross platform graphics library that's a bit more high level than Adafruit and TFT_eSPI, but not quite LVGL.
It does however, support anti-aliased TrueType vector fonts, JPG, alpha-blending, indexed color matching for things like loading jpgs onto 3 or 7 color e-paper displays, a completely decoupled driver interface (htcw_gfx is not tied to hardware, drivers can be written for any hardware)
It runs on Arduino, ESP-IDF, Windows, and Linux, and probably elsewhere.

Part of the reason I wrote it is I build professionally, and I needed a graphics library that fit my specific professional requirements and that I could add to readily as I needed it.
I'm heavily invested in it, and while it runs on the Teensy as is, I'd like to optimize the SPI bus interface code used by all the Arduino drivers. Right now it's falling back to my generic Arduino SPI ops, but I'm going to conditionally compile in Teensy specific optimizations like I did with the ESP32
_____________________________________________________

I've been looking through the ILI9341_t3 library for an idea of how to speak Teensy's language at the register level.

I hit line 400 of the ILI9341_t3.h and I'm stumped by a comment I found

Code:
if (!_dcport) _spi_tcr_current = IMXRT_LPSPI4_S.TCR; 	// Only if DC is on hardware CS

I don't know if I understand. Does this provide some sort of optimization for the DC line if you wire it to a hardware SPI CS line? (as shown in the diagram that ships with the teensy)

If not, then what does it mean?

Thanks in advance!
 
DC refers to a pin/signal, but I'm not sure what it stands for. I say that because "_dc" and "_dcport" are defined along with "_cs" and "_csport" which refer to chip select. Assuming that's correct, I think "_dcport" refers to an I/O port on the IMXRT and "_dc" is a signal controlled via that port. "_spi_tcr_current" is just the current value of the SPI TCR (transmit command register). The code below is from the CPP file

Code:
	if (_dcport) {
		// DC pin is controlled by GPIO
		DIRECT_WRITE_LOW(_dcport, _dcpinmask);
 
That's not quite what I'm wondering. I know what DC and CS do. I'm asking if there's some sort of hardware optimization for wiring the DC line to one of the hardware CS pins on the Teensy, because the comment suggests as much. Paul S. I'm sure knows the answer.
 
First of all, joepasquariello IIRC, dc is often written as D/C or device/command. It is a fast way to tell the SPI controller whether the bitstream via the MOSI pin is data or commands.

Note, I am a user of the libraries, not somebody who has delved in. Hopefully, Paul S, KurtE, mjs513, and Defragster can chime in at some point, since they've actually worked on the library. Mostly I use the optimizations for running the uncanny eyes program:

The uncanny eyes programs are available as examples under the ST7735_t3:
  • 240x240 TFT display (Teensy 4.0/4.1): uncannyEyes_async_st7789_240x240
  • 128x128 TFT or OLED display (Teens7 3.2/3.5/3.6/4.0: uncannyEyes7735

The uncanny eyes program was written by Phil Burgess / Paint Your Dragon for Adafruit Industries. He based his original Teensy 3.1/3.2 code on the ST7735_t3 library by Paul S. See the thread I posted above as a history (as I see it) of the uncanny eyes program.

Now, as I understand it, in the Teensy 3.1, 3.2, 3.5, and 3.6 there are some special pins that can be optimized in the SPI protocol. For uncanny eyes (and ST773_t3 in general) to work as fast as possible on the Teensy 3.x boards, you need to select both the CS and DC pins to be among these special pins. Since uncanny eyes uses 2 displays, you need to use 3 of the special pins. However, note that some of the special pins overlap (i.e. if you use the first pin, you can't use the second pin). The pins are:
  • Pin 2 or pin 10
  • Pin 6 or pin 9
  • Pin 15/A1
  • Pin 20/A6 or 23/A9
  • Pin 21/A7 or 22/A8

Paul described it better in this post:

Unfortunately when the Teensy 4.0 came out, the SPI stuff had to be completely rewritten due to the underlying processor changes. In the Teensy 4.0, there is only 1 special pin for each of the first two SPI buses:
  • On the main SPI bus (MOSI on pin 11, MISO on pin 12, SCLK on pin 13), the only special pin is pin 10.
  • On the second SPI bus (MOSI1 on pin 26, MISO1 on pin 1, SCLK1 on pin 27), the only special pin is pin 0.

The pinout card for the Teensy 4.0 does not list pin 0 being the special pin and pin 1 being the MISO pin for the second SPI bus.

This means the special Teensy 3.x optimization done for ST7735_t3 can't be done on the Teensy 4.0 since there is only one special pin available, and you need 2 pins. During the 4.0 beta time period, there was a discussion that with one special pin, you could optimize things a little better if the D/C pin (not CS) was the special pin. I don't recall if the changes discussed got back into the sources, or whether it helped in running the program.

When the Teensy 4.1 came out, a few more pins were brought out (and the pinout card now lists them).
  • The special pins for the main SPI bus are 10, 36, and 37.
  • The special pins for the secondary SPI bus are 0 and 38.
  • Pin 39 is an alternate MISO1 pin for the secondary SPI bus.

While the Teensy 4.x microprocessors, don't have the special pin support (as far as I know), a lot of work has gone on to optimize the displays to use DMA. There you need to talk to people who have worked on the library. With its different memory regions, you do have to also worry about caching since DMA at times by-passes the cache and goes straight to memory. So you need to either flush the cache at appropriate times, or know whether the memory you are using will work with DMA devices.
 
Back
Top