// Guarded because still unsure of how to deal with interrupt drivers. //go:build tinygo // Package ft6336 provides a driver for the FT6336 I2C Self-Capacitive touch // panel controller. // // Datasheet: https://focuslcds.com/content/FT6236.pdf package ft6336 import ( "machine" "tinygo.org/x/drivers" "tinygo.org/x/drivers/internal/legacy" "tinygo.org/x/drivers/touch" ) // Device wraps FT6336 I2C Self-Capacitive touch type Device struct { bus drivers.I2C buf []byte Address uint8 intPin machine.Pin } // New returns FT6336 device for the provided I2C bus using default address. func New(i2c drivers.I2C, intPin machine.Pin) *Device { return &Device{ bus: i2c, buf: make([]byte, 11), Address: Address, intPin: intPin, } } // Config contains settings for FT6636. type Config struct { } // Configure the FT6336 device. func (d *Device) Configure(config Config) error { d.write1Byte(0xA4, 0x00) d.intPin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) return nil } // SetGMode sets interrupt mode. // // 0x00 : Interrupt Polling mode // 0x01 : Interrupt Trigger mode (default) func (d *Device) SetGMode(v uint8) { d.write1Byte(RegGMode, v) } // GetGMode gets interrupt mode. func (d *Device) GetGMode() uint8 { return d.read8bit(RegGMode) } // SetPeriodActive sets report rate in Active mode. func (d *Device) SetPeriodActive(v uint8) { d.write1Byte(RegPeriodActive, v) } // GetPeriodActive gets report rate in Active mode. func (d *Device) GetPeriodActive() uint8 { return d.read8bit(RegPeriodActive) } // GetFirmwareID gets firmware version. func (d *Device) GetFirmwareID() uint8 { return d.read8bit(RegFirmid) } // Read reads the registers. func (d *Device) Read() []byte { d.bus.Tx(uint16(d.Address), []byte{0x02}, d.buf[:]) return d.buf[:] } // ReadTouchPoint reads a single touch.Point from the device. The maximum value // for each touch.Point is 0xFFFF. func (d *Device) ReadTouchPoint() touch.Point { d.Read() z := 0xFFFFF switch d.buf[0] { case 0, 255: z = 0 } //Scale X&Y to 16 bit for consistency across touch drivers return touch.Point{ X: (int(d.buf[1]&0x0F)<<8 + int(d.buf[2])) * ((1 << 16) / 320), Y: (int(d.buf[3]&0x0F)<<8 + int(d.buf[4])) * ((1 << 16) / 270), Z: z, } } // Touched returns if touched or not. func (d *Device) Touched() bool { p := d.ReadTouchPoint() return p.Z > 0 } func (d *Device) write1Byte(reg, data uint8) { legacy.WriteRegister(d.bus, d.Address, reg, []byte{data}) } func (d *Device) read8bit(reg uint8) uint8 { legacy.ReadRegister(d.bus, d.Address, reg, d.buf[:1]) return d.buf[0] }