Reassigning a pin (SPI SCK)

Status
Not open for further replies.

el_supremo

Well-known member
On the Teensy 3, the SPI SCK signal on pin 13 can be reassigned (in theory) to pin 14. I tried this out and can't get it to work. At the moment it seems that I can't get the SPI library to change SCK to pin 14. I have edited pins_arduino.h so that SCK is defined as 14 instead of 13 but when I run my sketch which reads an SPI real-time clock it still works on pin13.
Reassigning the pin also doesn't seem to work. If I set the SPI library code to use Pin 13 but reassign SCK to pin 14, the sketch still works with SCK on 13 whereas if the reassignment had worked the sketch should have failed.
So, two problems:
- how do I modify the SPI library so that it uses Pin 14?
- how to reassign SCK to pin14 properly. All I have done is reassign the pin to its ALT2 assignment with this
PORTD_PCR1 |= 0x200;
Is there something more that needs to be done to reassign the pin?

Pete
 
Thanks Paul. It needed the DSE. I suspect that in most cases when reassigning a pin you must also deassign whichever pin was handling the function previously, if there is one. In this case I used:
Code:
  CORE_PIN13_CONFIG = PORT_PCR_MUX(0);
  CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
If I don't deassign pin13 it will still have the SCK signal and the RTC will work on either pin.
The odd thing is that if I do those reassignments before I initialize the RTC, it doesn't work.
Now to see if I can get LPTMR0_ALT2 working on pin 13.

Thanks
Pete
 
Just an FYI in case anyone tries to reassign SCK from pin 13 to pin 14.
You must do the reassign AFTER all SPI setup has been done. I haven't followed the code completely but SPCRemulation (in avr_emulation.h) does some fancy footwork with the =, |= and &= operators and they can either call enable_pins() or disable_pins(). If you call setBitOrder and/or setDataMode after the reassignment, their use of the SPCRemulation operators will change the configuration of pin 13.This is how a complete reassignment sequence should be done:
Code:
  SPI.begin();
  SPI.setBitOrder(MSBFIRST); 
  SPI.setDataMode(SPI_MODE1);
  
// It is VERY IMPORTANT that the pins be reassigned AFTER ALL
// SPI initialization INCLUDING datamode or bitorder etc.

  // First reassign pin 13 to the default so that it is not SCK
  CORE_PIN13_CONFIG = PORT_PCR_MUX(0);
  // and then reassign pin 14 to SCK
  CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);

Pete
 
We need to capture this in a way that it is easy to reference later. Not sure what the plan for Teensy 3 documentation is... wiki or ?
 
I agree that it is so easy for these snippets to be come buried and hard to find without exactly the right search string. Some sort of harvesting and organisation effort is needed to update documentation (and the longer it's left the more daunting it is to start).

Evidently the core Teensy team is more community-involved than is the case in some other projects, but equally they can't do it all (and shouldn't, because their expertise is best applied elsewhere) and thus a community-edited wiki would be a good way to approach this.
 
Can these pins be assigned and re-asigned during runtime?

I am running led strips using pins: 11(DOUT) and 13(SCK)
I want to be able to access an sd card using pins: 11(DOUT), 12(DIN), 14(SCK), 10(CS0)

So I would have to switch SCK(13) to (14), DOUT(11) to (7), the strips wont display anything while I am retrieving data from the sd card.
 
I've been playing with reassigning the SPI SCK pin again and have made a slight modification to my previous code:
Code:
  SPI.begin();
  SPI.setBitOrder(MSBFIRST); 
  SPI.setDataMode(SPI_MODE1);
  
// It is VERY IMPORTANT that the pins be reassigned AFTER ALL
// SPI initialization INCLUDING datamode or bitorder etc.

  // First reassign pin 13 to Alt1 so that it is not SCK but the LED still works
  CORE_PIN13_CONFIG = PORT_PCR_MUX(1);
  // and then reassign pin 14 to SCK
  CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);

Assigning pin13 to Alt0 prevented the LED on that pin being used. Assigning the pin to Alt1 allows the LED to be used.

Pete
 
If a pin has been configured to some other function, you can always get it back to normal I/O mode by using pinMode(). Of course, if you're already writing directly to the config registers, maybe more config writes aren't a big deal. But if you'd like to use as few lines of hardware specific code as possible, calling pinMode() might be nicer?
 
How to reassign the pin DOUT(11) to (7), i am using Teensy audio adaptor board for a datalogger project. please help.
 
I've been playing with reassigning the SPI SCK pin again and have made a slight modification to my previous code:
Code:
  SPI.begin();
  SPI.setBitOrder(MSBFIRST); 
  SPI.setDataMode(SPI_MODE1);
  
// It is VERY IMPORTANT that the pins be reassigned AFTER ALL
// SPI initialization INCLUDING datamode or bitorder etc.

  // First reassign pin 13 to Alt1 so that it is not SCK but the LED still works
  CORE_PIN13_CONFIG = PORT_PCR_MUX(1);
  // and then reassign pin 14 to SCK
  CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);

Assigning pin13 to Alt0 prevented the LED on that pin being used. Assigning the pin to Alt1 allows the LED to be used.

