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);
}
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 ...
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).
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.
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: