mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 23:09:26 -05:00
Adding Rx IQ error phase CAL to SPEC Audio_App (#1963)
This commit is contained in:
parent
73c29f666f
commit
9d8132978f
@ -30,6 +30,7 @@
|
|||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
#include "ui_freqman.hpp"
|
#include "ui_freqman.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
#include "radio.hpp"
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
using namespace tonekey;
|
using namespace tonekey;
|
||||||
@ -112,10 +113,14 @@ SPECOptionsView::SPECOptionsView(
|
|||||||
: View{parent_rect} {
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
add_children({&label_config,
|
add_children({
|
||||||
|
&label_config,
|
||||||
&options_config,
|
&options_config,
|
||||||
&text_speed,
|
&text_speed,
|
||||||
&field_speed});
|
&field_speed,
|
||||||
|
&text_rx_cal,
|
||||||
|
hackrf_r9 ? &field_rx_iq_phase_cal_2839 : &field_rx_iq_phase_cal_2837 // max2839 has 6 bits [0..63], max2837 has 5 bits [0..31]
|
||||||
|
});
|
||||||
|
|
||||||
options_config.set_selected_index(view->get_spec_bw_index());
|
options_config.set_selected_index(view->get_spec_bw_index());
|
||||||
options_config.on_change = [this, view](size_t n, OptionsField::value_t bw) {
|
options_config.on_change = [this, view](size_t n, OptionsField::value_t bw) {
|
||||||
@ -126,6 +131,18 @@ SPECOptionsView::SPECOptionsView(
|
|||||||
field_speed.on_change = [this, view](int32_t v) {
|
field_speed.on_change = [this, view](int32_t v) {
|
||||||
view->set_spec_trigger(v);
|
view->set_spec_trigger(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (hackrf_r9) { // MAX2839 has 6 bits RX IQ CAL phasse adjustment.
|
||||||
|
field_rx_iq_phase_cal_2839.set_value(view->get_spec_iq_phase_calibration_value()); // using accessor function of AnalogAudioView to read iq_phase_calibration_value from rx_audio.ini
|
||||||
|
field_rx_iq_phase_cal_2839.on_change = [this, view](int32_t v) {
|
||||||
|
view->set_spec_iq_phase_calibration_value(v); // using accessor function of AnalogAudioView to write inside SPEC submenu, register value to max283x and save it to rx_audio.ini
|
||||||
|
};
|
||||||
|
} else { // MAX2837 has 5 bits RX IQ CAL phase adjustment.
|
||||||
|
field_rx_iq_phase_cal_2837.set_value(view->get_spec_iq_phase_calibration_value()); // using accessor function of AnalogAudioView to read iq_phase_calibration_value from rx_audio.ini
|
||||||
|
field_rx_iq_phase_cal_2837.on_change = [this, view](int32_t v) {
|
||||||
|
view->set_spec_iq_phase_calibration_value(v); // using accessor function of AnalogAudioView to write inside SPEC submenu, register value to max283x and save it to rx_audio.ini
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AnalogAudioView *******************************************************/
|
/* AnalogAudioView *******************************************************/
|
||||||
@ -213,6 +230,15 @@ void AnalogAudioView::set_spec_bw(size_t index, uint32_t bw) {
|
|||||||
receiver_model.set_baseband_bandwidth(bw / 2);
|
receiver_model.set_baseband_bandwidth(bw / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t AnalogAudioView::get_spec_iq_phase_calibration_value() { // define accessor functions inside AnalogAudioView to read & write real iq_phase_calibration_value
|
||||||
|
return iq_phase_calibration_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogAudioView::set_spec_iq_phase_calibration_value(uint8_t cal_value) { // define accessor functions
|
||||||
|
iq_phase_calibration_value = cal_value;
|
||||||
|
radio::set_rx_max283x_iq_phase_calibration(iq_phase_calibration_value);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t AnalogAudioView::get_spec_trigger() {
|
uint16_t AnalogAudioView::get_spec_trigger() {
|
||||||
return spec_trigger;
|
return spec_trigger;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,23 @@ class SPECOptionsView : public View {
|
|||||||
1,
|
1,
|
||||||
' ',
|
' ',
|
||||||
};
|
};
|
||||||
|
Text text_rx_cal{
|
||||||
|
{19 * 8, 0 * 16, 11 * 8, 1 * 16}, // 18 (x col.) x char_size, 12 (length) x 8 blanking space to delete previous chars.
|
||||||
|
"Rx_IQ_CAL "};
|
||||||
|
NumberField field_rx_iq_phase_cal_2837{
|
||||||
|
{28 * 8, 0 * 16},
|
||||||
|
2,
|
||||||
|
{0, 31}, // 5 bits IQ CAL phase adjustment.
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
};
|
||||||
|
NumberField field_rx_iq_phase_cal_2839{
|
||||||
|
{28 * 8, 0 * 16},
|
||||||
|
2,
|
||||||
|
{0, 63}, // 6 bits IQ CAL phase adjustment.
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnalogAudioView : public View {
|
class AnalogAudioView : public View {
|
||||||
@ -152,14 +169,22 @@ class AnalogAudioView : public View {
|
|||||||
uint16_t get_spec_trigger();
|
uint16_t get_spec_trigger();
|
||||||
void set_spec_trigger(uint16_t trigger);
|
void set_spec_trigger(uint16_t trigger);
|
||||||
|
|
||||||
|
uint8_t get_spec_iq_phase_calibration_value();
|
||||||
|
void set_spec_iq_phase_calibration_value(uint8_t cal_value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr ui::Dim header_height = 3 * 16;
|
static constexpr ui::Dim header_height = 3 * 16;
|
||||||
|
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
RxRadioState radio_state_{};
|
RxRadioState radio_state_{};
|
||||||
|
uint8_t iq_phase_calibration_value{15}; // initial default RX IQ phase calibration value , used for both max2837 & max2839
|
||||||
app_settings::SettingsManager settings_{
|
app_settings::SettingsManager settings_{
|
||||||
"rx_audio", app_settings::Mode::RX,
|
"rx_audio",
|
||||||
app_settings::Options::UseGlobalTargetFrequency};
|
app_settings::Mode::RX,
|
||||||
|
app_settings::Options::UseGlobalTargetFrequency,
|
||||||
|
{
|
||||||
|
{"iq_phase_calibration"sv, &iq_phase_calibration_value}, // we are saving and restoring that CAL from Settings.
|
||||||
|
}};
|
||||||
|
|
||||||
const Rect options_view_rect{0 * 8, 1 * 16, 30 * 8, 1 * 16};
|
const Rect options_view_rect{0 * 8, 1 * 16, 30 * 8, 1 * 16};
|
||||||
const Rect nbfm_view_rect{0 * 8, 1 * 16, 18 * 8, 1 * 16};
|
const Rect nbfm_view_rect{0 * 8, 1 * 16, 18 * 8, 1 * 16};
|
||||||
|
@ -150,7 +150,7 @@ void MAX2837::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MAX2837::set_tx_LO_iq_phase_calibration(const size_t v) {
|
void MAX2837::set_tx_LO_iq_phase_calibration(const size_t v) {
|
||||||
/* IQ phase deg CAL adj (+4 ...-4) in 32 steps (5 bits), 00000 = +4deg (Q lags I by 94degs, default), 01111 = +0deg, 11111 = -4deg (Q lags I by 86degs) */
|
/* TX IQ phase deg CAL adj (+4 ...-4) in 32 steps (5 bits), 00000 = +4deg (Q lags I by 94degs, default), 01111 = +0deg, 11111 = -4deg (Q lags I by 86degs) */
|
||||||
|
|
||||||
// TX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,0,1 (5dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1)
|
// TX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,0,1 (5dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1)
|
||||||
set_mode(Mode::Tx_Calibration); // write to ram 3 LOGIC Pins .
|
set_mode(Mode::Tx_Calibration); // write to ram 3 LOGIC Pins .
|
||||||
@ -324,14 +324,41 @@ bool MAX2837::set_frequency(const rf::Frequency lo_frequency) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void MAX2837::set_rx_lo_iq_calibration(const size_t v) {
|
void MAX2837::set_rx_lo_iq_calibration(const size_t v) { // Original code , rewritten below
|
||||||
_map.r.rx_top_rx_bias.RX_IQERR_SPI_EN = 1;
|
_map.r.rx_top_rx_bias.RX_IQERR_SPI_EN = 1;
|
||||||
_dirty[Register::RX_TOP_RX_BIAS] = 1;
|
_dirty[Register::RX_TOP_RX_BIAS] = 1;
|
||||||
_map.r.rxrf_2.iqerr_trim = v;
|
_map.r.rxrf_2.iqerr_trim = v;
|
||||||
_dirty[Register::RXRF_2] = 1;
|
_dirty[Register::RXRF_2] = 1;
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void MAX2837::set_rx_LO_iq_phase_calibration(const size_t v) {
|
||||||
|
/* RX IQ phase deg CAL adj (+4 ...-4) in 32 steps (5 bits), 00000 = +4deg (Q lags I by 94degs, default), 01111 = +0deg, 11111 = -4deg (Q lags I by 86degs) */
|
||||||
|
|
||||||
|
// RX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,1,0 (3dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1)
|
||||||
|
set_mode(Mode::Rx_Calibration); // write to ram 3 LOGIC Pins .
|
||||||
|
|
||||||
|
gpio_max283x_enable.output();
|
||||||
|
gpio_max2837_rxenable.output();
|
||||||
|
gpio_max2837_txenable.output();
|
||||||
|
|
||||||
|
_map.r.spi_en.CAL_SPI = 1; // Register Settings reg address 16, D1 (CAL mode 1)
|
||||||
|
_map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1)
|
||||||
|
flush_one(Register::SPI_EN);
|
||||||
|
|
||||||
|
_map.r.rx_top_rx_bias.RX_IQERR_SPI_EN = 1; // reg 8 D9, RX LO IQ Phase calibration SPI control. Active when Address 8 D<9> = 1.
|
||||||
|
flush_one(Register::RX_TOP_RX_BIAS);
|
||||||
|
|
||||||
|
_map.r.rxrf_2.iqerr_trim = v; // reg 1 D9:D5, RX LO I/Q Phase SPI 5 bits Adjust
|
||||||
|
flush_one(Register::RXRF_2);
|
||||||
|
|
||||||
|
// Exit Calibration mode, Go back to reg 16, D1:D0 , Out of CALIBRATION , back to default conditions, but keep CS activated.
|
||||||
|
_map.r.spi_en.CAL_SPI = 0; // Register Settings reg address 16, D1 (0 = Normal operation (default)
|
||||||
|
_map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (1 = Chip select enable )
|
||||||
|
flush_one(Register::SPI_EN);
|
||||||
|
}
|
||||||
|
|
||||||
void MAX2837::set_rx_bias_trim(const size_t v) {
|
void MAX2837::set_rx_bias_trim(const size_t v) {
|
||||||
_map.r.rx_top_rx_bias.EN_Bias_Trim = 1;
|
_map.r.rx_top_rx_bias.EN_Bias_Trim = 1;
|
||||||
|
@ -828,7 +828,7 @@ class MAX2837 : public MAX283x {
|
|||||||
|
|
||||||
bool set_frequency(const rf::Frequency lo_frequency) override;
|
bool set_frequency(const rf::Frequency lo_frequency) override;
|
||||||
|
|
||||||
void set_rx_lo_iq_calibration(const size_t v) override;
|
void set_rx_LO_iq_phase_calibration(const size_t v) override;
|
||||||
void set_tx_LO_iq_phase_calibration(const size_t v) override;
|
void set_tx_LO_iq_phase_calibration(const size_t v) override;
|
||||||
void set_rx_bias_trim(const size_t v);
|
void set_rx_bias_trim(const size_t v);
|
||||||
void set_vco_bias(const size_t v);
|
void set_vco_bias(const size_t v);
|
||||||
|
@ -367,13 +367,38 @@ bool MAX2839::set_frequency(const rf::Frequency lo_frequency) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void MAX2839::set_rx_lo_iq_calibration(const size_t v) {
|
void MAX2839::set_rx_LO_iq_phase_calibration(const size_t v) { // Original code , rewritten below
|
||||||
_map.r.rxrf_2.RX_IQERR_SPI_EN = 1;
|
_map.r.rxrf_2.RX_IQERR_SPI_EN = 1;
|
||||||
_dirty[Register::RXRF_2] = 1;
|
_dirty[Register::RXRF_2] = 1;
|
||||||
_map.r.rxrf_1.iqerr_trim = v;
|
_map.r.rxrf_1.iqerr_trim = v;
|
||||||
_dirty[Register::RXRF_1] = 1;
|
_dirty[Register::RXRF_1] = 1;
|
||||||
flush();
|
flush();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void MAX2839::set_rx_LO_iq_phase_calibration(const size_t v) {
|
||||||
|
/* RX IQ phase deg CAL adj (+4 ...-4) in 64 steps (6 bits), 000000 = +4deg (Q lags I by 94degs, default), 011111 = +0deg, 111111 = -4deg (Q lags I by 86degs) */
|
||||||
|
|
||||||
|
// RX calibration , Logic pins , ENABLE, RXENABLE, TXENABLE = 1,1,0 (3dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1)
|
||||||
|
set_mode(Mode::Rx_Calibration); // write to ram 3 LOGIC Pins .
|
||||||
|
|
||||||
|
gpio_max283x_enable.output(); // max2839 has only 2 x pins + regs to decide mode.
|
||||||
|
gpio_max2839_rxtx.output(); // Here is combined rx & tx pin in one port.
|
||||||
|
|
||||||
|
_map.r.spi_en.CAL_SPI = 1; // Register Settings reg address 16, D1 (CAL mode 1)
|
||||||
|
_map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1)
|
||||||
|
flush_one(Register::SPI_EN);
|
||||||
|
|
||||||
|
_map.r.rxrf_2.RX_IQERR_SPI_EN = 1; // reg 2 D<2> = 1, RX LO IQ calibration SPI control. Active when Address 2 D<2> = 1.
|
||||||
|
_dirty[Register::RXRF_2] = 1;
|
||||||
|
|
||||||
|
_map.r.rxrf_1.iqerr_trim = v;
|
||||||
|
_dirty[Register::RXRF_1] = 1;
|
||||||
|
flush();
|
||||||
|
|
||||||
|
_map.r.spi_en.CAL_SPI = 0; // Register Settings reg address 16, D1 (CAL mode 1)
|
||||||
|
_map.r.spi_en.EN_SPI = 1; // Register Settings reg address 16, DO (CHIP ENABLE 1)
|
||||||
|
flush_one(Register::SPI_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MAX2839::set_rx_buff_vcm(const size_t v) {
|
void MAX2839::set_rx_buff_vcm(const size_t v) {
|
||||||
|
@ -82,11 +82,11 @@ struct RXENABLE_Type {
|
|||||||
static_assert(sizeof(RXENABLE_Type) == sizeof(reg_t), "RXENABLE_Type wrong size");
|
static_assert(sizeof(RXENABLE_Type) == sizeof(reg_t), "RXENABLE_Type wrong size");
|
||||||
|
|
||||||
struct RXRF_1_Type {
|
struct RXRF_1_Type {
|
||||||
reg_t LNAband : 1;
|
reg_t LNAband : 2; // Datasheet says D1:D0 , 2 bits, maybe D1 Rx_B, D0 Rx_A , (original code said wrongly ,reg_t LNAband : 1; that was of for max2837, not max2839 )
|
||||||
reg_t RESERVED0 : 1;
|
reg_t RESERVED0 : 1;
|
||||||
reg_t MIMOmode : 1;
|
reg_t MIMOmode : 1;
|
||||||
reg_t iqerr_trim : 5;
|
reg_t iqerr_trim : 6; // Datasheet says D9_D4 , that means 6 bits, (original code said wrongly ,reg_t iqerr_trim : 5; )
|
||||||
reg_t RESERVED1 : 6;
|
reg_t RESERVED1 : 6; // we are using 16 bits , even top part mapping is not used
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(RXRF_1_Type) == sizeof(reg_t), "RXRF_1_Type wrong size");
|
static_assert(sizeof(RXRF_1_Type) == sizeof(reg_t), "RXRF_1_Type wrong size");
|
||||||
@ -689,7 +689,7 @@ class MAX2839 : public MAX283x {
|
|||||||
void set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) override;
|
void set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) override;
|
||||||
void set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) override;
|
void set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) override;
|
||||||
bool set_frequency(const rf::Frequency lo_frequency) override;
|
bool set_frequency(const rf::Frequency lo_frequency) override;
|
||||||
void set_rx_lo_iq_calibration(const size_t v) override;
|
void set_rx_LO_iq_phase_calibration(const size_t v) override;
|
||||||
void set_tx_LO_iq_phase_calibration(const size_t v) override;
|
void set_tx_LO_iq_phase_calibration(const size_t v) override;
|
||||||
void set_rx_buff_vcm(const size_t v) override;
|
void set_rx_buff_vcm(const size_t v) override;
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class MAX283x {
|
|||||||
|
|
||||||
virtual bool set_frequency(const rf::Frequency lo_frequency);
|
virtual bool set_frequency(const rf::Frequency lo_frequency);
|
||||||
|
|
||||||
virtual void set_rx_lo_iq_calibration(const size_t v);
|
virtual void set_rx_LO_iq_phase_calibration(const size_t v);
|
||||||
virtual void set_tx_LO_iq_phase_calibration(const size_t v);
|
virtual void set_tx_LO_iq_phase_calibration(const size_t v);
|
||||||
|
|
||||||
virtual void set_rx_buff_vcm(const size_t v);
|
virtual void set_rx_buff_vcm(const size_t v);
|
||||||
|
@ -253,6 +253,10 @@ void set_tx_max283x_iq_phase_calibration(const size_t v) {
|
|||||||
second_if->set_tx_LO_iq_phase_calibration(v);
|
second_if->set_tx_LO_iq_phase_calibration(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_rx_max283x_iq_phase_calibration(const size_t v) {
|
||||||
|
second_if->set_rx_LO_iq_phase_calibration(v);
|
||||||
|
}
|
||||||
|
|
||||||
/*void enable(Configuration configuration) {
|
/*void enable(Configuration configuration) {
|
||||||
configure(configuration);
|
configure(configuration);
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ void set_baseband_filter_bandwidth_tx(const uint32_t bandwidth_minimum);
|
|||||||
void set_baseband_rate(const uint32_t rate);
|
void set_baseband_rate(const uint32_t rate);
|
||||||
void set_antenna_bias(const bool on);
|
void set_antenna_bias(const bool on);
|
||||||
void set_tx_max283x_iq_phase_calibration(const size_t v);
|
void set_tx_max283x_iq_phase_calibration(const size_t v);
|
||||||
|
void set_rx_max283x_iq_phase_calibration(const size_t v);
|
||||||
|
|
||||||
/* Use ReceiverModel or TransmitterModel instead. */
|
/* Use ReceiverModel or TransmitterModel instead. */
|
||||||
// void enable(Configuration configuration);
|
// void enable(Configuration configuration);
|
||||||
|
Loading…
Reference in New Issue
Block a user