Double MSP (TLM and MAVLink) throughput for Gemini hardware (#3037)
[ExpressLRS.git] / src / lib / THERMAL / rpm.cpp
blob0fb30bced8aba8788a78427eedae280392d8fb6e
1 #include "targets.h"
3 #if defined(PLATFORM_ESP32) && !defined(PLATFORM_ESP32_C3)
4 #include "logging.h"
5 #include <driver/pcnt.h>
6 #include <soc/pcnt_struct.h>
8 #define TACHO_PULSES_PER_REV 4
10 static volatile int overflow = 0;
11 static uint32_t lastTime = 0;
13 static void IRAM_ATTR pcnt_overflow(void *arg)
15 overflow++;
16 PCNT.int_clr.val = BIT(PCNT_UNIT_0);
17 pcnt_counter_clear(PCNT_UNIT_0);
20 void init_rpm_counter(int pin)
22 pcnt_config_t pcnt_config = {};
23 pcnt_config.pulse_gpio_num = pin;
24 pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED;
25 // What to do on the positive / negative edge of pulse input?
26 pcnt_config.pos_mode = PCNT_COUNT_INC; // Count up on the positive edge
27 pcnt_config.neg_mode = PCNT_COUNT_DIS; // Keep the counter value on the negative edge
28 // Set the maximum and minimum limit values to watch
29 pcnt_config.counter_h_lim = 30000;
30 pcnt_config.counter_l_lim = -1;
31 pcnt_config.unit = PCNT_UNIT_0;
32 pcnt_config.channel = PCNT_CHANNEL_0;
34 /* Initialize PCNT unit */
35 pcnt_unit_config(&pcnt_config);
36 /* Configure and enable the input filter */
37 pcnt_set_filter_value(PCNT_UNIT_0, 100);
38 pcnt_filter_enable(PCNT_UNIT_0);
39 /* Enable interrupt on overflow */
40 pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM);
41 pcnt_isr_register(pcnt_overflow, NULL, 0, NULL);
42 pcnt_intr_enable(PCNT_UNIT_0);
43 /* Initialize PCNT's counter */
44 pcnt_counter_pause(PCNT_UNIT_0);
45 pcnt_counter_clear(PCNT_UNIT_0);
46 /* Everything is set up, now go to counting */
47 pcnt_counter_resume(PCNT_UNIT_0);
50 uint32_t get_rpm()
52 int16_t counter;
53 pcnt_get_counter_value(PCNT_UNIT_0, &counter);
54 pcnt_counter_clear(PCNT_UNIT_0);
55 uint32_t now = millis();
56 uint32_t rpm = ((overflow * 30000) + counter) * 60000 / TACHO_PULSES_PER_REV / (now - lastTime);
57 overflow = 0;
58 lastTime = now;
59 return rpm;
61 #endif