tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/shifter/shifter.go (about) 1 // Package shifter is for 8bit shift register, most common are 74HC165 and 74165 2 package shifter // import "tinygo.org/x/drivers/shifter" 3 4 import ( 5 "errors" 6 "machine" 7 ) 8 9 const ( 10 EIGHT_BITS NumberBit = 8 11 SIXTEEN_BITS NumberBit = 16 12 THIRTYTWO_BITS NumberBit = 32 13 ) 14 15 type NumberBit int8 16 17 // Device holds the Pins. 18 type Device struct { 19 latch machine.Pin 20 clk machine.Pin 21 out machine.Pin 22 Pins []ShiftPin 23 bits NumberBit 24 } 25 26 // ShiftPin is the implementation of the ShiftPin interface. 27 type ShiftPin struct { 28 pin machine.Pin 29 d *Device 30 pressed bool 31 } 32 33 // New returns a new shifter driver given the correct pins. 34 func New(numBits NumberBit, latch, clk, out machine.Pin) Device { 35 return Device{ 36 latch: latch, 37 clk: clk, 38 out: out, 39 Pins: make([]ShiftPin, int(numBits)), 40 bits: numBits, 41 } 42 } 43 44 // Configure here just for interface compatibility. 45 func (d *Device) Configure() { 46 d.latch.Configure(machine.PinConfig{Mode: machine.PinOutput}) 47 d.clk.Configure(machine.PinConfig{Mode: machine.PinOutput}) 48 d.out.Configure(machine.PinConfig{Mode: machine.PinInput}) 49 for i := 0; i < int(d.bits); i++ { 50 d.Pins[i] = d.GetShiftPin(i) 51 } 52 } 53 54 // GetShiftPin returns an ShiftPin for a specific input. 55 func (d *Device) GetShiftPin(input int) ShiftPin { 56 return ShiftPin{pin: machine.Pin(input), d: d} 57 } 58 59 // Read8Input updates the internal pins' states and returns it as an uint8. 60 func (d *Device) Read8Input() (uint8, error) { 61 if d.bits != EIGHT_BITS { 62 return 0, errors.New("wrong amount of registers") 63 } 64 return uint8(d.readInput(EIGHT_BITS)), nil 65 } 66 67 // Read16Input updates the internal pins' states and returns it as an uint16. 68 func (d *Device) Read16Input() (uint16, error) { 69 if d.bits != SIXTEEN_BITS { 70 return 0, errors.New("wrong amount of registers") 71 } 72 return uint16(d.readInput(SIXTEEN_BITS)), nil 73 } 74 75 // Read32Input updates the internal pins' states and returns it as an uint32. 76 func (d *Device) Read32Input() (uint32, error) { 77 if d.bits != THIRTYTWO_BITS { 78 return 0, errors.New("wrong amount of registers") 79 } 80 return d.readInput(THIRTYTWO_BITS), nil 81 } 82 83 // Get the pin's state for a specific ShiftPin. 84 // Read{8|16|32}Input should be called before to update the state. Read{8|16|32}Input updates 85 // all the pins, no need to call it for each pin individually. 86 func (p ShiftPin) Get() bool { 87 return p.pressed 88 } 89 90 // Configure here just for interface compatibility. 91 func (p ShiftPin) Configure() { 92 } 93 94 // readInput reads howMany bits from the shift register and updates the internal pins' states. 95 func (d *Device) readInput(howMany NumberBit) uint32 { 96 d.latch.High() 97 var data uint32 98 for i := howMany - 1; i >= 0; i-- { 99 d.clk.Low() 100 if d.out.Get() { 101 data |= 1 << i 102 d.Pins[i].pressed = true 103 } else { 104 d.Pins[i].pressed = false 105 } 106 d.clk.High() 107 } 108 d.latch.Low() 109 return data 110 }