Can someone help me understand direct port access?

Status
Not open for further replies.

Geomancer

Active member
Edit: This is in regards to Teensy 3.6, should of stated that first off. /Edit

I've seen the following example that allows you to output to 8 I/O pins at the same time. This is really going to help me in reading an 8x8 switch matrix.

I don't fully understand the syntax I've seen in examples though:

Code:
volatile uint8_t* ptb_16_23 = (volatile uint8_t*) (uintptr_t(&GPIOB_PTOR) + 2);
*ptb_16_23 = 0xffu;

The way I understand it, this is creating a pointer for an 8 bit value named ptb_16_23. It then assigns this to the Port B output register + 2 (since Port B is really 32 bits and it's bits 16 through 23 that are physically accessible contiguously).

I may have the details of that completely wrong since I don't 100% understand pointers syntax ... but here are my questions.

1) Why is it volatile? I would think the memory address of the Port B register is static. Is it because the value at that address could be changed elsewhere? That wouldn't make sense to me though as I don't think you'd care, since your goal is to change the output values anyways and not using the value already there.
2) Why is it GPIOB_PTOR that gets written to instead of GPIOB_PDOR? As written, this looks like it would toggle bits 16 through 23 rather than setting them all to a logic '1'

My other question would be, how can this be adapted to read the contents of bits 0 through 7 of Port D as an input. Is it as simple as:

Code:
uint8_t SwitchInput = (uint8_t) GPIOD_PDIR;

GPIOD_PDIR is 32 bits, but does casting it as 8 just truncate to the first 8 bits?

Thanks for any insight you can give me to help me understand how this works!
 
Last edited:
Yeah, it just seems weird to me as I'm not sure when I'd ever read the output register. I suppose if I wanted to know it's status, but in my particular case I'm only ever writing to that address, never reading from it. Especially with dedicated registers for setting specific bits, clearing specific bits, or toggling specific bits in addition to just plain old writing a specific output value.

Right now I have:

Code:
uint8_t* prb = (uint8_t*)&GPIOB_PDOR + 2;
*prb = any_8bit_value;

It appears to be working just fine, although I'm not sure if something I don't understand is going to bite me in the butt in the future.


Also, my initial testing seems to say that reading the first 8 bits of Port D really is as easy as I initially thought.

Really makes me long for the flexibility of FPGAs where you can assign functions to whatever pin you want, so getting 8/16/32 consecutive pins on a port being available for GPIO is easy without other functions like serial buses getting in the way!
 
Status
Not open for further replies.
Back
Top