0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-28 14:21:25 +03:00

fix major frequency/band bug

This commit is contained in:
OneOfEleven 2023-10-23 10:42:51 +01:00
parent df3d298487
commit 61f48bf629
8 changed files with 192 additions and 84 deletions

View File

@ -586,11 +586,12 @@ uint32_t APP_set_frequency_by_step(vfo_info_t *pInfo, int8_t Step)
Frequency = Lower + Base + (Index * 833);
}
if (Frequency >= FREQ_BAND_TABLE[pInfo->band].upper)
Frequency = FREQ_BAND_TABLE[pInfo->band].lower;
else
if (Frequency < FREQ_BAND_TABLE[pInfo->band].lower)
Frequency = FREQUENCY_FloorToStep(FREQ_BAND_TABLE[pInfo->band].upper, pInfo->step_freq, FREQ_BAND_TABLE[pInfo->band].lower);
// if (Frequency >= FREQ_BAND_TABLE[pInfo->band].upper)
// Frequency = FREQ_BAND_TABLE[pInfo->band].lower;
// else
// if (Frequency < FREQ_BAND_TABLE[pInfo->band].lower)
// Frequency = FREQUENCY_floor_to_step(FREQ_BAND_TABLE[pInfo->band].upper, pInfo->step_freq, FREQ_BAND_TABLE[pInfo->band].lower);
Frequency = FREQUENCY_wrap_to_step_band(Frequency, pInfo->step_freq, pInfo->band);
return Frequency;
}

View File

@ -43,7 +43,7 @@
void toggle_chan_scanlist(void)
{ // toggle the selected channels scanlist setting
// if (IS_FREQ_CHANNEL(g_tx_vfo->channel_save))
// if (IS_FREQ_CHANNEL(g_tx_vfo->channel_save)) // TODO: include the VFO freq as a channel when scanning
if (IS_NOAA_CHANNEL(g_tx_vfo->channel_save))
{
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@ -212,10 +212,10 @@ void processFKeyFunction(const key_code_t Key)
if (g_setting_350_enable || Band != BAND5_350MHz)
{
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
Band = BAND1_50MHz; // wrap-a-round
}
else
Band = BAND6_400MHz;
Band = BAND6_400MHz; // jump to next band
g_tx_vfo->band = Band;
g_eeprom.screen_channel[Vfo] = FREQ_CHANNEL_FIRST + Band;
@ -545,10 +545,9 @@ void MAIN_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
RADIO_configure_channel(Vfo, VFO_CONFIGURE_RELOAD);
}
// Frequency += 75; // is this meant to be rounding ?
Frequency += g_tx_vfo->step_freq / 2; // no idea, but this is
Frequency += g_tx_vfo->step_freq / 2; // for rounding to nearest step size
Frequency = FREQUENCY_FloorToStep(Frequency, g_tx_vfo->step_freq, FREQ_BAND_TABLE[g_tx_vfo->band].lower);
Frequency = FREQUENCY_floor_to_step(Frequency, g_tx_vfo->step_freq, FREQ_BAND_TABLE[g_tx_vfo->band].lower, FREQ_BAND_TABLE[g_tx_vfo->band].upper);
if (Frequency >= BX4819_BAND1.upper && Frequency < BX4819_BAND2.lower)
{ // clamp the frequency to the limit

View File

@ -1424,7 +1424,7 @@ static void MENU_Key_0_to_9(key_code_t Key, bool key_pressed, bool key_held)
NUMBER_Get(g_input_box, &Frequency);
g_input_box_index = 0;
g_sub_menu_selection = FREQUENCY_FloorToStep(Frequency + (g_tx_vfo->step_freq / 2), g_tx_vfo->step_freq, 0);
g_sub_menu_selection = FREQUENCY_floor_to_step(Frequency + (g_tx_vfo->step_freq / 2), g_tx_vfo->step_freq, 0, Frequency + (g_tx_vfo->step_freq / 2));
return;
}
@ -1852,7 +1852,7 @@ static void MENU_Key_UP_DOWN(bool key_pressed, bool key_held, int8_t Direction)
else
Offset = 0;
g_sub_menu_selection = FREQUENCY_FloorToStep(Offset, g_tx_vfo->step_freq, 0);
g_sub_menu_selection = FREQUENCY_floor_to_step(Offset, g_tx_vfo->step_freq, 0, Offset);
g_request_display_screen = DISPLAY_MENU;
return;
}

