The architecture's completely different in the SAM3X series.
There are 5 ports, A/B/C/D/E, each 32 bit, mapped to the pins as documented in variant.cpp.
There are several registers for each port that read and write it, and each pin can
be updated atomically so no special interrupt handling is needed:
PIO_PER - write 1's here to override other peripherals and allow GPIO use for pins
PIO_OER - write 1's here to set pins as OUTPUT
PIO_ODR - write 1's here to set pins as INPUT
PIO_SODR - write 1's here to set output pins HIGH
PIO_CODR - write 1's here to set output pins LOW
PIO_PDSR - read's actual state of the pins on the port.
PIO_PUDR - write 1's here to switch off internal pull-up for pins
PIO_PUER - write 1's here to switch on internal pull-up for pins
There are other registers to do with input filtering, interrupts, etc etc,
but I think these are the main ones. If you call pinMode() to setup the
pin you only need the one's marked '*' to do I/O
In fact to ensure the port(s) is enabled its simplest to call pinMode() for each
pin you want to directly manipulate, otherwise you have to configure the PIO
controller in more detail which isn't needed once pinMode() has done its thing.
many thanks for the reply I will have a go at a simple example of this and see what results I get, I am assuming that I will need to send a 32bit mask to the ports ?
eg
pinMode (32, OUTPUT) ;
D -> PIO_SODR = B11111111111111111111111111111111 ; // set pin
delay (1) ;
D -> PIO_CODR = B1111111111111111111111111111111 ; // clear pin
As I understand it you can't simultaneously set some pins high and some low, you have
to set some high and then others low, or vice versa, using two instructions.
many thanks for the reply I will have a go at a simple example of this and see what results I get, I am assuming that I will need to send a 32bit mask to the ports ?
eg
pinMode (32, OUTPUT) ;
D -> PIO_SODR = B11111111111111111111111111111111 ; // set pin
delay (1) ;
D -> PIO_CODR = B1111111111111111111111111111111 ; // clear pin
That sets 32 pins simultaneously (if they are outputs). You need to find
the relevant bit(s) for the pin(s) you're interested in as my example shows.
The syntax is 0b1111111111111111111111111111111 BTW.
Hii!!
Sorry for asking an out of context question but i was browsing through this topic to find something and i got a lot of help reading these conversations, let me ask a question-
There are 5 ports A,B,C,D,E in Due but what are the pin numbers in those ports?
sorry again for asking such a dumb question but i am kinda starter in this field.
In that document you will find DUE pin numbers, the SAM3X pin name and the Mapped Pin Name...
The first column shows the pin number as you are used to... such as the famous LED pin 13. Across in the table you will find the pin name PB27, which implies you can find that pin on PORTB, pin 27.
Therefore you can access that pin at REG_PIOx_SODR, where x would be for PORTB, as in REG_PIOB_SODR and REG_PIOB_CODR, for setting and clearing that particular register...
To set or clear the particular bit, try this...
// This will create a mask with a one in a 32 bit number to set this bit 27 of PORTB
REG_PIOB_SODR |= (0x01 << 27); // Turn on the LED
REG_PIOB_CODR |= (0x01 << 27); // Turn off the LED using the CODR register
"As I understand it you can't simultaneously set some pins high and some low, you have
to set some high and then others low, or vice versa, using two instructions."
Yes, you can. The magic trick is to write directly on the register status rather than on
the SET and CLEAR registers. Here is how:
PIOC->PIO_PER = 0x01FF; // Configure PORTC to PIO controller, pins 33-40
PIOC->PIO_OER = 0x01FF; // Enable PORTC to output
....
PIOC->PIO_ODSR = something; // Write something on pins 33-40.
The Output Data Status Register (ODSR) is available for reading and writing (under
weird circunstances). However, this does not happen for all the registers; that's why
there are so many SET and CLEAR status registers. Of course you can add also bit
masks in order to avoid writing on protected pins.
Ah, yes you can do that, but its not interrupt-safe so you have to be careful
if driving several pins from the same port (especially via libraries).
Or is there an atomic read-modify-write for this? Been a while since I played
with the Due, my impression was the set and clear registers are there specifically
to allow single-instruction update without having to worry about interrupts using the
same port. Effectively the read-modify-write is done implicitly at the lowest level
in hardware.
How can i define OUTPUT and INPUT ? For example DDRB |=B00000100 is for sets D10 output in nano. How can i write it for due? I think i use PIO_OER but i couldnt write it completely.