Direct Port Addressing vs digitalRead-Write() on Arduino DUE

Playing around with bit banging and discovered something and would like to know the reason.
On a DUE, I set up a single input (pin8) and a single output (pin4) with a very short program. The purpose of the program is to read input pin8 using bit banging, and set output pin4 as a result. As part of the program, I print out the results of both digitalRead status for pin4 and pin8, along with bit banging status also. I noticed that the digitalRead(pin4) does not follow the register status of pin4. Why is this?
I have no need to mix bit banging and conventional digitalRead-Write but was just checking my bit banging work with something I knew like digitalRead. I was surprised it did not follow the status register.


boolean pin4; //output
boolean pin8; //input

void setup() {
  Serial.begin(115200);
  pinMode(4, OUTPUT);
  pinMode(8, INPUT_PULLUP);
}

void loop() {
  pin8 = !(PIOC->PIO_PDSR & (1 << 22)); //READ DUE INPUT REGISTER C22 (digital pin8)
  if (pin8) {
    REG_PIOC_SODR |= (0X01 << 26); //SET DUE OUTPUT REGISTER C26 (digital pin4)
  }
  else {
    REG_PIOC_CODR |= (0X01 << 26);
  }
  //INPUT
  Serial.print("digital pin8 = ");
  Serial.print(digitalRead(8));
  Serial.print(" digital pin4 = ");
  Serial.print(digitalRead(4));  
  //OUTPUT
  Serial.print(" || BitBang pin8 = ");
  Serial.print(PIOC->PIO_PDSR & 0b00000100000000000000000000000000);
  Serial.print(" BitBang pin4 = ");
  Serial.println(PIOC->PIO_PDSR & 0b00000000010000000000000000000000);  
  //Serial.println(PIOC->PIO_PDSR, BIN);
  
}

These are the Serial Monitor results I get when I change the status of input pin8:

digital pin8 = 1 digital pin4 = 0 || BitBang pin8 = 0 BitBang pin4 = 4194304
digital pin8 = 1 digital pin4 = 0 || BitBang pin8 = 0 BitBang pin4 = 4194304
digital pin8 = 1 digital pin4 = 0 || BitBang pin8 = 0 BitBang pin4 = 4194304
digital pin8 = 1 digital pin4 = 0 || BitBang pin8 = 0 BitBang pin4 = 4194304
digital pin8 = 0 digital pin4 = 0 || BitBang pin8 = 0 BitBang pin4 = 0
digital pin8 = 0 digital pin4 = 0 || BitBang pin8 = 67108864 BitBang pin4 = 0
digital pin8 = 0 digital pin4 = 0 || BitBang pin8 = 67108864 BitBang pin4 = 0
digital pin8 = 0 digital pin4 = 0 || BitBang pin8 = 67108864 BitBang pin4 = 0

What you are doing is not bit banging.

Bit banging is where you recreate a protocol like I2C or SPI by just using digital write / read commands.

What you are doing is known as direct port addressing.

Click on the large pencil on the title and change it to be what you are actually doing.

1 Like

Register has 32bits length, but return value of digitalRead() is limited to 0 or 1 only. How they can followed each other?
By the way - you printed the bit register as a long decimal number that is perfectly senseless

Changed. Thanks

So sorry for the mistakes! I have simplified the logic to this:
I blink the LED pin by "Direct Port Manipulation" and then try to "digitalRead" the same pin. I print out both the ON and OFF results to the serial monitor, but digitalRead never changes from zero. The LED DOES blink, and the actual pin (13) DOES toggle respectively
(I verified the output goes from 0.0064V to 3.3052 by connecting a multimeter to pin 13 and GND.

This is the results displayed on the serial monitor:
LED ON = 0
LED OFF = 0
LED ON = 0
LED OFF = 0
LED ON = 0
LED OFF = 0
LED ON = 0
LED OFF = 0

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT); //LED Pin 13
}

void loop() {
  REG_PIOB_SODR |= (0X01 << 27); //SET DUE OUTPUT REGISTER B27 (LED Pin 13)
  Serial.print("LED ON  = ");
  Serial.println(digitalRead(LED_BUILTIN));
  delay(1000);
  REG_PIOB_CODR |= (0X01 << 27); //RESET DUE OUTPUT REGISTER B27 (LED Pin 13)
  Serial.print("LED OFF = ");
  Serial.println(digitalRead(LED_BUILTIN));
  delay(1000);


}

Is the led LED_BUILTIN turns on and off when you control it with register writing?

I think you accessing register incorrectly
try this:

REG_PIOB_SODR = (0X01 << 27);

instead of this

I see terms used that to me

digitalRead() is an Arduino beginner-safed, filtered read function.

Using PINx and some bit logic in a branch condition is another thing.

When I'm not sure which is referred to by another I stop reading.

Yes, the LED IS turning on and off and so is the physical output (PIN 13). All of that works, but if I use digitalRead(13) to look at the output (PIN 13), it does NOT show the bit changing at all.
If digitalRead(13) is looking at the actual output, it should toggle OFF and ON along with the LED. But digitalRead(13) ALWAYS returns zero even when the LED is ON. Based on this, I'm thinking digitalRead only works if the bit was set with digitalWrite.
I have no need to mix using Direct Port Manipulation with digitalRead/Write(). I was just using a known method (digitalRead) to verify that an unknown method (Dir Port Man) was working. When the "known" method did not show the correct status, I was very curious why.

Can you say why an assignment here is going to work when using bitwise or would not or did not?

a7

Apparently, if the pin is in output mode, the digitalRead() function returns a saved value from digitialWrite() instead of reading any of the actual registers. Since you're not writing using digitalWrite, the value isnt set.

I dont know why it isn't reading actual registers. Due us built on top of a long-obsolete Atmel-provided "libsam" library; perhaps it doesn't have a function for reading the ODR.

Have you read this post?

THANKS! This is exactly what I suspected, but I am way too green to attempt understanding functions like digitalRead/Write. I am 64 years old and just recently started working with Arduino. I must say I fell in love over night. I haven't left my first love yet (PLC's and process control), and I'm hoping they can both get along so I don't have to give up one or the other! LOL

THANKS! Yes, I had read that post and actually used it to figure out how to do Direct Port Manipulation (DPM). I was testing my DPM code using digitalRead, when I found out digitalRead wouldn't work.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.