Alternate SPI pins on Teensyduino 1.37 not working

hmpws

Member
I have just installed Teensyduino 1.37 and it seems that the setSCK(), setMOSI() and setMISO() are not working as before. I probed the pins on my Teensy 3.2 and got signal out on the default SPI pins. Reinstalling Teensyduino 1.36 worked properly. Hopefully I haven't missed something!
 
Last edited:
You need to post a complete program, even if it's trivial. Complete means I or anyone else can copy and paste it into Arduino and upload it to a Teensy 3.6 to recreate the exact same problem you saw.

That's how things work here.
 
Of course, my apologies. The test code is now attached. I have also got a couple of screenshots from the logic analyser on both Teensyduino 1.36 and 1.37 on the alternate pins.
 

Attachments

  • SPITest.ino
    785 bytes · Views: 118
  • alternateSPI_136.jpg
    alternateSPI_136.jpg
    50.3 KB · Views: 144
  • alternateSPI_137.jpg
    alternateSPI_137.jpg
    48.8 KB · Views: 143
You are calling 'SPI.begin()' before setting the alternate pins, which sets the default pins to SPI mode. The old SPI library used to deconfigure the previous pins from SPI mode, the new version doesn't anymore.

Things will work correctly, if you call the 'SPI.setXXX()' stuff before 'SPI.begin()'. There is no reason to call 'SPI.begin()' more than once (i.e. in 'setup()').
 
What is the correct method to change the SPI pins in the loop? I actually have SPI devices connected on both set of pins. In the older version, I simply called the setxxx() functions before beginning a new transaction. Sorry, I am not too familiar with microprocessor programming.
 
You could probably just call begin again right after you set the the new SPI pins. But to be cleaner you should probably call end first in order to make the old pins not be in SPI mode as you change to different pins.
 
You could probably just call begin again right after you set the the new SPI pins. But to be cleaner you should probably call end first in order to make the old pins not be in SPI mode as you change to different pins.

Thanks for your help everyone! I have changed the code following your suggestions.

I find that the pins don't 'unset' without ending the last begin(). I am guess the output pins are set by an appropriate mask in the register. I will have to look at the functions and dive into the datasheet if the switch timing is more important but it is good to see it working again!
 

Attachments

  • SPITest.ino
    1,009 bytes · Views: 132
  • SPIPins_withEnd_137.jpg
    SPIPins_withEnd_137.jpg
    61.3 KB · Views: 221
  • SPIPins_withoutEnd_137.jpg
    SPIPins_withoutEnd_137.jpg
    62.2 KB · Views: 102
@Paul - If desired I could add the functionality back in to the SPI library (like the code in avr_emulation.h)
So the code would probably change something like:
Code:
void SPIClass::setMOSI(uint8_t pin)
{
	if (pin != hardware().mosi_pin[mosi_pin_index]) {
		for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
			if  (pin == hardware().mosi_pin[i]) {
				mosi_pin_index = i;
				return;
			}
		}
	}
}
To something like:
Code:
void SPIClass::setMOSI(uint8_t pin)
{
	if (pin != hardware().mosi_pin[mosi_pin_index]) {
		for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
			if  (pin == hardware().mosi_pin[i]) {
				if (hardware().clock_gate_register & hardware().clock_gate_mask) {
					volatile uint32_t *reg;
					reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
					*reg = 0;
					reg = portConfigRegister(hardware().mosi_pin[i]);
					*reg = hardware().mosi_mux[i];
				}	
				mosi_pin_index = i;
				return;
			}
		}
	}
}
And similar for the setMISO and setSCK
 
Back
Top