Cant't read pin status with ports...

Hello!!

I try to read the pin value with direct port manipulation.
My code can change the value of the pin 2, but I can’t read this value.
p2 is always 0.
This is my code:
The syntax is not correct?
Please, help…
Thanks

boolean p2;
void setup() {
   Serial.begin(9600);
  
  REG_PIOB_OER  |= (0x01 << 25); //pinMode (2,OUTPUT) : it works!

}

void loop() {


REG_PIOB_SODR |= (0x01 << 25); // Turn on the LED Pin 2= PB25  : it works!
p2=!!(PIOB->PIO_PDSR & (1<<25)); //read pin 2
Serial.println(p2);
delay(1000);
REG_PIOB_CODR |= (0x01 << 25); // Turn off the LED Pin 2= PB25  : it works!
p2=!!(PIOB->PIO_PDSR & (1<<25)); //read pin 2
Serial.println(p2);
delay(1000);
}

I answer my self!

The syntaxe is PIO_ODSR and not PIO_PDSR, correct?
It seems to work now…

But I have another question:
is that possible to read the pin status (INPUT or OUTPUT) with registers?

Thanks!

It’s in the datasheet:

The results of these write operations are detected in PIO_OSR (Output Status Register). When
a bit in this register is at 0, the corresponding I/O line is used as an input only. When the bit is at
1, the corresponding I/O line is driven by the PIO controller.

Yes, MorganS: everything is in the datasheet or on internet!
I spend many hours to find something ...
But for someone, like me, which is not familiar with english and arduino,
people like you will always be indispensable ...

And now it looks to works!!!

Great thanks, MorganS!!!

I thought about this today. The better answer is: “don’t do this.” You will tie your program tightly to the Due and it won’t work on any other Arduino. This is called a “fragile program” because it is very easily broken by tiny changes.

Unless you are willing to commit to supporting a product that might be discontinued or changed, then don’t use direct port manipulation.

As I understand it PDSR is the correct register to read for pin state - ODSR is just what you
last wrote out (and doesn't sense the actual pin's voltage at all).

See my reply on this thread:

Hi.
I understand, Morgans, that it’s a fragile program. I will take care about that.

MarkT, I have already saw your post , but I’m not sure to understand:
If ODSR is what I wrote, in witch case the actual pin voltage may be different?
And if PDSR is the correct register, why p2 in my code is always=0?
I’m a little confuse …
Where is my mistake?

int p2;
void setup() {
  Serial.begin(9600);

  REG_PIOB_OER  |= (0x01 << 25);//- write 1's here to set pins as OUTPUT     //pinMode (2,OUTPUT);

}

void loop() {

  PIOB->PIO_SODR = 1 << (25); //lights the LED on pin2: it works
  p2 = !!(PIOB->PIO_PDSR & (1 << 25)); //read pin 2
  Serial.print(p2);
  delay(1000);

  PIOB->PIO_CODR = 1 << (25); //clears the LED on pin2: it works
  p2 = !!(PIOB->PIO_PDSR & (1 << 25)); //read pin 2
  Serial.println(p2);
  delay(1000);

PDSR reads the pin, ODSR reads the flip-flop that controls the output driver (which
may or may not be enabled so may or may not represent the pin’s state). If the pin
is externally shorted then ODSR knows nothing about this.

You probably haven’t made the pin an output. Use pinMode () in setup, I’ve no
idea what REG_PIOB_OER is, a #define? The wrong #define? Its definitely wrong
to OR in to these control registers, they are write-only.

I use now pinMode(2,OUTPUT) instead of OER, but p2 is still =0 (see code above)

int p2;
void setup() {
Serial.begin(9600);
pinMode(2,OUTPUT);

}

void loop() {

digitalWrite(2,HIGH);
p2 = !!(PIOB->PIO_PDSR & (1 << 25)); //read pin 2
Serial.print(p2);
delay(1000);

digitalWrite(2,LOW);
p2 = !!(PIOB->PIO_PDSR & (1 << 25)); //read pin 2
Serial.println(p2);
delay(1000);
}

Looking at the diagram 32-3 “I/O line control logic” on the version of the datasheet
I have it shows a chunk of logic controlling the input to the hardware glitch-filter which
might be the culprit - you may have to jump through hoops to get the input glitch
filter to be clocked when the pin is configured as an output - if its not clocked then
PDSR will indeed be locked. I suppose then the best you can do is look at POSR
if the pin is current an output and PDSR if its an input…

Reading further it seems you need to enable the clocking to the PIO unit, possibly
something that pinMode(INPUT) does but pinMode (OUTPUT) does not - try:

  pinMode (13, INPUT) ;
  pinMode (2, OUTPUT) ;

As pin 13 is also on PIOB