Strange GPIO Port Behaviour (Teensy 3.6)
Hi all.
I am working on some code that reads a 16 bit address using 16 of the GPIO pins. I want these reads to be fast and as close to atomic as possible, therefore I am using the GPIO ports directly. However, when I read the address bits from the ports I get different results than if I use digitalReadFast for each pin and shift the bits.
Using this great post as a guide https://forum.pjrc.com/threads/1753...PORT-DDR-D-B-registers-vs-ARM-GPIO_PDIR-_PDOR along with the code documentation in core_pins.h I have chosen GPIO port C for the first 12 bits of the address and port B for the highest 4 bits. This is nice because the bits for the ranges I mention are contiguous, and makes read/write code fairly simple.
Here is how I am testing this (currently only testing first 12 bits from port C):
With the above code, I get the following output:
100001101
1101
x
100011110
11110
x
I am really not sure how this can be. A8 is clearly high active when using the traditional method, but it is low when reading the C port register directly. I would expect the cPortInput to match addr exactly in this test condition.
Would love to hear thoughts and suggestions.
Thanks.
Hi all.
I am working on some code that reads a 16 bit address using 16 of the GPIO pins. I want these reads to be fast and as close to atomic as possible, therefore I am using the GPIO ports directly. However, when I read the address bits from the ports I get different results than if I use digitalReadFast for each pin and shift the bits.
Using this great post as a guide https://forum.pjrc.com/threads/1753...PORT-DDR-D-B-registers-vs-ARM-GPIO_PDIR-_PDOR along with the code documentation in core_pins.h I have chosen GPIO port C for the first 12 bits of the address and port B for the highest 4 bits. This is nice because the bits for the ranges I mention are contiguous, and makes read/write code fairly simple.
Here is how I am testing this (currently only testing first 12 bits from port C):
Code:
// A0 - A11 maps to GPIO port C (bits 0 - 11) . A12 - A15 maps to GPIO port B (bits 0 - 3)
#define A0 15
#define A1 22
#define A2 23
#define A3 9
#define A4 10
#define A5 13
#define A6 11
#define A7 12
#define A8 28
#define A9 27
#define A10 29
#define A11 30
#define A12 16
#define A13 17
#define A14 19
#define A15 18
static inline void setAddressMode(uint8_t mode)
{
pinMode(A0, mode);
pinMode(A1, mode);
// ... do this for all the pins
}
// traditional address access
static inline uint16_t getAddr()
{
uint16_t addr = 0;
addr |= (digitalReadFast(A0));
addr |= (digitalReadFast(A1) << 1);
addr |= (digitalReadFast(A2) << 2);
addr |= (digitalReadFast(A3) << 3);
addr |= (digitalReadFast(A4) << 4);
addr |= (digitalReadFast(A5) << 5);
addr |= (digitalReadFast(A6) << 6);
addr |= (digitalReadFast(A7) << 7);
addr |= (digitalReadFast(A8) << 8);
addr |= (digitalReadFast(A9) << 9);
addr |= (digitalReadFast(A10) << 10);
addr |= (digitalReadFast(A11) << 11);
//addr |= (digitalReadFast(A12) << 12);
//addr |= (digitalReadFast(A13) << 13);
//addr |= (digitalReadFast(A14) << 14);
//addr |= (digitalReadFast(A15) << 15);
return addr;
}
void setup()
{
setAddressMode(INPUT); // set A0 - A15 to INPUT
Serial.begin(250000);
}
void loop()
{
Serial.begin(250000);
while (1)
{
// currently just testing the lower 12 bits from the c register
uint32_t cPortInput = GPIOC_PDIR;
uint16_t addr = getAddr();
Serial.println(addr, BIN);
Serial.println(cPortInput , BIN);
Serial.println("x");
}
Serial.end();
}
100001101
1101
x
100011110
11110
x
I am really not sure how this can be. A8 is clearly high active when using the traditional method, but it is low when reading the C port register directly. I would expect the cPortInput to match addr exactly in this test condition.
Would love to hear thoughts and suggestions.
Thanks.
Last edited by a moderator: