diff --git a/src/machine/machine_atmega.go b/src/machine/machine_atmega.go index ed93fc3e..fef10a46 100644 --- a/src/machine/machine_atmega.go +++ b/src/machine/machine_atmega.go @@ -23,23 +23,6 @@ func (p GPIO) Configure(config GPIOConfig) { } } -// Set changes the value of the GPIO pin. The pin must be configured as output. -func (p GPIO) Set(value bool) { - if value { // set bits - if p.Pin < 8 { - *avr.PORTD |= 1 << p.Pin - } else { - *avr.PORTB |= 1 << (p.Pin - 8) - } - } else { // clear bits - if p.Pin < 8 { - *avr.PORTD &^= 1 << p.Pin - } else { - *avr.PORTB &^= 1 << (p.Pin - 8) - } - } -} - // Get returns the current value of a GPIO pin. func (p GPIO) Get() bool { if p.Pin < 8 { @@ -51,6 +34,14 @@ func (p GPIO) Get() bool { } } +func (p GPIO) getPortMask() (*avr.RegValue, uint8) { + if p.Pin < 8 { + return avr.PORTD, 1 << p.Pin + } else { + return avr.PORTB, 1 << (p.Pin - 8) + } +} + // InitPWM initializes the registers needed for PWM. func InitPWM() { // use waveform generation diff --git a/src/machine/machine_attiny.go b/src/machine/machine_attiny.go index eadcee2a..23ed589b 100644 --- a/src/machine/machine_attiny.go +++ b/src/machine/machine_attiny.go @@ -15,13 +15,8 @@ func (p GPIO) Configure(config GPIOConfig) { } } -// Set changes the value of the GPIO pin. The pin must be configured as output. -func (p GPIO) Set(value bool) { - if value { // set bits - *avr.PORTB |= 1 << p.Pin - } else { // clear bits - *avr.PORTB &^= 1 << p.Pin - } +func (p GPIO) getPortMask() (*avr.RegValue, uint8) { + return avr.PORTB, 1 << p.Pin } // Get returns the current value of a GPIO pin. diff --git a/src/machine/machine_avr.go b/src/machine/machine_avr.go index 5a6c4bab..c7a97622 100644 --- a/src/machine/machine_avr.go +++ b/src/machine/machine_avr.go @@ -13,6 +13,39 @@ const ( GPIO_OUTPUT ) +// Set changes the value of the GPIO pin. The pin must be configured as output. +func (p GPIO) Set(value bool) { + if value { // set bits + port, mask := p.PortMaskSet() + *port = mask + } else { // clear bits + port, mask := p.PortMaskClear() + *port = mask + } +} + +// Return the register and mask to enable a given GPIO pin. This can be used to +// implement bit-banged drivers. +// +// Warning: there are no separate pin set/clear registers on the AVR. The +// returned mask is only valid as long as no other pin in the same port has been +// changed. +func (p GPIO) PortMaskSet() (*avr.RegValue, avr.RegValue) { + port, mask := p.getPortMask() + return port, *port | avr.RegValue(mask) +} + +// Return the register and mask to disable a given port. This can be used to +// implement bit-banged drivers. +// +// Warning: there are no separate pin set/clear registers on the AVR. The +// returned mask is only valid as long as no other pin in the same port has been +// changed. +func (p GPIO) PortMaskClear() (*avr.RegValue, avr.RegValue) { + port, mask := p.getPortMask() + return port, *port &^ avr.RegValue(mask) +} + // InitADC initializes the registers needed for ADC. func InitADC() { // set a2d prescaler so we are inside the desired 50-200 KHz range at 16MHz.