SPI pins of each ports

As far as I know, nobody has written any libraries to use those SPI-based ethernet chips with DMA. Will you do this work? Are you experienced in writing such DMA-based code? It's not easy and if you haven't done so before, the learning curve is very steep. Not impossible, but you would be wise to consider how difficult it can be.

Even with the traditional polled SPI code, those chips have a long history of sluggish performance. I am the person who optimized the Arduino Ethernet library (for Wiznet W5100, W5200, W5500). Even without the extra complexity of DMA, just using simple polled SPI, for many years nobody really did comprehensive optimizations until I made version 2.0, rewriting quite a lot of that library.

Maybe you will do so much better, but if you have zero experience with these chips, consider how poorly that relatively simple non-DMA library worked for so many years because nobody was willing to put in the needed effort.
 
Last edited:
I'm also a bit skeptical those SPI-based ethernet chips can ever achieve low overhead, even with use of SPI FIFOs and DMA. Will admit, I really only have experience with Wiznet W5500. I haven't used ENC28J60. Maybe it is better? But I can say from experience the Wiznet chip has quite a lot of overhead for many small transfers needed to manage the registers before you're able to perform a longer transfer just to move 1 packet over SPI.
 
The Teensy 4.1 CARD ideally delivered with the Teensy, or linked on PJRC.COM, shows pins associated with SPI and SPI1 on the front and SPI2 on the bottom.

The color code for SPI is 'green bubbles' around SCK/MOSI/MISO in BOLDand the CS indicated are usable but often any free pin can be used for CS.
Those for SPI1 and SPI2 have that # digit appended to the pin function name noted above.

Any secondary SPI pins that can be used as alternates are in green bubbles, but not BOLD, and their usage requires appropriate SET commands to use them instead.
I am designing a T4.1-based board, and want to make sure that I cannot use, say, the SPI1 SCK1 pin with the SPI(0) MOSI and MISO pins. This is allowed for Teensy up to 3.5/3.6, according to the pjrc SPI Library, section on "Alternate SPI pins". That page has not been updates for T4.x. I have all kinds of constraints on this new board (e.g.: can't use pin 13 (SCK) because of the LED, can't use SPI1 because it would be difficult to move TX1/RX1 to another serial port (legacy compatibility), finding PWM pin groups that use the same timer for driving groups of LEDs, etc.).
So can I mix SPI and SPI1 signals individually on T4.1? (please, fingers crossed)
 
I am designing a T4.1-based board, and want to make sure that I cannot use, say, the SPI1 SCK1 pin with the SPI(0) MOSI and MISO pins. This is allowed for Teensy up to 3.5/3.6, according to the pjrc SPI Library, section on "Alternate SPI pins
Sorry, the Simple answer is No.

There are not very many Alternate SPI pins that are brought out on the Teensy 4.1
I believe none on the SPI object, a few on the SPI1 and 2 objects. Which are shown on the Cards that come with the Teensy which is also shown on the product page
 
Sorry, the Simple answer is No.

There are not very many Alternate SPI pins that are brought out on the Teensy 4.1
I believe none on the SPI object, a few on the SPI1 and 2 objects. Which are shown on the Cards that come with the Teensy which is also shown on the product page
I appreciate the reply. That made me look at it a little harder. The answer (for me) is to use SPI1 with the alternate MISO1 and CS1 pins. That leaves TX1/RX1 available. Thanks, Kurt!
 
Sorry, the Simple answer is No.

There are not very many Alternate SPI pins that are brought out on the Teensy 4.1
I believe none on the SPI object, a few on the SPI1 and 2 objects. Which are shown on the Cards that come with the Teensy which is also shown on the product page
For reference this is:

Teensy 4.1:
  • CS pins for SPI0: 10, 36, 37; MOSI0: 11; MISO0: 12; SCLK0: 13
  • CS pins for SPI1: 0, 38; MOSI1: 26; MISO1: 1 (alternate 39); SCLK1: 27
  • CS pins for SPI2: 44; MOSI2 (alternate 50): 43; MISO2: 42 (alternate 54); SCLK2: 45 (alternate 49)

