SAM3X8E (Arduino DUE) manipolazione registri PIO

Non c'è assolutamente nulla di concreto in rete su questo argomento a parte le descrizioni sul datasheet molto difficili da capire.

Ho fatto un pò di letture e scritture sui vari PIO A/B/C/D, che tra l'altro 3 errori di descrizione sulla libreria variant.h mi hanno fatto sbagliare e diventare pazzo un giorno prendendo i dati da quella tabella

il pin 4 non si trova sul bit 29 del PIOA, ma sul bit 26 del PIOC il pin 10 non si trova sul bit 28 del PIOA, ma sul bit 29 del PIOC irrilevante comunque all'utilizzo perchè le istruzioni assembler danno risultati corretti.

Prima di postare sketch di test che ho fatto sui registri, dilungarmi su quesiti chiedo a qualcuno interessa approfondire l'argomento, capire meglio il datasheet e fare una documentazione un po' più alla mano di tutti?

ciao p

pablos … “cui prodest” ?

Se mi ci devo dedicare, mi dedico a qualche cosa di più attuale:roll_eyes:

Guglielmo

perchè il SAM3X8E è antico? obsoleto? Senza strafare e usare opzioni del micro complesse è una MEGA 15 volte più veloce, il discorso 3.3v basta un chippino da mettere in mezzo e porti tutto a 5v o viceversa.

Non sono uno che collega una lampada 220v sui pin e poi dice che non si accende, ma non sono nemmeno uno che vuole andare all'università per usare una scheda di prototipazione :)

Anche una raspberry ha i pio pio, però va interfacciato tutto con altre schede, se vedi i progetti vari ci piazzano alla fine un arduino in cascata, l'audio e il video non mi interessano come a un 50% degli utenti, la yun ha 400 Mhz per fare un discreto web server, ma poi la restante parte è un UNO 16Mhz, cosa altro c'è di attuale che ti possa dare accesso diretto a una discreta quantità di pin senza complicarsi troppo la vita?

Me la fai una Mega a 400Mhz con i pin a 5v? dai impegnati :) :)

ciao

pablos:
Senza strafare e usare opzioni del micro complesse è una MEGA 15 volte più veloce, il discorso 3.3v basta un chippino da mettere in mezzo e porti tutto a 5v o viceversa.

Segnalo questa piccola board da tindie come bidirezionale:

Io l’ho provato con un TFT 2.2" e dando i 5V alla board e regolando il trimmer in uscita ho i 3V (fino a 300mA) per il TFT direttamente dal modulo.
Il modulo può anche funzionare in 2 modalità sul VCC/GND (vedere schema a riguardo del LDO) io l’ho provato in LDO=ENabled.

grazie nid

anche questa http://www.breakdown-technology.com/blog/elettronica/elettronica-digitale/conversione-di-livello-3v-5v/

l'hai comprata su quel sito?

pablos: l'hai comprata su quel sito?

si, Tindie, Indie dei Maker

bhe se queste caratteristiche sono vere è una scheda antiscemo :D

-Auto-direction Sensing. -Current Limit Protection. -Short Circuit Protection. -Thermal Shutdown Protection.

carina!

pablos: bhe se queste caratteristiche sono vere è una scheda antiscemo :D

Infatti l'ho comprata io. :grin: :grin: Quel maker ha altre cose interessanti, tipo il UsbTiny85 (una specie di Digispark) . Mi sembrano di buona fattura.

pablos: perchè il SAM3X8E è antico? obsoleto? Senza strafare e usare opzioni del micro complesse è una MEGA 15 volte più veloce, il discorso 3.3v basta un chippino da mettere in mezzo e porti tutto a 5v o viceversa.

NO, dei 3.3v non me ne può fregare di meno, né della corrente che è in grado di erogare ... fossero quelli i problemi ... ]:D

E SI, la DUE è ormai vecchia e obsoleta e ... se devo investire del tempo, preferisco investirlo sulla nuova Zero, sul chip EDGB e su quello che comporta. Tutto qui.

Guglielmo

E SI, la DUE è ormai vecchia e obsoleta preferisco investirlo sulla nuova Zero

