Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: modem_info: Update RSRP/RSRQ calculation #17528

Merged
merged 2 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,15 @@ Modem libraries

* :ref:`modem_info_readme` library:

* Updated to use the :ref:`at_parser_readme` library instead of the :ref:`at_cmd_parser_readme` library.
* Updated:

* To use the :ref:`at_parser_readme` library instead of the :ref:`at_cmd_parser_readme` library.
* The formulas of RSRP and RSRQ values in :c:macro:`RSRP_IDX_TO_DBM` and :c:macro:`RSRQ_IDX_TO_DB` based on AT command reference guide updates.
The formulas are now aligned with the modem implementation that has not changed
but the AT command reference guide has not been up to date with the modem implementation.

* Removed ``RSRP_OFFSET_VAL``, ``RSRQ_OFFSET_VAL`` and ``RSRQ_SCALE_VAL`` from the API.
Clients should have used the :c:macro:`RSRP_IDX_TO_DBM` and the :c:macro:`RSRQ_IDX_TO_DB` macros.

* :ref:`nrf_modem_lib_lte_net_if` library:

Expand Down
22 changes: 15 additions & 7 deletions include/modem/lte_lc.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,14 +399,14 @@ struct lte_lc_ncell {
/**
* RSRP.
*
* Format is the same as for @c rsrp member of struct @ref lte_lc_cell.
* Format is the same as for @c lte_lc_cell.rsrp member.
*/
int16_t rsrp;

/**
* RSRQ.
*
* Format is the same as for @c rsrq member of struct @ref lte_lc_cell.
* Format is the same as for @c lte_lc_cell.rsrq member.
*/
int16_t rsrq;
};
Expand Down Expand Up @@ -466,13 +466,15 @@ struct lte_lc_cell {
/**
* RSRP.
*
* Can be converted into dBm using @ref RSRP_IDX_TO_DBM macro.
*
* * -17: RSRP < -156 dBm
* * -16: -156 ≤ RSRP < -155 dBm
* * ...
* * -3: -143 ≤ RSRP < -142 dBm
* * -2: -142 ≤ RSRP < -141 dBm
* * -1: -141 ≤ RSRP < -140 dBm
* * 0: RSRP < -140 dBm
* * 0: Not used.
* * 1: -140 ≤ RSRP < -139 dBm
* * 2: -139 ≤ RSRP < -138 dBm
* * ...
Expand All @@ -486,12 +488,14 @@ struct lte_lc_cell {
/**
* RSRQ.
*
* * -30: RSRQ < -34 dB
* Can be converted into dB using @ref RSRQ_IDX_TO_DB macro.
*
* * -30: RSRQ < -34.5 dB
* * -29: -34 ≤ RSRQ < -33.5 dB
* * ...
* * -2: -20.5 ≤ RSRQ < -20 dB
* * -1: -20 ≤ RSRQ < -19.5 dB
* * 0: RSRQ < -19.5 dB
* * 0: Not used.
* * 1: -19.5 ≤ RSRQ < -19 dB
* * 2: -19 ≤ RSRQ < -18.5 dB
* * ...
Expand Down Expand Up @@ -807,13 +811,15 @@ struct lte_lc_conn_eval_params {
/**
* Current RSRP level at time of report.
*
* Can be converted into dBm using @ref RSRP_IDX_TO_DBM macro.
*
* * -17: RSRP < -156 dBm
* * -16: -156 ≤ RSRP < -155 dBm
* * ...
* * -3: -143 ≤ RSRP < -142 dBm
* * -2: -142 ≤ RSRP < -141 dBm
* * -1: -141 ≤ RSRP < -140 dBm
* * 0: RSRP < -140 dBm
* * 0: Not used.
* * 1: -140 ≤ RSRP < -139 dBm
* * 2: -139 ≤ RSRP < -138 dBm
* * ...
Expand All @@ -827,12 +833,14 @@ struct lte_lc_conn_eval_params {
/**
* Current RSRQ level at time of report.
*
* Can be converted into dB using @ref RSRQ_IDX_TO_DB macro.
*
* * -30: RSRQ < -34 dB
* * -29: -34 ≤ RSRQ < -33.5 dB
* * ...
* * -2: -20.5 ≤ RSRQ < -20 dB
* * -1: -20 ≤ RSRQ < -19.5 dB
* * 0: RSRQ < -19.5 dB
* * 0: Not used.
* * 1: -19.5 ≤ RSRQ < -19 dB
* * 2: -19 ≤ RSRQ < -18.5 dB
* * ...
Expand Down
87 changes: 71 additions & 16 deletions include/modem/modem_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ extern "C" {
/** Size of the JSON string. */
#define MODEM_INFO_JSON_STRING_SIZE 512

/** RSRP offset value. */
#define RSRP_OFFSET_VAL 140

/** RSRQ offset value. */
#define RSRQ_OFFSET_VAL 19.5f

/** RSRQ scale value. */
#define RSRQ_SCALE_VAL 0.5f

/** Modem firmware version string can be up to 40 characters long. */
#define MODEM_INFO_FWVER_SIZE 41

Expand All @@ -57,14 +48,78 @@ extern "C" {
/** SNR offset value. */
#define SNR_OFFSET_VAL 24

/** Modem returns RSRP and RSRQ as index values which require
* a conversion to dBm and dB respectively. See modem AT
* command reference guide for more information.
/** @brief Converts RSRP index value returned by the modem to dBm.
*
* The index value of RSRP can be converted to dBm with the following formula:
* * index < 0: index – 140
* * index = 0: Not used
* * index > 0: index – 141
*
* Example values:
* * -17: RSRP < -156 dBm
* * -16: -156 ≤ RSRP < -155 dBm
* * ...
* * -3: -143 ≤ RSRP < -142 dBm
* * -2: -142 ≤ RSRP < -141 dBm
* * -1: -141 ≤ RSRP < -140 dBm
* * 0: Not used.
* * 1: -140 ≤ RSRP < -139 dBm
* * 2: -139 ≤ RSRP < -138 dBm
* * ...
* * 95: -46 ≤ RSRP < -45 dBm
* * 96: -45 ≤ RSRP < -44 dBm
* * 97: -44 ≤ RSRP dBm
*
* There are use cases where the index value 0 is used to represent RSRP < -140 dBm.
*
* See modem AT command reference guide for more information.
trantanen marked this conversation as resolved.
Show resolved Hide resolved
*
* @param[in] rsrp RSRP index value as 'int'.
*
* @return RSRP in dBm as 'int'.
*/
#define RSRP_IDX_TO_DBM(rsrp) ((rsrp) - RSRP_OFFSET_VAL)

#define RSRQ_IDX_TO_DB(rsrq) ((((float)(rsrq)) * RSRQ_SCALE_VAL) - \
RSRQ_OFFSET_VAL)
#define RSRP_IDX_TO_DBM(rsrp) ((rsrp) < 0 ? (rsrp) - 140 : (rsrp) - 141)

/** @brief Converts RSRQ index value returned by the modem to dB.
*
* The index value of RSRQ can be converted to dB with the following formula:
* * index < 0: (index – 39) / 2
* * index = 0: Not used
* * index > 0 and index < 35: (index – 40) / 2
* * index ≥ 35: (index – 41) / 2
*
* Example values:
* * -30: RSRQ < -34.5 dB
* * -29: -34 ≤ RSRQ < -33.5 dB
* * ...
* * -2: -20.5 ≤ RSRQ < -20 dB
* * -1: -20 ≤ RSRQ < -19.5 dB
* * 0: Not used.
* * 1: -19.5 ≤ RSRQ < -19 dB
* * 2: -19 ≤ RSRQ < -18.5 dB
* * ...
* * 32: -4 ≤ RSRQ < -3.5 dB
* * 33: -3.5 ≤ RSRQ < -3 dB
* * 34: -3 ≤ RSRQ dB
* * 35: -3 ≤ RSRQ < -2.5 dB
* * 36: -2.5 ≤ RSRQ < -2 dB
* * ...
* * 45: 2 ≤ RSRQ < 2.5 dB
* * 46: 2.5 ≤ RSRQ dB
*
* There are use cases where the index value 0 is used to represent RSRQ < −19.5 dB.
*
* See modem AT command reference guide for more information.
*
* @param[in] rsrq RSRQ index value as 'int'.
*
* @return RSRQ in dB as 'float'.
*/
#define RSRQ_IDX_TO_DB(rsrq) ((rsrq) < 0 ? \
(((float)(rsrq) - 39) * 0.5f) : \
((rsrq) < 35 ? \
(((float)(rsrq) - 40) * 0.5f) : \
(((float)(rsrq) - 41) * 0.5f)))

