mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-31 06:36:33 +00:00
One more ISR improvement
This commit is contained in:
parent
2426dbf8e5
commit
11921eb928
@ -49,13 +49,41 @@
|
||||
|
||||
Timing of an ALL OFF frame in clock cycles T=377µs, triggering on rising edge:
|
||||
IDLE-2222444422224444-IDLE
|
||||
|
||||
*********************
|
||||
* About this driver *
|
||||
*********************
|
||||
|
||||
This driver implements the reverse engineered protocol of the FTC532 touch controller.
|
||||
The protocol encodes the bitmap of touched keys in variable length pulses comprising a
|
||||
fixed length frame. These frames are then sent out continuously from the FTC532 chip.
|
||||
The first version of this driver was working fine on well behaved hardware. After being
|
||||
released to the field and installed on crappy hardware in noisy environments it developed
|
||||
a habit of random 'ghost' switchings at night, much to the chagrin of some users.
|
||||
This is almost a re-write containing a lot more timing (and other) checks in order to
|
||||
detect and mitigate various incarnations of noise.
|
||||
If you should still experience 'ghost switching' issues a solution may be increasing
|
||||
FTC532_DEBOUNCE to 2 or higher. That will enable the de-bouncing code, at the expense of
|
||||
'snappiness' of touch reactions. Higher values will accumulate more samples in 50 ms steps
|
||||
before actually firing the rules trigger. It will eat a few bytes off your RAM and Flash
|
||||
budget, too.
|
||||
|
||||
Usage:
|
||||
------
|
||||
This driver does not actually switch anything. It is a pure "rules" driver that solely emits
|
||||
{"FTC532":{"KEYS":"XX"}} JSON messages to be used in a rule or by an MQTT broker. "XX" stands
|
||||
for the hexadecimal (big endian) representation of a bitmap of keys currently touched, where
|
||||
e.g. "00" means "no key touched" while "03" means "keys 1 and 2 touched simultaneously".
|
||||
Selecting "FTC532" on a GPIO will awake the driver. This driver can only be selected once.
|
||||
|
||||
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_47 47
|
||||
|
||||
#define FTC532_DEBOUNCE 0 // no. of cycles, < 2 disables the code
|
||||
#define FTC532_KEYS 4 // number of key pins on chip
|
||||
#define FTC532_KEYS_MAX 8 // number of key slots in protocol
|
||||
#define FTC532_DEBOUNCE 0 // number of consecutive cycles until key accepted
|
||||
|
||||
#define FTC532_STATE_WAITING 0x1
|
||||
#define FTC532_STATE_READING 0x2
|
||||
@ -79,15 +107,15 @@ struct FTC532 {
|
||||
volatile uint16_t state; // ISR state
|
||||
uint8_t keys = 0; // bitmap of active keys
|
||||
uint8_t old_keys = 0; // previously active keys
|
||||
bool present = false; // driver active
|
||||
#if FTC532_DEBOUNCE > 1
|
||||
uint8_t key_cnt = 0; // used to de-bounce
|
||||
#endif // FTC532_DEBOUNCE > 1
|
||||
bool present = false; // driver active
|
||||
#ifdef DEBUG_FTC532
|
||||
volatile uint16_t e_inv = 0; // inv. key error counter
|
||||
volatile uint16_t e_inv = 0; // inverted key error counter
|
||||
volatile uint16_t e_frame = 0; // frame error counter
|
||||
volatile uint16_t e_noise = 0; // noise detection counter
|
||||
volatile bool valid = 0; // did we ever receive valid data?
|
||||
volatile bool valid = 0; // did we ever receive valid data?
|
||||
#endif // DEBUG_FTC532
|
||||
} Ftc532;
|
||||
|
||||
@ -108,37 +136,36 @@ void ICACHE_RAM_ATTR ftc532_ISR(void) { // Hardware interrupt routine, trigger
|
||||
#endif // DEBUG_FTC532
|
||||
}
|
||||
Ftc532.state = FTC532_STATE_READING;
|
||||
Ftc532.tsmp = 0;
|
||||
} else {
|
||||
Ftc532.state = FTC532_STATE_WAITING;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// FTC532_STATE_READING starts here
|
||||
// FTC532_STATE_READING starts here
|
||||
if (time_diff > FTC532_LONG + FTC532_BIT) {
|
||||
#ifdef DEBUG_FTC532
|
||||
++Ftc532.e_frame; // frame error
|
||||
++Ftc532.e_frame; // frame error
|
||||
#endif // DEBUG_FTC532
|
||||
Ftc532.state = FTC532_STATE_WAITING;
|
||||
return;
|
||||
}
|
||||
if (time_diff > FTC532_SHORT + FTC532_BIT) {
|
||||
Ftc532.tsmp |= (1 << Ftc532.rxbit); // LONG
|
||||
} else if (time_diff < FTC532_NOISE) { // noise detector
|
||||
Ftc532.tsmp |= (1 << Ftc532.rxbit); // LONG
|
||||
} else if (time_diff < FTC532_NOISE) { // NOISE
|
||||
#ifdef DEBUG_FTC532
|
||||
++Ftc532.e_noise;
|
||||
#endif // DEBUG_FTC532
|
||||
Ftc532.state = FTC532_STATE_WAITING;
|
||||
return;
|
||||
} else {
|
||||
Ftc532.tsmp &= ~(1 << Ftc532.rxbit); // SHORT
|
||||
}
|
||||
++Ftc532.rxbit;
|
||||
if (Ftc532.rxbit == FTC532_KEYS_MAX * 2) { // frame complete
|
||||
if (Ftc532.rxbit == FTC532_KEYS_MAX * 2) { // frame complete
|
||||
Ftc532.state = FTC532_STATE_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
void ftc532_init(void) { // Initialize
|
||||
void ftc532_init(void) { // Initialize
|
||||
if (!PinUsed(GPIO_FTC532)) { return; }
|
||||
Ftc532.state = FTC532_STATE_WAITING;
|
||||
pinMode(Pin(GPIO_FTC532), INPUT_PULLUP);
|
||||
@ -147,7 +174,7 @@ void ftc532_init(void) { // Initialize
|
||||
Ftc532.present = true;
|
||||
}
|
||||
|
||||
void ftc532_update(void) { // Usually called every 50 ms
|
||||
void ftc532_update(void) { // Usually called every 50 ms
|
||||
if ((Ftc532.sample & 0xF0F0) == ((~Ftc532.sample & 0x0F0F) << 4) && (Ftc532.sample >> 8) == 0xF0) {
|
||||
Ftc532.keys = Ftc532.sample & 0xF;
|
||||
if (Ftc532.keys != Ftc532.old_keys) {
|
||||
@ -156,7 +183,8 @@ void ftc532_update(void) { // Usually called every 50 ms
|
||||
#endif // FTC532_DEBOUNCE > 1
|
||||
#ifdef DEBUG_FTC532
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("FTC: SAM=%04X KEY=%X OLD=%X INV=%u NOI=%u FRM=%u OK=%u TIME=%lu Pin=%u"),
|
||||
Ftc532.sample, Ftc532.keys, Ftc532.old_keys, Ftc532.e_inv, Ftc532.e_noise, Ftc532.e_frame, Ftc532.valid, Ftc532.rxtime, Pin(GPIO_FTC532));
|
||||
Ftc532.sample, Ftc532.keys, Ftc532.old_keys, Ftc532.e_inv, Ftc532.e_noise, Ftc532.e_frame,
|
||||
Ftc532.valid, Ftc532.rxtime, Pin(GPIO_FTC532));
|
||||
#endif // DEBUG_FTC532
|
||||
ftc532_publish();
|
||||
Ftc532.old_keys = Ftc532.keys;
|
||||
@ -171,7 +199,7 @@ void ftc532_update(void) { // Usually called every 50 ms
|
||||
#ifdef DEBUG_FTC532
|
||||
else {
|
||||
++Ftc532.e_inv;
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("FTC: SAM=%04X"), Ftc532.sample);
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("FTC: ILL SAM=%04X"), Ftc532.sample);
|
||||
}
|
||||
#endif // DEBUG_FTC532
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user