View File

@ -157,29 +157,49 @@ uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t T
return pwr;
}
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower)
uint32_t FREQUENCY_floor_to_step(uint32_t freq, const uint32_t step_size, const uint32_t lower, const uint32_t upper)
{
#if 1
uint32_t Index;
uint32_t delta;
if (Step == 833)
if (freq <= lower)
return lower;
if (freq > (upper - 1))
freq = upper - 1;
delta = freq - lower;
if (delta < step_size)
return lower;
if (step_size == 833)
{
const uint32_t Delta = Upper - Lower;
uint32_t Base = (Delta / 2500) * 2500;
const uint32_t Index = ((Delta - Base) % 2500) / 833;
uint32_t base = (delta / 2500) * 2500; // 25kHz step
const unsigned int index = ((delta - base) % 2500) / step_size;
if (Index == 2)
Base++;
if (index == 2)
base++;
return Lower + Base + (Index * 833);
freq = lower + base + (step_size * index);
}
else
freq = lower + ((delta / step_size) * step_size);
Index = (Upper - Lower) / Step;
return freq;
}
return Lower + (Step * Index);
#else
return Lower + (((Upper - Lower) / Step) * Step);
#endif
uint32_t FREQUENCY_wrap_to_step_band(uint32_t freq, const uint32_t step_size, const unsigned int band)
{
const uint32_t upper = FREQ_BAND_TABLE[band].upper;
const uint32_t lower = FREQ_BAND_TABLE[band].lower;
if (freq < lower)
return FREQUENCY_floor_to_step(upper, step_size, lower, upper);
if (freq >= upper)
freq = lower;
return freq;
}
int FREQUENCY_tx_freq_check(const uint32_t Frequency)

View File

@ -93,7 +93,9 @@ void FREQUENCY_init(void);
frequency_band_t FREQUENCY_GetBand(uint32_t Frequency);
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency);
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower);
uint32_t FREQUENCY_floor_to_step(uint32_t freq, const uint32_t step_size, const uint32_t lower, const uint32_t upper);
uint32_t FREQUENCY_wrap_to_step_band(uint32_t freq, const uint32_t step_size, const unsigned int band);
int FREQUENCY_tx_freq_check(const uint32_t Frequency);
int FREQUENCY_rx_freq_check(const uint32_t Frequency);

100
mdc1200.c
View File

