9#include "STM32BusIORegister.hpp"
16constexpr uint8_t kAddrSerTemp0 = 0b000;
17constexpr uint8_t kAddrSerVBat = 0b010;
18constexpr uint8_t kAddrSerAux = 0b110;
19constexpr uint8_t kAddrSerTemp1 = 0b111;
23constexpr uint8_t kAddrDfrYPos = 0b001;
24constexpr uint8_t kAddrDfrZ1Pos = 0b011;
25constexpr uint8_t kAddrDfrZ2Pos = 0b100;
26constexpr uint8_t kAddrDfrXPos = 0b101;
28constexpr float kInternalVRef = 2.5f;
41uint8_t buildControlByte(uint8_t channelSelect,
bool singleEndedRef,
bool enableInternalVRef,
bool enableOrIdleADC) {
43 word |=
static_cast<uint8_t
>((channelSelect & 0x07) << 4);
45 word |= singleEndedRef ? (1u << 2) : 0;
46 word |= enableInternalVRef ? (1u << 1) : 0;
47 word |= enableOrIdleADC ? (1u << 0) : 0;
54 : _spiDevice(hspi, csPort, csPin), _xPlateResistance(400), _vref(-1.f),
55 _touchedThreshold(100000.f), _interruptsEnabled(true) {
59 _xPlateResistance = xPlateResistance;
68 _touchedThreshold = touchedThresholdOhms;
71float TSC2046::effectiveVRef() {
72 return (_vref < 0.f) ? kInternalVRef : _vref;
75uint16_t TSC2046::extractTwelveBitValue(uint32_t registerValue) {
79 return static_cast<uint16_t
>((registerValue >> 3) & 0xFFF);
82uint16_t TSC2046::readCoord(uint8_t channelSelect) {
83 bool enableInternalVRef;
90 if (_interruptsEnabled) {
91 enableInternalVRef =
false;
92 enableOrIdleADC =
false;
94 enableInternalVRef =
true;
95 enableOrIdleADC =
true;
98 uint8_t controlByte = buildControlByte(channelSelect,
false, enableInternalVRef, enableOrIdleADC);
101 return extractTwelveBitValue(controlReg.read());
104uint16_t TSC2046::readExtra(uint8_t channelSelect) {
105 bool enableInternalVRef = !(_vref > 0.f);
106 bool enableOrIdleADC = !_interruptsEnabled;
108 uint8_t controlByte = buildControlByte(channelSelect,
true, enableInternalVRef, enableOrIdleADC);
111 return extractTwelveBitValue(controlReg.read());
115 if (_interruptsEnabled) {
119 int16_t xResult =
static_cast<int16_t
>(readCoord(kAddrDfrXPos));
120 int16_t yResult =
static_cast<int16_t
>(readCoord(kAddrDfrYPos));
121 int16_t z1Result =
static_cast<int16_t
>(readCoord(kAddrDfrZ1Pos));
122 int16_t z2Result =
static_cast<int16_t
>(readCoord(kAddrDfrZ2Pos));
124 if (_interruptsEnabled) {
129 float pressure = _xPlateResistance * (xResult / 4096.f) *
130 ((
static_cast<float>(z2Result) /
static_cast<float>(z1Result)) - 1.f);
135 point.pressure = pressure;
145 _interruptsEnabled = enable;
153 return readTemperatureKelvin() - 273.f;
160float TSC2046::readTemperatureKelvin() {
161 uint16_t temp0 = readExtra(kAddrSerTemp0);
162 uint16_t temp1 = readExtra(kAddrSerTemp1);
166 float deltaMillivolts = ((
static_cast<float>(temp1) -
static_cast<float>(temp0)) * effectiveVRef() / 4096.f) * 1000.f;
167 return deltaMillivolts * 2.573f;
171 constexpr float kVBatMultiplier = 4.f;
172 uint16_t rawVBat = readExtra(kAddrSerVBat);
173 return (rawVBat * kVBatMultiplier * effectiveVRef()) / 4096.f;
177 uint16_t rawVAux = readExtra(kAddrSerAux);
178 return (rawVAux * effectiveVRef()) / 4096.f;
Represents one addressable, read-only, MSB-first register accessed over an STM32SPIDevice,...
void begin()
Deasserts chip-select (idle-high) so the bus starts in a known state. Call once before the first tran...
float readTemperatureF()
Same reading as readTemperatureC(), converted to degrees Fahrenheit.
void setVRef(float vref)
Sets the voltage connected to the TSC2046's VRef pin, if any.
TSC2046(SPI_HandleTypeDef *hspi, GPIO_TypeDef *csPort, uint16_t csPin)
Constructs the driver and its underlying STM32SPIDevice. Does not touch hardware – call begin() befor...
float readAuxiliaryVoltage()
float readBatteryVoltage()
void enableInterrupts(bool enable)
Enables or disables the TSC2046's own touch interrupt (IRQ pin pulled low on touch)....
TSC2046TouchPoint getPoint()
Reads the current touch position and pressure.
bool isTouched()
Determines if the touchscreen is currently being touched, based on the pressure value from getPoint()...
void setTouchedThreshold(float touchedThresholdOhms)
Sets the pressure threshold used by isTouched().
float readTemperatureC()
Reads the TSC2046's on-die temperature sensor, in degrees Celsius.
void begin(uint32_t xPlateResistance=400)
Initializes the driver. Call once before any other method.
One touch reading: raw X/Y position and a pressure-proportional resistance value.
int16_t x
Raw 12-bit X coordinate (0-4095). Meaningless if not touched.