OneWire Arduino Zero

Ho trovato una libreria OneWire adattata per l'Arduino Due
--> GitHub - ntruchsess/arduino-OneWire: OneWire lets you access 1-wire devices made by Maxim/Dallas, such as temperature sensors and ibutton secure memory. Library for arduino

Secondo voi è possibile l'adattamento anche per l'Arduino Zero?

#elif defined(__SAMD21G18A__)
// Arduino Zero
#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         (((*((base)+15)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+5)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+4)) = (mask))
#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+13)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+12)) = (mask))
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#endif

Penso siano da modificare tutti i define.

Queste sono alcune define nel file variant.h del core della Zero.

#define digitalPinToPort(P)        ( &(PORT->Group[g_APinDescription[P].ulPort]) )
#define digitalPinToBitMask(P)     ( 1 << g_APinDescription[P].ulPin )
//#define analogInPinToBit(P)        ( )
#define portOutputRegister(port)   ( &(port->OUT.reg) )
#define portInputRegister(port)    ( &(port->IN.reg) )
#define portModeRegister(port)     ( &(port->DIR.reg) )
#define digitalPinHasPWM(P)        ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER )

L’indirizzamento interno alle porte ed ai registri è completamente diverso sia dalla UNO che dalla DUE. :frowning:

I primi due dovrebbero essere:

#elif defined(__SAMD21G18A__)
// Arduino Zero
#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM

Per i modi diretti non ho idea.
Anche perché se si va a vedere il file wiring_digital.c della ZERO

void pinMode( uint32_t ulPin, uint32_t ulMode )
{
  // Handle the case the pin isn't usable as PIO
  if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
  {
    return ;
  }

  // Set pin mode according to chapter '22.6.3 I/O Pin Configuration'
  switch ( ulMode )
  {
    case INPUT:
      // Set pin to input mode
      PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN) ;
      PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
    break ;

    case INPUT_PULLUP:
      // Set pin to input mode with pull-up resistor enabled
      PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ;
      PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;

      // Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.7 Data Output Value Set')
      PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
    break ;

    case INPUT_PULLDOWN:
      // Set pin to input mode with pull-down resistor enabled
      PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ;
      PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;

      // Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.6 Data Output Value Clear')
      PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
    break ;

    case OUTPUT:
      // Set pin to output mode
      PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg&=~(uint8_t)(PORT_PINCFG_INEN) ;
      PORT->Group[g_APinDescription[ulPin].ulPort].DIRSET.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
    break ;

    default:
      // do nothing
    break ;
  }
}

void digitalWrite( uint32_t ulPin, uint32_t ulVal )
{
  // Handle the case the pin isn't usable as PIO
  if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
  {
    return ;
  }

  // Enable pull-up resistor
  PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_PULLEN) ;

  switch ( ulVal )
  {
    case LOW:
      PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (1ul << g_APinDescription[ulPin].ulPin) ;
    break ;

    case HIGH:
      PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (1ul << g_APinDescription[ulPin].ulPin) ;
    break ;

    default:
    break ;
  }

  return ;
}

int digitalRead( uint32_t ulPin )
{
  // Handle the case the pin isn't usable as PIO
  if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
  {
    return LOW ;
  }

  if ( (PORT->Group[g_APinDescription[ulPin].ulPort].IN.reg & (1ul << g_APinDescription[ulPin].ulPin)) != 0 )
  {
    return HIGH ;
  }

  return LOW ;
}

Non è così semplice come il core AVR.

x iscizione

Non parlo italiano , ma provato i tempi qui (non ancora approvata da Paul Stoffregen! ) Non una bella esecuzione ma funziona (Google translate!)

OneWire_with_Zero.zip (16.6 KB)

Grazie Marcus.

Ho visto che è stato aggiunto questo codice

#elif defined (__SAMD21G18A__)
#define PIN_TO_BASEREG(pin)             &(PORT->Group[g_APinDescription[pin].ulPort])
#define PIN_TO_BITMASK(pin)             g_APinDescription[pin].ulPin
#define IO_MASK_TYPE uint8_t
#define IO_REG_TYPE PortGroup
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         ( base->IN.reg & (1 << mask) ? 1 : 0 )
#define DIRECT_MODE_INPUT(base, mask)   { base->PINCFG[mask].reg = (uint8_t)(PORT_PINCFG_INEN); base->DIRCLR.reg = (1 << mask);}
#define DIRECT_MODE_OUTPUT(base, mask)  { base->PINCFG[mask].reg&=~(uint8_t)(PORT_PINCFG_INEN); base->DIRSET.reg = (1 << mask);}
//Works also
//#define DIRECT_MODE_INPUT(base, mask)   base->DIRCLR.reg = (1 << mask)
//#define DIRECT_MODE_OUTPUT(base, mask)  base->DIRSET.reg = (1 << mask)
#define DIRECT_WRITE_LOW(base, mask)    base->OUTCLR.reg = (1 << mask)
#define DIRECT_WRITE_HIGH(base, mask)   base->OUTSET.reg = (1 << mask)
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#endif

Appena posso lo provo.

Ok, compila ma il mio DS18B20 è guasto. :confused:

In attesa di acquisto....

Intanto comunico che la versione 2.3 della OneWire scaricabile dal library manager contiene un work-around per l'uso di architetture non supportate. Al posto dei registri diretti usa semplicemente pinMode e digitalRead/Write.

Da provare....

PaoloP:
Intanto comunico che la versione 2.3 della OneWire scaricabile dal library manager contiene un work-around per l'uso di architetture non supportate. Al posto dei registri diretti usa semplicemente pinMode e digitalRead/Write.

Da provare....

Sì vero solo quando la funzione overdrive è usato sono di lettura digitale / scrittura troppo lentamente.

E sì , la soluzione funziona a Zero.

Eureka!

Don't work on pin 2 and 4. No tested on pin 10, 11, 12, 13 and A0-A6

PaoloP:
Don't work on pin 2 and 4. No tested on pin 10, 11, 12, 13 and A0-A6

... su che piedini funziona allora ? ? ? :o

Guglielmo

Funziona sui piedini: 0,1,3,5,6,7,8,9.
Da provare i piedino dal 10 al 13 e gli Ax.

Il perché non vada sul 2 e su 4 è un mistero.
Anche perché uso la digitalWrite e la digitalRead.

PaoloP:
Funziona sui piedini: 0,1,3,5,6,7,8,9.
Da provare i piedino dal 10 al 13 e gli Ax.

Il perché non vada sul 2 e su 4 è un mistero.
Anche perché uso la digitalWrite e la digitalRead.

Ha un Arduino Pro Zero di Arduino.org è cablato in modo diverso .

Zero Pro sinistra (arduino.org, ora si chiama M0 Pro), originale Zero destra(arduino.cc)

Consente di visualizzare anche il soggetto qui

Markus_L811:
http://forum.arduino.cc/index.php?topic=330370.msg2281167#msg2281167

Grazie. :slight_smile: