Understanding Due direct port addressing

Hi,
I have some questions from tests with direct port addressing with a Due.

From the manual and posts here in this forum I learned that the register ODSR, output data status register, can be written and read. Therefore with e.g. REG_PIOD_ODSR = x port D can be written to and with x = REG_PIOD_ODSR the bits on port D can be read.

Further there is a read-only register PDSR.
Info from forum says: PIO_PDSR - read's actual state of the pins on the port

I my tests I get unexpected results and there is a difference between reading with
x = REG_PIOD_ODSR
and reading with
x = REG_PIOD_PDSR

void setup() {
...
// configure port D
// Out|Port PD10: Flag Clear
  REG_PIOD_PER = 0x00000400;   // assign bit to peripheral IO controller PIOD 
  REG_PIOD_OER = 0x00000400;   // set bit for ouput

  // In|Port PD0-PD3, PD6: Stellung Drehschalter
  REG_PIOD_PER = 0x000004F;   // assign bits to peripheral IO controller PIOD
  REG_PIOD_ODR = 0x000004F;   // set bits for input
  REG_PIOD_PUER = 0x000004F;   // activate pull ups

// check port D
Serial.print("  PortD: 0x");
  Serial.println(REG_PIOD_ODSR, HEX);

// some outputs on port D to bits defined as input!
REG_PIOD_ODSR = REG_PIOD_ODSR | 0x00000046;
Serial.print("PortD: 0x");
  Serial.println(REG_PIOD_ODSR, HEX);

// more outputs
REG_PIOD_ODSR = (REG_PIOD_ODSR & 0xFFFFFBF8) | 0x00000407;
  Serial.print("PortD: 0x");
  Serial.println(REG_PIOD_ODSR, HEX);
  Serial.print("PortPinsD: 0x");
  Serial.println(REG_PIOD_PDSR, HEX);
}

The results on Serial Monitor:

PortD: 0x80             from check port D
PortD: 0xC6             after first output,  0x80 | 0x46 = 0xC6
PortD: 0x4C7           after second output 
PortPinsD: 0x0        what's that?

Because bits PD0 .. PD3, PD6 are configured as inputs with pull up I expected to read all 1's on these bits, i.e. after first output: 0xCF and not 0xC6.

The difference between reading with ODSR and PDSR is a mystery.

I'd be happy to get explanations to understand direct port addressing.

Usually reading the output port (ODSR) will give you the last values written to that port, and NOT the current pin values if the pins are in INPUT mode. Whereas reading the Status register will give you the pin values regardless of the ODSR values.

(I didn't look at the details of your code to see if that's consistent with what you're seeing.)

First, I was just reading chapter 6, Input/Output lines, of the Cortex M3 Manual. But to really understand the complex input/output logic of a Due chapter 31, Parallel Input/Output Controller, is important. There the purpose of ODSR and PDSR is described clearly and what further settings are necessary, i.e. activating clock for input. According to this chapter I will adapt my test program.

Note that some things will be done by the Arduino core, prior to setup().
Not all of them "right." IIRC, the core did not set anything in PIO_OWSR, which meant that port-wide writes via PIO_ODSR did not work as expected, even though set/clear operations via PIO_SODR/PIO_CODR were fine.

I thought that was fixed at some point, but ... I can't find it in the code.

The Cortex-M3-SAM3X-Manual says:

Reading the I/O line levels requires the clock of the PIO controller to be enabled, otherwise PIO_PDSR reads the levels present on the I/O line at the time the clock was disabled.

I cannot find where to enable the clock of the PIO controller.
Looking at the input part of figure 31-3 there are clock inputs only for the Glitch or Debouncing Filter:
grafik
But I don't use this filter.

After setting some pins to input with pinMode() I can see correct input levels in PIO_PDSR Register. But I have a lot of inputs to read, and want to avoid so many pinMode() calls.

Then I tried to read PIO_IFSCR Register (lower left corner of figure) to see if pinMode() is defining something there. The compiler says that 'struct Pio' has no member named 'PIO_IFSCR'.
There is an error in figure 31-3. The name should be PIO_IFDGSR, not PIO_IFSCR.
Reading PIO_IFDGSR works and shows that even before calling pinMode() the multiplexer is set to System Clock.

Maybe figure 31-3 is not detailled enough but also the list of all PIO registers in table 31-3 does'nt contain a register to generally enable PIO clock.

Where is the right place to enable PIO clock?

In the peripheral clock controller, which is part of the power management controller (PMC)
See section 28 of the datasheet.

(The PIO clock will already have been turned on by the arduino core. I usually use pinMode(), in a loop if appropriate, because you can do that in setup() where speed is irrelevant.)