@ -57,11 +57,12 @@ uint16_t reverse_bits(const uint16_t bits_in, const unsigned int num_bits)
return bits_out;
}
#if 0
#if 1
uint16_t compute_crc(const uint8_t *data, const unsigned int data_len)
{ // using the reverse computation avoids having to reverse the bit order during and after
unsigned int i;
uint16_t crc = 0;
for (i = 0; i < len; i++)
for (i = 0; i < data_len; i++)
{
unsigned int k;
crc ^= data[i];
@ -129,54 +130,80 @@ uint16_t reverse_bits(const uint16_t bits_in, const unsigned int num_bits)
}
#endif
#define FEC_K 7
uint8_t * encode_data(uint8_t *data)
{
unsigned int i;
// R=1/2 K=7 convolutional coder
//
// create the FEC bits
//
// op 0x01
// arg 0x80
// id 0x1234
// crc 0x2E3E
// status 0x00
// FEC 0x6580A862DD8808
//
// 01 80 1234 2E3E 00 6580A862DD8808
//
// 1. reverse the bit order for each byte of the first 7 bytes (to undo the reversal performed for display, above)
// 2. feed those bits into a shift register which is preloaded with all zeros
// 3. for each bit, calculate the modulo-2 sum: bit(n-0) + bit(n-2) + bit(n-5) + bit(n-6)
// 4. then for each byte of resulting output, again reverse those bits to generate the values listed above (for display)
//
{
uint8_t shift_reg = 0;
for (i = 0; i < FEC_K; i++)
{
unsigned int bit;
const uint8_t bi = data[i];
uint8_t bo = 0;
for (bit = 0; bit < 8; bit++)
{
shift_reg = (shift_reg << 1) | ((bi >> bit) & 1u);
bo |= (((shift_reg >> 6) ^ (shift_reg >> 5) ^ (shift_reg >> 2) ^ (shift_reg >> 0)) & 1u) << bit;
}
data[i + FEC_K] = bo;
}
}
{
unsigned int k;
unsigned int m;
uint8_t csr[7];
uint8_t lbits[(ARRAY_SIZE(csr) * 2) * 8];
uint8_t interleaved[(FEC_K * 2) * 8];
for (i = 0; i < ARRAY_SIZE(csr); i++)
csr[i] = 0;
for (i = 0; i < ARRAY_SIZE(csr); i++)
// bit interleaver
for (i = 0, k = 0, m = 0; i < (FEC_K * 2); i++)
{
unsigned int bit;
data[i + ARRAY_SIZE(csr)] = 0;
const uint8_t b = data[i];
for (bit = 0; bit < 8; bit++)
{
uint8_t b;
for (k = 6; k > 0; k--)
csr[k] = csr[k - 1];
csr[0] = (data[i] >> bit) & 1u;
b = csr[0] + csr[2] + csr[5] + csr[6];
data[i + ARRAY_SIZE(csr)] |= (b & 1u) << bit;
}
}
for (i = 0, k = 0, m = 0; i < (ARRAY_SIZE(csr) * 2); i++)
{
unsigned int bit;
for (bit = 0; bit < 8; bit++)
{
lbits[k] = (data[i] >> bit) & 1u;
interleaved[k] = (b >> bit) & 1u;
k += 16;
if (k >= ARRAY_SIZE(lbits))
if (k >= sizeof(interleaved))
k = ++m;
}
}
for (i = 0, k = 0; i < (ARRAY_SIZE(csr) * 2); i++)
// copy the interleaved bits to the output buffer
for (i = 0, k = 0; i < (FEC_K * 2); i++)
{
int bit;
data[i] = 0;
uint8_t b = 0;
for (bit = 7; bit >= 0; bit--)
if (lbits[k++])
data[i] |= 1u << bit;
if (interleaved[k++])
b |= 1u << bit;
data[i] = b;
}
}
return data + 14;
return data + (FEC_K * 2);
}
void delta_modulation(uint8_t *data, const unsigned int size)
@ -215,12 +242,15 @@ unsigned int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const
crc = compute_crc(p, 4);
p[4] = (crc >> 0) & 0x00ff;
p[5] = (crc >> 8) & 0x00ff;
p[6] = 0;
p[6] = 0; // unknown field (00 for PTTIDs, 76 for STS and MSG)
p = encode_data(p);
#if 1
{ // op 0x01, arg 0x80, id 0xB183
#if 0
{ // test packet
//
// op 0x01, arg 0x80, id 0xB183
//
const uint8_t test_packet[] = {0x07, 0x25, 0xDD, 0xD5, 0x9F, 0xC5, 0x3D, 0x89, 0x2D, 0xBD, 0x57, 0x35, 0xE7, 0x44};
memcpy(data + sizeof(header), test_packet, sizeof(test_packet));
}
@ -250,7 +280,7 @@ unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const
crc = compute_crc(p, 4);
p[4] = (crc >> 0) & 0x00ff;
p[5] = (crc >> 8) & 0x00ff;
p[6] = 0;
p[6] = 0; // status byte
p = encode_data(p);
@ -261,7 +291,7 @@ unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const
crc = compute_crc(p, 4);
p[4] = (crc >> 0) & 0x00ff;
p[5] = (crc >> 8) & 0x00ff;
p[6] = 0;
p[6] = 0; // status byte
p = encode_data(p);

View File

@ -4,6 +4,9 @@
#include <stdint.h>
// 0x00 (0x81) emergency alarm
// 0x20 (0x00) emergency alarm ack
//
// 0x01 (0x80) is PTT ID
// 0x01 (0x00) is POST ID
// 0x11 (0x8A) is REMOTE MONITOR
@ -13,7 +16,61 @@
// 0x35 (0x89) is CALL ALERT
// 0x46 (0xXX) is STS XX
// 0x47 (0xXX) is MSG XX
//
// 0x63 (0x85) is RADIO CHECK
// 0x30 (0x00) is RADIO CHECK ack
//
// * CALL ALERT [Double packet - 2 codewords, 1234 places call to 5678]
// 3589 5678 830D 1234 [Spectra, Astro Saber "PAGE", Maxtrac "CA" w/Ack Expected=Y]
// 3589 5678 810D 1234 [Maxtrac "CA" w/Ack Expected=N]
//
// * VOICE SELECTIVE CALL [Double packet - 2 codewords, 1234 places call to 5678]
// 3589 5678 8205 1234 [Spectra "CALL"]
// 3589 5678 8015 1234 [Maxtrac "SC", Astro Saber "CALL"]
//
// * CALL ALERT ACKNOWLEDGE [Double packet - 2 codewords, 5678 acks the call from 1234]
// 3589 1234 A000 5678
//
// * SIMPLE STATUS [unit 1234 transmits status number X]
// 460X 1234
//
// * STATUS ACKNOWLEDGE
// 2300 1234
//
// * STATUS REQUEST [i.e. unit 5678 report your last status]
// 2206 5678
//
// * STATUS RESPONSE [from target 5678 when interrogated]
// 060X 5678
//
// * INBOUND MESSAGE
// 470X 1234 [ack expected]
// 070X 1234 [ack not expected CDM1550]
//
// * INBOUND MESSAGE ACKNOWLEDGE
// 2300 1234
//
// * REMOTE MONITOR [No MDC response from target unless it has PTT ID]
// 118A 5678 [118A per KA6SQG]
//
// * SELECTIVE RADIO INHIBIT [Fixed end inhibits target 5678]
// 2B00 5678
//
// * SELECTIVE RADIO INHIBIT ACKNOWLEDGE [5678 acks the inhibit]
// 0B00 5678
//
// * SELECTIVE RADIO INHIBIT CANCEL [Fixed end enables target 5678]
// 2B0C 5678
//
// * SELECTIVE RADIO INHIBIT CANCEL [5678 acks the enable]
// 0B0C 5678
//
// * REQUEST TO TALK [Unit 1234 asks fixed end for permission to PTT]
// 4001 1234 [CDM1550 dedicated button]
// 4101 1234 [CDM1550 slaved to mic PTT]
//
// * REQUEST TO TALK ACKNOWLEDGE
// 2300 1234 [general ack - not same as permission to PTT]
enum mdc1200_op_code_e {
MDC1200_OP_CODE_PTT_ID = 0x01,

21
radio.c
View File

@ -311,25 +311,19 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur
Frequency = p_vfo->freq_config_rx.frequency;
#if 1
// fix previously maybe incorrect set band
Band = FREQUENCY_GetBand(Frequency);
p_vfo->band = Band;
#endif
if (Frequency < FREQ_BAND_TABLE[Band].lower)
Frequency = FREQ_BAND_TABLE[Band].lower;
else
if (Frequency > FREQ_BAND_TABLE[Band].upper)
Frequency = FREQ_BAND_TABLE[Band].upper;
if (Frequency >= FREQ_BAND_TABLE[Band].upper)
Frequency = FREQUENCY_floor_to_step(Frequency, p_vfo->step_freq, FREQ_BAND_TABLE[Band].lower, FREQ_BAND_TABLE[Band].upper);
else
if (Channel >= FREQ_CHANNEL_FIRST)
Frequency = FREQUENCY_FloorToStep(Frequency, p_vfo->step_freq, FREQ_BAND_TABLE[Band].lower);
Frequency = FREQUENCY_floor_to_step(Frequency, p_vfo->step_freq, FREQ_BAND_TABLE[Band].lower, FREQ_BAND_TABLE[Band].upper);
if (!g_setting_350_enable && Frequency >= 35000000 && Frequency < 40000000)
{ // 350~400Mhz not allowed
// hop onto the euro ham band
// hop onto the next band up
Frequency = 43350000;
p_vfo->freq_config_rx.frequency = Frequency;
p_vfo->freq_config_tx.frequency = Frequency;
@ -338,6 +332,11 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur
p_vfo->frequency_reverse = 0;
p_vfo->tx_offset_freq_dir = TX_OFFSET_FREQ_DIR_OFF;
p_vfo->tx_offset_freq = 0;
// TODO: also update other settings such as step size
}
p_vfo->freq_config_rx.frequency = Frequency;
@ -350,7 +349,7 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur
else
if (Channel > USER_CHANNEL_LAST)
{
p_vfo->tx_offset_freq = FREQUENCY_FloorToStep(p_vfo->tx_offset_freq, p_vfo->step_freq, 0);
p_vfo->tx_offset_freq = FREQUENCY_floor_to_step(p_vfo->tx_offset_freq, p_vfo->step_freq, 0, p_vfo->tx_offset_freq);
}
RADIO_ApplyOffset(p_vfo);