non ti rispondo perchè ti rispetto e poi litighiamo :D :D

pablos: non ti rispondo perchè ti rispetto e poi litighiamo :D :D

Perché dobbiamo litigare ???

Tu hai chiesto se qualcuno era interessato, dato che ti stimo e mi piace seguire i progetti che fai, ti ho solo spiegato perché, per questa volta, non ti seguo ... senza nessun interno polemico o di disaccordo ;)

Dato che il tempo non è purtroppo illimitato, [u]personalmente[/u] ritengo più utile vedere un cosa che uscirà a breve (... speriamo) che una cosa che è ha già qualche anno ... XD

Guglielmo

Ci sto diventando pazzo!!!

Il digitalread mi da sempre 0

 pinMode(13, OUTPUT);
digitalWrite(13, 1);
Serial.print(digitalRead(13)); //>>>>>> legge 0
delay(2000);
digitalWrite(13, 0);
Serial.print(digitalRead(13)); //>>>>>> legge 0

sempre 0, se leggo i registri invece vedo la variazione e il led fa quello che deve fare .....ma perchè??

Prova: pinMode(13, INPUT);

Fai cambiare stato al pin da esterno e vediamo se digitalRead lavora correttamente.

Ciao.

Prova:
pinMode(13, INPUT);

Qui c’è un altra bella sorpresa che ho visto ieri, quando setto un pin in INPUT tutto il PIO che contiene quel pin va a 1, poichè in automatico sono in PULLUP, probabilmente posso ovviare a questo agendo su

 PIO_PUDR;      /**< \brief (Pio Offset: 0x0060) Pull-up Disable Register */
  PIO_PUER;      /**< \brief (Pio Offset: 0x0064) Pull-up Enable Register */
  PIO_PUSR;      /**< \brief (Pio Offset: 0x0068) Pad Pull-up Status Register */

in questo caso il digitalread mi indica 1 e se porto il pin su GND mi indica correttamente 0, ma solo il pin interessato, tutti gli altri restano a 1

praticamente non riesco a leggere con digitalread lo stato del pin se è configurato in OUTPUT, se è in INPUT si.

ciao

Qui c'è un altra bella sorpresa che ho visto ieri, quando setto un pin in INPUT tutto il PIO che contiene quel pin va a 1, poichè in automatico sono in PULLUP

Allora c'è un bug. Però è strano quello che dici, tutto il PIO intendi tutto Port IO, poi però dici che solo quel pin funziona in input con pull-up e questo è corretto.

Aspetta sto confuso, vediamo se l'impostazione di un pin mode coinvolge tutta la porta allora c'è un bug, ma solo per logica perché sarei costretto ad usare tutta la porta come imput.

in questo caso il digitalread mi indica 1 e se porto il pin su GND mi indica correttamente 0, ma solo il pin interessato, tutti gli altri restano a 1

E se metti a GND un altro pin di quella porta cosa legge digitalRead().

PS: Arduino 2 o zero sempre ARM è quindi obsoleto e quanto meno opinabile.

Le porte dell'ARM non sono così semplici come quelle di AVR atmega, già con Xmega diventano complicate, anche se l'architettura di xmega semplifica e agevola molto. Occorre leggere il datasheet del sam e impostare i pin manualmente.

Buon divertimento ]:D

Ciao.

No ma io mi diverto, non vorrei superare le 10k scritture sulla flash ahahahahhaa

prendiamo questo esempio elementare scritto in modi diversi di fretta per vedere se è l’interprete che ha problemi o sono io :slight_smile:

void setup() {
   delay(2000);
   Serial.begin(9600);
   pinMode(13, OUTPUT);
}