/**@brief RSRP event handler function prototype. */
typedef void (*rsrp_cb_t)(char rsrp_value);
Expand Down
2 changes: 1 addition & 1 deletion lib/modem_info/modem_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ int modem_info_get_rsrp(int *val)
return -ENOENT;
}

*val = *val - RSRP_OFFSET_VAL;
*val = RSRP_IDX_TO_DBM(*val);
trantanen marked this conversation as resolved.
Show resolved Hide resolved
return 0;
}

Expand Down
114 changes: 113 additions & 1 deletion tests/lib/modem_info/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ FAKE_VALUE_FUNC_VARARG(int, nrf_modem_at_cmd, void *, size_t, const char *, ...)
#define EXAMPLE_TEMP 24
#define EXAMPLE_RSRP_INVALID 255
#define EXAMPLE_RSRP_VALID 160
#define RSRP_OFFSET 140
#define RSRP_OFFSET 141
#define EXAMPLE_BAND 13
#define EXAMPLE_BAND_MAX_VAL 71
#define EXAMPLE_ONE_LETTER_OPERATOR_NAME "O"
Expand Down Expand Up @@ -525,6 +525,118 @@ void test_modem_info_get_rsrp_success(void)
TEST_ASSERT_EQUAL(1, nrf_modem_at_scanf_fake.call_count);
}

