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

233 lines
5.3 KiB
C
Raw Normal View History

2023-09-09 08:03:56 +01:00
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_AIRCOPY
2023-09-09 08:03:56 +01:00
#include "app/aircopy.h"
#include "audio.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
#include "driver/eeprom.h"
#include "frequencies.h"
#include "misc.h"
#include "radio.h"
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
static const uint16_t Obfuscation[8] = {0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9};
2023-10-08 20:23:37 +01:00
aircopy_state_t g_aircopy_state;
uint16_t g_air_copy_block_number;
uint16_t g_errors_during_air_copyy;
uint8_t g_air_copy_is_send_mode;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
uint16_t g_fsk_buffer[36];
2023-09-09 08:03:56 +01:00
void AIRCOPY_SendMessage(void)
{
unsigned int i;
2023-10-08 20:23:37 +01:00
g_fsk_buffer[1] = (g_air_copy_block_number & 0x3FF) << 6;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
EEPROM_ReadBuffer(g_fsk_buffer[1], &g_fsk_buffer[2], 64);
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
g_fsk_buffer[34] = CRC_Calculate(&g_fsk_buffer[1], 2 + 64);
2023-09-09 08:03:56 +01:00
for (i = 0; i < 34; i++)
2023-10-08 20:23:37 +01:00
g_fsk_buffer[i + 1] ^= Obfuscation[i % 8];
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
if (++g_air_copy_block_number >= 0x78)
g_aircopy_state = AIRCOPY_COMPLETE;
2023-09-09 08:03:56 +01:00
RADIO_SetTxParameters();
2023-10-08 20:23:37 +01:00
BK4819_SendFSKData(g_fsk_buffer);
2023-09-09 08:03:56 +01:00
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
2023-10-08 20:23:37 +01:00
g_air_copy_send_count_down = 30;
2023-09-09 08:03:56 +01:00
}
void AIRCOPY_StorePacket(void)
{
uint16_t Status;
2023-10-08 20:23:37 +01:00
if (g_fsk_wite_index < 36)
2023-09-09 08:03:56 +01:00
return;
2023-10-08 20:23:37 +01:00
g_fsk_wite_index = 0;
g_update_display = true;
Status = BK4819_ReadRegister(BK4819_REG_0B);
2023-09-09 08:03:56 +01:00
BK4819_PrepareFSKReceive();
// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL.
2023-10-08 20:23:37 +01:00
if ((Status & 0x0010U) == 0 && g_fsk_buffer[0] == 0xABCD && g_fsk_buffer[35] == 0xDCBA)
2023-09-09 08:03:56 +01:00
{
uint16_t CRC;
unsigned int i;
for (i = 0; i < 34; i++)
2023-10-08 20:23:37 +01:00
g_fsk_buffer[i + 1] ^= Obfuscation[i % 8];
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
CRC = CRC_Calculate(&g_fsk_buffer[1], 2 + 64);
if (g_fsk_buffer[34] == CRC)
2023-09-09 08:03:56 +01:00
{
const uint16_t *pData;
uint16_t Offset;
2023-10-08 20:23:37 +01:00
Offset = g_fsk_buffer[1];
2023-09-09 08:03:56 +01:00
if (Offset < 0x1E00)
{
2023-10-08 20:23:37 +01:00
pData = &g_fsk_buffer[2];
2023-09-09 08:03:56 +01:00
for (i = 0; i < 8; i++)
{
EEPROM_WriteBuffer(Offset, pData);
pData += 4;
Offset += 8;
}
2023-10-08 20:23:37 +01:00
2023-09-09 08:03:56 +01:00
if (Offset == 0x1E00)
2023-10-08 20:23:37 +01:00
g_aircopy_state = AIRCOPY_COMPLETE;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
g_air_copy_block_number++;
2023-09-09 08:03:56 +01:00
return;
}
}
}
2023-10-08 20:23:37 +01:00
g_errors_during_air_copyy++;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held && key_pressed)
2023-09-09 08:03:56 +01:00
{
uint32_t Frequency;
unsigned int i;
INPUTBOX_Append(Key);
2023-10-08 20:23:37 +01:00
g_request_display_screen = DISPLAY_AIRCOPY;
if (g_input_box_index < 6)
2023-09-09 08:03:56 +01:00
{
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_VOICE
2023-10-08 17:14:13 +01:00
g_another_voice_id = (voice_id_t)Key;
2023-09-09 08:03:56 +01:00
#endif
return;
}
2023-10-08 20:23:37 +01:00
g_input_box_index = 0;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
NUMBER_Get(g_input_box, &Frequency);
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
for (i = 0; i < ARRAY_SIZE(FREQ_BAND_TABLE); i++)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (Frequency >= FREQ_BAND_TABLE[i].lower && Frequency < FREQ_BAND_TABLE[i].upper)
2023-09-09 08:03:56 +01:00
{
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_VOICE
2023-10-08 20:23:37 +01:00
g_another_voice_id = (voice_id_t)Key;
2023-09-09 08:03:56 +01:00
#endif
2023-10-08 20:23:37 +01:00
g_rx_vfo->band = i;
Frequency += 75;
Frequency = FREQUENCY_FloorToStep(Frequency, g_rx_vfo->step_freq, 0);
g_rx_vfo->freq_config_rx.frequency = Frequency;
g_rx_vfo->freq_config_tx.frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(g_rx_vfo);
g_current_vfo = g_rx_vfo;
2023-09-09 08:03:56 +01:00
RADIO_SetupRegisters(true);
BK4819_SetupAircopy();
BK4819_ResetFSK();
return;
}
}
2023-10-08 20:23:37 +01:00
g_request_display_screen = DISPLAY_AIRCOPY;
2023-09-09 08:03:56 +01:00
}
}
2023-10-08 20:23:37 +01:00
static void AIRCOPY_Key_EXIT(bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held && key_pressed)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_input_box_index == 0)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
g_fsk_wite_index = 0;
g_air_copy_block_number = 0;
g_errors_during_air_copyy = 0;
g_input_box_index = 0;
g_air_copy_is_send_mode = 0;
2023-09-09 08:03:56 +01:00
BK4819_PrepareFSKReceive();
2023-10-08 20:23:37 +01:00
g_aircopy_state = AIRCOPY_TRANSFER;
2023-09-09 08:03:56 +01:00
}
else
2023-10-08 20:23:37 +01:00
g_input_box[--g_input_box_index] = 10;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
g_request_display_screen = DISPLAY_AIRCOPY;
2023-09-09 08:03:56 +01:00
}
}
2023-10-08 20:23:37 +01:00
static void AIRCOPY_Key_MENU(bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held && key_pressed)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
g_fsk_wite_index = 0;
g_air_copy_block_number = 0;
g_input_box_index = 0;
g_air_copy_is_send_mode = 1;
g_fsk_buffer[0] = 0xABCD;
g_fsk_buffer[1] = 0;
g_fsk_buffer[35] = 0xDCBA;
2023-09-09 08:03:56 +01:00
AIRCOPY_SendMessage();
2023-09-09 08:03:56 +01:00
GUI_DisplayScreen();
2023-10-08 20:23:37 +01:00
g_aircopy_state = AIRCOPY_TRANSFER;
2023-09-09 08:03:56 +01:00
}
}
2023-10-08 20:23:37 +01:00
void AIRCOPY_ProcessKeys(key_code_t Key, bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
2023-10-08 20:23:37 +01:00
AIRCOPY_Key_DIGITS(Key, key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case KEY_MENU:
2023-10-08 20:23:37 +01:00
AIRCOPY_Key_MENU(key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case KEY_EXIT:
2023-10-08 20:23:37 +01:00
AIRCOPY_Key_EXIT(key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
default:
break;
}
}
#endif