Will this same methodology work to reassign SCK0 from PIN 13 to Alternate PIN 27 on the Teensy 3.6
This will get all the ILI9341 wires to the same side of the Teensy and eliminate that annoying flashing LED.
I'll give it a try later when I'm at my hobby bench.
 
Will this same methodology work to reassign SCK0 from PIN 13 to Alternate PIN 27 on the Teensy 3.6
This will get all the ILI9341 wires to the same side of the Teensy and eliminate that annoying flashing LED.
I'll give it a try later when I'm at my hobby bench.

You should simple be able to do: SPI.setSCK(27);
You should be able to do this before or after SPI.begin().

Looks like I did not catch that one when I played with SPI... Mainly Worried about SPI1 and SPI2... Will go back and check these.
 
It seems that SCLK = 27 is not defined in ILI9341_t3.cpp or avr_emulation.h
I gave it a try, but could still not get alternate SCK0 PIN 27 to work in my ILI9341_t3 based sketch.
Fortunately I was able to undo what I changed and it still works with PINs 13 & 14
 
Last edited:
Wozzy, I am in the process of adding it to base code right as we speak.

Will also see about adding it to ILI9341 as well. I have added them to my SPIN version (not pushed up yet),
In addition to pin 27 not being supported, Pin 28 for MOSI, 39 for Miso and 45 as an CS were not supported.

Just getting ready to test the code now.
Had to update all of the internal functions from having 1 bit per option (either this pin or that pin) to two bits... #ifdefed to only these boards.

Should hopefully be pushing up changes to my forks later today or tomorrow, but probably won't be picked up by Paul for a bit of time.
 
Kurt - let me know when you have something to test - I'll get back to putting displays on my beta boards.
 
I Pushed up changes: will comment in beta thread as well:

Updated Cores (new Miso/mosi/sck pins): https://github.com/PaulStoffregen/cores/pull/173
Updated SPI (New CS pin): https://github.com/PaulStoffregen/SPI/pull/20
Updated ILI9341_t3: https://github.com/PaulStoffregen/ILI9341_t3/pull/31

I also updated my SPIN library: https://github.com/KurtE/SPIN

Which I use in my version of ILI9341_t3n library: https://github.com/KurtE/ILI9341_t3n
to be able to be used on all of the SPI busses and works OK with just on hardware CS. No changes needed here as the check for valid MISO/MOSI/SCK is done in SPIN. Actually would be nice to add it instead to SPI library like the is valid CS calls.

Anyway with all of these changes I was able to get my PJRC touch screen working with ILI9341_t3 library on the new pins:
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, 6, 28, 27, 39);

I first tried it on my library with pins (11, 12, 13) then (7, 8, 14), and then 29, 39, 27
 
Thanks KurtE,

Great work.
It's working on SCLK = 27 now with your pull requests.
I updated to Teensyduino 1.30 B4 then applied your 3 changes.
Now I can wire up a ribbon cable and save all that breadboard space since all the pins are on the same side of the Teensy.

Code:
#include "SPI.h"
#include "ILI9341_t3.h"

#define TFT_DC      9  // 20
#define TFT_CS      10 // 21
#define TFT_RST     8  // 255 = unused, connect to 3.3V
#define TFT_MOSI    11 // 7, 11, 28
#define TFT_SCLK    27 // 13, 14, 27
#define TFT_MISO    12 // 8, 12, 39
 
Last edited:
On the Teensy 4.0 what is the process to reassign the SPI SCK signal on pin 13 to pin 14. I am having a conflict when trying to drive a stepper driver ( Popolu HPSD), I tried some of the solutions here with the 3.6 but they aren't the same. I can get it to display it is on pin 14, but it still operates when I use 13 and pin 14 has no connection. I was thinking of using SPI1 but 2 of the pins are on the backside and I don't have any connectivity to those yet.
Thanks
 
That's what I had:
I saw that Paul had some other more detailed lines added in, I am still just getting pin 13 as the CLK pin.
Thanks.....

void setup()
{
Serial.begin(115200);
Wire.begin();
lcd.begin();
lcd.backlight();
SPI.begin();
SPI.setSCK(14);
hpsd.setChipSelectPin(SS);
 
On the Teensy 4.0 what is the process to reassign the SPI SCK signal on pin 13 to pin 14. I am having a conflict when trying to drive a stepper driver ( Popolu HPSD), I tried some of the solutions here with the 3.6 but they aren't the same. I can get it to display it is on pin 14, but it still operates when I use 13 and pin 14 has no connection. I was thinking of using SPI1 but 2 of the pins are on the backside and I don't have any connectivity to those yet.
Thanks

I don't think the Teensy 4.0 has the alternate SPI pins like the Teensy 3.x/LC had. That's why the beta users were given a break out board that mapped the Teensy 4.0's pins to the pins the audio shield used.

Note, the I2S output pins are different on the Teensy 4.0 as well (on the 3.x, you needed to use several of the pins normally used for SPI for I2S).

Here is the breakout board:
 
Status
Not open for further replies.
Back
Top