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 }