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

     1  //go:build avr && atmega1280
     2  
     3  package machine
     4  
     5  import (
     6  	"device/avr"
     7  	"runtime/interrupt"
     8  	"runtime/volatile"
     9  )
    10  
    11  const irq_USART0_RX = avr.IRQ_USART0_RX
    12  
    13  const (
    14  	portA Pin = iota * 8
    15  	portB
    16  	portC
    17  	portD
    18  	portE
    19  	portF
    20  	portG
    21  	portH
    22  	portJ
    23  	portK
    24  	portL
    25  )
    26  
    27  const (
    28  	PA0 = portA + 0
    29  	PA1 = portA + 1
    30  	PA2 = portA + 2
    31  	PA3 = portA + 3
    32  	PA4 = portA + 4
    33  	PA5 = portA + 5
    34  	PA6 = portA + 6
    35  	PA7 = portA + 7
    36  	PB0 = portB + 0
    37  	PB1 = portB + 1
    38  	PB2 = portB + 2
    39  	PB3 = portB + 3
    40  	PB4 = portB + 4 // peripherals: Timer2 channel A
    41  	PB5 = portB + 5 // peripherals: Timer1 channel A
    42  	PB6 = portB + 6 // peripherals: Timer1 channel B
    43  	PB7 = portB + 7 // peripherals: Timer0 channel A
    44  	PC0 = portC + 0
    45  	PC1 = portC + 1
    46  	PC2 = portC + 2
    47  	PC3 = portC + 3
    48  	PC4 = portC + 4
    49  	PC5 = portC + 5
    50  	PC6 = portC + 6
    51  	PC7 = portC + 7
    52  	PD0 = portD + 0
    53  	PD1 = portD + 1
    54  	PD2 = portD + 2
    55  	PD3 = portD + 3
    56  	PD7 = portD + 7
    57  	PE0 = portE + 0
    58  	PE1 = portE + 1
    59  	PE3 = portE + 3 // peripherals: Timer3 channel A
    60  	PE4 = portE + 4 // peripherals: Timer3 channel B
    61  	PE5 = portE + 5 // peripherals: Timer3 channel C
    62  	PE6 = portE + 6
    63  	PF0 = portF + 0
    64  	PF1 = portF + 1
    65  	PF2 = portF + 2
    66  	PF3 = portF + 3
    67  	PF4 = portF + 4
    68  	PF5 = portF + 5
    69  	PF6 = portF + 6
    70  	PF7 = portF + 7
    71  	PG0 = portG + 0
    72  	PG1 = portG + 1
    73  	PG2 = portG + 2
    74  	PG5 = portG + 5 // peripherals: Timer0 channel B
    75  	PH0 = portH + 0
    76  	PH1 = portH + 1
    77  	PH3 = portH + 3 // peripherals: Timer4 channel A
    78  	PH4 = portH + 4 // peripherals: Timer4 channel B
    79  	PH5 = portH + 5 // peripherals: Timer4 channel C
    80  	PH6 = portH + 6 // peripherals: Timer0 channel B
    81  	PJ0 = portJ + 0
    82  	PJ1 = portJ + 1
    83  	PK0 = portK + 0
    84  	PK1 = portK + 1
    85  	PK2 = portK + 2
    86  	PK3 = portK + 3
    87  	PK4 = portK + 4
    88  	PK5 = portK + 5
    89  	PK6 = portK + 6
    90  	PK7 = portK + 7
    91  	PL0 = portL + 0
    92  	PL1 = portL + 1
    93  	PL2 = portL + 2
    94  	PL3 = portL + 3 // peripherals: Timer5 channel A
    95  	PL4 = portL + 4 // peripherals: Timer5 channel B
    96  	PL5 = portL + 5 // peripherals: Timer5 channel C
    97  	PL6 = portL + 6
    98  	PL7 = portL + 7
    99  )
   100  
   101  // getPortMask returns the PORTx register and mask for the pin.
   102  func (p Pin) getPortMask() (*volatile.Register8, uint8) {
   103  	switch {
   104  	case p >= PA0 && p <= PA7:
   105  		return avr.PORTA, 1 << uint8(p-portA)
   106  	case p >= PB0 && p <= PB7:
   107  		return avr.PORTB, 1 << uint8(p-portB)
   108  	case p >= PC0 && p <= PC7:
   109  		return avr.PORTC, 1 << uint8(p-portC)
   110  	case p >= PD0 && p <= PD7:
   111  		return avr.PORTD, 1 << uint8(p-portD)
   112  	case p >= PE0 && p <= PE6:
   113  		return avr.PORTE, 1 << uint8(p-portE)
   114  	case p >= PF0 && p <= PF7:
   115  		return avr.PORTF, 1 << uint8(p-portF)
   116  	case p >= PG0 && p <= PG5:
   117  		return avr.PORTG, 1 << uint8(p-portG)
   118  	case p >= PH0 && p <= PH6:
   119  		return avr.PORTH, 1 << uint8(p-portH)
   120  	case p >= PJ0 && p <= PJ1:
   121  		return avr.PORTJ, 1 << uint8(p-portJ)
   122  	case p >= PK0 && p <= PK7:
   123  		return avr.PORTK, 1 << uint8(p-portK)
   124  	case p >= PL0 && p <= PL7:
   125  		return avr.PORTL, 1 << uint8(p-portL)
   126  	default:
   127  		return avr.PORTA, 255
   128  	}
   129  }
   130  
   131  // PWM is one PWM peripheral, which consists of a counter and two output
   132  // channels (that can be connected to two fixed pins). You can set the frequency
   133  // using SetPeriod, but only for all the channels in this PWM peripheral at
   134  // once.
   135  type PWM struct {
   136  	num uint8
   137  }
   138  
   139  var (
   140  	Timer0 = PWM{0} // 8 bit timer for PB7 and PG5
   141  	Timer1 = PWM{1} // 16 bit timer for PB5 and PB6
   142  	Timer2 = PWM{2} // 8 bit timer for PB4 and PH6
   143  	Timer3 = PWM{3} // 16 bit timer for PE3, PE4 and PE5
   144  	Timer4 = PWM{4} // 16 bit timer for PH3, PH4 and PH5
   145  	Timer5 = PWM{5} // 16 bit timer for PL3, PL4 and PL5
   146  )
   147  
   148  // Configure enables and configures this PWM.
   149  //
   150  // For the two 8 bit timers, there is only a limited number of periods
   151  // available, namely the CPU frequency divided by 256 and again divided by 1, 8,
   152  // 64, 256, or 1024. For a MCU running at 16MHz, this would be a period of 16µs,
   153  // 128µs, 1024µs, 4096µs, or 16384µs.
   154  func (pwm PWM) Configure(config PWMConfig) error {
   155  
   156  	switch pwm.num {
   157  	case 0, 2: // 8-bit timers (Timer/counter 0 and Timer/counter 2)
   158  		// Calculate the timer prescaler.
   159  		// While we could configure a flexible top, that would sacrifice one of
   160  		// the PWM output compare registers and thus a PWM channel. I've chosen
   161  		// to instead limit this timer to a fixed number of frequencies.
   162  		var prescaler uint8
   163  		switch config.Period {
   164  		case 0, (uint64(1e9) * 256 * 1) / uint64(CPUFrequency()):
   165  			prescaler = 1
   166  		case (uint64(1e9) * 256 * 8) / uint64(CPUFrequency()):
   167  			prescaler = 2
   168  		case (uint64(1e9) * 256 * 64) / uint64(CPUFrequency()):
   169  			prescaler = 3
   170  		case (uint64(1e9) * 256 * 256) / uint64(CPUFrequency()):
   171  			prescaler = 4
   172  		case (uint64(1e9) * 256 * 1024) / uint64(CPUFrequency()):
   173  			prescaler = 5
   174  		default:
   175  			return ErrPWMPeriodTooLong
   176  		}
   177  
   178  		if pwm.num == 0 {
   179  			avr.TCCR0B.Set(prescaler)
   180  			// Set the PWM mode to fast PWM (mode = 3).
   181  			avr.TCCR0A.Set(avr.TCCR0A_WGM00 | avr.TCCR0A_WGM01)
   182  			// monotonic timer is using the same time as PWM:0
   183  			// we must adust internal settings of monotonic timer when PWM:0 settings changed
   184  			adjustMonotonicTimer()
   185  		} else {
   186  			avr.TCCR2B.Set(prescaler)
   187  			// Set the PWM mode to fast PWM (mode = 3).
   188  			avr.TCCR2A.Set(avr.TCCR2A_WGM20 | avr.TCCR2A_WGM21)
   189  		}
   190  	case 1, 3, 4, 5:
   191  		// The top value is the number of PWM ticks a PWM period takes. It is
   192  		// initially picked assuming an unlimited counter top and no PWM
   193  		// prescaler.
   194  		var top uint64
   195  		if config.Period == 0 {
   196  			// Use a top appropriate for LEDs. Picking a relatively low period
   197  			// here (0xff) for consistency with the other timers.
   198  			top = 0xff
   199  		} else {
   200  			// The formula below calculates the following formula, optimized:
   201  			//     top = period * (CPUFrequency() / 1e9)
   202  			// By dividing the CPU frequency first (an operation that is easily
   203  			// optimized away) the period has less chance of overflowing.
   204  			top = config.Period * (uint64(CPUFrequency()) / 1000000) / 1000
   205  		}
   206  
   207  		// The ideal PWM period may be larger than would fit in the PWM counter,
   208  		// which is 16 bits (see maxTop). Therefore, try to make the PWM clock
   209  		// speed lower with a prescaler to make the top value fit the maximum
   210  		// top value.
   211  
   212  		const maxTop = 0x10000
   213  		var prescalingTop uint8
   214  		switch {
   215  		case top <= maxTop:
   216  			prescalingTop = 3<<3 | 1 // no prescaling
   217  		case top/8 <= maxTop:
   218  			prescalingTop = 3<<3 | 2 // divide by 8
   219  			top /= 8
   220  		case top/64 <= maxTop:
   221  			prescalingTop = 3<<3 | 3 // divide by 64
   222  			top /= 64
   223  		case top/256 <= maxTop:
   224  			prescalingTop = 3<<3 | 4 // divide by 256
   225  			top /= 256
   226  		case top/1024 <= maxTop:
   227  			prescalingTop = 3<<3 | 5 // divide by 1024
   228  			top /= 1024
   229  		default:
   230  			return ErrPWMPeriodTooLong
   231  		}
   232  
   233  		// A top of 0x10000 is at 100% duty cycle. Subtract one because the
   234  		// counter counts from 0, not 1 (avoiding an off-by-one).
   235  		top -= 1
   236  
   237  		switch pwm.num {
   238  		case 1:
   239  			avr.TCCR1A.Set(avr.TCCR1A_WGM11)
   240  			avr.TCCR1B.Set(prescalingTop)
   241  			avr.ICR1H.Set(uint8(top >> 8))
   242  			avr.ICR1L.Set(uint8(top))
   243  		case 3:
   244  			avr.TCCR3A.Set(avr.TCCR3A_WGM31)
   245  			avr.TCCR3B.Set(prescalingTop)
   246  			avr.ICR3H.Set(uint8(top >> 8))
   247  			avr.ICR3L.Set(uint8(top))
   248  		case 4:
   249  			avr.TCCR4A.Set(avr.TCCR4A_WGM41)
   250  			avr.TCCR4B.Set(prescalingTop)
   251  			avr.ICR4H.Set(uint8(top >> 8))
   252  			avr.ICR4L.Set(uint8(top))
   253  		case 5:
   254  			avr.TCCR5A.Set(avr.TCCR5A_WGM51)
   255  			avr.TCCR5B.Set(prescalingTop)
   256  			avr.ICR5H.Set(uint8(top >> 8))
   257  			avr.ICR5L.Set(uint8(top))
   258  		}
   259  	}
   260  	return nil
   261  }
   262  
   263  // SetPeriod updates the period of this PWM peripheral.
   264  // To set a particular frequency, use the following formula:
   265  //
   266  //	period = 1e9 / frequency
   267  //
   268  // If you use a period of 0, a period that works well for LEDs will be picked.
   269  //
   270  // SetPeriod will not change the prescaler, but also won't change the current
   271  // value in any of the channels. This means that you may need to update the
   272  // value for the particular channel.
   273  //
   274  // Note that you cannot pick any arbitrary period after the PWM peripheral has
   275  // been configured. If you want to switch between frequencies, pick the lowest
   276  // frequency (longest period) once when calling Configure and adjust the
   277  // frequency here as needed.
   278  func (pwm PWM) SetPeriod(period uint64) error {
   279  	if pwm.num == 0 || pwm.num == 2 {
   280  		return ErrPWMPeriodTooLong // TODO better error message
   281  	}
   282  
   283  	// The top value is the number of PWM ticks a PWM period takes. It is
   284  	// initially picked assuming an unlimited counter top and no PWM
   285  	// prescaler.
   286  	var top uint64
   287  	if period == 0 {
   288  		// Use a top appropriate for LEDs. Picking a relatively low period
   289  		// here (0xff) for consistency with the other timers.
   290  		top = 0xff
   291  	} else {
   292  		// The formula below calculates the following formula, optimized:
   293  		//     top = period * (CPUFrequency() / 1e9)
   294  		// By dividing the CPU frequency first (an operation that is easily
   295  		// optimized away) the period has less chance of overflowing.
   296  		top = period * (uint64(CPUFrequency()) / 1000000) / 1000
   297  	}
   298  
   299  	var prescaler uint8
   300  
   301  	switch pwm.num {
   302  	case 1:
   303  		prescaler = avr.TCCR1B.Get() & 0x7
   304  	case 3:
   305  		prescaler = avr.TCCR3B.Get() & 0x7
   306  	case 4:
   307  		prescaler = avr.TCCR4B.Get() & 0x7
   308  	case 5:
   309  		prescaler = avr.TCCR5B.Get() & 0x7
   310  	}
   311  
   312  	switch prescaler {
   313  	case 1:
   314  		top /= 1
   315  	case 2:
   316  		top /= 8
   317  	case 3:
   318  		top /= 64
   319  	case 4:
   320  		top /= 256
   321  	case 5:
   322  		top /= 1024
   323  	}
   324  
   325  	// A top of 0x10000 is at 100% duty cycle. Subtract one because the counter
   326  	// counts from 0, not 1 (avoiding an off-by-one).
   327  	top -= 1
   328  
   329  	if top > 0xffff {
   330  		return ErrPWMPeriodTooLong
   331  	}
   332  
   333  	switch pwm.num {
   334  	case 1:
   335  		// Warning: this change is not atomic!
   336  		avr.ICR1H.Set(uint8(top >> 8))
   337  		avr.ICR1L.Set(uint8(top))
   338  
   339  		// ... and because of that, set the counter back to zero to avoid most of
   340  		// the effects of this non-atomicity.
   341  		avr.TCNT1H.Set(0)
   342  		avr.TCNT1L.Set(0)
   343  	case 3:
   344  		// Warning: this change is not atomic!
   345  		avr.ICR3H.Set(uint8(top >> 8))
   346  		avr.ICR3L.Set(uint8(top))
   347  
   348  		// ... and because of that, set the counter back to zero to avoid most of
   349  		// the effects of this non-atomicity.
   350  		avr.TCNT3H.Set(0)
   351  		avr.TCNT3L.Set(0)
   352  	case 4:
   353  		// Warning: this change is not atomic!
   354  		avr.ICR4H.Set(uint8(top >> 8))
   355  		avr.ICR4L.Set(uint8(top))
   356  
   357  		// ... and because of that, set the counter back to zero to avoid most of
   358  		// the effects of this non-atomicity.
   359  		avr.TCNT4H.Set(0)
   360  		avr.TCNT4L.Set(0)
   361  	case 5:
   362  		// Warning: this change is not atomic!
   363  		avr.ICR5H.Set(uint8(top >> 8))
   364  		avr.ICR5L.Set(uint8(top))
   365  
   366  		// ... and because of that, set the counter back to zero to avoid most of
   367  		// the effects of this non-atomicity.
   368  		avr.TCNT5H.Set(0)
   369  		avr.TCNT5L.Set(0)
   370  	}
   371  
   372  	return nil
   373  }
   374  
   375  // Top returns the current counter top, for use in duty cycle calculation. It
   376  // will only change with a call to Configure or SetPeriod, otherwise it is
   377  // constant.
   378  //
   379  // The value returned here is hardware dependent. In general, it's best to treat
   380  // it as an opaque value that can be divided by some number and passed to Set
   381  // (see Set documentation for more information).
   382  func (pwm PWM) Top() uint32 {
   383  	switch pwm.num {
   384  	case 1:
   385  		// Timer 1 has a configurable top value.
   386  		low := avr.ICR1L.Get()
   387  		high := avr.ICR1H.Get()
   388  		return uint32(high)<<8 | uint32(low) + 1
   389  	case 3:
   390  		// Timer 3 has a configurable top value.
   391  		low := avr.ICR3L.Get()
   392  		high := avr.ICR3H.Get()
   393  		return uint32(high)<<8 | uint32(low) + 1
   394  	case 4:
   395  		// Timer 4 has a configurable top value.
   396  		low := avr.ICR4L.Get()
   397  		high := avr.ICR4H.Get()
   398  		return uint32(high)<<8 | uint32(low) + 1
   399  	case 5:
   400  		// Timer 5 has a configurable top value.
   401  		low := avr.ICR5L.Get()
   402  		high := avr.ICR5H.Get()
   403  		return uint32(high)<<8 | uint32(low) + 1
   404  	}
   405  
   406  	// Other timers go from 0 to 0xff (0x100 or 256 in total).
   407  	return 256
   408  }
   409  
   410  // Counter returns the current counter value of the timer in this PWM
   411  // peripheral. It may be useful for debugging.
   412  func (pwm PWM) Counter() uint32 {
   413  	switch pwm.num {
   414  	case 0:
   415  		return uint32(avr.TCNT0.Get())
   416  	case 1:
   417  		mask := interrupt.Disable()
   418  		low := avr.TCNT1L.Get()
   419  		high := avr.TCNT1H.Get()
   420  		interrupt.Restore(mask)
   421  		return uint32(high)<<8 | uint32(low)
   422  	case 2:
   423  		return uint32(avr.TCNT2.Get())
   424  	case 3:
   425  		mask := interrupt.Disable()
   426  		low := avr.TCNT3L.Get()
   427  		high := avr.TCNT3H.Get()
   428  		interrupt.Restore(mask)
   429  		return uint32(high)<<8 | uint32(low)
   430  	case 4:
   431  		mask := interrupt.Disable()
   432  		low := avr.TCNT4L.Get()
   433  		high := avr.TCNT4H.Get()
   434  		interrupt.Restore(mask)
   435  		return uint32(high)<<8 | uint32(low)
   436  	case 5:
   437  		mask := interrupt.Disable()
   438  		low := avr.TCNT5L.Get()
   439  		high := avr.TCNT5H.Get()
   440  		interrupt.Restore(mask)
   441  		return uint32(high)<<8 | uint32(low)
   442  	}
   443  
   444  	// Unknown PWM.
   445  	return 0
   446  }
   447  
   448  // Period returns the used PWM period in nanoseconds. It might deviate slightly
   449  // from the configured period due to rounding.
   450  func (pwm PWM) Period() uint64 {
   451  	var prescaler uint8
   452  	switch pwm.num {
   453  	case 0:
   454  		prescaler = avr.TCCR0B.Get() & 0x7
   455  	case 1:
   456  		prescaler = avr.TCCR1B.Get() & 0x7
   457  	case 2:
   458  		prescaler = avr.TCCR2B.Get() & 0x7
   459  	case 3:
   460  		prescaler = avr.TCCR3B.Get() & 0x7
   461  	case 4:
   462  		prescaler = avr.TCCR4B.Get() & 0x7
   463  	case 5:
   464  		prescaler = avr.TCCR5B.Get() & 0x7
   465  	}
   466  	top := uint64(pwm.Top())
   467  	switch prescaler {
   468  	case 1: // prescaler 1
   469  		return 1 * top * 1000 / uint64(CPUFrequency()/1e6)
   470  	case 2: // prescaler 8
   471  		return 8 * top * 1000 / uint64(CPUFrequency()/1e6)
   472  	case 3: // prescaler 64
   473  		return 64 * top * 1000 / uint64(CPUFrequency()/1e6)
   474  	case 4: // prescaler 256
   475  		return 256 * top * 1000 / uint64(CPUFrequency()/1e6)
   476  	case 5: // prescaler 1024
   477  		return 1024 * top * 1000 / uint64(CPUFrequency()/1e6)
   478  	default: // unknown clock source
   479  		return 0
   480  	}
   481  }
   482  
   483  // Channel returns a PWM channel for the given pin.
   484  func (pwm PWM) Channel(pin Pin) (uint8, error) {
   485  	pin.Configure(PinConfig{Mode: PinOutput})
   486  	pin.Low()
   487  	switch pwm.num {
   488  	case 0:
   489  		switch pin {
   490  		case PB7: // channel A
   491  			avr.TCCR0A.SetBits(avr.TCCR0A_COM0A1)
   492  			return 0, nil
   493  		case PG5: // channel B
   494  			avr.TCCR0A.SetBits(avr.TCCR0A_COM0B1)
   495  			return 1, nil
   496  		}
   497  	case 1:
   498  		switch pin {
   499  		case PB5: // channel A
   500  			avr.TCCR1A.SetBits(avr.TCCR1A_COM1A1)
   501  			return 0, nil
   502  		case PB6: // channel B
   503  			avr.TCCR1A.SetBits(avr.TCCR1A_COM1B1)
   504  			return 1, nil
   505  		}
   506  	case 2:
   507  		switch pin {
   508  		case PB4: // channel A
   509  			avr.TCCR2A.SetBits(avr.TCCR2A_COM2A1)
   510  			return 0, nil
   511  		case PH6: // channel B
   512  			avr.TCCR2A.SetBits(avr.TCCR2A_COM2B1)
   513  			return 1, nil
   514  		}
   515  	case 3:
   516  		switch pin {
   517  		case PE3: // channel A
   518  			avr.TCCR3A.SetBits(avr.TCCR3A_COM3A1)
   519  			return 0, nil
   520  		case PE4: //channel B
   521  			avr.TCCR3A.SetBits(avr.TCCR3A_COM3B1)
   522  			return 1, nil
   523  		case PE5: //channel C
   524  			avr.TCCR3A.SetBits(avr.TCCR3A_COM3C1)
   525  			return 2, nil
   526  		}
   527  	case 4:
   528  		switch pin {
   529  		case PH3: // channel A
   530  			avr.TCCR4A.SetBits(avr.TCCR4A_COM4A1)
   531  			return 0, nil
   532  		case PH4: //channel B
   533  			avr.TCCR4A.SetBits(avr.TCCR4A_COM4B1)
   534  			return 1, nil
   535  		case PH5: //channel C
   536  			avr.TCCR4A.SetBits(avr.TCCR4A_COM4C1)
   537  			return 2, nil
   538  		}
   539  	case 5:
   540  		switch pin {
   541  		case PL3: // channel A
   542  			avr.TCCR5A.SetBits(avr.TCCR5A_COM5A1)
   543  			return 0, nil
   544  		case PL4: //channel B
   545  			avr.TCCR5A.SetBits(avr.TCCR5A_COM5B1)
   546  			return 1, nil
   547  		case PL5: //channel C
   548  			avr.TCCR5A.SetBits(avr.TCCR5A_COM5C1)
   549  			return 2, nil
   550  		}
   551  	}
   552  	return 0, ErrInvalidOutputPin
   553  }
   554  
   555  // SetInverting sets whether to invert the output of this channel.
   556  // Without inverting, a 25% duty cycle would mean the output is high for 25% of
   557  // the time and low for the rest. Inverting flips the output as if a NOT gate
   558  // was placed at the output, meaning that the output would be 25% low and 75%
   559  // high with a duty cycle of 25%.
   560  //
   561  // Note: the invert state may not be applied on the AVR until the next call to
   562  // ch.Set().
   563  func (pwm PWM) SetInverting(channel uint8, inverting bool) {
   564  	switch pwm.num {
   565  	case 0:
   566  		switch channel {
   567  		case 0: // channel A, PB7
   568  			if inverting {
   569  				avr.PORTB.SetBits(1 << 7) // PB7 high
   570  				avr.TCCR0A.SetBits(avr.TCCR0A_COM0A0)
   571  			} else {
   572  				avr.PORTB.ClearBits(1 << 7) // PB7 low
   573  				avr.TCCR0A.ClearBits(avr.TCCR0A_COM0A0)
   574  			}
   575  		case 1: // channel B, PG5
   576  			if inverting {
   577  				avr.PORTG.SetBits(1 << 5) // PG5 high
   578  				avr.TCCR0A.SetBits(avr.TCCR0A_COM0B0)
   579  			} else {
   580  				avr.PORTG.ClearBits(1 << 5) // PG5 low
   581  				avr.TCCR0A.ClearBits(avr.TCCR0A_COM0B0)
   582  			}
   583  		}
   584  	case 1:
   585  		// Note: the COM1A0/COM1B0 bit is not set with the configuration below.
   586  		// It will be set the following call to Set(), however.
   587  		switch channel {
   588  		case 0: // channel A, PB5
   589  			if inverting {
   590  				avr.PORTB.SetBits(1 << 5) // PB5 high
   591  			} else {
   592  				avr.PORTB.ClearBits(1 << 5) // PB5 low
   593  			}
   594  		case 1: // channel B, PB6
   595  			if inverting {
   596  				avr.PORTB.SetBits(1 << 6) // PB6 high
   597  			} else {
   598  				avr.PORTB.ClearBits(1 << 6) // PB6 low
   599  			}
   600  		}
   601  	case 2:
   602  		switch channel {
   603  		case 0: // channel A, PB4
   604  			if inverting {
   605  				avr.PORTB.SetBits(1 << 4) // PB4 high
   606  				avr.TCCR2A.SetBits(avr.TCCR2A_COM2A0)
   607  			} else {
   608  				avr.PORTB.ClearBits(1 << 4) // PB4 low
   609  				avr.TCCR2A.ClearBits(avr.TCCR2A_COM2A0)
   610  			}
   611  		case 1: // channel B, PH6
   612  			if inverting {
   613  				avr.PORTH.SetBits(1 << 6) // PH6 high
   614  				avr.TCCR2A.SetBits(avr.TCCR2A_COM2B0)
   615  			} else {
   616  				avr.PORTH.ClearBits(1 << 6) // PH6 low
   617  				avr.TCCR2A.ClearBits(avr.TCCR2A_COM2B0)
   618  			}
   619  		}
   620  	case 3:
   621  		// Note: the COM3A0/COM3B0 bit is not set with the configuration below.
   622  		// It will be set the following call to Set(), however.
   623  		switch channel {
   624  		case 0: // channel A, PE3
   625  			if inverting {
   626  				avr.PORTE.SetBits(1 << 3) // PE3 high
   627  			} else {
   628  				avr.PORTE.ClearBits(1 << 3) // PE3 low
   629  			}
   630  		case 1: // channel B, PE4
   631  			if inverting {
   632  				avr.PORTE.SetBits(1 << 4) // PE4 high
   633  			} else {
   634  				avr.PORTE.ClearBits(1 << 4) // PE4 low
   635  			}
   636  		case 2: // channel C, PE5
   637  			if inverting {
   638  				avr.PORTE.SetBits(1 << 5) // PE4 high
   639  			} else {
   640  				avr.PORTE.ClearBits(1 << 5) // PE4 low
   641  			}
   642  		}
   643  	case 4:
   644  		// Note: the COM3A0/COM3B0 bit is not set with the configuration below.
   645  		// It will be set the following call to Set(), however.
   646  		switch channel {
   647  		case 0: // channel A, PH3
   648  			if inverting {
   649  				avr.PORTH.SetBits(1 << 3) // PH3 high
   650  			} else {
   651  				avr.PORTH.ClearBits(1 << 3) // PH3 low
   652  			}
   653  		case 1: // channel B, PH4
   654  			if inverting {
   655  				avr.PORTH.SetBits(1 << 4) // PH4 high
   656  			} else {
   657  				avr.PORTH.ClearBits(1 << 4) // PH4 low
   658  			}
   659  		case 2: // channel C, PH5
   660  			if inverting {
   661  				avr.PORTH.SetBits(1 << 5) // PH4 high
   662  			} else {
   663  				avr.PORTH.ClearBits(1 << 5) // PH4 low
   664  			}
   665  		}
   666  	case 5:
   667  		// Note: the COM3A0/COM3B0 bit is not set with the configuration below.
   668  		// It will be set the following call to Set(), however.
   669  		switch channel {
   670  		case 0: // channel A, PL3
   671  			if inverting {
   672  				avr.PORTL.SetBits(1 << 3) // PL3 high
   673  			} else {
   674  				avr.PORTL.ClearBits(1 << 3) // PL3 low
   675  			}
   676  		case 1: // channel B, PL4
   677  			if inverting {
   678  				avr.PORTL.SetBits(1 << 4) // PL4 high
   679  			} else {
   680  				avr.PORTL.ClearBits(1 << 4) // PL4 low
   681  			}
   682  		case 2: // channel C, PH5
   683  			if inverting {
   684  				avr.PORTL.SetBits(1 << 5) // PL4 high
   685  			} else {
   686  				avr.PORTL.ClearBits(1 << 5) // PL4 low
   687  			}
   688  		}
   689  	}
   690  }
   691  
   692  // Set updates the channel value. This is used to control the channel duty
   693  // cycle, in other words the fraction of time the channel output is high (or low
   694  // when inverted). For example, to set it to a 25% duty cycle, use:
   695  //
   696  //	pwm.Set(channel, pwm.Top() / 4)
   697  //
   698  // pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
   699  // pwm.Top()) will set the output to high, assuming the output isn't inverted.
   700  func (pwm PWM) Set(channel uint8, value uint32) {
   701  	switch pwm.num {
   702  	case 0:
   703  		value := uint16(value)
   704  		switch channel {
   705  		case 0: // channel A
   706  			if value == 0 {
   707  				avr.TCCR0A.ClearBits(avr.TCCR0A_COM0A1)
   708  			} else {
   709  				avr.OCR0A.Set(uint8(value - 1))
   710  				avr.TCCR0A.SetBits(avr.TCCR0A_COM0A1)
   711  			}
   712  		case 1: // channel B
   713  			if value == 0 {
   714  				avr.TCCR0A.ClearBits(avr.TCCR0A_COM0B1)
   715  			} else {
   716  				avr.OCR0B.Set(uint8(value) - 1)
   717  				avr.TCCR0A.SetBits(avr.TCCR0A_COM0B1)
   718  			}
   719  		}
   720  		// monotonic timer is using the same time as PWM:0
   721  		// we must adust internal settings of monotonic timer when PWM:0 settings changed
   722  		adjustMonotonicTimer()
   723  	case 1:
   724  		mask := interrupt.Disable()
   725  		switch channel {
   726  		case 0: // channel A, PB5
   727  			if value == 0 {
   728  				avr.TCCR1A.ClearBits(avr.TCCR1A_COM1A1 | avr.TCCR1A_COM1A0)
   729  			} else {
   730  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   731  				avr.OCR1AH.Set(uint8(value >> 8))
   732  				avr.OCR1AL.Set(uint8(value))
   733  				if avr.PORTB.HasBits(1 << 5) { // is PB1 high?
   734  					// Yes, set the inverting bit.
   735  					avr.TCCR1A.SetBits(avr.TCCR1A_COM1A1 | avr.TCCR1A_COM1A0)
   736  				} else {
   737  					// No, output is non-inverting.
   738  					avr.TCCR1A.SetBits(avr.TCCR1A_COM1A1)
   739  				}
   740  			}
   741  		case 1: // channel B, PB6
   742  			if value == 0 {
   743  				avr.TCCR1A.ClearBits(avr.TCCR1A_COM1B1 | avr.TCCR1A_COM1B0)
   744  			} else {
   745  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   746  				avr.OCR1BH.Set(uint8(value >> 8))
   747  				avr.OCR1BL.Set(uint8(value))
   748  				if avr.PORTB.HasBits(1 << 6) { // is PB6 high?
   749  					// Yes, set the inverting bit.
   750  					avr.TCCR1A.SetBits(avr.TCCR1A_COM1B1 | avr.TCCR1A_COM1B0)
   751  				} else {
   752  					// No, output is non-inverting.
   753  					avr.TCCR1A.SetBits(avr.TCCR1A_COM1B1)
   754  				}
   755  			}
   756  		}
   757  		interrupt.Restore(mask)
   758  	case 2:
   759  		value := uint16(value)
   760  		switch channel {
   761  		case 0: // channel A
   762  			if value == 0 {
   763  				avr.TCCR2A.ClearBits(avr.TCCR2A_COM2A1)
   764  			} else {
   765  				avr.OCR2A.Set(uint8(value - 1))
   766  				avr.TCCR2A.SetBits(avr.TCCR2A_COM2A1)
   767  			}
   768  		case 1: // channel B
   769  			if value == 0 {
   770  				avr.TCCR2A.ClearBits(avr.TCCR2A_COM2B1)
   771  			} else {
   772  				avr.OCR2B.Set(uint8(value - 1))
   773  				avr.TCCR2A.SetBits(avr.TCCR2A_COM2B1)
   774  			}
   775  		}
   776  	case 3:
   777  		mask := interrupt.Disable()
   778  		switch channel {
   779  		case 0: // channel A, PE3
   780  			if value == 0 {
   781  				avr.TCCR3A.ClearBits(avr.TCCR3A_COM3A1 | avr.TCCR3A_COM3A0)
   782  			} else {
   783  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   784  				avr.OCR3AH.Set(uint8(value >> 8))
   785  				avr.OCR3AL.Set(uint8(value))
   786  				if avr.PORTE.HasBits(1 << 3) { // is PE3 high?
   787  					// Yes, set the inverting bit.
   788  					avr.TCCR3A.SetBits(avr.TCCR3A_COM3A1 | avr.TCCR3A_COM3A0)
   789  				} else {
   790  					// No, output is non-inverting.
   791  					avr.TCCR3A.SetBits(avr.TCCR3A_COM3A1)
   792  				}
   793  			}
   794  		case 1: // channel B, PE4
   795  			if value == 0 {
   796  				avr.TCCR3A.ClearBits(avr.TCCR3A_COM3B1 | avr.TCCR3A_COM3B0)
   797  			} else {
   798  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   799  				avr.OCR3BH.Set(uint8(value >> 8))
   800  				avr.OCR3BL.Set(uint8(value))
   801  				if avr.PORTE.HasBits(1 << 4) { // is PE4 high?
   802  					// Yes, set the inverting bit.
   803  					avr.TCCR3A.SetBits(avr.TCCR3A_COM3B1 | avr.TCCR3A_COM3B0)
   804  				} else {
   805  					// No, output is non-inverting.
   806  					avr.TCCR3A.SetBits(avr.TCCR3A_COM3B1)
   807  				}
   808  			}
   809  		case 2: // channel C, PE5
   810  			if value == 0 {
   811  				avr.TCCR3A.ClearBits(avr.TCCR3A_COM3C1 | avr.TCCR3A_COM3C0)
   812  			} else {
   813  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   814  				avr.OCR3CH.Set(uint8(value >> 8))
   815  				avr.OCR3CL.Set(uint8(value))
   816  				if avr.PORTE.HasBits(1 << 5) { // is PE5 high?
   817  					// Yes, set the inverting bit.
   818  					avr.TCCR3A.SetBits(avr.TCCR3A_COM3C1 | avr.TCCR3A_COM3C0)
   819  				} else {
   820  					// No, output is non-inverting.
   821  					avr.TCCR3A.SetBits(avr.TCCR3A_COM3C1)
   822  				}
   823  			}
   824  		}
   825  		interrupt.Restore(mask)
   826  	case 4:
   827  		mask := interrupt.Disable()
   828  		switch channel {
   829  		case 0: // channel A, PH3
   830  			if value == 0 {
   831  				avr.TCCR4A.ClearBits(avr.TCCR4A_COM4A1 | avr.TCCR4A_COM4A0)
   832  			} else {
   833  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   834  				avr.OCR4AH.Set(uint8(value >> 8))
   835  				avr.OCR4AL.Set(uint8(value))
   836  				if avr.PORTH.HasBits(1 << 3) { // is PH3 high?
   837  					// Yes, set the inverting bit.
   838  					avr.TCCR4A.SetBits(avr.TCCR4A_COM4A1 | avr.TCCR4A_COM4A0)
   839  				} else {
   840  					// No, output is non-inverting.
   841  					avr.TCCR4A.SetBits(avr.TCCR4A_COM4A1)
   842  				}
   843  			}
   844  		case 1: // channel B, PH4
   845  			if value == 0 {
   846  				avr.TCCR4A.ClearBits(avr.TCCR4A_COM4B1 | avr.TCCR4A_COM4B0)
   847  			} else {
   848  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   849  				avr.OCR4BH.Set(uint8(value >> 8))
   850  				avr.OCR4BL.Set(uint8(value))
   851  				if avr.PORTH.HasBits(1 << 4) { // is PH4 high?
   852  					// Yes, set the inverting bit.
   853  					avr.TCCR4A.SetBits(avr.TCCR4A_COM4B1 | avr.TCCR4A_COM4B0)
   854  				} else {
   855  					// No, output is non-inverting.
   856  					avr.TCCR4A.SetBits(avr.TCCR4A_COM4B1)
   857  				}
   858  			}
   859  		case 2: // channel C, PH5
   860  			if value == 0 {
   861  				avr.TCCR4A.ClearBits(avr.TCCR4A_COM4C1 | avr.TCCR4A_COM4C0)
   862  			} else {
   863  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   864  				avr.OCR4CH.Set(uint8(value >> 8))
   865  				avr.OCR4CL.Set(uint8(value))
   866  				if avr.PORTH.HasBits(1 << 5) { // is PH5 high?
   867  					// Yes, set the inverting bit.
   868  					avr.TCCR4A.SetBits(avr.TCCR4A_COM4C1 | avr.TCCR4A_COM4C0)
   869  				} else {
   870  					// No, output is non-inverting.
   871  					avr.TCCR4A.SetBits(avr.TCCR4A_COM4C1)
   872  				}
   873  			}
   874  		}
   875  		interrupt.Restore(mask)
   876  	case 5:
   877  		mask := interrupt.Disable()
   878  		switch channel {
   879  		case 0: // channel A, PL3
   880  			if value == 0 {
   881  				avr.TCCR5A.ClearBits(avr.TCCR5A_COM5A1 | avr.TCCR5A_COM5A0)
   882  			} else {
   883  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   884  				avr.OCR5AH.Set(uint8(value >> 8))
   885  				avr.OCR5AL.Set(uint8(value))
   886  				if avr.PORTL.HasBits(1 << 3) { // is PL3 high?
   887  					// Yes, set the inverting bit.
   888  					avr.TCCR5A.SetBits(avr.TCCR5A_COM5A1 | avr.TCCR5A_COM5A0)
   889  				} else {
   890  					// No, output is non-inverting.
   891  					avr.TCCR5A.SetBits(avr.TCCR5A_COM5A1)
   892  				}
   893  			}
   894  		case 1: // channel B, PL4
   895  			if value == 0 {
   896  				avr.TCCR5A.ClearBits(avr.TCCR5A_COM5B1 | avr.TCCR5A_COM5B0)
   897  			} else {
   898  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   899  				avr.OCR5BH.Set(uint8(value >> 8))
   900  				avr.OCR5BL.Set(uint8(value))
   901  				if avr.PORTL.HasBits(1 << 4) { // is PL4 high?
   902  					// Yes, set the inverting bit.
   903  					avr.TCCR5A.SetBits(avr.TCCR5A_COM5B1 | avr.TCCR5A_COM5B0)
   904  				} else {
   905  					// No, output is non-inverting.
   906  					avr.TCCR5A.SetBits(avr.TCCR5A_COM5B1)
   907  				}
   908  			}
   909  		case 2: // channel C, PL5
   910  			if value == 0 {
   911  				avr.TCCR5A.ClearBits(avr.TCCR5A_COM5C1 | avr.TCCR5A_COM5C0)
   912  			} else {
   913  				value := uint16(value) - 1 // yes, this is safe (it relies on underflow)
   914  				avr.OCR5CH.Set(uint8(value >> 8))
   915  				avr.OCR5CL.Set(uint8(value))
   916  				if avr.PORTL.HasBits(1 << 5) { // is PL5 high?
   917  					// Yes, set the inverting bit.
   918  					avr.TCCR5A.SetBits(avr.TCCR5A_COM5C1 | avr.TCCR5A_COM5C0)
   919  				} else {
   920  					// No, output is non-inverting.
   921  					avr.TCCR5A.SetBits(avr.TCCR5A_COM5C1)
   922  				}
   923  			}
   924  		}
   925  		interrupt.Restore(mask)
   926  	}
   927  }
   928  
   929  // SPI configuration
   930  var SPI0 = SPI{
   931  	spcr: avr.SPCR,
   932  	spdr: avr.SPDR,
   933  	spsr: avr.SPSR,
   934  	sck:  PB1,
   935  	sdo:  PB2,
   936  	sdi:  PB3,
   937  	cs:   PB0}