PDA

View Full Version : Specifying Teensy 3.0 Alternate Pin Functions



loglow
01-28-2013, 10:54 PM
Hi there, this is my first post here on the forum (hopefully the first of many).

Instead of asking a question, I'd like to share something that might be useful to other users.

I was needing to use some of the alternate functions of the Teensy 3.0's pins, and ended up locating the following comment from Paul:


Currently there isn't software support to enable the alternates, but it is possible to make the signals appear on those pins with some direct register writes.

I created the following generic process (via macros) which seems to work for redefining the pins' functions:


#define CORE_PIN_CONFIG(pin) (CORE_PIN##pin##_CONFIG)
#define pinAlt(pin, alt) {CORE_PIN_CONFIG(pin) = PORT_PCR_DSE | PORT_PCR_MUX(alt);}
Note: Edited based on updated information.

The benefit of this is that you can define your pins in the typical way (using the Teensy 3.0 pin numbers) without needing to worry about their obscure port designations.

For example, if we have a Teensy pin defined like this:


#define I2S_MCLK_PIN 28

We can then simply switch to it's alternate function like this:


pinAlt(I2S_MCLK_PIN, 4);

Information about the alternate functions of each pin can be found in the data sheet (K20 Sub-Family Data Sheet, Rev. 4 5/2012 (http://cache.freescale.com/files/32bit/doc/data_sheet/K20P64M50SF0.pdf)) in Section 8.1 (K20 Signal Multiplexing and Pin Assignments) which is located on pages 56-58.

Please let me know if I'm missing a more recent or elegant solution to this particular issue. I'm relatively new to embedded development, so I'm learning this stuff as I go.

-Dan

el_supremo
01-28-2013, 11:09 PM
There's some stuff about pin reassignment in this thread: http://forum.pjrc.com/threads/431-Reassigning-a-pin-%28SPI-SCK%29

Pete

loglow
01-29-2013, 12:50 AM
Thanks Pete, I've updated my macros above as a result.

I'm swapping SPI0_SCK from pin 13 to pin 14 because I need to use I2S0_RXD0 which is only available on pin 13.

Unfortunately, the SdFat library's use of pin 13 for the SPI's SCK is hardcoded (Sd2Card.cpp, line 345), so the library itself needs to be modified too. Tracking this down led me to realize something important: Just because a pin's function has been reassigned to a new pin doesn't mean some library isn't still trying to use the old pin.

This makes me even less a fan of hardcoded pin numbers in libraries. I'd rather pass all the needed pins to an init function than have incorrect (albeit typical) assumptions made under the hood.

ploveday
01-29-2013, 03:04 AM
Agreed. There are so many libraries that go and do this kind of thing, it's a real mess. We're basically in the situation of having to use hand-edited versions of other libraries for each project, and deal with update merges and such as needed.

In an ideal world, one ought be able to pass an instance of an "SPI" object/interface to any library that uses SPI, and have it use it. Unfortunately the arduino stuff was pretty poorly thought out, and there's little chance of this working so well with different hardware configurations (ie T3).

Another annoyance with SdFat is that it screws with all the chip selects, so during its SPI access all 5 hardware CS lines will be set to low, even though it never uses hardware CS itself :-/

- Peter

PaulStoffregen
01-29-2013, 05:06 PM
I agree, it is a poorly planned mess.

On my longer term TO-DO list is a native SPI library, which supports the chip selects, arbitrates between different libraries, and uses DMA.

I'm open to ideas on how this mess can eventually be made better... as long as we all understand it will need to be a gradual process to improve this situation.

mxxx
06-14-2013, 05:29 PM
[QUOTE=loglow;20859]
Unfortunately, the SdFat library's use of pin 13 for the SPI's SCK is hardcoded (Sd2Card.cpp, line 345), so the library itself needs to be modified too.

i'm in the same situation, with regular SPI pins being used up by DMA/I2S. i can't seem to get sdFAT working on the alternate pins though (7,8,14 in my case). where/how exactly would one de-assign/re-assign those pins? i assume it's not enough to simply replace the relevant pin assignments in sd2card with something along the lines of your macro?

thanks!

linuxgeek
06-17-2013, 11:31 PM
This is what has soured me on shields. Shields create more problems then they solve, because now you have hardcoded hardware AND hardcoded software. And each (hardware & software) try and do workarounds for the hardcoded shortcomings of the other. You end up in situations, where after deep inspection, the pins seem to be matched up in hardware & software. Only to be thwarted by somewhere in the code, that was anticipated that a certain chip with a certain profile (on a certain day of the week, lol) should use a different pin.

Thus, shields create much more work then just creating your own breadboard or circuit board, even adjusting for the learning curve of learning how to make your first circuit board.
I don't know how to get around it without having something like an extra header file, that every library would do a lookup in to find out which pins to use. Then, every shield would come with that header file. Or some other scheme that does a lookup.

mxxx
06-18-2013, 05:21 PM
Thus, shields create much more work then just creating your own breadboard or circuit board, even adjusting for the learning curve of learning how to make your first circuit board.


well, i actually did make my own pcb, as i have no use for the standard audio shields you get. the SD card was more of an afterthought, as there was some space left on the board, just assuming that using the alt spi pins was ok. well, i figure i'll have to invest some time, when there's time

mxxx
07-04-2013, 06:52 AM
ps. sorry my bad. getting sdFAT to run on pins 7,8 and 14 was as simple as replacing those few lines in Sd2Card.cpp, ie

CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
CORE_PIN8_CONFIG = PORT_PCR_MUX(2);
CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);

where it has:

CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);