github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_atsamd21g18.go (about)

     1  //go:build sam && atsamd21 && atsamd21g18
     2  
     3  // Peripheral abstraction layer for the atsamd21.
     4  //
     5  // Datasheet:
     6  // http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
     7  package machine
     8  
     9  import (
    10  	"device/sam"
    11  	"runtime/interrupt"
    12  )
    13  
    14  var (
    15  	sercomUSART0 = UART{Buffer: NewRingBuffer(), Bus: sam.SERCOM0_USART, SERCOM: 0}
    16  	sercomUSART1 = UART{Buffer: NewRingBuffer(), Bus: sam.SERCOM1_USART, SERCOM: 1}
    17  	sercomUSART2 = UART{Buffer: NewRingBuffer(), Bus: sam.SERCOM2_USART, SERCOM: 2}
    18  	sercomUSART3 = UART{Buffer: NewRingBuffer(), Bus: sam.SERCOM3_USART, SERCOM: 3}
    19  	sercomUSART4 = UART{Buffer: NewRingBuffer(), Bus: sam.SERCOM4_USART, SERCOM: 4}
    20  	sercomUSART5 = UART{Buffer: NewRingBuffer(), Bus: sam.SERCOM5_USART, SERCOM: 5}
    21  
    22  	sercomI2CM0 = &I2C{Bus: sam.SERCOM0_I2CM, SERCOM: 0}
    23  	sercomI2CM1 = &I2C{Bus: sam.SERCOM1_I2CM, SERCOM: 1}
    24  	sercomI2CM2 = &I2C{Bus: sam.SERCOM2_I2CM, SERCOM: 2}
    25  	sercomI2CM3 = &I2C{Bus: sam.SERCOM3_I2CM, SERCOM: 3}
    26  	sercomI2CM4 = &I2C{Bus: sam.SERCOM4_I2CM, SERCOM: 4}
    27  	sercomI2CM5 = &I2C{Bus: sam.SERCOM5_I2CM, SERCOM: 5}
    28  
    29  	sercomSPIM0 = SPI{Bus: sam.SERCOM0_SPI, SERCOM: 0}
    30  	sercomSPIM1 = SPI{Bus: sam.SERCOM1_SPI, SERCOM: 1}
    31  	sercomSPIM2 = SPI{Bus: sam.SERCOM2_SPI, SERCOM: 2}
    32  	sercomSPIM3 = SPI{Bus: sam.SERCOM3_SPI, SERCOM: 3}
    33  	sercomSPIM4 = SPI{Bus: sam.SERCOM4_SPI, SERCOM: 4}
    34  	sercomSPIM5 = SPI{Bus: sam.SERCOM5_SPI, SERCOM: 5}
    35  )
    36  
    37  func init() {
    38  	sercomUSART0.Interrupt = interrupt.New(sam.IRQ_SERCOM0, sercomUSART0.handleInterrupt)
    39  	sercomUSART1.Interrupt = interrupt.New(sam.IRQ_SERCOM1, sercomUSART1.handleInterrupt)
    40  	sercomUSART2.Interrupt = interrupt.New(sam.IRQ_SERCOM2, sercomUSART2.handleInterrupt)
    41  	sercomUSART3.Interrupt = interrupt.New(sam.IRQ_SERCOM3, sercomUSART3.handleInterrupt)
    42  	sercomUSART4.Interrupt = interrupt.New(sam.IRQ_SERCOM4, sercomUSART4.handleInterrupt)
    43  	sercomUSART5.Interrupt = interrupt.New(sam.IRQ_SERCOM5, sercomUSART5.handleInterrupt)
    44  }
    45  
    46  // Return the register and mask to enable a given GPIO pin. This can be used to
    47  // implement bit-banged drivers.
    48  func (p Pin) PortMaskSet() (*uint32, uint32) {
    49  	// Note: using PORT_IOBUS for faster pin accesses.
    50  	// The regular PORT registers appear to take around 4 clock cycles to store,
    51  	// which is longer than the ws2812 driver expects. The IOBUS is is fast
    52  	// enough to avoid this issue.
    53  	if p < 32 {
    54  		return &sam.PORT_IOBUS.OUTSET0.Reg, 1 << uint8(p)
    55  	} else {
    56  		return &sam.PORT_IOBUS.OUTSET1.Reg, 1 << uint8(p-32)
    57  	}
    58  }
    59  
    60  // Return the register and mask to disable a given port. This can be used to
    61  // implement bit-banged drivers.
    62  func (p Pin) PortMaskClear() (*uint32, uint32) {
    63  	if p < 32 {
    64  		return &sam.PORT_IOBUS.OUTCLR0.Reg, 1 << uint8(p)
    65  	} else {
    66  		return &sam.PORT_IOBUS.OUTCLR1.Reg, 1 << uint8(p-32)
    67  	}
    68  }
    69  
    70  // Set the pin to high or low.
    71  // Warning: only use this on an output pin!
    72  func (p Pin) Set(high bool) {
    73  	if p < 32 {
    74  		if high {
    75  			sam.PORT.OUTSET0.Set(1 << uint8(p))
    76  		} else {
    77  			sam.PORT.OUTCLR0.Set(1 << uint8(p))
    78  		}
    79  	} else {
    80  		if high {
    81  			sam.PORT.OUTSET1.Set(1 << uint8(p-32))
    82  		} else {
    83  			sam.PORT.OUTCLR1.Set(1 << uint8(p-32))
    84  		}
    85  	}
    86  }
    87  
    88  // Get returns the current value of a GPIO pin when configured as an input or as
    89  // an output.
    90  func (p Pin) Get() bool {
    91  	if p < 32 {
    92  		return (sam.PORT.IN0.Get()>>uint8(p))&1 > 0
    93  	} else {
    94  		return (sam.PORT.IN1.Get()>>uint8(p-32))&1 > 0
    95  	}
    96  }
    97  
    98  // Configure this pin with the given configuration.
    99  func (p Pin) Configure(config PinConfig) {
   100  	switch config.Mode {
   101  	case PinOutput:
   102  		if p < 32 {
   103  			sam.PORT.DIRSET0.Set(1 << uint8(p))
   104  			// output is also set to input enable so pin can read back its own value
   105  			p.setPinCfg(sam.PORT_PINCFG0_INEN)
   106  		} else {
   107  			sam.PORT.DIRSET1.Set(1 << uint8(p-32))
   108  			// output is also set to input enable so pin can read back its own value
   109  			p.setPinCfg(sam.PORT_PINCFG0_INEN)
   110  		}
   111  
   112  	case PinInput:
   113  		if p < 32 {
   114  			sam.PORT.DIRCLR0.Set(1 << uint8(p))
   115  			p.setPinCfg(sam.PORT_PINCFG0_INEN)
   116  		} else {
   117  			sam.PORT.DIRCLR1.Set(1 << uint8(p-32))
   118  			p.setPinCfg(sam.PORT_PINCFG0_INEN)
   119  		}
   120  
   121  	case PinInputPulldown:
   122  		if p < 32 {
   123  			sam.PORT.DIRCLR0.Set(1 << uint8(p))
   124  			sam.PORT.OUTCLR0.Set(1 << uint8(p))
   125  			p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
   126  		} else {
   127  			sam.PORT.DIRCLR1.Set(1 << uint8(p-32))
   128  			sam.PORT.OUTCLR1.Set(1 << uint8(p-32))
   129  			p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
   130  		}
   131  
   132  	case PinInputPullup:
   133  		if p < 32 {
   134  			sam.PORT.DIRCLR0.Set(1 << uint8(p))
   135  			sam.PORT.OUTSET0.Set(1 << uint8(p))
   136  			p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
   137  		} else {
   138  			sam.PORT.DIRCLR1.Set(1 << uint8(p-32))
   139  			sam.PORT.OUTSET1.Set(1 << uint8(p-32))
   140  			p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
   141  		}
   142  
   143  	case PinSERCOM:
   144  		if p&1 > 0 {
   145  			// odd pin, so save the even pins
   146  			val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
   147  			p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXO_Pos))
   148  		} else {
   149  			// even pin, so save the odd pins
   150  			val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
   151  			p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXE_Pos))
   152  		}
   153  		// enable port config
   154  		p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR | sam.PORT_PINCFG0_INEN)
   155  
   156  	case PinSERCOMAlt:
   157  		if p&1 > 0 {
   158  			// odd pin, so save the even pins
   159  			val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
   160  			p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXO_Pos))
   161  		} else {
   162  			// even pin, so save the odd pins
   163  			val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
   164  			p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXE_Pos))
   165  		}
   166  		// enable port config
   167  		p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
   168  
   169  	case PinCom:
   170  		if p&1 > 0 {
   171  			// odd pin, so save the even pins
   172  			val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
   173  			p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXO_Pos))
   174  		} else {
   175  			// even pin, so save the odd pins
   176  			val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
   177  			p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXE_Pos))
   178  		}
   179  		// enable port config
   180  		p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
   181  	case PinAnalog:
   182  		if p&1 > 0 {
   183  			// odd pin, so save the even pins
   184  			val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
   185  			p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXO_Pos))
   186  		} else {
   187  			// even pin, so save the odd pins
   188  			val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
   189  			p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXE_Pos))
   190  		}
   191  		// enable port config
   192  		p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
   193  	}
   194  }
   195  
   196  // getPMux returns the value for the correct PMUX register for this pin.
   197  func (p Pin) getPMux() uint8 {
   198  	switch uint8(p) >> 1 {
   199  	case 0:
   200  		return sam.PORT.PMUX0_0.Get()
   201  	case 1:
   202  		return sam.PORT.PMUX0_1.Get()
   203  	case 2:
   204  		return sam.PORT.PMUX0_2.Get()
   205  	case 3:
   206  		return sam.PORT.PMUX0_3.Get()
   207  	case 4:
   208  		return sam.PORT.PMUX0_4.Get()
   209  	case 5:
   210  		return sam.PORT.PMUX0_5.Get()
   211  	case 6:
   212  		return sam.PORT.PMUX0_6.Get()
   213  	case 7:
   214  		return sam.PORT.PMUX0_7.Get()
   215  	case 8:
   216  		return sam.PORT.PMUX0_8.Get()
   217  	case 9:
   218  		return sam.PORT.PMUX0_9.Get()
   219  	case 10:
   220  		return sam.PORT.PMUX0_10.Get()
   221  	case 11:
   222  		return sam.PORT.PMUX0_11.Get()
   223  	case 12:
   224  		return sam.PORT.PMUX0_12.Get()
   225  	case 13:
   226  		return sam.PORT.PMUX0_13.Get()
   227  	case 14:
   228  		return sam.PORT.PMUX0_14.Get()
   229  	case 15:
   230  		return sam.PORT.PMUX0_15.Get()
   231  	case 16:
   232  		return uint8(sam.PORT.PMUX1_0.Get()>>0) & 0xff
   233  	case 17:
   234  		return uint8(sam.PORT.PMUX1_0.Get()>>8) & 0xff
   235  	case 18:
   236  		return uint8(sam.PORT.PMUX1_0.Get()>>16) & 0xff
   237  	case 19:
   238  		return uint8(sam.PORT.PMUX1_0.Get()>>24) & 0xff
   239  	case 20:
   240  		return uint8(sam.PORT.PMUX1_4.Get()>>0) & 0xff
   241  	case 21:
   242  		return uint8(sam.PORT.PMUX1_4.Get()>>8) & 0xff
   243  	case 22:
   244  		return uint8(sam.PORT.PMUX1_4.Get()>>16) & 0xff
   245  	case 23:
   246  		return uint8(sam.PORT.PMUX1_4.Get()>>24) & 0xff
   247  	case 24:
   248  		return uint8(sam.PORT.PMUX1_8.Get()>>0) & 0xff
   249  	case 25:
   250  		return uint8(sam.PORT.PMUX1_8.Get()>>8) & 0xff
   251  	case 26:
   252  		return uint8(sam.PORT.PMUX1_8.Get()>>16) & 0xff
   253  	case 27:
   254  		return uint8(sam.PORT.PMUX1_8.Get()>>24) & 0xff
   255  	case 28:
   256  		return uint8(sam.PORT.PMUX1_12.Get()>>0) & 0xff
   257  	case 29:
   258  		return uint8(sam.PORT.PMUX1_12.Get()>>8) & 0xff
   259  	case 30:
   260  		return uint8(sam.PORT.PMUX1_12.Get()>>16) & 0xff
   261  	case 31:
   262  		return uint8(sam.PORT.PMUX1_12.Get()>>24) & 0xff
   263  	default:
   264  		return 0
   265  	}
   266  }
   267  
   268  // setPMux sets the value for the correct PMUX register for this pin.
   269  func (p Pin) setPMux(val uint8) {
   270  	switch uint8(p) >> 1 {
   271  	case 0:
   272  		sam.PORT.PMUX0_0.Set(val)
   273  	case 1:
   274  		sam.PORT.PMUX0_1.Set(val)
   275  	case 2:
   276  		sam.PORT.PMUX0_2.Set(val)
   277  	case 3:
   278  		sam.PORT.PMUX0_3.Set(val)
   279  	case 4:
   280  		sam.PORT.PMUX0_4.Set(val)
   281  	case 5:
   282  		sam.PORT.PMUX0_5.Set(val)
   283  	case 6:
   284  		sam.PORT.PMUX0_6.Set(val)
   285  	case 7:
   286  		sam.PORT.PMUX0_7.Set(val)
   287  	case 8:
   288  		sam.PORT.PMUX0_8.Set(val)
   289  	case 9:
   290  		sam.PORT.PMUX0_9.Set(val)
   291  	case 10:
   292  		sam.PORT.PMUX0_10.Set(val)
   293  	case 11:
   294  		sam.PORT.PMUX0_11.Set(val)
   295  	case 12:
   296  		sam.PORT.PMUX0_12.Set(val)
   297  	case 13:
   298  		sam.PORT.PMUX0_13.Set(val)
   299  	case 14:
   300  		sam.PORT.PMUX0_14.Set(val)
   301  	case 15:
   302  		sam.PORT.PMUX0_15.Set(val)
   303  	case 16:
   304  		sam.PORT.PMUX1_0.ReplaceBits(uint32(val), 0xff, 0)
   305  	case 17:
   306  		sam.PORT.PMUX1_0.ReplaceBits(uint32(val), 0xff, 8)
   307  	case 18:
   308  		sam.PORT.PMUX1_0.ReplaceBits(uint32(val), 0xff, 16)
   309  	case 19:
   310  		sam.PORT.PMUX1_0.ReplaceBits(uint32(val), 0xff, 24)
   311  	case 20:
   312  		sam.PORT.PMUX1_4.ReplaceBits(uint32(val), 0xff, 0)
   313  	case 21:
   314  		sam.PORT.PMUX1_4.ReplaceBits(uint32(val), 0xff, 8)
   315  	case 22:
   316  		sam.PORT.PMUX1_4.ReplaceBits(uint32(val), 0xff, 16)
   317  	case 23:
   318  		sam.PORT.PMUX1_4.ReplaceBits(uint32(val), 0xff, 24)
   319  	case 24:
   320  		sam.PORT.PMUX1_8.ReplaceBits(uint32(val), 0xff, 0)
   321  	case 25:
   322  		sam.PORT.PMUX1_8.ReplaceBits(uint32(val), 0xff, 8)
   323  	case 26:
   324  		sam.PORT.PMUX1_8.ReplaceBits(uint32(val), 0xff, 16)
   325  	case 27:
   326  		sam.PORT.PMUX1_8.ReplaceBits(uint32(val), 0xff, 24)
   327  	case 28:
   328  		sam.PORT.PMUX1_12.ReplaceBits(uint32(val), 0xff, 0)
   329  	case 29:
   330  		sam.PORT.PMUX1_12.ReplaceBits(uint32(val), 0xff, 8)
   331  	case 30:
   332  		sam.PORT.PMUX1_12.ReplaceBits(uint32(val), 0xff, 16)
   333  	case 31:
   334  		sam.PORT.PMUX1_12.ReplaceBits(uint32(val), 0xff, 24)
   335  	}
   336  }
   337  
   338  // getPinCfg returns the value for the correct PINCFG register for this pin.
   339  func (p Pin) getPinCfg() uint8 {
   340  	switch p {
   341  	case 0:
   342  		return sam.PORT.PINCFG0_0.Get()
   343  	case 1:
   344  		return sam.PORT.PINCFG0_1.Get()
   345  	case 2:
   346  		return sam.PORT.PINCFG0_2.Get()
   347  	case 3:
   348  		return sam.PORT.PINCFG0_3.Get()
   349  	case 4:
   350  		return sam.PORT.PINCFG0_4.Get()
   351  	case 5:
   352  		return sam.PORT.PINCFG0_5.Get()
   353  	case 6:
   354  		return sam.PORT.PINCFG0_6.Get()
   355  	case 7:
   356  		return sam.PORT.PINCFG0_7.Get()
   357  	case 8:
   358  		return sam.PORT.PINCFG0_8.Get()
   359  	case 9:
   360  		return sam.PORT.PINCFG0_9.Get()
   361  	case 10:
   362  		return sam.PORT.PINCFG0_10.Get()
   363  	case 11:
   364  		return sam.PORT.PINCFG0_11.Get()
   365  	case 12:
   366  		return sam.PORT.PINCFG0_12.Get()
   367  	case 13:
   368  		return sam.PORT.PINCFG0_13.Get()
   369  	case 14:
   370  		return sam.PORT.PINCFG0_14.Get()
   371  	case 15:
   372  		return sam.PORT.PINCFG0_15.Get()
   373  	case 16:
   374  		return sam.PORT.PINCFG0_16.Get()
   375  	case 17:
   376  		return sam.PORT.PINCFG0_17.Get()
   377  	case 18:
   378  		return sam.PORT.PINCFG0_18.Get()
   379  	case 19:
   380  		return sam.PORT.PINCFG0_19.Get()
   381  	case 20:
   382  		return sam.PORT.PINCFG0_20.Get()
   383  	case 21:
   384  		return sam.PORT.PINCFG0_21.Get()
   385  	case 22:
   386  		return sam.PORT.PINCFG0_22.Get()
   387  	case 23:
   388  		return sam.PORT.PINCFG0_23.Get()
   389  	case 24:
   390  		return sam.PORT.PINCFG0_24.Get()
   391  	case 25:
   392  		return sam.PORT.PINCFG0_25.Get()
   393  	case 26:
   394  		return sam.PORT.PINCFG0_26.Get()
   395  	case 27:
   396  		return sam.PORT.PINCFG0_27.Get()
   397  	case 28:
   398  		return sam.PORT.PINCFG0_28.Get()
   399  	case 29:
   400  		return sam.PORT.PINCFG0_29.Get()
   401  	case 30:
   402  		return sam.PORT.PINCFG0_30.Get()
   403  	case 31:
   404  		return sam.PORT.PINCFG0_31.Get()
   405  	case 32: // PB00
   406  		return uint8(sam.PORT.PINCFG1_0.Get()>>0) & 0xff
   407  	case 33: // PB01
   408  		return uint8(sam.PORT.PINCFG1_0.Get()>>8) & 0xff
   409  	case 34: // PB02
   410  		return uint8(sam.PORT.PINCFG1_0.Get()>>16) & 0xff
   411  	case 35: // PB03
   412  		return uint8(sam.PORT.PINCFG1_0.Get()>>24) & 0xff
   413  	case 36: // PB04
   414  		return uint8(sam.PORT.PINCFG1_4.Get()>>0) & 0xff
   415  	case 37: // PB05
   416  		return uint8(sam.PORT.PINCFG1_4.Get()>>8) & 0xff
   417  	case 38: // PB06
   418  		return uint8(sam.PORT.PINCFG1_4.Get()>>16) & 0xff
   419  	case 39: // PB07
   420  		return uint8(sam.PORT.PINCFG1_4.Get()>>24) & 0xff
   421  	case 40: // PB08
   422  		return uint8(sam.PORT.PINCFG1_8.Get()>>0) & 0xff
   423  	case 41: // PB09
   424  		return uint8(sam.PORT.PINCFG1_8.Get()>>8) & 0xff
   425  	case 42: // PB10
   426  		return uint8(sam.PORT.PINCFG1_8.Get()>>16) & 0xff
   427  	case 43: // PB11
   428  		return uint8(sam.PORT.PINCFG1_8.Get()>>24) & 0xff
   429  	case 44: // PB12
   430  		return uint8(sam.PORT.PINCFG1_12.Get()>>0) & 0xff
   431  	case 45: // PB13
   432  		return uint8(sam.PORT.PINCFG1_12.Get()>>8) & 0xff
   433  	case 46: // PB14
   434  		return uint8(sam.PORT.PINCFG1_12.Get()>>16) & 0xff
   435  	case 47: // PB15
   436  		return uint8(sam.PORT.PINCFG1_12.Get()>>24) & 0xff
   437  	case 48: // PB16
   438  		return uint8(sam.PORT.PINCFG1_16.Get()>>0) & 0xff
   439  	case 49: // PB17
   440  		return uint8(sam.PORT.PINCFG1_16.Get()>>8) & 0xff
   441  	case 50: // PB18
   442  		return uint8(sam.PORT.PINCFG1_16.Get()>>16) & 0xff
   443  	case 51: // PB19
   444  		return uint8(sam.PORT.PINCFG1_16.Get()>>24) & 0xff
   445  	case 52: // PB20
   446  		return uint8(sam.PORT.PINCFG1_20.Get()>>0) & 0xff
   447  	case 53: // PB21
   448  		return uint8(sam.PORT.PINCFG1_20.Get()>>8) & 0xff
   449  	case 54: // PB22
   450  		return uint8(sam.PORT.PINCFG1_20.Get()>>16) & 0xff
   451  	case 55: // PB23
   452  		return uint8(sam.PORT.PINCFG1_20.Get()>>24) & 0xff
   453  	case 56: // PB24
   454  		return uint8(sam.PORT.PINCFG1_24.Get()>>0) & 0xff
   455  	case 57: // PB25
   456  		return uint8(sam.PORT.PINCFG1_24.Get()>>8) & 0xff
   457  	case 58: // PB26
   458  		return uint8(sam.PORT.PINCFG1_24.Get()>>16) & 0xff
   459  	case 59: // PB27
   460  		return uint8(sam.PORT.PINCFG1_24.Get()>>24) & 0xff
   461  	case 60: // PB28
   462  		return uint8(sam.PORT.PINCFG1_28.Get()>>0) & 0xff
   463  	case 61: // PB29
   464  		return uint8(sam.PORT.PINCFG1_28.Get()>>8) & 0xff
   465  	case 62: // PB30
   466  		return uint8(sam.PORT.PINCFG1_28.Get()>>16) & 0xff
   467  	case 63: // PB31
   468  		return uint8(sam.PORT.PINCFG1_28.Get()>>24) & 0xff
   469  	default:
   470  		return 0
   471  	}
   472  }
   473  
   474  // setPinCfg sets the value for the correct PINCFG register for this pin.
   475  func (p Pin) setPinCfg(val uint8) {
   476  	switch p {
   477  	case 0:
   478  		sam.PORT.PINCFG0_0.Set(val)
   479  	case 1:
   480  		sam.PORT.PINCFG0_1.Set(val)
   481  	case 2:
   482  		sam.PORT.PINCFG0_2.Set(val)
   483  	case 3:
   484  		sam.PORT.PINCFG0_3.Set(val)
   485  	case 4:
   486  		sam.PORT.PINCFG0_4.Set(val)
   487  	case 5:
   488  		sam.PORT.PINCFG0_5.Set(val)
   489  	case 6:
   490  		sam.PORT.PINCFG0_6.Set(val)
   491  	case 7:
   492  		sam.PORT.PINCFG0_7.Set(val)
   493  	case 8:
   494  		sam.PORT.PINCFG0_8.Set(val)
   495  	case 9:
   496  		sam.PORT.PINCFG0_9.Set(val)
   497  	case 10:
   498  		sam.PORT.PINCFG0_10.Set(val)
   499  	case 11:
   500  		sam.PORT.PINCFG0_11.Set(val)
   501  	case 12:
   502  		sam.PORT.PINCFG0_12.Set(val)
   503  	case 13:
   504  		sam.PORT.PINCFG0_13.Set(val)
   505  	case 14:
   506  		sam.PORT.PINCFG0_14.Set(val)
   507  	case 15:
   508  		sam.PORT.PINCFG0_15.Set(val)
   509  	case 16:
   510  		sam.PORT.PINCFG0_16.Set(val)
   511  	case 17:
   512  		sam.PORT.PINCFG0_17.Set(val)
   513  	case 18:
   514  		sam.PORT.PINCFG0_18.Set(val)
   515  	case 19:
   516  		sam.PORT.PINCFG0_19.Set(val)
   517  	case 20:
   518  		sam.PORT.PINCFG0_20.Set(val)
   519  	case 21:
   520  		sam.PORT.PINCFG0_21.Set(val)
   521  	case 22:
   522  		sam.PORT.PINCFG0_22.Set(val)
   523  	case 23:
   524  		sam.PORT.PINCFG0_23.Set(val)
   525  	case 24:
   526  		sam.PORT.PINCFG0_24.Set(val)
   527  	case 25:
   528  		sam.PORT.PINCFG0_25.Set(val)
   529  	case 26:
   530  		sam.PORT.PINCFG0_26.Set(val)
   531  	case 27:
   532  		sam.PORT.PINCFG0_27.Set(val)
   533  	case 28:
   534  		sam.PORT.PINCFG0_28.Set(val)
   535  	case 29:
   536  		sam.PORT.PINCFG0_29.Set(val)
   537  	case 30:
   538  		sam.PORT.PINCFG0_30.Set(val)
   539  	case 31:
   540  		sam.PORT.PINCFG0_31.Set(val)
   541  	case 32: // PB00
   542  		sam.PORT.PINCFG1_0.ReplaceBits(uint32(val), 0xff, 0)
   543  	case 33: // PB01
   544  		sam.PORT.PINCFG1_0.ReplaceBits(uint32(val), 0xff, 8)
   545  	case 34: // PB02
   546  		sam.PORT.PINCFG1_0.ReplaceBits(uint32(val), 0xff, 16)
   547  	case 35: // PB03
   548  		sam.PORT.PINCFG1_0.ReplaceBits(uint32(val), 0xff, 24)
   549  	case 36: // PB04
   550  		sam.PORT.PINCFG1_4.ReplaceBits(uint32(val), 0xff, 0)
   551  	case 37: // PB05
   552  		sam.PORT.PINCFG1_4.ReplaceBits(uint32(val), 0xff, 8)
   553  	case 38: // PB06
   554  		sam.PORT.PINCFG1_4.ReplaceBits(uint32(val), 0xff, 16)
   555  	case 39: // PB07
   556  		sam.PORT.PINCFG1_4.ReplaceBits(uint32(val), 0xff, 24)
   557  	case 40: // PB08
   558  		sam.PORT.PINCFG1_8.ReplaceBits(uint32(val), 0xff, 0)
   559  	case 41: // PB09
   560  		sam.PORT.PINCFG1_8.ReplaceBits(uint32(val), 0xff, 8)
   561  	case 42: // PB10
   562  		sam.PORT.PINCFG1_8.ReplaceBits(uint32(val), 0xff, 16)
   563  	case 43: // PB11
   564  		sam.PORT.PINCFG1_8.ReplaceBits(uint32(val), 0xff, 24)
   565  	case 44: // PB12
   566  		sam.PORT.PINCFG1_12.ReplaceBits(uint32(val), 0xff, 0)
   567  	case 45: // PB13
   568  		sam.PORT.PINCFG1_12.ReplaceBits(uint32(val), 0xff, 8)
   569  	case 46: // PB14
   570  		sam.PORT.PINCFG1_12.ReplaceBits(uint32(val), 0xff, 16)
   571  	case 47: // PB15
   572  		sam.PORT.PINCFG1_12.ReplaceBits(uint32(val), 0xff, 24)
   573  	case 48: // PB16
   574  		sam.PORT.PINCFG1_16.ReplaceBits(uint32(val), 0xff, 0)
   575  	case 49: // PB17
   576  		sam.PORT.PINCFG1_16.ReplaceBits(uint32(val), 0xff, 8)
   577  	case 50: // PB18
   578  		sam.PORT.PINCFG1_16.ReplaceBits(uint32(val), 0xff, 16)
   579  	case 51: // PB19
   580  		sam.PORT.PINCFG1_16.ReplaceBits(uint32(val), 0xff, 24)
   581  	case 52: // PB20
   582  		sam.PORT.PINCFG1_20.ReplaceBits(uint32(val), 0xff, 0)
   583  	case 53: // PB21
   584  		sam.PORT.PINCFG1_20.ReplaceBits(uint32(val), 0xff, 8)
   585  	case 54: // PB22
   586  		sam.PORT.PINCFG1_20.ReplaceBits(uint32(val), 0xff, 16)
   587  	case 55: // PB23
   588  		sam.PORT.PINCFG1_20.ReplaceBits(uint32(val), 0xff, 24)
   589  	case 56: // PB24
   590  		sam.PORT.PINCFG1_24.ReplaceBits(uint32(val), 0xff, 0)
   591  	case 57: // PB25
   592  		sam.PORT.PINCFG1_24.ReplaceBits(uint32(val), 0xff, 8)
   593  	case 58: // PB26
   594  		sam.PORT.PINCFG1_24.ReplaceBits(uint32(val), 0xff, 16)
   595  	case 59: // PB27
   596  		sam.PORT.PINCFG1_24.ReplaceBits(uint32(val), 0xff, 24)
   597  	case 60: // PB28
   598  		sam.PORT.PINCFG1_28.ReplaceBits(uint32(val), 0xff, 0)
   599  	case 61: // PB29
   600  		sam.PORT.PINCFG1_28.ReplaceBits(uint32(val), 0xff, 8)
   601  	case 62: // PB30
   602  		sam.PORT.PINCFG1_28.ReplaceBits(uint32(val), 0xff, 16)
   603  	case 63: // PB31
   604  		sam.PORT.PINCFG1_28.ReplaceBits(uint32(val), 0xff, 24)
   605  	}
   606  }