void test_modem_info_RSRP_IDX_TO_DBM(void)
{
int rsrp;

/* index < 0: index – 140 */
rsrp = RSRP_IDX_TO_DBM(-16);
TEST_ASSERT_EQUAL(-156, rsrp);

rsrp = RSRP_IDX_TO_DBM(-1);
TEST_ASSERT_EQUAL(-141, rsrp);

/* index > 0: index – 141 */
rsrp = RSRP_IDX_TO_DBM(1);
TEST_ASSERT_EQUAL(-140, rsrp);

rsrp = RSRP_IDX_TO_DBM(2);
TEST_ASSERT_EQUAL(-139, rsrp);

rsrp = RSRP_IDX_TO_DBM(96);
TEST_ASSERT_EQUAL(-45, rsrp);

rsrp = RSRP_IDX_TO_DBM(97);
TEST_ASSERT_EQUAL(-44, rsrp);

/* 0 defined as not used but we'll test because macro accepts anything */
rsrp = RSRP_IDX_TO_DBM(0);
TEST_ASSERT_EQUAL(-141, rsrp);

/* Values outside the range of AT command examples */
rsrp = RSRP_IDX_TO_DBM(-17);
TEST_ASSERT_EQUAL(-157, rsrp);

rsrp = RSRP_IDX_TO_DBM(98);
TEST_ASSERT_EQUAL(-43, rsrp);
}

void test_modem_info_RSRQ_IDX_TO_DB(void)
{
float rsrq;

/* index < 0: (index – 39) / 2 */
rsrq = RSRQ_IDX_TO_DB(-30);
TEST_ASSERT_EQUAL_FLOAT(-34.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(-29);
TEST_ASSERT_EQUAL_FLOAT(-34, rsrq);

rsrq = RSRQ_IDX_TO_DB(-2);
TEST_ASSERT_EQUAL_FLOAT(-20.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(-1);
TEST_ASSERT_EQUAL_FLOAT(-20, rsrq);

/* index > 0 and index < 35: (index – 40) / 2 */
rsrq = RSRQ_IDX_TO_DB(1);
TEST_ASSERT_EQUAL_FLOAT(-19.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(2);
TEST_ASSERT_EQUAL_FLOAT(-19, rsrq);

rsrq = RSRQ_IDX_TO_DB(32);
TEST_ASSERT_EQUAL_FLOAT(-4, rsrq);

rsrq = RSRQ_IDX_TO_DB(33);
TEST_ASSERT_EQUAL_FLOAT(-3.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(34);
TEST_ASSERT_EQUAL_FLOAT(-3, rsrq);

/* index ≥ 35: (index – 41) / 2 */
rsrq = RSRQ_IDX_TO_DB(35);
TEST_ASSERT_EQUAL_FLOAT(-3, rsrq);

rsrq = RSRQ_IDX_TO_DB(36);
TEST_ASSERT_EQUAL_FLOAT(-2.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(37);
TEST_ASSERT_EQUAL_FLOAT(-2, rsrq);

rsrq = RSRQ_IDX_TO_DB(38);
TEST_ASSERT_EQUAL_FLOAT(-1.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(39);
TEST_ASSERT_EQUAL_FLOAT(-1, rsrq);

rsrq = RSRQ_IDX_TO_DB(40);
TEST_ASSERT_EQUAL_FLOAT(-0.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(41);
TEST_ASSERT_EQUAL_FLOAT(0, rsrq);

rsrq = RSRQ_IDX_TO_DB(42);
TEST_ASSERT_EQUAL_FLOAT(0.5, rsrq);

rsrq = RSRQ_IDX_TO_DB(45);
TEST_ASSERT_EQUAL_FLOAT(2, rsrq);

rsrq = RSRQ_IDX_TO_DB(46);
TEST_ASSERT_EQUAL_FLOAT(2.5, rsrq);

/* 0 defined as not used but we'll test because macro accepts anything */
rsrq = RSRQ_IDX_TO_DB(0);
TEST_ASSERT_EQUAL_FLOAT(-20, rsrq);

/* Values outside the range of AT command examples */
rsrq = RSRQ_IDX_TO_DB(-31);
TEST_ASSERT_EQUAL_FLOAT(-35, rsrq);

rsrq = RSRQ_IDX_TO_DB(47);
TEST_ASSERT_EQUAL_FLOAT(3, rsrq);
}

void test_modem_info_get_current_band_null(void)
{
int ret = modem_info_get_current_band(NULL);
Expand Down
Loading