Using signed 32-bit data type for RSSI instead of floating points

Switched to int32_t for RSSI representation to allow running the code also
on devices with limited resources. Defined a new ad-hoc type to still keep
the possibility of using floating points on more capable devices.
This commit is contained in:
Silvano Seva 2023-12-29 00:27:33 +01:00
parent 963f402f1b
commit 44385b3b25
18 changed files with 50 additions and 36 deletions

View File

@ -45,6 +45,13 @@ typedef unsigned int tone_t;
*/ */
typedef uint32_t freq_t; typedef uint32_t freq_t;
/**
* \brief RSSI type.
*
* Data type for RSSI, in dBm.
*/
typedef int32_t rssi_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -20,6 +20,7 @@
#ifndef GRAPHICS_H #ifndef GRAPHICS_H
#define GRAPHICS_H #define GRAPHICS_H
#include <datatypes.h>
#include <symbols.h> #include <symbols.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
@ -307,7 +308,7 @@ void gfx_drawBattery(point_t start, uint16_t width, uint16_t height,
* @param drawVolume: whether the volume bar should be drawn * @param drawVolume: whether the volume bar should be drawn
* @param color: color of the squelch bar * @param color: color of the squelch bar
*/ */
void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, float rssi, void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, rssi_t rssi,
uint8_t squelch, uint8_t volume, bool drawVolume, color_t color); uint8_t squelch, uint8_t volume, bool drawVolume, color_t color);
/** /**
@ -323,7 +324,7 @@ void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, float rssi,
* @param drawVolume: whether the volume bar should be drawn * @param drawVolume: whether the volume bar should be drawn
*/ */
void gfx_drawSmeterLevel(point_t start, uint16_t width, uint16_t height, void gfx_drawSmeterLevel(point_t start, uint16_t width, uint16_t height,
float rssi, uint8_t level, uint8_t volume, bool drawVolume); rssi_t rssi, uint8_t level, uint8_t volume, bool drawVolume);
/** /**
* Function to draw GPS SNR bar graph of arbitrary size. * Function to draw GPS SNR bar graph of arbitrary size.

View File

@ -39,7 +39,7 @@ typedef struct
datetime_t time; datetime_t time;
uint16_t v_bat; uint16_t v_bat;
uint8_t charge; uint8_t charge;
float rssi; rssi_t rssi;
uint8_t ui_screen; uint8_t ui_screen;
uint8_t tuner_mode; uint8_t tuner_mode;

View File

@ -124,7 +124,7 @@ void radio_updateConfiguration();
* *
* @return RSSI level in dBm. * @return RSSI level in dBm.
*/ */
float radio_getRssi(); rssi_t radio_getRssi();
/** /**
* Get the current operating status of the radio module. * Get the current operating status of the radio module.

View File

@ -138,7 +138,7 @@ void rtx_task();
* Get current RSSI in dBm. * Get current RSSI in dBm.
* @return RSSI value in dBm. * @return RSSI value in dBm.
*/ */
float rtx_getRssi(); rssi_t rtx_getRssi();
/** /**
* Get current status of the RX squelch. This function is thread-safe and can * Get current status of the RX squelch. This function is thread-safe and can

View File

@ -740,7 +740,7 @@ void gfx_drawBattery(point_t start, uint16_t width, uint16_t height,
* Width (px) * Width (px)
* *
*/ */
void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, float rssi, void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, rssi_t rssi,
uint8_t squelch, uint8_t volume, bool drawVolume, color_t color) uint8_t squelch, uint8_t volume, bool drawVolume, color_t color)
{ {
color_t white = {255, 255, 255, 255}; color_t white = {255, 255, 255, 255};
@ -794,9 +794,9 @@ void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, float rssi,
// RSSI bar // RSSI bar
uint16_t rssi_height = bar_height * 4 / bar_height_divider; uint16_t rssi_height = bar_height * 4 / bar_height_divider;
float s_level = (127.0f + rssi) / 6.0f; int16_t s_level = (127 + rssi) / 6;
uint16_t rssi_width = (s_level < 0.0f) ? 0 : (s_level * (width - 1) / 11); uint16_t rssi_width = (s_level < 0) ? 0 : (s_level * (width - 1) / 11);
rssi_width = (s_level > 10.0f) ? width : rssi_width; rssi_width = (s_level > 10) ? width : rssi_width;
point_t rssi_pos = { start.x, (uint8_t) (start.y + 2 + squelch_height + volume_height)}; point_t rssi_pos = { start.x, (uint8_t) (start.y + 2 + squelch_height + volume_height)};
gfx_drawRect(rssi_pos, rssi_width, rssi_height, white, true); gfx_drawRect(rssi_pos, rssi_width, rssi_height, white, true);
} }
@ -826,7 +826,7 @@ void gfx_drawSmeter(point_t start, uint16_t width, uint16_t height, float rssi,
* Width (px) * Width (px)
* *
*/ */
void gfx_drawSmeterLevel(point_t start, uint16_t width, uint16_t height, float rssi, void gfx_drawSmeterLevel(point_t start, uint16_t width, uint16_t height, rssi_t rssi,
uint8_t level, uint8_t volume, bool drawVolume) uint8_t level, uint8_t volume, bool drawVolume)
{ {
color_t red = {255, 0, 0 , 255}; color_t red = {255, 0, 0 , 255};
@ -863,10 +863,10 @@ void gfx_drawSmeterLevel(point_t start, uint16_t width, uint16_t height, float r
point_t level_pos = { start.x, (uint8_t) (start.y + 2 + volume_height)}; point_t level_pos = { start.x, (uint8_t) (start.y + 2 + volume_height)};
gfx_drawRect(level_pos, level_width, level_height, green, true); gfx_drawRect(level_pos, level_width, level_height, green, true);
// RSSI bar // RSSI bar
float s_level = (127.0f + rssi) / 6.0f; int16_t s_level = (127 + rssi) / 6;
uint16_t rssi_height = bar_height * 3 / bar_height_divider; uint16_t rssi_height = bar_height * 3 / bar_height_divider;
uint16_t rssi_width = (s_level < 0.0f) ? 0 : (s_level * (width - 1) / 11); uint16_t rssi_width = (s_level < 0) ? 0 : (s_level * (width - 1) / 11);
rssi_width = (s_level > 10.0f) ? width : rssi_width; rssi_width = (s_level > 10) ? width : rssi_width;
point_t rssi_pos = {start.x, (uint8_t) (start.y + 5 + level_height + volume_height)}; point_t rssi_pos = {start.x, (uint8_t) (start.y + 5 + level_height + volume_height)};
gfx_drawRect(rssi_pos, rssi_width, rssi_height, white, true); gfx_drawRect(rssi_pos, rssi_width, rssi_height, white, true);
// S-level marks and numbers // S-level marks and numbers

View File

@ -103,13 +103,13 @@ void OpMode_FM::update(rtxStatus_t *const status, const bool newCfg)
{ {
// RF squelch mechanism // RF squelch mechanism
// This turns squelch (0 to 15) into RSSI (-127.0dbm to -61dbm) // This turns squelch (0 to 15) into RSSI (-127.0dbm to -61dbm)
float squelch = -127.0f + status->sqlLevel * 66.0f / 15.0f; rssi_t squelch = -127 + (status->sqlLevel * 66) / 15;
float rssi = rtx_getRssi(); rssi_t rssi = rtx_getRssi();
// Provide a bit of hysteresis, only change state if the RSSI has // Provide a bit of hysteresis, only change state if the RSSI has
// moved more than .1dbm on either side of the current squelch setting. // moved more than 1dBm on either side of the current squelch setting.
if((rfSqlOpen == false) && (rssi > (squelch + 0.1f))) rfSqlOpen = true; if((rfSqlOpen == false) && (rssi > (squelch + 1))) rfSqlOpen = true;
if((rfSqlOpen == true) && (rssi < (squelch - 0.1f))) rfSqlOpen = false; if((rfSqlOpen == true) && (rssi < (squelch - 1))) rfSqlOpen = false;
// Local flags for current RF and tone squelch status // Local flags for current RF and tone squelch status
bool rfSql = ((status->rxToneEn == 0) && (rfSqlOpen == true)); bool rfSql = ((status->rxToneEn == 0) && (rfSqlOpen == true));

View File

@ -28,7 +28,7 @@
static pthread_mutex_t *cfgMutex; // Mutex for incoming config messages static pthread_mutex_t *cfgMutex; // Mutex for incoming config messages
static const rtxStatus_t *newCnf; // Pointer for incoming config messages static const rtxStatus_t *newCnf; // Pointer for incoming config messages
static rtxStatus_t rtxStatus; // RTX driver status static rtxStatus_t rtxStatus; // RTX driver status
static float rssi; // Current RSSI in dBm static rssi_t rssi; // Current RSSI in dBm
static bool reinitFilter; // Flag for RSSI filter re-initialisation static bool reinitFilter; // Flag for RSSI filter re-initialisation
static OpMode *currMode; // Pointer to currently active opMode handler static OpMode *currMode; // Pointer to currently active opMode handler
@ -190,7 +190,13 @@ void rtx_task()
{ {
if(!reinitFilter) if(!reinitFilter)
{ {
rssi = 0.74*radio_getRssi() + 0.26*rssi; /*
* Filter RSSI value using 15.16 fixed point math. Equivalent
* floating point code is: rssi = 0.74*radio_getRssi() + 0.26*rssi
*/
int32_t filt_rssi = radio_getRssi() * 0xBD70 // 0.74 * radio_getRssi
+ rssi * 0x428F; // 0.26 * rssi
rssi = (filt_rssi + 32768) >> 16; // Round to nearest
} }
else else
{ {
@ -213,7 +219,7 @@ void rtx_task()
currMode->update(&rtxStatus, reconfigure); currMode->update(&rtxStatus, reconfigure);
} }
float rtx_getRssi() rssi_t rtx_getRssi()
{ {
return rssi; return rssi;
} }

View File

@ -260,7 +260,7 @@ void _ui_drawVFOMiddleInput(ui_state_t* ui_state)
void _ui_drawMainBottom() void _ui_drawMainBottom()
{ {
// Squelch bar // Squelch bar
float rssi = last_state.rssi; rssi_t rssi = last_state.rssi;
uint8_t squelch = last_state.settings.sqlLevel; uint8_t squelch = last_state.settings.sqlLevel;
uint8_t volume = platform_getVolumeLevel(); uint8_t volume = platform_getVolumeLevel();
uint16_t meter_width = CONFIG_SCREEN_WIDTH - 2 * layout.horizontal_pad; uint16_t meter_width = CONFIG_SCREEN_WIDTH - 2 * layout.horizontal_pad;

View File

@ -516,7 +516,7 @@ int _ui_getInfoValueName(char *buf, uint8_t max_len, uint8_t index)
snprintf(buf, max_len, "%d%%", last_state.charge); snprintf(buf, max_len, "%d%%", last_state.charge);
break; break;
case 3: // RSSI case 3: // RSSI
snprintf(buf, max_len, "%.1fdBm", last_state.rssi); snprintf(buf, max_len, "%ddBm", last_state.rssi);
break; break;
case 4: // Heap usage case 4: // Heap usage
snprintf(buf, max_len, "%dB", getHeapSize() - getCurrentFreeHeap()); snprintf(buf, max_len, "%dB", getHeapSize() - getCurrentFreeHeap());

View File

@ -369,9 +369,9 @@ void radio_updateConfiguration()
if(radioStatus == TX) radio_enableTx(); if(radioStatus == TX) radio_enableTx();
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
return static_cast< float >(at1846s.readRSSI()); return static_cast< rssi_t > (at1846s.readRSSI());
} }
enum opstatus radio_getStatus() enum opstatus radio_getStatus()

View File

@ -397,7 +397,7 @@ void radio_updateConfiguration()
if(radioStatus == TX) radio_enableTx(); if(radioStatus == TX) radio_enableTx();
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
/* /*
* On MD3x0 devices, RSSI value is get by reading the analog RSSI output * On MD3x0 devices, RSSI value is get by reading the analog RSSI output
@ -415,7 +415,7 @@ float radio_getRssi()
float rssi_mv = ((float) 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; float rssi_dbm = (rssi_mv - rssi_offset[offset_index]) / rssi_gain;
return rssi_dbm; return static_cast< rssi_t >(rssi_dbm);
} }
enum opstatus radio_getStatus() enum opstatus radio_getStatus()

View File

@ -76,7 +76,7 @@ void radio_updateConfiguration()
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
return -154.0f; return -154.0f;
} }

View File

@ -99,7 +99,7 @@ void radio_updateConfiguration()
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
return -123.0f; return -123.0f;
} }

View File

@ -366,9 +366,9 @@ void radio_updateConfiguration()
if(radioStatus == TX) radio_enableTx(); if(radioStatus == TX) radio_enableTx();
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
return static_cast< float > (at1846s.readRSSI()); return static_cast< rssi_t >(at1846s.readRSSI());
} }
enum opstatus radio_getStatus() enum opstatus radio_getStatus()

View File

@ -78,11 +78,11 @@ void radio_updateConfiguration()
puts("radio_linux: updateConfiguration() called"); puts("radio_linux: updateConfiguration() called");
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
// Commented to reduce verbosity on Linux // Commented to reduce verbosity on Linux
// printf("radio_linux: requested RSSI at freq %d, returning -100dBm\n", rxFreq); // printf("radio_linux: requested RSSI at freq %d, returning -100dBm\n", rxFreq);
return emulator_state.RSSI; return static_cast< rssi_t >(emulator_state.RSSI);
} }
enum opstatus radio_getStatus() enum opstatus radio_getStatus()

View File

@ -181,9 +181,9 @@ void radio_updateConfiguration()
if(radioStatus == TX) radio_enableTx(); if(radioStatus == TX) radio_enableTx();
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
return static_cast< float > (at1846s.readRSSI()); return static_cast< rssi_t > (at1846s.readRSSI());
} }
enum opstatus radio_getStatus() enum opstatus radio_getStatus()

View File

@ -67,7 +67,7 @@ void radio_updateConfiguration()
} }
float radio_getRssi() rssi_t radio_getRssi()
{ {
return -121.0f; // S1 level: -121dBm return -121.0f; // S1 level: -121dBm
} }