-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Steven Pearson
committed
Dec 11, 2021
1 parent
114e248
commit f71cb78
Showing
3 changed files
with
219 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package main | ||
|
||
import ( | ||
"machine" | ||
"time" | ||
|
||
"tinygo.org/x/drivers/xpt2046" | ||
) | ||
|
||
func main() { | ||
|
||
clk := machine.GPIO0 | ||
cs := machine.GPIO1 | ||
din := machine.GPIO2 | ||
dout := machine.GPIO3 | ||
irq := machine.GPIO4 | ||
precision := uint8(10) //Maximum number of samples for a single ReadTouchPoint to improve accuracy. | ||
|
||
touchScreen := xpt2046.New(clk, cs, din, dout, irq, precision) | ||
|
||
touchScreen.Configure() | ||
|
||
for { | ||
|
||
//Wait for a touch | ||
for !touchScreen.Touched() { | ||
time.Sleep(50 * time.Millisecond) | ||
} | ||
|
||
touch := touchScreen.ReadTouchPoint() | ||
//X and Y are 12 bit (0-4096) and need to be scaled for the display size | ||
//Z is 24 bit and is typically > 2000 for a touch | ||
println("touch:", touch.X, touch.Y, touch.Z) | ||
//Example of scaling for a 240x320 display | ||
println("screen:", (touch.X*240)>>12, (touch.Y*320)>>12) | ||
|
||
//Wait for touch to end | ||
for touchScreen.Touched() { | ||
time.Sleep(50 * time.Millisecond) | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// Package xpt2046 implements a driver for the XPT2046 resistive touch controller as packaged on the TFT_320QVT board | ||
// | ||
// Datasheet: http://grobotronics.com/images/datasheets/xpt2046-datasheed.pdf | ||
package xpt2046 | ||
|
||
import ( | ||
"machine" | ||
"time" | ||
|
||
"tinygo.org/x/drivers/touch" | ||
) | ||
|
||
type Device struct { | ||
t_clk machine.Pin | ||
t_cs machine.Pin | ||
t_din machine.Pin | ||
t_dout machine.Pin | ||
t_irq machine.Pin | ||
|
||
precision uint8 | ||
} | ||
|
||
func New(t_clk, t_cs, t_din, t_dout, t_irq machine.Pin, precision uint8) Device { | ||
return Device{ | ||
precision: precision, | ||
|
||
t_clk: t_clk, | ||
t_cs: t_cs, | ||
t_din: t_din, | ||
t_dout: t_dout, | ||
t_irq: t_irq, | ||
} | ||
} | ||
|
||
func (d *Device) Configure() { | ||
d.t_clk.Configure(machine.PinConfig{Mode: machine.PinOutput}) | ||
d.t_cs.Configure(machine.PinConfig{Mode: machine.PinOutput}) | ||
d.t_din.Configure(machine.PinConfig{Mode: machine.PinOutput}) | ||
|
||
d.t_dout.Configure(machine.PinConfig{Mode: machine.PinInput}) | ||
d.t_irq.Configure(machine.PinConfig{Mode: machine.PinInput}) | ||
|
||
d.t_clk.Low() | ||
d.t_cs.High() | ||
d.t_din.Low() | ||
|
||
d.readRaw() //Set Powerdown mode to enable T_IRQ | ||
} | ||
|
||
func busSleep() { | ||
time.Sleep(5 * time.Nanosecond) | ||
} | ||
|
||
func pulseHigh(p machine.Pin) { | ||
p.High() | ||
busSleep() | ||
p.Low() | ||
busSleep() | ||
} | ||
|
||
func (d *Device) writeCommand(data uint8) { | ||
|
||
for count := uint8(0); count < 8; count++ { | ||
d.t_din.Set((data & 0x80) != 0) | ||
data <<= 1 | ||
pulseHigh(d.t_clk) | ||
} | ||
|
||
} | ||
|
||
func (d *Device) readData() uint16 { | ||
|
||
data := uint16(0) | ||
|
||
for count := uint8(0); count < 12; count++ { | ||
data <<= 1 | ||
pulseHigh(d.t_clk) | ||
if d.t_dout.Get() { | ||
data |= 1 | ||
} | ||
} | ||
pulseHigh(d.t_clk) //13 | ||
pulseHigh(d.t_clk) //14 | ||
pulseHigh(d.t_clk) //15 | ||
pulseHigh(d.t_clk) //16 | ||
|
||
return data | ||
} | ||
|
||
func (d *Device) ReadTouchPoint() touch.Point { | ||
|
||
tx := uint32(0) | ||
ty := uint32(0) | ||
tz := uint32(0) | ||
sampleCount := uint8(0) | ||
|
||
d.t_cs.Low() | ||
|
||
for ; sampleCount < d.precision && d.Touched(); sampleCount++ { | ||
rx, ry, rz := d.readRaw() | ||
tx += uint32(rx) | ||
ty += uint32(ry) | ||
tz += uint32(rz) | ||
} | ||
d.t_cs.High() | ||
|
||
if sampleCount > 0 { | ||
x := int(tx / uint32(sampleCount)) | ||
y := int(ty / uint32(sampleCount)) | ||
z := int(tz / uint32(sampleCount)) | ||
return touch.Point{ | ||
X: x, | ||
Y: y, | ||
Z: z, | ||
} | ||
} else { | ||
return touch.Point{ | ||
X: 0, | ||
Y: 0, | ||
Z: 0, | ||
} | ||
} | ||
} | ||
|
||
func (d *Device) Touched() bool { | ||
avail := !d.t_irq.Get() | ||
return avail | ||
} | ||
|
||
func (d *Device) readRaw() (int32, int32, int32) { | ||
|
||
d.t_cs.Low() | ||
|
||
//S = 1 --> Required Control bit | ||
//A2-A0 = 001 --> Y-Position | ||
//MODE = 0 --> 12 bit conversion | ||
//SER/DFR = 0 --> Differential preferred for X,Y position | ||
//PD1-PD0 = 00 --> Powerdown and enable PEN_IRQ | ||
d.writeCommand(0x90) | ||
ty := d.readData() | ||
|
||
//S = 1 --> Required Control bit | ||
//A2-A0 = 101 --> X-Position | ||
//MODE = 0 --> 12 bit conversion | ||
//SER/DFR = 0 --> Differential preferred for X,Y position | ||
//PD1-PD0 = 00 --> Powerdown and enable PEN_IRQ | ||
d.writeCommand(0xD0) | ||
tx := d.readData() | ||
|
||
//S = 1 --> Required Control bit | ||
//A2-A0 = 011 --> Z1-position (pressure) | ||
//MODE = 0 --> 12 bit conversion | ||
//SER/DFR = 0 --> Differential preferred for pressure | ||
//PD1-PD0 = 00 --> Powerdown and enable PEN_IRQ | ||
d.writeCommand(0xB0) | ||
tz1 := int32(d.readData()) | ||
|
||
//S = 1 --> Required Control bit | ||
//A2-A0 = 100 --> Z2-position (pressure) | ||
//MODE = 0 --> 12 bit conversion | ||
//SER/DFR = 0 --> Differential preferred for pressure | ||
//PD1-PD0 = 00 --> Powerdown and enable PEN_IRQ | ||
d.writeCommand(0xC0) | ||
tz2 := int32(d.readData()) | ||
|
||
tz := int32(0) | ||
if tz1 != 0 { | ||
//Touch pressure is proportional to the ratio of z2 to z1 and the x position. | ||
tz = int32(tx) * ((tz2 << 12) / (tz1 << 12)) | ||
} | ||
|
||
d.t_cs.High() | ||
|
||
return int32(tx), int32(4096 - ty), tz | ||
} |