Direct port manipulation on Teensy 3.6

Status
Not open for further replies.

calphool

Active member
I've sort of bumbled onto the fact that unless I use pinMode() at least once, my direct port manipulation code doesn't work.

So for example, I've got code like

Code:
GPIOC_PDDR = GPIOC_PDDR & 0xff00;
that in theory ought to turn the bottom 8 pins of port C to INPUT mode, but unless I've run pinMode() invocations (either INPUT or OUTPUT), it doesn't seem to do anything.

I'm guessing there's something under the covers that pinMode() does that I'm unfamiliar with. While I tried to dig into pinMode()'s code to figure out what's going on, it's a rather complex block of code, and I'm not quite following what it's doing.

Is there a *canonical* description (or better yet, code example) of how to do direct port manipulation (both input and output) on Teensy 3.6 somewhere? I read the MK66FX1M0 chip documentation, but it's a bit overwhelming as well, or at least it's not obvious to me how I turn the descriptions there into working C code.


Also, if I've got a function I want to call say 40 times a second (25 mS intervals), and I've also got a bunch of input pin driven interrupts, what's the best way to set up the code so they don't interfere with each other? That is to say, I need both the clock driven interrupts and the pin driven interrupts to wait until their code block is complete before "interrupting" each other. I was using the Metro library in my loop() function, but that seems unlikely to work, since that loop gets interrupted by the pin interrupts.
 
I've sort of bumbled onto the fact that unless I use pinMode() at least once, my direct port manipulation code doesn't work.
While I tried to dig into pinMode()'s code to figure out what's going on, it's a rather complex block of code, and I'm not quite following what it's doing.
So, let pinMode() do the setup for you and then use your direct port input / output.
 
pinMode() is needed to configure the pins (which are hi-z and/or analog by default) as GPIO pins by changing the pinMUX configuration for each pin from ALT0 to ALT1.

This might be confusing, since on the old AVR processors, pins were GPIO by default. But this isn’t the case for the Kinetis K processors.
 
Yes pinmode is only needed once.

Also, if I've got a function I want to call say 40 times a second (25 mS intervals), and I've also got a bunch of input pin driven interrupts, what's the best way to set up the code so they don't interfere with each other? That is to say, I need both the clock driven interrupts and the pin driven interrupts to wait until their code block is complete before "interrupting" each other.

Two thoughts:
- 25ms is not much for Teensy T3.6. If that's your interval, stay with digitalRadFast/WriteFast. They need one cpu-cycle if called with a constant pin-number. 8 Pins - 8 cycles. Keep it simple, at least for a first try.
- If the interrupts have the same priority (by default yes) they will not interfere with each other. They will be called one after the other, if both get triggered.
 
Yes pinmode is only needed once.



Two thoughts:
- 25ms is not much for Teensy T3.6. If that's your interval, stay with digitalRadFast/WriteFast. They need one cpu-cycle if called with a constant pin-number. 8 Pins - 8 cycles. Keep it simple, at least for a first try.
- If the interrupts have the same priority (by default yes) they will not interfere with each other. They will be called one after the other, if both get triggered.

So you're saying don't use Metro in the loop() for the clock driven code. Use something else. IntervalTimer I'm guessing?
 
That's what I needed. Thanks. Docs sort of encourage you to use Metro, but it really depends on what you're doing. Metro sort of gets in the way if you're trying to combine interrupts and timing stuff.
 
pinMode() is needed to configure the pins (which are hi-z and/or analog by default) as GPIO pins by changing the pinMUX configuration for each pin from ALT0 to ALT1.

This might be confusing, since on the old AVR processors, pins were GPIO by default. But this isn’t the case for the Kinetis K processors.

Yeah, I found that kind of stuff in the processor documentation, but what exactly one needs to code to "change the pinMux configuration" isn't obvious to me.
 
Status
Not open for further replies.
Back
Top