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

     1  // Package ttp229 is for the 16 keys or 8 keys touch pad detector IC
     2  // Datasheet (BSF version): https://www.sunrom.com/download/SUNROM-TTP229-BSF_V1.1_EN.pdf
     3  package ttp229 // import "tinygo.org/x/drivers/ttp229"
     4  
     5  import (
     6  	"time"
     7  
     8  	"machine"
     9  )
    10  
    11  // Device wraps a connection to a TTP229 device.
    12  type Device struct {
    13  	bus      Buser
    14  	keys     uint16
    15  	prevKeys uint16
    16  	inputs   byte
    17  }
    18  
    19  // PinBus holds the structure for GPIO protocol
    20  type PinBus struct {
    21  	scl machine.Pin
    22  	sdo machine.Pin
    23  }
    24  
    25  // Buser interface since there are different versions with different protocols
    26  type Buser interface {
    27  	readBits(data byte) uint16
    28  }
    29  
    30  // Configuration
    31  type Configuration struct {
    32  	Inputs byte
    33  }
    34  
    35  // NewPin creates a new TTP229 connection through 2 machine.Pin, this is suitable for the BSF variant of the TTP229.
    36  func NewPin(scl, sdo machine.Pin) Device {
    37  	scl.Configure(machine.PinConfig{Mode: machine.PinOutput})
    38  	sdo.Configure(machine.PinConfig{Mode: machine.PinInput})
    39  	return Device{
    40  		bus: &PinBus{
    41  			scl: scl,
    42  			sdo: sdo,
    43  		},
    44  		inputs: 16,
    45  	}
    46  }
    47  
    48  // Configure sets up the device for communication
    49  func (d *Device) Configure(cfg Configuration) bool {
    50  	if cfg.Inputs != 0 {
    51  		d.inputs = cfg.Inputs
    52  	}
    53  	return true
    54  }
    55  
    56  // ReadKeys returns the pressed keys as bits of a uint16
    57  func (d *Device) ReadKeys() uint16 {
    58  	d.prevKeys = d.keys
    59  	d.keys = d.bus.readBits(d.inputs)
    60  	return d.keys
    61  }
    62  
    63  // bitRead return if the specific bit is on/off of the given uint16
    64  func (d *Device) bitRead(number uint16, bit byte) bool {
    65  	return (number & (0x0001 << bit)) != 0
    66  }
    67  
    68  // GetKey returns the current pressed key (only returns one key, even in multitouch mode)
    69  func (d *Device) GetKey() int8 {
    70  	for i := byte(0); i < d.inputs; i++ {
    71  		if !d.bitRead(d.keys, byte(i)) {
    72  			return int8(i)
    73  		}
    74  	}
    75  	return -1
    76  }
    77  
    78  // IsKeyPressed returns true if the given key is pressed
    79  func (d *Device) IsKeyPressed(key byte) bool {
    80  	return !d.bitRead(d.keys, key)
    81  }
    82  
    83  // IsKeyDown returns true if the given key was just pressed (and it wasn't previously)
    84  func (d *Device) IsKeyDown(key byte) bool {
    85  	return d.bitRead(d.prevKeys, key) && !d.bitRead(d.keys, key)
    86  }
    87  
    88  // IsKeyUp returns true if the given key was released
    89  func (d *Device) IsKeyUp(key byte) bool {
    90  	return !d.bitRead(d.prevKeys, key) && d.bitRead(d.keys, key)
    91  }
    92  
    93  // readBits returns the pressed keys as bits of a uint16
    94  func (b *PinBus) readBits(inputs byte) uint16 {
    95  	b.scl.High()
    96  	time.Sleep(1 * time.Millisecond)
    97  	var pressed uint16
    98  	for i := byte(0); i < inputs; i++ {
    99  		b.scl.Low()
   100  		time.Sleep(1 * time.Millisecond)
   101  		if b.sdo.Get() {
   102  			pressed = pressed | (0x0001 << i)
   103  		}
   104  		b.scl.High()
   105  		time.Sleep(1 * time.Millisecond)
   106  	}
   107  	time.Sleep(1 * time.Millisecond)
   108  	return pressed
   109  }