tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/shiftregister/shiftregister.go (about)

     1  // Package shiftregister is for 8bit shift output register using 3 GPIO pins like SN74ALS164A, SN74AHC594, SN74AHC595, ...
     2  package shiftregister
     3  
     4  import (
     5  	"machine"
     6  )
     7  
     8  type NumberBit int8
     9  
    10  // Bit number of the register
    11  const (
    12  	EIGHT_BITS     NumberBit = 8
    13  	SIXTEEN_BITS   NumberBit = 16
    14  	THIRTYTWO_BITS NumberBit = 32
    15  )
    16  
    17  // Device holds pin number
    18  type Device struct {
    19  	latch, clock, out machine.Pin // IC wiring
    20  	bits              NumberBit   // Pin number
    21  	mask              uint32      // keep all pins state
    22  }
    23  
    24  // ShiftPin is the implementation of the ShiftPin interface.
    25  // ShiftPin provide an interface like regular machine.Pin
    26  type ShiftPin struct {
    27  	mask uint32  // Bit representing the pin
    28  	d    *Device // Reference to the register
    29  }
    30  
    31  // New returns a new shift output register device
    32  func New(Bits NumberBit, Latch, Clock, Out machine.Pin) *Device {
    33  	return &Device{
    34  		latch: Latch,
    35  		clock: Clock,
    36  		out:   Out,
    37  		bits:  Bits,
    38  	}
    39  }
    40  
    41  // Configure set hardware configuration
    42  func (d *Device) Configure() {
    43  	d.latch.Configure(machine.PinConfig{Mode: machine.PinOutput})
    44  	d.clock.Configure(machine.PinConfig{Mode: machine.PinOutput})
    45  	d.out.Configure(machine.PinConfig{Mode: machine.PinOutput})
    46  	d.latch.High()
    47  }
    48  
    49  // WriteMask applies mask's bits to register's outputs pin
    50  // mask's MSB set Q1, LSB set Q8 (for 8 bits mask)
    51  func (d *Device) WriteMask(mask uint32) {
    52  	d.mask = mask // Keep the mask for individual addressing
    53  	d.latch.Low()
    54  	for i := 0; i < int(d.bits); i++ {
    55  		d.clock.Low()
    56  		d.out.Set(mask&1 != 0)
    57  		mask = mask >> 1
    58  		d.clock.High()
    59  	}
    60  	d.latch.High()
    61  }
    62  
    63  // GetShiftPin return an individually addressable pin
    64  func (d *Device) GetShiftPin(pin int) *ShiftPin {
    65  	if pin < 0 || pin > int(d.bits) {
    66  		panic("invalid pin number")
    67  	}
    68  	return &ShiftPin{
    69  		mask: 1 << pin,
    70  		d:    d,
    71  	}
    72  
    73  }
    74  
    75  // Set changes the value of this register pin.
    76  func (p ShiftPin) Set(value bool) {
    77  	d := p.d
    78  	if value {
    79  		d.WriteMask(d.mask | p.mask)
    80  	} else {
    81  		d.WriteMask(d.mask & ^p.mask)
    82  	}
    83  }
    84  
    85  // High sets this shift register pin to high.
    86  func (p ShiftPin) High() {
    87  	p.Set(true)
    88  }
    89  
    90  // Low sets this shift register pin to low.
    91  func (p ShiftPin) Low() {
    92  	p.Set(false)
    93  }