diff --git a/openrtx/include/calibration/calibInfo_CS7000.h b/openrtx/include/calibration/calibInfo_CS7000.h index ffcdc477..bf65ec9d 100644 --- a/openrtx/include/calibration/calibInfo_CS7000.h +++ b/openrtx/include/calibration/calibInfo_CS7000.h @@ -40,4 +40,14 @@ struct CS7000Calib uint8_t errorRate[8]; // 0x0DC }; +/** + * \brief RSSI calibration data. + */ +struct rssiParams +{ + float slope; + float offset; + uint32_t rxFreq; +}; + #endif /* CALIBINFO_CS7000_H */ diff --git a/platform/drivers/baseband/radio_CS7000.cpp b/platform/drivers/baseband/radio_CS7000.cpp index f111a6e6..9456282e 100644 --- a/platform/drivers/baseband/radio_CS7000.cpp +++ b/platform/drivers/baseband/radio_CS7000.cpp @@ -35,6 +35,7 @@ static struct CS7000Calib calData; // Calibration data static uint8_t vtune_rx = 0; // Tuning voltage for RX input filter static uint8_t txpwr_lo = 0; // APC voltage for TX output power control, low power static uint8_t txpwr_hi = 0; // APC voltage for TX output power control, high power +static struct rssiParams rssi; // RSSI curve parameters static enum opstatus radioStatus; // Current operating status @@ -42,14 +43,22 @@ HR_C6000 C6000((const struct spiDevice *) &c6000_spi, { C6K_CS }); /* * Parameters for RSSI voltage (mV) to input power (dBm) conversion. - * Gain is constant, while offset values are aligned to calibration frequency - * test points. + * Measurements have been taked in the RX calibration points with input signal + * going from -121dBm to -63dBm. * Thanks to Wojciech SP5WWP for the measurements! + * + * NOTE: there are seven calibration points over eight RX frequencies. */ -const float rssi_gain = 22.0f; -const float rssi_offset[] = {3277.618f, 3654.755f, 3808.191f, - 3811.318f, 3804.936f, 3806.591f, - 3723.882f, 3621.373f, 3559.782f}; +static const struct rssiParams rssiCal[] = +{ // slope offset rxFreq + {0.0370f, -138.76814f, 400250000 }, // 400.250MHz + {0.0371f, -135.07381f, 425050000 }, // 425.050MHz + {0.0372f, -136.61596f, 449950000 }, // 449.950MHz + {0.0375f, -136.87895f, 460050000 }, // 460.050MHz + {0.0374f, -136.56000f, 470050000 }, // 470.050MHz + {0.0374f, -136.34097f, 478985000 }, // 478.985MHz + {0.0372f, -135.62165f, 479050000 } // 479.050MHz +}; static uint8_t interpParameter(uint32_t freq, uint32_t *calFreq, uint8_t param[8]) { @@ -94,6 +103,35 @@ static uint8_t interpParameter(uint32_t freq, uint32_t *calFreq, uint8_t param[8 return ret; } +static struct rssiParams interpRssi(const uint32_t freq, const struct rssiParams cal[7]) +{ + if(freq < cal[0].rxFreq) + return cal[0]; + + if(freq > cal[6].rxFreq) + return cal[6]; + + uint8_t idx; + for(idx = 5; idx > 0; idx--) + { + if(freq >= cal[idx].rxFreq) + break; + } + + const struct rssiParams *calLo = &cal[idx]; + const struct rssiParams *calHi = &cal[idx + 1]; + + float num = ((float)(freq - calLo->rxFreq)); + float den = ((float)(calHi->rxFreq - calLo->rxFreq)); + float offs = calHi->offset - calLo->offset; + float slope = calHi->slope - calLo->slope; + + struct rssiParams result; + result.offset = calLo->offset + ((offs * num) / den); + result.slope = calLo->slope + ((slope * num) / den); + + return result; +} void radio_init(const rtxStatus_t *rtxState) { @@ -301,6 +339,9 @@ void radio_updateConfiguration() C6000.writeCfgRegister(0x45, qAmp); // Adjustment of Mod2 amplitude C6000.writeCfgRegister(0x46, iAmp); // Adjustment of Mod1 amplitude + // RSSI interpolation curve + rssi = interpRssi(config->rxFrequency, rssiCal); + /* * Update VCO frequency and tuning parameters if current operating status * is different from OFF. @@ -314,21 +355,12 @@ void radio_updateConfiguration() rssi_t radio_getRssi() { /* - * On MD3x0 devices, RSSI value is get by reading the analog RSSI output - * from second IF stage (GT3136 IC). - * The corresponding power value is obtained through the linear correlation - * existing between measured voltage in mV and power in dBm. While gain is - * constant, offset depends from the rx frequency. + * RSSI value is get by reading the analog RSSI output from second IF stage + * (AK2365 IC). The corresponding power value is obtained through the linear + * correlation existing between measured voltage in mV and power in dBm. */ - - freq_t rxFreq = config->rxFrequency; - uint32_t offset_index = (rxFreq - 400035000)/10000000; - - if(rxFreq < 401035000) offset_index = 0; - if(rxFreq > 479995000) offset_index = 8; - float rssi_mv = ((float) adc_getVoltage(&adc1, ADC_RSSI_CH)) / 1000.0f; - float rssi_dbm = (rssi_mv - rssi_offset[offset_index]) / rssi_gain; + float rssi_dbm = (rssi_mv * rssi.slope) + rssi.offset; return static_cast< rssi_t >(rssi_dbm); }