Teensy 4.0:
  • CS pins for SPI0: 10; MOSI0: 11; MISO0: 12; SCLK0: 13
  • CS pins for SPI1: 0; MOSI1: 26; MISO1: 1; SCLK1: 27
  • CS pins for SPI2: 36; MOSI2: 34; MISO2: 35; SCLK2: 37
  • Note, the Teensy 4.0 card did not call out 0 being the special CS pin or 1 being the MISO1 pin.

Unlike the Teensy 3.x processors, I'm not aware of any of the display driver libraries having special optimizations if you use the special CS pins. In the Teensy 3.x processors, you needed both the CS and the D/C pins to be in the special set. The Teensy 4.0 did not have 2 CS pins for any of the 3 SPI ports. In theory, the Teensy 4.1 could do the optimization. On the other hand, the Teensy 4.0/4.1 drivers now have DMA support.
 
Unlike the Teensy 3.x processors, I'm not aware of any of the display driver libraries having special optimizations if you use the special CS pins. In the Teensy 3.x processors, you needed both the CS and the D/C pins to be in the special set. The Teensy 4.0 did not have 2 CS pins for any of the 3 SPI ports. In theory, the Teensy 4.1 could do the optimization. On the other hand, the Teensy 4.0/4.1 drivers now have DMA support.
Minor background comments:

CS Pins: Most libraries do not do anything special with the CS pin. That is they typically use something like digitalWrite to set and clear the state. However, there are some libraries, like some of our display libraries that uses the hardware to control the CS (and/or DC) pins.

On T3.x - in most of the display libraries, I tried to relax the requirement that both CS and DC had to be hardware CS pins. There is a significant performance difference with the DC pin being on one and some for the CS pin.

Why: on The T3.x processors you can encode the state of up to 4 hardware CS pins onto each item you push onto the Hardware output queue. Without this: each time the DC pin changes state, you have to wait until the hardware has completely shifted out the last bits of the data being output before you change the state of the IO pin and then can queue up the next data. This leaves gaps between groups of bytes output.
So if your code does something like: tft.drawPixel(x, y, color):
This outputs something like: <2A> xs xs xe xe <2B> ys ys ye ye <2C> CC CC

Note: some of the <2A> ... and <2B> ... parts on some displays might be optimized out if X start and end are the same as previous.
But in the above case the state of DC changed 6 times.

on T4.x - The Chip select pins work differently. As I mentioned in the T3.x section, the output queue you can encode the state of each of up to 4 CS pins states as part of the queue as a mask. With T4.x the data that you can encode onto the SPI output queue is which of the 4 CS pins should be asserted during the output. So, for example you cannot tell it to have both the DC and CS pins asserted. ...

In some of the libraries there is some performance gain if you use a hardware CS pin for the DC pin.

Good luck
 
I am working on connecting an AD7380 to the Teensy 4.1 using SPI1 (LPSPI3) and I have run into a problem with pin initialization which results in no data returned on the SDI pin of the Teensy. So, I decided to print out the pin mux values after initialization alongside those of the SPI port that is working for the TFT and TS.


// start the SPI library:
SPI1.begin();
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE3));
Serial.printf("\nMISO_1 mux %x\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_13);
Serial.printf("MOSI_1 mux %x\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_14);
Serial.printf("SCLK_1 mux %x\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_15);
Serial.printf("CS_1 mux %x\n\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_12);
Serial.printf("\nSDI_0 mux %x\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_01);
Serial.printf("SDO_0 mux %x\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_02);
Serial.printf("SCK_0 mux %x\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03);
Serial.printf("CS_0 mux %x\n\n", IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_00);

Here is what I get:
SDI_1 mux 5 <-----
SDO_1 mux 12
SCK_1 mux 12
CS_1 mux 15


SDI_0 mux 13
SDO_0 mux 13
SCK_0 mux 13
CS_0 mux 15

The results for the SPI port are as expected, but the SDI pin mux for SPI1 is not being set correctly. Is there a data structure I needed to set up to tell the SPI library which a pins I intended to use?
Thanks.
 
Back
Top