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.
pull/238/head
Silvano Seva 2023-12-26 16:27:13 +01:00
rodzic dc930f4a4b
commit 5b3929ef44
19 zmienionych plików z 41 dodań i 53 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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.

Wyświetl plik

@ -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);
/**
*

Wyświetl plik

@ -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 */

Wyświetl plik

@ -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];

Wyświetl plik

@ -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 +

Wyświetl plik

@ -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(&currentLanguage->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);

Wyświetl plik

@ -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:

Wyświetl plik

@ -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)

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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 */
}
/*

Wyświetl plik

@ -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 */
}
/*

Wyświetl plik

@ -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");

Wyświetl plik

@ -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.

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);