mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-02-18 13:44:14 -05:00
Adding_TX_IQ_phase_Calibration_to_Mic_App (#1843)
* Adding_TX_IQ_phase_Calibration_to_Mic_App * Adding_persistent_CAL_data_and_correct_init_data
This commit is contained in:
parent
c30a61441b
commit
b8073bca0f
@ -31,6 +31,7 @@
|
|||||||
#include "tonesets.hpp"
|
#include "tonesets.hpp"
|
||||||
#include "ui_tone_key.hpp"
|
#include "ui_tone_key.hpp"
|
||||||
#include "wm8731.hpp"
|
#include "wm8731.hpp"
|
||||||
|
#include "radio.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -336,6 +337,7 @@ MicTXView::MicTXView(
|
|||||||
&field_rxlna,
|
&field_rxlna,
|
||||||
&field_rxvga,
|
&field_rxvga,
|
||||||
&field_rxamp,
|
&field_rxamp,
|
||||||
|
hackrf_r9 ? &field_tx_iq_phase_cal_2839 : &field_tx_iq_phase_cal_2837,
|
||||||
&tx_button,
|
&tx_button,
|
||||||
&tx_icon});
|
&tx_icon});
|
||||||
|
|
||||||
@ -368,6 +370,21 @@ MicTXView::MicTXView(
|
|||||||
receiver_model.set_rf_amp(v);
|
receiver_model.set_rf_amp(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
radio::set_tx_max283x_iq_phase_calibration(iq_phase_calibration_value);
|
||||||
|
if (hackrf_r9) { // MAX2839 has 6 bits IQ CAL phasse adjustment.
|
||||||
|
field_tx_iq_phase_cal_2839.set_value(iq_phase_calibration_value);
|
||||||
|
field_tx_iq_phase_cal_2839.on_change = [this](int32_t v) {
|
||||||
|
iq_phase_calibration_value = v;
|
||||||
|
radio::set_tx_max283x_iq_phase_calibration(iq_phase_calibration_value);
|
||||||
|
};
|
||||||
|
} else { // MAX2837 has 5 bits IQ CAL phase adjustment.
|
||||||
|
field_tx_iq_phase_cal_2837.set_value(iq_phase_calibration_value);
|
||||||
|
field_tx_iq_phase_cal_2837.on_change = [this](int32_t v) {
|
||||||
|
iq_phase_calibration_value = v;
|
||||||
|
radio::set_tx_max283x_iq_phase_calibration(iq_phase_calibration_value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
options_gain.on_change = [this](size_t, int32_t v) {
|
options_gain.on_change = [this](size_t, int32_t v) {
|
||||||
mic_gain_x10 = v;
|
mic_gain_x10 = v;
|
||||||
configure_baseband();
|
configure_baseband();
|
||||||
|
@ -113,6 +113,7 @@ class MicTXView : public View {
|
|||||||
uint32_t va_level{40};
|
uint32_t va_level{40};
|
||||||
uint32_t attack_ms{500};
|
uint32_t attack_ms{500};
|
||||||
uint32_t decay_ms{1000};
|
uint32_t decay_ms{1000};
|
||||||
|
uint8_t iq_phase_calibration_value{15};
|
||||||
app_settings::SettingsManager settings_{
|
app_settings::SettingsManager settings_{
|
||||||
"tx_mic",
|
"tx_mic",
|
||||||
app_settings::Mode::RX_TX,
|
app_settings::Mode::RX_TX,
|
||||||
@ -132,6 +133,7 @@ class MicTXView : public View {
|
|||||||
{"vox"sv, &va_enabled},
|
{"vox"sv, &va_enabled},
|
||||||
{"rogerbeep"sv, &rogerbeep_enabled},
|
{"rogerbeep"sv, &rogerbeep_enabled},
|
||||||
{"tone_key_index"sv, &tone_key_index},
|
{"tone_key_index"sv, &tone_key_index},
|
||||||
|
{"iq_phase_calibration"sv, &iq_phase_calibration_value},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
rf::Frequency tx_frequency{0};
|
rf::Frequency tx_frequency{0};
|
||||||
@ -160,7 +162,8 @@ class MicTXView : public View {
|
|||||||
{{5 * 8, (25 * 8) + 2}, "F_RX:", Color::light_grey()},
|
{{5 * 8, (25 * 8) + 2}, "F_RX:", Color::light_grey()},
|
||||||
{{5 * 8, (27 * 8) + 2}, "LNA:", Color::light_grey()},
|
{{5 * 8, (27 * 8) + 2}, "LNA:", Color::light_grey()},
|
||||||
{{12 * 8, (27 * 8) + 2}, "VGA:", Color::light_grey()},
|
{{12 * 8, (27 * 8) + 2}, "VGA:", Color::light_grey()},
|
||||||
{{19 * 8, (27 * 8) + 2}, "AMP:", Color::light_grey()}};
|
{{19 * 8, (27 * 8) + 2}, "AMP:", Color::light_grey()},
|
||||||
|
{{21 * 8, (31 * 8)}, "TX-IQ-CAL:", Color::light_grey()}};
|
||||||
Labels labels_WM8731{
|
Labels labels_WM8731{
|
||||||
{{17 * 8, 1 * 8}, "Boost", Color::light_grey()}};
|
{{17 * 8, 1 * 8}, "Boost", Color::light_grey()}};
|
||||||
Labels labels_AK4951{
|
Labels labels_AK4951{
|
||||||
@ -338,6 +341,22 @@ class MicTXView : public View {
|
|||||||
' ',
|
' ',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NumberField field_tx_iq_phase_cal_2837{
|
||||||
|
{24 * 8, (33 * 8)},
|
||||||
|
2,
|
||||||
|
{0, 31}, // 5 bits IQ CAL phase adjustment.
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
};
|
||||||
|
|
||||||
|
NumberField field_tx_iq_phase_cal_2839{
|
||||||
|
{24 * 8, (33 * 8)},
|
||||||
|
2,
|
||||||
|
{0, 63}, // 6 bits IQ CAL phasse adjustment.
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
};
|
||||||
|
|
||||||
Button tx_button{
|
Button tx_button{
|
||||||
{10 * 8, 30 * 8, 10 * 8, 5 * 8},
|
{10 * 8, 30 * 8, 10 * 8, 5 * 8},
|
||||||
"PTT TX",
|
"PTT TX",
|
||||||
|
@ -149,7 +149,33 @@ void MAX2837::init() {
|
|||||||
set_mode(Mode::Standby);
|
set_mode(Mode::Standby);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Mask {
|
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 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 .
|
||||||
|
|
||||||
|
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.tx_lo_iq.TXLO_IQ_SPI_EN = 1; // reg 30 D5, TX LO I/Q Phase SPI Adjust. Active when Address 30 D5 (TXLO_IQ_SPI_EN) = 1.
|
||||||
|
_map.r.tx_lo_iq.TXLO_IQ_SPI = v; // reg 30 D4:D0, TX LO I/Q Phase SPI Adjust.
|
||||||
|
flush_one(Register::TX_LO_IQ);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
set_mode(Mode::Standby); // Back 3 logic pins CALIBRATION mode -> Standby.
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Mask { // There are class Mask ,and class mode with same names, but they are not same.
|
||||||
Enable = 0b001,
|
Enable = 0b001,
|
||||||
RxEnable = 0b010,
|
RxEnable = 0b010,
|
||||||
TxEnable = 0b100,
|
TxEnable = 0b100,
|
||||||
@ -157,9 +183,11 @@ enum class Mask {
|
|||||||
Standby = Enable,
|
Standby = Enable,
|
||||||
Receive = Enable | RxEnable,
|
Receive = Enable | RxEnable,
|
||||||
Transmit = Enable | TxEnable,
|
Transmit = Enable | TxEnable,
|
||||||
|
Rx_calibration = Enable | RxEnable, // sets the same 3 x logic pins to the Receive operating mode.
|
||||||
|
Tx_calibration = Enable | TxEnable, // sets the same 3 x logic pins to the Transmit operating mode.
|
||||||
};
|
};
|
||||||
|
|
||||||
Mask mode_mask(const Mode mode) {
|
Mask mode_mask(const Mode mode) { // based on enum Mode cases, we set up the correct 3 logic PINS .
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case Mode::Standby:
|
case Mode::Standby:
|
||||||
return Mask::Standby;
|
return Mask::Standby;
|
||||||
@ -167,12 +195,16 @@ Mask mode_mask(const Mode mode) {
|
|||||||
return Mask::Receive;
|
return Mask::Receive;
|
||||||
case Mode::Transmit:
|
case Mode::Transmit:
|
||||||
return Mask::Transmit;
|
return Mask::Transmit;
|
||||||
|
case Mode::Rx_Calibration: // Let's add those two CAL logic pin settings- Rx and Tx calibration modes.
|
||||||
|
return Mask::Rx_calibration; // same logic pins as Receive mode = Enable | RxEnable, (the difference is in Reg add 16 D1:DO)
|
||||||
|
case Mode::Tx_Calibration: // Let's add this CAL Tx calibration mode = Transmit.
|
||||||
|
return Mask::Tx_calibration; // same logic pins as Transmit = Enable | TxEnable,(the difference is in Reg add 16 D1:DO)
|
||||||
default:
|
default:
|
||||||
return Mask::Shutdown;
|
return Mask::Shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MAX2837::set_mode(const Mode mode) {
|
void MAX2837::set_mode(const Mode mode) { // We set up the 3 Logic Pins ENABLE, RXENABLE, TXENABLE accordingly to the max2837 mode case, that we want to set up .
|
||||||
Mask mask = mode_mask(mode);
|
Mask mask = mode_mask(mode);
|
||||||
gpio_max283x_enable.write(toUType(mask) & toUType(Mask::Enable));
|
gpio_max283x_enable.write(toUType(mask) & toUType(Mask::Enable));
|
||||||
gpio_max2837_rxenable.write(toUType(mask) & toUType(Mask::RxEnable));
|
gpio_max2837_rxenable.write(toUType(mask) & toUType(Mask::RxEnable));
|
||||||
|
@ -829,6 +829,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_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);
|
||||||
void set_rx_buff_vcm(const size_t v) override;
|
void set_rx_buff_vcm(const size_t v) override;
|
||||||
|
@ -142,6 +142,31 @@ void MAX2839::init() {
|
|||||||
set_mode(Mode::Standby);
|
set_mode(Mode::Standby);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MAX2839::set_tx_LO_iq_phase_calibration(const size_t v) {
|
||||||
|
/* IQ phase deg CAL adj (+4 ...-4) This IC in 64 steps (6 bits), 000000 = +4deg (Q lags I by 94degs, default), 011111 = +0deg, 111111 = -4deg (Q lags I by 86degs) */
|
||||||
|
|
||||||
|
// TX calibration , 2 x Logic pins , ENABLE, RXENABLE = 1,0, (2dec), and Reg address 16, D1 (CAL mode 1):DO (CHIP ENABLE 1)
|
||||||
|
set_mode(Mode::Tx_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.pa_drv.TXLO_IQ_SPI_EN = 1; // reg 27 D6, TX LO I/Q Phase SPI Adjust. Active when Address 27 D6 (TXLO_IQ_SPI_EN) = 1.
|
||||||
|
_map.r.pa_drv.TXLO_IQ_SPI = v; // reg 27 D5:D0 6 bits, TX LO I/Q Phase SPI Adjust.
|
||||||
|
flush_one(Register::PA_DRV);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
set_mode(Mode::Standby); // Back 3 logic pins CALIBRATION mode -> Standby.
|
||||||
|
}
|
||||||
|
|
||||||
enum class Mask {
|
enum class Mask {
|
||||||
Enable = 0b01,
|
Enable = 0b01,
|
||||||
RxTx = 0b10,
|
RxTx = 0b10,
|
||||||
@ -149,6 +174,8 @@ enum class Mask {
|
|||||||
Standby = RxTx,
|
Standby = RxTx,
|
||||||
Receive = Enable | RxTx,
|
Receive = Enable | RxTx,
|
||||||
Transmit = Enable,
|
Transmit = Enable,
|
||||||
|
Rx_calibration = Enable | RxTx, // sets the same 2 x logic pins to the Receive operating mode.
|
||||||
|
Tx_calibration = Enable, // sets the same 2 x logic pins to the Transmit operating mode.
|
||||||
};
|
};
|
||||||
|
|
||||||
Mask mode_mask(const Mode mode) {
|
Mask mode_mask(const Mode mode) {
|
||||||
@ -159,6 +186,10 @@ Mask mode_mask(const Mode mode) {
|
|||||||
return Mask::Receive;
|
return Mask::Receive;
|
||||||
case Mode::Transmit:
|
case Mode::Transmit:
|
||||||
return Mask::Transmit;
|
return Mask::Transmit;
|
||||||
|
case Mode::Rx_Calibration: // Let's add this not used previously Rx calibration mode.
|
||||||
|
return Mask::Rx_calibration; // same logic pins as Receive mode = Enable | RxTx, ,(the difference is in Regs )
|
||||||
|
case Mode::Tx_Calibration: // Let's add this not used previously Tx calibration mode.
|
||||||
|
return Mask::Tx_calibration; // same logic pins as Transmit = Enable , (the difference is in Reg add 16 D1:DO)
|
||||||
default:
|
default:
|
||||||
return Mask::Shutdown;
|
return Mask::Shutdown;
|
||||||
}
|
}
|
||||||
|
@ -690,6 +690,7 @@ class MAX2839 : public MAX283x {
|
|||||||
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_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;
|
||||||
|
|
||||||
int8_t temp_sense() override;
|
int8_t temp_sense() override;
|
||||||
|
@ -98,11 +98,13 @@ constexpr auto bandwidth_maximum = bandwidths[bandwidths.size() - 1];
|
|||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
enum Mode {
|
enum Mode { // MAX283x Operating modes.
|
||||||
Shutdown,
|
Shutdown,
|
||||||
Standby,
|
Standby,
|
||||||
Receive,
|
Receive,
|
||||||
Transmit,
|
Transmit,
|
||||||
|
Rx_Calibration, // just add the sequential enum of those two CAL operating modes .
|
||||||
|
Tx_Calibration,
|
||||||
};
|
};
|
||||||
|
|
||||||
using reg_t = uint16_t;
|
using reg_t = uint16_t;
|
||||||
@ -124,6 +126,8 @@ 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_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);
|
||||||
|
|
||||||
virtual int8_t temp_sense();
|
virtual int8_t temp_sense();
|
||||||
|
@ -248,6 +248,10 @@ void set_antenna_bias(const bool on) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_tx_max283x_iq_phase_calibration(const size_t v) {
|
||||||
|
second_if->set_tx_LO_iq_phase_calibration(v);
|
||||||
|
}
|
||||||
|
|
||||||
/*void enable(Configuration configuration) {
|
/*void enable(Configuration configuration) {
|
||||||
configure(configuration);
|
configure(configuration);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ void set_baseband_filter_bandwidth_rx(const uint32_t bandwidth_minimum);
|
|||||||
void set_baseband_filter_bandwidth_tx(const uint32_t bandwidth_minimum);
|
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);
|
||||||
|
|
||||||
/* Use ReceiverModel or TransmitterModel instead. */
|
/* Use ReceiverModel or TransmitterModel instead. */
|
||||||
// void enable(Configuration configuration);
|
// void enable(Configuration configuration);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user