void loop(){
 
  digitalWrite(13, 1);
  Serial.println("Led ON");
  leggi_reg();
  delay(1000);
  digitalWrite(13, 0);
  Serial.println("Led OFF");
  leggi_reg();  
 }
 
  void leggi_reg(){  
  byte state = digitalRead(13);
  if (state == HIGH) Serial.println("digitalRead con variab state PIN 13 = HIGH ");
  if (state == LOW) Serial.println("digitalRead con variab state PIN 13 = LOW "); 
  if (state == 1) Serial.println("digitalRead con variab state PIN 13 = HIGH ");
  if (state == 0) Serial.println("digitalRead con variab state PIN 13 = LOW "); 
  if (digitalRead(13) == true) Serial.println("digitalRead con variab state PIN 13 = HIGH ");
  if (digitalRead(13) == false) Serial.println("digitalRead con variab state PIN 13 = LOW "); 
  Serial.println();   
  Serial.print("digitalRead Serial.print(digitalRead(13)) PIN 13 = "); Serial.print(digitalRead(13)); 
   Serial.println();  
  Serial.print("Lettura registro PIOB_ODSR Output Data Status Register -BIN = "); Serial.print(PIOB->PIO_ODSR,BIN); Serial.print(" -HEX = "); Serial.print(PIOB->PIO_ODSR,HEX);  
   Serial.println();  
   Serial.print("lettura dei singoli bit BitRead PIOB->PIO_ODSR = ");
  for (byte i=0; i <= 32; i++){     
   Serial.print(bitRead(PIOB->PIO_ODSR,i));    
  }   
  Serial.println(); 
  
  Serial.println("----------------------------------------------------------------------------------------");  
}

ecco l’uscita

Led ON
digitalRead con variab if state L - PIN 13 = LOW
digitalRead con variab state 0 - PIN 13 = LOW
digitalRead con variab state FALSE - PIN 13 = LOW
digitalRead lettura con Serial.print(digitalRead(13)) PIN 13 = 0

Lettura del registro PIOB_ODSR Output Data Status Register -BIN = 1000000000000000000000000000 -HEX = 8000000
lettura dei singoli bit con BitRead PIOB->PIO_ODSR = 000000000000000000000000000100000

Led OFF
digitalRead con variab if state L - PIN 13 = LOW
digitalRead con variab state 0 - PIN 13 = LOW
digitalRead con variab state FALSE - PIN 13 = LOW
digitalRead lettura con Serial.print(digitalRead(13)) PIN 13 = 0

Lettura del registro PIOB_ODSR Output Data Status Register -BIN = 0 -HEX = 0
lettura dei singoli bit con BitRead PIOB->PIO_ODSR = 000000000000000000000000000000000

Led ON
digitalRead con variab if state L - PIN 13 = LOW
digitalRead con variab state 0 - PIN 13 = LOW
digitalRead con variab state FALSE - PIN 13 = LOW
digitalRead lettura con Serial.print(digitalRead(13)) PIN 13 = 0

Lettura del registro PIOB_ODSR Output Data Status Register -BIN = 1000000000000000000000000000 -HEX = 8000000
lettura dei singoli bit con BitRead PIOB->PIO_ODSR = 000000000000000000000000000100000

Led OFF
digitalRead con variab if state L - PIN 13 = LOW
digitalRead con variab state 0 - PIN 13 = LOW
digitalRead con variab state FALSE - PIN 13 = LOW
digitalRead lettura con Serial.print(digitalRead(13)) PIN 13 = 0

Lettura del registro PIOB_ODSR Output Data Status Register -BIN = 0 -HEX = 0
lettura dei singoli bit con BitRead PIOB->PIO_ODSR = 000000000000000000000000000000000

il registro GPIOB dove si trova il pin 13 al bit 4/32 cambia
la lettura diretta con bit read cambia
ma il digitalread non ne vuole sapere

Diciamo che è raro che qualcuno voglia leggere un OUTPUT quando è il programmatore stesso che lo attiva o disattiva, normalmente è importante da parte del programma conoscere lo stato degli INPUT, però su richiesta dovrei riuscire a leggerlo

PS: Arduino 2 o zero sempre ARM è quindi obsoleto e quanto meno opinabile.

cosa intendi? l'ARM Cortex in generale è superato? obsoleto?

ecco cosa intendo quando vanno tutti a 1 quando imposto solo un pin in INPUT in questo caso solo il pin 10

sketch di test

