diff --git a/openrtx/include/interfaces/graphics.h b/openrtx/include/interfaces/graphics.h index af38676f..27146e6b 100644 --- a/openrtx/include/interfaces/graphics.h +++ b/openrtx/include/interfaces/graphics.h @@ -240,7 +240,7 @@ uint8_t gfx_getFontHeight(fontSize_t size); * @param buf: char buffer * @return text width and height as point_t coordinates */ -point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, +point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, color_t color, const char *buf); /** @@ -252,7 +252,7 @@ point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, * @param fmt: printf style format string * @return text width and height as point_t coordinates */ -point_t gfx_print(point_t start, fontSize_t size, textAlign_t alignment, +point_t gfx_print(point_t start, fontSize_t size, textAlign_t alignment, color_t color, const char* fmt, ... ); /** @@ -269,8 +269,8 @@ point_t gfx_print(point_t start, fontSize_t size, textAlign_t alignment, * @param fmt: printf style format string * @return text width and height as point_t coordinates */ -point_t gfx_printLine(uint8_t cur, uint8_t tot, uint16_t startY, uint16_t endY, - uint16_t startX, fontSize_t size, textAlign_t alignment, +point_t gfx_printLine(uint8_t cur, uint8_t tot, uint16_t startY, uint16_t endY, + uint16_t startX, fontSize_t size, textAlign_t alignment, color_t color, const char* fmt, ... ); /** @@ -288,7 +288,7 @@ void gfx_printError(const char *text, fontSize_t size); * @param height: battery icon height * @param percentage: battery charge percentage */ -void gfx_drawBattery(point_t start, uint16_t width, uint16_t height, float percentage); +void gfx_drawBattery(point_t start, uint16_t width, uint16_t height, uint8_t percentage); /** * Function to draw Smeter of arbitrary size. diff --git a/openrtx/include/state.h b/openrtx/include/state.h index 786ae1f8..b572d94b 100644 --- a/openrtx/include/state.h +++ b/openrtx/include/state.h @@ -69,8 +69,8 @@ typedef struct { bool radioStateUpdated; curTime_t time; - float v_bat; - float charge; + uint16_t v_bat; + uint8_t charge; float rssi; uint8_t ui_screen; diff --git a/openrtx/src/graphics.c b/openrtx/src/graphics.c index c8038790..e94128e5 100644 --- a/openrtx/src/graphics.c +++ b/openrtx/src/graphics.c @@ -392,7 +392,7 @@ uint8_t gfx_getFontHeight(fontSize_t size) return glyph.height; } -point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, +point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, color_t color, const char *buf) { GFXfont f = fonts[size]; @@ -480,11 +480,11 @@ point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, return text_size; } -point_t gfx_print(point_t start, fontSize_t size, textAlign_t alignment, +point_t gfx_print(point_t start, fontSize_t size, textAlign_t alignment, color_t color, const char *fmt, ... ) { // Get format string and arguments from var char - va_list ap; + va_list ap; va_start(ap, fmt); vsnprintf(text, sizeof(text)-1, fmt, ap); va_end(ap); @@ -492,19 +492,19 @@ point_t gfx_print(point_t start, fontSize_t size, textAlign_t alignment, return gfx_printBuffer(start, size, alignment, color, text); } -point_t gfx_printLine(uint8_t cur, uint8_t tot, uint16_t startY, uint16_t endY, - uint16_t startX, fontSize_t size, textAlign_t alignment, +point_t gfx_printLine(uint8_t cur, uint8_t tot, uint16_t startY, uint16_t endY, + uint16_t startX, fontSize_t size, textAlign_t alignment, color_t color, const char* fmt, ... ) { // Get format string and arguments from var char - va_list ap; + va_list ap; va_start(ap, fmt); vsnprintf(text, sizeof(text)-1, fmt, ap); va_end(ap); - + // Estimate font height by reading the gliph | height uint8_t fontH = gfx_getFontHeight(size); - + // If endY is 0 set it to default value = SCREEN_HEIGHT if(endY == 0) endY = SCREEN_HEIGHT; @@ -561,13 +561,13 @@ void gfx_printError(const char *text, fontSize_t size) * */ void gfx_drawBattery(point_t start, uint16_t width, uint16_t height, - float percentage) + uint8_t percentage) { color_t white = {255, 255, 255, 255}; color_t black = {0, 0, 0 , 255}; // Cap percentage to 1 - percentage = (percentage > 1.0f) ? 1.0f : percentage; + percentage = (percentage > 100) ? 100 : percentage; #ifdef PIX_FMT_RGB565 color_t green = {0, 255, 0 , 255}; @@ -576,9 +576,9 @@ void gfx_drawBattery(point_t start, uint16_t width, uint16_t height, // Select color according to percentage color_t bat_color = yellow; - if (percentage < 0.3) + if (percentage < 30) bat_color = red; - else if (percentage > 0.6) + else if (percentage > 60) bat_color = green; #elif defined PIX_FMT_BW color_t bat_color = white; @@ -589,8 +589,8 @@ void gfx_drawBattery(point_t start, uint16_t width, uint16_t height, // Draw the battery fill point_t fill_start = {start.x + 2, start.y + 2}; - gfx_drawRect(fill_start, (int)(((float)(width - 4)) * percentage), - height - 4, bat_color, true); + int fillWidth = ((width - 4) * percentage) / 100; + gfx_drawRect(fill_start, fillWidth, height - 4, bat_color, true); // Round corners point_t top_left = start; @@ -715,7 +715,7 @@ void gfx_drawGPSgraph(point_t start, color_t bar_color = (active_sats & 1 << (sats[i].id - 1)) ? yellow : white; gfx_drawRect(bar_pos, bar_width, bar_height, bar_color, true); point_t id_pos = {bar_pos.x, start.y + height}; - gfx_print(id_pos, FONT_SIZE_5PT, TEXT_ALIGN_LEFT, + gfx_print(id_pos, FONT_SIZE_5PT, TEXT_ALIGN_LEFT, bar_color, "%2d ", sats[i].id); } uint8_t bars_width = 9 + 11 * (bar_width + 2); diff --git a/openrtx/src/threads.c b/openrtx/src/threads.c index 7d97e21a..f88579cb 100644 --- a/openrtx/src/threads.c +++ b/openrtx/src/threads.c @@ -225,9 +225,14 @@ void *dev_task(void *arg) state.time = rtc_getTime(); #endif - // Low-pass filtering with a time constant of 10s when updated at 1Hz - float vbat = platform_getVbat(); - state.v_bat = 0.02*vbat + 0.98*state.v_bat; + /* + * Low-pass filtering with a time constant of 10s when updated at 1Hz + * Original computation: state.v_bat = 0.02*vbat + 0.98*state.v_bat + * Peak error is 18mV when input voltage is 49mV. + */ + uint16_t vbat = platform_getVbat(); + state.v_bat -= (state.v_bat * 2) / 100; + state.v_bat += (vbat * 2) / 100; state.charge = battery_getCharge(state.v_bat); state.rssi = rtx_getRssi(); diff --git a/openrtx/src/ui/ui.c b/openrtx/src/ui/ui.c index 246f8a69..8bf4120a 100644 --- a/openrtx/src/ui/ui.c +++ b/openrtx/src/ui/ui.c @@ -363,7 +363,7 @@ void _ui_drawLowBatteryScreen() uint16_t bat_width = SCREEN_WIDTH / 2; uint16_t bat_height = SCREEN_HEIGHT / 3; point_t bat_pos = {SCREEN_WIDTH / 4, SCREEN_HEIGHT / 8}; - gfx_drawBattery(bat_pos, bat_width, bat_height, 0.1f); + gfx_drawBattery(bat_pos, bat_width, bat_height, 10); point_t text_pos_1 = {0, SCREEN_HEIGHT * 2 / 3}; point_t text_pos_2 = {0, SCREEN_HEIGHT * 2 / 3 + 16}; @@ -440,16 +440,16 @@ bool _ui_freq_check_limits(freq_t freq) if(hwinfo->vhf_band) { // hwInfo_t frequencies are in MHz - if(freq >= (hwinfo->vhf_minFreq * 1000000) && + if(freq >= (hwinfo->vhf_minFreq * 1000000) && freq <= (hwinfo->vhf_maxFreq * 1000000)) - valid = true; + valid = true; } if(hwinfo->uhf_band) { // hwInfo_t frequencies are in MHz - if(freq >= (hwinfo->uhf_minFreq * 1000000) && + if(freq >= (hwinfo->uhf_minFreq * 1000000) && freq <= (hwinfo->uhf_maxFreq * 1000000)) - valid = true; + valid = true; } return valid; } @@ -1126,10 +1126,10 @@ void ui_updateFSM(event_t event, bool *sync_rtx) state.settings.gps_set_time = !state.settings.gps_set_time; break; case G_TIMEZONE: - if(msg.keys & KEY_LEFT || msg.keys & KEY_UP || + if(msg.keys & KEY_LEFT || msg.keys & KEY_UP || msg.keys & KNOB_LEFT) state.settings.utc_timezone -= 1; - else if(msg.keys & KEY_RIGHT || msg.keys & KEY_DOWN || + else if(msg.keys & KEY_RIGHT || msg.keys & KEY_DOWN || msg.keys & KNOB_RIGHT) state.settings.utc_timezone += 1; break; diff --git a/openrtx/src/ui/ui_menu.c b/openrtx/src/ui/ui_menu.c index 72e9511d..d24ffff3 100644 --- a/openrtx/src/ui/ui_menu.c +++ b/openrtx/src/ui/ui_menu.c @@ -48,7 +48,7 @@ void _ui_drawMenuList(uint8_t selected, int (*getCurrentEntry)(char *buf, uint8_ text_color = color_black; // Draw rectangle under selected item, compensating for text height point_t rect_pos = {0, pos.y - layout.menu_h + 3}; - gfx_drawRect(rect_pos, SCREEN_WIDTH, layout.menu_h, color_white, true); + gfx_drawRect(rect_pos, SCREEN_WIDTH, layout.menu_h, color_white, true); } gfx_print(pos, layout.menu_font, TEXT_ALIGN_LEFT, text_color, entry_buf); pos.y += layout.menu_h; @@ -56,8 +56,8 @@ void _ui_drawMenuList(uint8_t selected, int (*getCurrentEntry)(char *buf, uint8_ } } -void _ui_drawMenuListValue(ui_state_t* ui_state, uint8_t selected, - int (*getCurrentEntry)(char *buf, uint8_t max_len, uint8_t index), +void _ui_drawMenuListValue(ui_state_t* ui_state, uint8_t selected, + int (*getCurrentEntry)(char *buf, uint8_t max_len, uint8_t index), int (*getCurrentValue)(char *buf, uint8_t max_len, uint8_t index)) { point_t pos = layout.line1_pos; @@ -91,7 +91,7 @@ void _ui_drawMenuListValue(ui_state_t* ui_state, uint8_t selected, full_rect = false; } point_t rect_pos = {0, pos.y - layout.menu_h + 3}; - gfx_drawRect(rect_pos, SCREEN_WIDTH, layout.menu_h, color_white, full_rect); + gfx_drawRect(rect_pos, SCREEN_WIDTH, layout.menu_h, color_white, full_rect); } gfx_print(pos, layout.menu_font, TEXT_ALIGN_LEFT, text_color, entry_buf); gfx_print(pos, layout.menu_font, TEXT_ALIGN_RIGHT, text_color, value_buf); @@ -188,10 +188,16 @@ int _ui_getInfoValueName(char *buf, uint8_t max_len, uint8_t index) snprintf(buf, max_len, "%s", GIT_VERSION); break; case 1: // Battery voltage - snprintf(buf, max_len, "%.1fV", last_state.v_bat); + { + // Compute integer part and mantissa of voltage value, adding 50mV + // to mantissa for rounding to nearest integer + uint16_t volt = last_state.v_bat / 1000; + uint16_t mvolt = ((last_state.v_bat - volt * 1000) + 50) / 100; + snprintf(buf, max_len, "%d.%dV", volt, mvolt); + } break; case 2: // Battery charge - snprintf(buf, max_len, "%.1f%%", last_state.charge * 100); + snprintf(buf, max_len, "%d%%", last_state.charge); break; case 3: // RSSI snprintf(buf, max_len, "%.1fdBm", last_state.rssi); @@ -255,7 +261,7 @@ void _ui_drawMenuTop(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Menu" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Menu"); // Print menu entries _ui_drawMenuList(ui_state->menu_selected, _ui_getMenuTopEntryName); @@ -265,7 +271,7 @@ void _ui_drawMenuZone(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Zone" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Zone"); // Print zone entries _ui_drawMenuList(ui_state->menu_selected, _ui_getZoneName); @@ -275,7 +281,7 @@ void _ui_drawMenuChannel(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Channel" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Channels"); // Print channel entries _ui_drawMenuList(ui_state->menu_selected, _ui_getChannelName); @@ -285,7 +291,7 @@ void _ui_drawMenuContacts(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Contacts" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Contacts"); // Print contact entries _ui_drawMenuList(ui_state->menu_selected, _ui_getContactName); @@ -297,18 +303,18 @@ void _ui_drawMenuGPS() char *fix_buf, *type_buf; gfx_clearScreen(); // Print "GPS" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "GPS"); point_t fix_pos = {layout.line2_pos.x, SCREEN_HEIGHT * 2 / 5}; // Print GPS status, if no fix, hide details if(!last_state.settings.gps_enabled) - gfx_print(fix_pos, layout.line3_font, TEXT_ALIGN_CENTER, + gfx_print(fix_pos, layout.line3_font, TEXT_ALIGN_CENTER, color_white, "GPS OFF"); else if (last_state.gps_data.fix_quality == 0) - gfx_print(fix_pos, layout.line3_font, TEXT_ALIGN_CENTER, + gfx_print(fix_pos, layout.line3_font, TEXT_ALIGN_CENTER, color_white, "No Fix"); else if (last_state.gps_data.fix_quality == 6) - gfx_print(fix_pos, layout.line3_font, TEXT_ALIGN_CENTER, + gfx_print(fix_pos, layout.line3_font, TEXT_ALIGN_CENTER, color_white, "Fix Lost"); else { @@ -385,7 +391,7 @@ void _ui_drawMenuSettings(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Settings" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Settings"); // Print menu entries _ui_drawMenuList(ui_state->menu_selected, _ui_getSettingsEntryName); @@ -395,7 +401,7 @@ void _ui_drawMenuInfo(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Info" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Info"); // Print menu entries _ui_drawMenuListValue(ui_state, ui_state->menu_selected, _ui_getInfoEntryName, @@ -409,13 +415,13 @@ void _ui_drawMenuAbout() if(SCREEN_HEIGHT >= 100) ui_drawSplashScreen(false); else - gfx_print(openrtx_pos, layout.line3_font, TEXT_ALIGN_CENTER, + gfx_print(openrtx_pos, layout.line3_font, TEXT_ALIGN_CENTER, color_white, "OpenRTX"); uint8_t line_h = layout.menu_h; point_t pos = {SCREEN_WIDTH / 7, SCREEN_HEIGHT - (line_h * (author_num - 1)) - 5}; for(int author = 0; author < author_num; author++) { - gfx_print(pos, layout.top_font, TEXT_ALIGN_LEFT, + gfx_print(pos, layout.top_font, TEXT_ALIGN_LEFT, color_white, "%s", authors[author]); pos.y += line_h; } @@ -425,7 +431,7 @@ void _ui_drawSettingsDisplay(ui_state_t* ui_state) { gfx_clearScreen(); // Print "Display" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Display"); // Print display settings entries _ui_drawMenuListValue(ui_state, ui_state->menu_selected, _ui_getDisplayEntryName, @@ -437,10 +443,10 @@ void _ui_drawSettingsGPS(ui_state_t* ui_state) { gfx_clearScreen(); // Print "GPS Settings" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "GPS Settings"); // Print display settings entries - _ui_drawMenuListValue(ui_state, ui_state->menu_selected, + _ui_drawMenuListValue(ui_state, ui_state->menu_selected, _ui_getSettingsGPSEntryName, _ui_getSettingsGPSValueName); } @@ -452,14 +458,14 @@ void _ui_drawSettingsTimeDate() gfx_clearScreen(); curTime_t local_time = state_getLocalTime(last_state.time); // Print "Time&Date" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Time&Date"); // Print current time and date gfx_print(layout.line2_pos, layout.input_font, TEXT_ALIGN_CENTER, - color_white, "%02d/%02d/%02d", + color_white, "%02d/%02d/%02d", local_time.date, local_time.month, local_time.year); gfx_print(layout.line3_pos, layout.input_font, TEXT_ALIGN_CENTER, - color_white, "%02d:%02d:%02d", + color_white, "%02d:%02d:%02d", local_time.hour, local_time.minute, local_time.second); } @@ -469,7 +475,7 @@ void _ui_drawSettingsTimeDateSet(ui_state_t* ui_state) gfx_clearScreen(); // Print "Time&Date" on top bar - gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, + gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, "Time&Date"); if(ui_state->input_position <= 0) { @@ -494,7 +500,7 @@ void _ui_drawSettingsTimeDateSet(ui_state_t* ui_state) uint8_t pos = ui_state->input_position -7; // Skip ":" if(ui_state->input_position > 8) pos += 1; - ui_state->new_time_buf[pos] = input_char; + ui_state->new_time_buf[pos] = input_char; } } gfx_print(layout.line2_pos, layout.input_font, TEXT_ALIGN_CENTER, @@ -535,7 +541,7 @@ bool _ui_drawMacroMenu() { color_white, "%.1gW", last_state.channel.power); // Second row // Calculate symmetric second row position, line2_pos is asymmetric like main screen - point_t pos_2 = {layout.line1_pos.x, layout.line1_pos.y + + point_t pos_2 = {layout.line1_pos.x, layout.line1_pos.y + (layout.line3_pos.y - layout.line1_pos.y)/2}; gfx_print(pos_2, layout.top_font, TEXT_ALIGN_LEFT, yellow_fab413, "4"); diff --git a/platform/drivers/baseband/radio_MD3x0.cpp b/platform/drivers/baseband/radio_MD3x0.cpp index ca8c3f62..968f29f3 100644 --- a/platform/drivers/baseband/radio_MD3x0.cpp +++ b/platform/drivers/baseband/radio_MD3x0.cpp @@ -387,7 +387,7 @@ float radio_getRssi() if(rxFreq < 401035000) offset_index = 0; if(rxFreq > 479995000) offset_index = 8; - float rssi_mv = adc1_getMeasurement(ADC_RSSI_CH); + float rssi_mv = ((float) adc1_getMeasurement(ADC_RSSI_CH)); float rssi_dbm = (rssi_mv - rssi_offset[offset_index]) / rssi_gain; return rssi_dbm; }