From 5b3929ef4442ec6075829bffa220b13184803f6f Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Tue, 26 Dec 2023 16:27:13 +0100 Subject: [PATCH] Moved from float to uint32_t for TX power, substituted dBm with mW in CPS channel struct General code optimization allowing to reduce the overall binary size, especially for devices without hardware floating point support. On the MD-380 (which has the FPU) the .text size has been reduced of 4'928 bytes. --- openrtx/include/core/cps.h | 2 +- openrtx/include/core/utils.h | 10 ---------- openrtx/include/core/voicePromptUtils.h | 2 +- openrtx/include/rtx/rtx.h | 2 +- openrtx/src/core/threads.c | 4 +--- openrtx/src/core/utils.c | 8 -------- openrtx/src/core/voicePromptUtils.c | 15 ++++++++------- openrtx/src/ui/default/ui.c | 9 ++++----- openrtx/src/ui/default/ui_menu.c | 7 ++++++- platform/drivers/CPS/cps_io_native_GDx.c | 2 +- platform/drivers/CPS/cps_io_native_MD3x0.c | 2 +- platform/drivers/CPS/cps_io_native_MD9600.c | 6 +++--- platform/drivers/CPS/cps_io_native_MDUV3x0.c | 6 +++--- platform/drivers/baseband/SA8x8.c | 4 ++-- platform/drivers/baseband/SA8x8.h | 4 ++-- platform/drivers/baseband/radio_GDx.cpp | 3 ++- platform/drivers/baseband/radio_MD3x0.cpp | 3 ++- platform/drivers/baseband/radio_UV3x0.cpp | 3 ++- platform/drivers/baseband/radio_ttwrplus.cpp | 2 +- 19 files changed, 41 insertions(+), 53 deletions(-) diff --git a/openrtx/include/core/cps.h b/openrtx/include/core/cps.h index 8c7d72f9..76e06d0d 100644 --- a/openrtx/include/core/cps.h +++ b/openrtx/include/core/cps.h @@ -195,7 +195,7 @@ typedef struct rx_only : 1, //< 1 means RX-only channel _unused : 5; //< Padding to 8 bits - uint8_t power; //< P = 10dBm + n*0.2dBm, we store n + uint32_t power; //< Tx power, in mW freq_t rx_frequency; //< RX Frequency, in Hz freq_t tx_frequency; //< TX Frequency, in Hz diff --git a/openrtx/include/core/utils.h b/openrtx/include/core/utils.h index eea6dbfd..a407c2de 100644 --- a/openrtx/include/core/utils.h +++ b/openrtx/include/core/utils.h @@ -47,16 +47,6 @@ extern "C" { uint8_t interpCalParameter(const freq_t freq, const freq_t *calPoints, const uint8_t *param, const uint8_t elems); -/** - * Convert from "OpenRTX dBm" to watt. - * In OpenRTX cps power is stored as the coefficient n of the equation - * P(dBm) = 10 + 2*0.2. - * - * @param n: coefficient of the dBm equation. - * @return power in watt. - */ -float dBmToWatt(const uint8_t n); - /** * \internal Utility function to convert 4 byte BCD values into a 32-bit * unsigned integer ones. diff --git a/openrtx/include/core/voicePromptUtils.h b/openrtx/include/core/voicePromptUtils.h index f62c2e29..3a35bbf7 100644 --- a/openrtx/include/core/voicePromptUtils.h +++ b/openrtx/include/core/voicePromptUtils.h @@ -114,7 +114,7 @@ void vp_announceCTCSS(const bool rxToneEnabled, const uint8_t rxTone, /** * */ -void vp_anouncePower(const float power, const vpQueueFlags_t flags); +void vp_announcePower(const uint32_t power, const vpQueueFlags_t flags); /** * diff --git a/openrtx/include/rtx/rtx.h b/openrtx/include/rtx/rtx.h index 092cd4bb..55b9484a 100644 --- a/openrtx/include/rtx/rtx.h +++ b/openrtx/include/rtx/rtx.h @@ -43,7 +43,7 @@ typedef struct freq_t rxFrequency; /**< RX frequency, in Hz */ freq_t txFrequency; /**< TX frequency, in Hz */ - float txPower; /**< TX power, in W */ + uint32_t txPower; /**< TX power, in mW */ uint8_t sqlLevel; /**< Squelch opening level */ uint16_t rxToneEn : 1, /**< RX CTC/DCS tone enable */ diff --git a/openrtx/src/core/threads.c b/openrtx/src/core/threads.c index 986c277c..27c05a4d 100644 --- a/openrtx/src/core/threads.c +++ b/openrtx/src/core/threads.c @@ -85,14 +85,12 @@ void *ui_threadFunc(void *arg) // If synchronization needed take mutex and update RTX configuration if(sync_rtx) { - float power = dBmToWatt(state.channel.power); - pthread_mutex_lock(&rtx_mutex); rtx_cfg.opMode = state.channel.mode; rtx_cfg.bandwidth = state.channel.bandwidth; rtx_cfg.rxFrequency = state.channel.rx_frequency; rtx_cfg.txFrequency = state.channel.tx_frequency; - rtx_cfg.txPower = power; + rtx_cfg.txPower = state.channel.power; rtx_cfg.sqlLevel = state.settings.sqlLevel; rtx_cfg.rxToneEn = state.channel.fm.rxToneEn; rtx_cfg.rxTone = ctcss_tone[state.channel.fm.rxTone]; diff --git a/openrtx/src/core/utils.c b/openrtx/src/core/utils.c index ba33dace..647fa004 100644 --- a/openrtx/src/core/utils.c +++ b/openrtx/src/core/utils.c @@ -51,14 +51,6 @@ uint8_t interpCalParameter(const freq_t freq, const freq_t *calPoints, return interpValue; } -float dBmToWatt(const uint8_t n) -{ - float dBm = 10.0f + ((float) n) * 0.2f; - float power = pow(10.0f, (dBm - 30.0f)/10.0f); - - return power; -} - uint32_t bcdToBin(uint32_t bcd) { return ((bcd >> 28) & 0x0F) * 10000000 + diff --git a/openrtx/src/core/voicePromptUtils.c b/openrtx/src/core/voicePromptUtils.c index fd86c075..d65a4157 100644 --- a/openrtx/src/core/voicePromptUtils.c +++ b/openrtx/src/core/voicePromptUtils.c @@ -179,7 +179,7 @@ void vp_announceBandwidth(const uint8_t bandwidth, const vpQueueFlags_t flags) playIfNeeded(flags); } -void vp_anouncePower(const float power, const vpQueueFlags_t flags) +void vp_announcePower(const uint32_t power, const vpQueueFlags_t flags) { clearCurrPromptIfNeeded(flags); @@ -188,8 +188,10 @@ void vp_anouncePower(const float power, const vpQueueFlags_t flags) vp_queuePrompt(PROMPT_POWER); } + // Compute x.y format avoiding to pull in floating point math. + // Remember that power is expressed in mW! char buffer[16] = "\0"; - snprintf(buffer, 16, "%1.1f", power); + snprintf(buffer, 16, "%d.%d", (power / 1000), (power % 1000) / 100); vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queuePrompt(PROMPT_WATTS); @@ -281,8 +283,7 @@ void vp_announceChannelSummary(const channel_t* channel, if ((infoFlags & vpPower) != 0) { - float power = dBmToWatt(channel->power); - vp_anouncePower(power, localFlags); + vp_announcePower(channel->power, localFlags); addSilenceIfNeeded(localFlags); } @@ -1042,7 +1043,7 @@ void vp_announceSplashScreen() { if (state.settings.vpLevel < vpBeep) return; - + vp_flush(); if (state.settings.vpLevel == vpBeep) @@ -1050,7 +1051,7 @@ void vp_announceSplashScreen() vp_beepSeries(BOOT_MELODY); return; } - + vpQueueFlags_t localFlags = vpqAddSeparatingSilence; // Force on the descriptions for level 3. @@ -1061,7 +1062,7 @@ void vp_announceSplashScreen() vp_queueStringTableEntry(¤tLanguage->openRTX); vp_queuePrompt(PROMPT_VFO); - vp_announceFrequencies(state.channel.rx_frequency, + vp_announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, localFlags); vp_announceRadioMode(state.channel.mode, localFlags); diff --git a/openrtx/src/ui/default/ui.c b/openrtx/src/ui/default/ui.c index 19c5af46..451abe8b 100644 --- a/openrtx/src/ui/default/ui.c +++ b/openrtx/src/ui/default/ui.c @@ -996,13 +996,12 @@ static void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx) vp_announceRadioMode(state.channel.mode, queueFlags); break; case 6: - if (state.channel.power == 100) - state.channel.power = 135; + if (state.channel.power == 1000) + state.channel.power = 5000; else - state.channel.power = 100; + state.channel.power = 1000; *sync_rtx = true; - float power = dBmToWatt(state.channel.power); - vp_anouncePower(power, queueFlags); + vp_announcePower(state.channel.power, queueFlags); break; #ifdef CONFIG_SCREEN_BRIGHTNESS case 7: diff --git a/openrtx/src/ui/default/ui_menu.c b/openrtx/src/ui/default/ui_menu.c index 9119ae32..12c2ee16 100644 --- a/openrtx/src/ui/default/ui_menu.c +++ b/openrtx/src/ui/default/ui_menu.c @@ -1156,8 +1156,13 @@ bool _ui_drawMacroMenu(ui_state_t* ui_state) #endif // CONFIG_UI_NO_KEYBOARD gfx_print(pos_2, layout.top_font, TEXT_ALIGN_RIGHT, yellow_fab413, "6 "); + + // Compute x.y format for TX power avoiding to pull in floating point math. + // Remember that power is expressed in mW! + unsigned int power_int = (last_state.channel.power / 1000); + unsigned int power_dec = (last_state.channel.power % 1000) / 100; gfx_print(pos_2, layout.top_font, TEXT_ALIGN_RIGHT, - color_white, "%.1gW", dBmToWatt(last_state.channel.power)); + color_white, "%d.%dW", power_int, power_dec); // Third row #if defined(CONFIG_UI_NO_KEYBOARD) diff --git a/platform/drivers/CPS/cps_io_native_GDx.c b/platform/drivers/CPS/cps_io_native_GDx.c index a36d5325..71eb7984 100644 --- a/platform/drivers/CPS/cps_io_native_GDx.c +++ b/platform/drivers/CPS/cps_io_native_GDx.c @@ -137,7 +137,7 @@ int cps_readChannel(channel_t *channel, uint16_t pos) channel->mode = chData.channel_mode + 1; channel->bandwidth = chData.bandwidth; channel->rx_only = chData.rx_only; - channel->power = ((chData.power == 1) ? 135 : 100); + channel->power = ((chData.power == 1) ? 5000 : 1000); // 5W or 1W channel->rx_frequency = bcdToBin(chData.rx_frequency) * 10; channel->tx_frequency = bcdToBin(chData.tx_frequency) * 10; channel->scanList_index = chData.scan_list_index; diff --git a/platform/drivers/CPS/cps_io_native_MD3x0.c b/platform/drivers/CPS/cps_io_native_MD3x0.c index a81800c8..5ab4ade6 100644 --- a/platform/drivers/CPS/cps_io_native_MD3x0.c +++ b/platform/drivers/CPS/cps_io_native_MD3x0.c @@ -77,7 +77,7 @@ int cps_readChannel(channel_t *channel, uint16_t pos) channel->mode = chData.channel_mode; channel->bandwidth = chData.bandwidth; channel->rx_only = chData.rx_only; - channel->power = ((chData.power == 1) ? 135 : 100); + channel->power = ((chData.power == 1) ? 5000 : 1000); // 5W or 1W channel->rx_frequency = bcdToBin(chData.rx_frequency) * 10; channel->tx_frequency = bcdToBin(chData.tx_frequency) * 10; channel->scanList_index = chData.scan_list_index; diff --git a/platform/drivers/CPS/cps_io_native_MD9600.c b/platform/drivers/CPS/cps_io_native_MD9600.c index ee366074..a2208743 100644 --- a/platform/drivers/CPS/cps_io_native_MD9600.c +++ b/platform/drivers/CPS/cps_io_native_MD9600.c @@ -62,15 +62,15 @@ static int _readChannelAtAddress(channel_t *channel, uint32_t addr) if(chData.power == 3) { - channel->power = 135; /* High power -> 5W = 37dBm */ + channel->power = 5000; /* High power, 5W */ } else if(chData.power == 2) { - channel->power = 120; /* Mid power -> 2.5W = 34dBm */ + channel->power = 2500; /* Mid power, 2.5W */ } else { - channel->power = 100; /* Low power -> 1W = 30dBm */ + channel->power = 1000; /* Low power, 1W */ } /* diff --git a/platform/drivers/CPS/cps_io_native_MDUV3x0.c b/platform/drivers/CPS/cps_io_native_MDUV3x0.c index 67f0d6a4..c2b2a473 100644 --- a/platform/drivers/CPS/cps_io_native_MDUV3x0.c +++ b/platform/drivers/CPS/cps_io_native_MDUV3x0.c @@ -60,15 +60,15 @@ static int _readChannelAtAddress(channel_t *channel, uint32_t addr) if(chData.power == 3) { - channel->power = 135; /* High power -> 5W = 37dBm */ + channel->power = 5000; /* High power, 5W */ } else if(chData.power == 2) { - channel->power = 120; /* Mid power -> 2.5W = 34dBm */ + channel->power = 2500; /* Mid power, 2.5W */ } else { - channel->power = 100; /* Low power -> 1W = 30dBm */ + channel->power = 1000; /* Low power, 1W */ } /* diff --git a/platform/drivers/baseband/SA8x8.c b/platform/drivers/baseband/SA8x8.c index 373fa57d..b936b77d 100644 --- a/platform/drivers/baseband/SA8x8.c +++ b/platform/drivers/baseband/SA8x8.c @@ -272,12 +272,12 @@ int sa8x8_enableHSMode() return 0; } -void sa8x8_setTxPower(const float power) +void sa8x8_setTxPower(const uint32_t power) { char buf[SA8X8_MSG_SIZE] = { 0 }; // TODO: Implement fine-grained power control through PA_BIAS SA8x8 register - uint8_t amp_enable = (power > 1.0f) ? 1 : 0; + uint8_t amp_enable = (power > 1000) ? 1 : 0; int ret = gpio_pin_set_dt(&radio_pwr, amp_enable); if(ret != 0) printk("SA8x8: failed to change power mode"); diff --git a/platform/drivers/baseband/SA8x8.h b/platform/drivers/baseband/SA8x8.h index d9a30eb0..025957c4 100644 --- a/platform/drivers/baseband/SA8x8.h +++ b/platform/drivers/baseband/SA8x8.h @@ -58,9 +58,9 @@ int sa8x8_enableHSMode(); /** * Set the transmission power. * - * @param power: transmission power in Watt. + * @param power: transmission power in mW. */ -void sa8x8_setTxPower(const float power); +void sa8x8_setTxPower(const uint32_t power); /** * Enable or disable the speaker power amplifier. diff --git a/platform/drivers/baseband/radio_GDx.cpp b/platform/drivers/baseband/radio_GDx.cpp index caed49d1..25137950 100644 --- a/platform/drivers/baseband/radio_GDx.cpp +++ b/platform/drivers/baseband/radio_GDx.cpp @@ -331,7 +331,8 @@ void radio_updateConfiguration() C6000.setModAmplitude(0, mod1Amp); // Calculate APC voltage, constraining output power between 1W and 5W. - float power = std::max(std::min(config->txPower, 5.0f), 1.0f); + float power = static_cast < float >(config->txPower) / 1000.0f; + power = std::max(std::min(power, 5.0f), 1.0f); float pwrHi = static_cast< float >(txpwr_hi); float pwrLo = static_cast< float >(txpwr_lo); float apc = pwrLo + (pwrHi - pwrLo)/4.0f*(power - 1.0f); diff --git a/platform/drivers/baseband/radio_MD3x0.cpp b/platform/drivers/baseband/radio_MD3x0.cpp index a3a1671a..af9cc772 100644 --- a/platform/drivers/baseband/radio_MD3x0.cpp +++ b/platform/drivers/baseband/radio_MD3x0.cpp @@ -280,7 +280,8 @@ void radio_enableTx() SKY73210_setFrequency(pllFreq, 5); // Set TX output power, constrain between 1W and 5W. - float power = std::max(std::min(config->txPower, 5.0f), 1.0f); + float power = static_cast < float >(config->txPower) / 1000.0f; + power = std::max(std::min(power, 5.0f), 1.0f); float pwrHi = static_cast< float >(txpwr_hi); float pwrLo = static_cast< float >(txpwr_lo); float apc = pwrLo + (pwrHi - pwrLo)/4.0f*(power - 1.0f); diff --git a/platform/drivers/baseband/radio_UV3x0.cpp b/platform/drivers/baseband/radio_UV3x0.cpp index f077abe4..d3085c86 100644 --- a/platform/drivers/baseband/radio_UV3x0.cpp +++ b/platform/drivers/baseband/radio_UV3x0.cpp @@ -211,7 +211,8 @@ void radio_enableTx() at1846s.setFrequency(config->txFrequency); // Constrain output power between 1W and 5W. - float power = std::max(std::min(config->txPower, 5.0f), 1.0f); + float power = static_cast < float >(config->txPower) / 1000.0f; + power = std::max(std::min(power, 5.0f), 1.0f); float pwrHi = static_cast< float >(txpwr_hi); float pwrLo = static_cast< float >(txpwr_lo); float apc = pwrLo + (pwrHi - pwrLo)/4.0f*(power - 1.0f); diff --git a/platform/drivers/baseband/radio_ttwrplus.cpp b/platform/drivers/baseband/radio_ttwrplus.cpp index 96442300..e7fc45ff 100644 --- a/platform/drivers/baseband/radio_ttwrplus.cpp +++ b/platform/drivers/baseband/radio_ttwrplus.cpp @@ -131,7 +131,7 @@ void radio_enableTx() if(config->txDisable == 1) return; // Constrain output power between 1W and 5W. - float power = std::max(std::min(config->txPower, 5.0f), 1.0f); + uint32_t power = std::max(std::min(config->txPower, 5000U), 1000U); sa8x8_setTxPower(power); at1846s.setFrequency(config->txFrequency);