void setup() {
 delay(2000);
 Serial.begin(9600);
//facciamo una bella lettura di tutti pin allo stato iniziale di reset con digitalread
leggi_pin();
//leggiamo anche i registri PIO A/B/C/D
leggi_reg();
//ora mettiamo il pin 10 in INPUT, niente è collegato sui pin e nessuno shield è installato
pinMode(10, INPUT);
Serial.println("pinMode(10, INPUT);"); 
//andiamo a rileggere i pin con digital read
leggi_pin();
//andiamo a rileggere anche i registri PIO A/B/C/D 
 leggi_reg();
}

void loop() {}

void leggi_reg(){  
      
Serial.println();
Serial.println("lettura registri PIO A B C D"); 
Serial.print(" PIOA_ODSR Output Data Status Register -BIN = "); Serial.print(PIOA->PIO_ODSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOA->PIO_ODSR,HEX);
Serial.print(" PIOB_ODSR Output Data Status Register -BIN = "); Serial.print(PIOB->PIO_ODSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOB->PIO_ODSR,HEX);
Serial.print(" PIOC_ODSR Output Data Status Register -BIN = "); Serial.print(PIOC->PIO_ODSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOC->PIO_ODSR,HEX);
Serial.print(" PIOD_ODSR Output Data Status Register -BIN = "); Serial.print(PIOD->PIO_ODSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOD->PIO_ODSR,HEX);
Serial.println();
Serial.print(" PIOA_PDSR Pin Data Status Register -BIN = "); Serial.print(PIOA->PIO_PDSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOA->PIO_PDSR,HEX);
Serial.print(" PIOB_PDSR Pin Data Status Register -BIN = "); Serial.print(PIOB->PIO_PDSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOB->PIO_PDSR,HEX);
Serial.print(" PIOC_PDSR Pin Data Status Register -BIN = "); Serial.print(PIOC->PIO_PDSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOC->PIO_PDSR,HEX);
Serial.print(" PIOD_PDSR Pin Data Status Register -BIN = "); Serial.print(PIOD->PIO_PDSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOD->PIO_PDSR,HEX);
Serial.println();
Serial.print(" PIOA_OSR Output Status Register -BIN = "); Serial.print(PIOA->PIO_OSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOA->PIO_OSR,HEX);
Serial.print(" PIOB_OSR Output Status Register -BIN = "); Serial.print(PIOB->PIO_OSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOB->PIO_OSR,HEX);
Serial.print(" PIOC_OSR Output Status Register -BIN = "); Serial.print(PIOC->PIO_OSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOC->PIO_OSR,HEX);
Serial.print(" PIOD_OSR Output Status Register -BIN = "); Serial.print(PIOD->PIO_OSR,BIN); Serial.print(" ; -HEX = "); Serial.println(PIOD->PIO_OSR,HEX);
 } 

void leggi_pin(){ 
Serial.println();  
Serial.println("lettura pin 0-69"); 
 for (byte i=0; i <= 69; i++){
  Serial.print("PIN = "); Serial.print(i); Serial.print(" ");Serial.println(digitalRead(i));     
  }  
}

uscita debug

lettura pin 0-69 senza nessuna impostazione sui pin
PIN = 0 0
PIN = 1 0
PIN = 2 0
PIN = 3 0
PIN = 4 0
PIN = 5 0
PIN = 6 0
PIN = 7 0
PIN = 8 0
PIN = 9 0
PIN = 10 0
PIN = 11 0
PIN = 12 0
PIN = 13 0
PIN = 14 0
PIN = 15 0
PIN = 16 0
PIN = 17 0
PIN = 18 0
PIN = 19 0
PIN = 20 0
PIN = 21 0
PIN = 22 0
PIN = 23 0
PIN = 24 0
PIN = 25 0
PIN = 26 0
PIN = 27 0
PIN = 28 0
PIN = 29 0
PIN = 30 0
PIN = 31 0
PIN = 32 0
PIN = 33 0
PIN = 34 0
PIN = 35 0
PIN = 36 0
PIN = 37 0
PIN = 38 0
PIN = 39 0
PIN = 40 0
PIN = 41 0
PIN = 42 0
PIN = 43 0
PIN = 44 0
PIN = 45 0
PIN = 46 0
PIN = 47 0
PIN = 48 0
PIN = 49 0
PIN = 50 0
PIN = 51 0
PIN = 52 0
PIN = 53 0
PIN = 54 0
PIN = 55 0
PIN = 56 0
PIN = 57 0
PIN = 58 0
PIN = 59 0
PIN = 60 0
PIN = 61 0
PIN = 62 0
PIN = 63 0
PIN = 64 0
PIN = 65 0
PIN = 66 0
PIN = 67 0
PIN = 68 0
PIN = 69 0

