Merge pull request #1269 from pkendall64/crsf-max-output
[ExpressLRS.git] / src / lib / SCREEN / devScreen.cpp
blobf4eb184856981fe4f7d8e58183d8fbfb2803fe74
1 #include "targets.h"
2 #include "common.h"
3 #include "device.h"
5 #if defined(USE_OLED_SPI) || defined(USE_OLED_SPI_SMALL) || defined(USE_OLED_I2C) || defined(HAS_TFT_SCREEN)
7 #include "logging.h"
8 #include "Wire.h"
9 #include "config.h"
10 #include "POWERMGNT.h"
11 #include "hwTimer.h"
13 #ifdef HAS_TFT_SCREEN
14 #include "TFT/tftscreen.h"
15 TFTScreen screen;
16 #else
17 #include "OLED/oledscreen.h"
18 OLEDScreen screen;
19 #endif
21 #ifdef HAS_FIVE_WAY_BUTTON
22 #include "FiveWayButton/FiveWayButton.h"
23 FiveWayButton fivewaybutton;
25 static uint32_t none_input_start_time = 0;
26 static bool isUserInputCheck = false;
27 #endif
29 #ifdef HAS_GSENSOR
30 #include "gsensor.h"
31 extern Gsensor gsensor;
32 static bool is_screen_flipped = false;
33 static bool is_pre_screen_flipped = false;
34 #endif
36 #ifdef HAS_THERMAL
37 #include "thermal.h"
38 extern Thermal thermal;
40 #define UPDATE_TEMP_TIMEOUT 5000
41 uint32_t update_temp_start_time = 0;
42 #endif
44 #define SCREEN_DURATION 20
46 #define LOGO_DISPLAY_TIMEOUT 5000
47 static bool isLogoDisplayed = false;
49 #define SCREEN_IDLE_TIMEOUT 20000
51 extern bool ICACHE_RAM_ATTR IsArmed();
52 extern void EnterBindingMode();
53 extern void ExitBindingMode();
55 #if defined(TARGET_TX)
56 extern TxConfig config;
57 #else
58 extern RxConfig config;
59 #endif
61 #ifdef PLATFORM_ESP32
62 extern unsigned long rebootTime;
63 #endif
65 #define BINDING_MODE_TIME_OUT 5000
66 static uint32_t binding_mode_start_time = 0;
69 static void ScreenUpdateCallback(int updateType)
71 switch(updateType)
73 case USER_UPDATE_TYPE_RATE:
74 DBGLN("User set AirRate %d", screen.getUserRateIndex());
75 config.SetRate(screen.getUserRateIndex());
76 break;
77 case USER_UPDATE_TYPE_POWER:
78 DBGLN("User set Power %d", screen.getUserPowerIndex());
79 config.SetPower(screen.getUserPowerIndex());
80 break;
81 case USER_UPDATE_TYPE_RATIO:
82 DBGLN("User set TLM RATIO %d", screen.getUserRatioIndex());
83 config.SetTlm(screen.getUserRatioIndex());
84 break;
85 case USER_UPDATE_TYPE_BINDING:
86 DBGLN("User request binding!");
87 EnterBindingMode();
88 binding_mode_start_time = millis();
89 break;
90 case USER_UPDATE_TYPE_EXIT_BINDING:
91 DBGLN("User request exit binding!");
92 ExitBindingMode();
93 break;
94 case USER_UPDATE_TYPE_WIFI:
95 DBGLN("User request Wifi Update Mode!");
96 connectionState = wifiUpdate;
97 break;
98 case USER_UPDATE_TYPE_EXIT_WIFI:
99 DBGLN("User request exit Wifi Update Mode!");
100 #ifdef PLATFORM_ESP32
101 if (connectionState == wifiUpdate) {
102 rebootTime = millis() + 200;
104 #endif
105 break;
106 #ifdef HAS_THERMAL
107 case USER_UPDATE_TYPE_SMARTFAN:
108 DBGLN("User request SMART FAN Mode!");
109 config.SetFanMode(screen.getUserSmartFanIndex());
110 break;
111 #endif
112 #ifdef HAS_GSENSOR
113 case USER_UPDATE_TYPE_POWERSAVING:
114 DBGLN("User request Power Saving Mode!");
115 config.SetMotionMode(screen.getUserPowerSavingIndex());
116 break;
117 #endif
118 default:
119 DBGLN("Error handle user request %d", updateType);
120 break;
124 #ifdef HAS_FIVE_WAY_BUTTON
125 static int handle(void)
127 #if defined(JOY_ADC_VALUES) && defined(PLATFORM_ESP32)
128 // if we are using analog joystick then we can't cancel because WiFi is using the ADC2 (i.e. channel >= 8)!
129 if (connectionState == wifiUpdate && digitalPinToAnalogChannel(GPIO_PIN_JOYSTICK) >= 8)
131 return DURATION_NEVER;
133 #endif
135 #ifdef HAS_GSENSOR
136 is_screen_flipped = gsensor.isFlipped();
138 if ((is_screen_flipped == true) && (is_pre_screen_flipped == false))
140 screen.doScreenBackLight(SCREEN_BACKLIGHT_OFF);
142 else if ((is_screen_flipped == false) && (is_pre_screen_flipped == true))
144 screen.doScreenBackLight(SCREEN_BACKLIGHT_ON);
146 is_pre_screen_flipped = is_screen_flipped;
147 if (is_screen_flipped)
149 return 100; // no need to check as often if the screen is off!
151 #endif
153 if(!IsArmed())
155 int key;
156 bool isLongPressed;
157 fivewaybutton.handle();
158 fivewaybutton.getKeyState(&key, &isLongPressed);
159 if(screen.getScreenStatus() == SCREEN_STATUS_IDLE)
161 #ifdef HAS_THERMAL
162 if(millis() - update_temp_start_time > UPDATE_TEMP_TIMEOUT)
164 screen.doTemperatureUpdate(thermal.getTempValue());
165 update_temp_start_time = millis();
167 #endif
168 if(isLongPressed)
170 screen.activeScreen();
173 else if(screen.getScreenStatus() == SCREEN_STATUS_WORK)
175 if(!isUserInputCheck)
177 none_input_start_time = millis();
178 isUserInputCheck = true;
181 if (key != INPUT_KEY_NO_PRESS)
183 DBGLN("user key = %d", key);
184 isUserInputCheck = false;
185 if(key == INPUT_KEY_DOWN_PRESS)
187 screen.doUserAction(USER_ACTION_DOWN);
189 else if(key == INPUT_KEY_UP_PRESS)
191 screen.doUserAction(USER_ACTION_UP);
193 else if(key == INPUT_KEY_LEFT_PRESS)
195 screen.doUserAction(USER_ACTION_LEFT);
197 else if(key == INPUT_KEY_RIGHT_PRESS)
199 screen.doUserAction(USER_ACTION_RIGHT);
201 else if(key == INPUT_KEY_OK_PRESS)
203 screen.doUserAction(USER_ACTION_CONFIRM);
206 else if((millis() - none_input_start_time) > SCREEN_IDLE_TIMEOUT)
208 isUserInputCheck = false;
209 screen.idleScreen();
212 else if(screen.getScreenStatus() == SCREEN_STATUS_BINDING)
214 if((millis() - binding_mode_start_time) > BINDING_MODE_TIME_OUT)
216 screen.doUserAction(USER_ACTION_LEFT);
220 return SCREEN_DURATION;
222 #else
223 static int handle(void)
225 return DURATION_NEVER;
227 #endif
229 static void initialize()
231 #ifdef HAS_FIVE_WAY_BUTTON
232 fivewaybutton.init();
233 #endif
234 screen.updatecallback = &ScreenUpdateCallback;
235 #if defined(PLATFORM_ESP32)
236 screen.init(esp_reset_reason() == ESP_RST_SW);
237 #else
238 screen.init(false);
239 #endif
242 static int start()
244 if (screen.getScreenStatus() == SCREEN_STATUS_INIT)
246 screen.doParamUpdate(config.GetRate(), (uint8_t)(POWERMGNT::currPower()), config.GetTlm(), config.GetMotionMode(), config.GetFanMode());
247 return LOGO_DISPLAY_TIMEOUT;
249 return DURATION_IMMEDIATELY;
252 static int event()
254 if (connectionState == wifiUpdate)
256 screen.setInWifiMode();
258 else
260 screen.doParamUpdate(config.GetRate(), (uint8_t)(POWERMGNT::currPower()), config.GetTlm(), config.GetMotionMode(), config.GetFanMode());
263 return DURATION_IGNORE;
266 static int timeout()
268 if(screen.getScreenStatus() == SCREEN_STATUS_INIT)
270 isLogoDisplayed = true;
271 screen.idleScreen();
274 return handle();
277 device_t Screen_device = {
278 .initialize = initialize,
279 .start = start,
280 .event = event,
281 .timeout = timeout
283 #endif