lettura registri PIO A B C D
PIOA_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0
PIOB_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0
PIOC_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0
PIOD_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0

PIOA_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0
PIOB_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0
PIOC_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0
PIOD_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0

PIOA_OSR Output Status Register -BIN = 0 ; -HEX = 0
PIOB_OSR Output Status Register -BIN = 0 ; -HEX = 0
PIOC_OSR Output Status Register -BIN = 0 ; -HEX = 0
PIOD_OSR Output Status Register -BIN = 0 ; -HEX = 0

pinMode(10, INPUT);

lettura pin 0-69
PIN = 0 0
PIN = 1 0
PIN = 2 0
PIN = 3 1
PIN = 4 1
PIN = 5 1
PIN = 6 1
PIN = 7 1
PIN = 8 1
PIN = 9 1
PIN = 10 1
PIN = 11 0
PIN = 12 0
PIN = 13 0
PIN = 14 0
PIN = 15 0
PIN = 16 0
PIN = 17 0
PIN = 18 0
PIN = 19 0
PIN = 20 0
PIN = 21 0
PIN = 22 0
PIN = 23 0
PIN = 24 0
PIN = 25 0
PIN = 26 0
PIN = 27 0
PIN = 28 0
PIN = 29 0
PIN = 30 0
PIN = 31 0
PIN = 32 0
PIN = 33 1
PIN = 34 1
PIN = 35 1
PIN = 36 1
PIN = 37 1
PIN = 38 1
PIN = 39 1
PIN = 40 1
PIN = 41 1
PIN = 42 0
PIN = 43 0
PIN = 44 1
PIN = 45 1
PIN = 46 1
PIN = 47 1
PIN = 48 1
PIN = 49 1
PIN = 50 1
PIN = 51 1
PIN = 52 0
PIN = 53 0
PIN = 54 0
PIN = 55 0
PIN = 56 0
PIN = 57 0
PIN = 58 0
PIN = 59 0
PIN = 60 0
PIN = 61 0
PIN = 62 0
PIN = 63 0
PIN = 64 0
PIN = 65 0
PIN = 66 0
PIN = 67 0
PIN = 68 0
PIN = 69 0

lettura registri PIO A B C D
PIOA_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0
PIOB_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0
PIOC_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0
PIOD_ODSR Output Data Status Register -BIN = 0 ; -HEX = 0

PIOA_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0
PIOB_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0
PIOC_PDSR Pin Data Status Register -BIN = 1111111111111111111111111111110 ; -HEX = 7FFFFFFE
PIOD_PDSR Pin Data Status Register -BIN = 0 ; -HEX = 0

PIOA_OSR Output Status Register -BIN = 0 ; -HEX = 0
PIOB_OSR Output Status Register -BIN = 0 ; -HEX = 0
PIOC_OSR Output Status Register -BIN = 0 ; -HEX = 0
PIOD_OSR Output Status Register -BIN = 0 ; -HEX = 0

in tutto 25 pin vanno a 1 a causa del PULLUP e guarda caso sono quelli che appartengono al PIO C esattamente questi
33 34 35 36 37 38 39 40 41 51 50 49 48 47 46 45 44 9 8 7 6 5 4 3 10

nel caso precedente i valori erano letti con PIOB_ODSR Output Data Status Register perchè parlavamo di OUTPUT
in questo caso i valori sono letti con PIOC_PDSR Pin Data Status Register perchè parliamo di INPUT