mirror of
https://github.com/OneOfEleven/uv-k5-firmware-custom.git
synced 2025-04-28 14:21:25 +03:00
AIRCOPY now has error correction (REQ-ACKs) to fix corrupted/lost packets during transfer
This commit is contained in:
parent
7c3717549a
commit
319f22dcb8
2
Makefile
2
Makefile
@ -38,7 +38,7 @@ ENABLE_AM_FIX := 1
|
|||||||
ENABLE_AM_FIX_SHOW_DATA := 1
|
ENABLE_AM_FIX_SHOW_DATA := 1
|
||||||
ENABLE_SQUELCH_MORE_SENSITIVE := 1
|
ENABLE_SQUELCH_MORE_SENSITIVE := 1
|
||||||
ENABLE_FASTER_CHANNEL_SCAN := 1
|
ENABLE_FASTER_CHANNEL_SCAN := 1
|
||||||
ENABLE_RSSI_BAR := 0
|
ENABLE_RSSI_BAR := 1
|
||||||
ENABLE_SHOW_TX_TIMEOUT := 0
|
ENABLE_SHOW_TX_TIMEOUT := 0
|
||||||
ENABLE_AUDIO_BAR := 1
|
ENABLE_AUDIO_BAR := 1
|
||||||
ENABLE_COPY_CHAN_TO_VFO := 1
|
ENABLE_COPY_CHAN_TO_VFO := 1
|
||||||
|
653
app/aircopy.c
653
app/aircopy.c
@ -18,10 +18,14 @@
|
|||||||
|
|
||||||
#include "app/aircopy.h"
|
#include "app/aircopy.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
#include "bsp/dp32g030/gpio.h"
|
||||||
|
#include "driver/backlight.h"
|
||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
#include "driver/crc.h"
|
#include "driver/crc.h"
|
||||||
#include "driver/eeprom.h"
|
#include "driver/eeprom.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
#include "driver/system.h"
|
#include "driver/system.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
@ -30,274 +34,528 @@
|
|||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
#define AIRCOPY_MAGIC_START 0xABCD
|
// **********************
|
||||||
#define AIRCOPY_MAGIC_END 0xDCBA
|
|
||||||
|
|
||||||
#define AIRCOPY_LAST_EEPROM_ADDR 0x1E00
|
#define AIRCOPY_MAGIC_START_REQ 0xBCDA // used to request a block resend
|
||||||
|
#define AIRCOPY_MAGIC_END_REQ 0xCDBA // used to request a block resend
|
||||||
|
|
||||||
const uint8_t g_aircopy_block_max = 120;
|
#define AIRCOPY_MAGIC_START 0xABCD // normal start value
|
||||||
uint8_t g_aircopy_block_number;
|
#define AIRCOPY_MAGIC_END 0xDCBA // normal end value
|
||||||
uint8_t g_aircopy_rx_errors;
|
|
||||||
aircopy_state_t g_aircopy_state;
|
|
||||||
|
|
||||||
uint8_t aircopy_send_count_down_10ms;
|
#define AIRCOPY_LAST_EEPROM_ADDR 0x1E00 // size of eeprom transferred
|
||||||
|
|
||||||
uint16_t g_fsk_buffer[36];
|
// FSK Data Length .. 0xABCD + 2 byte eeprom address + 64 byte payload + 2 byte CRC + 0xDCBA
|
||||||
unsigned int g_fsk_write_index;
|
#define AIRCOPY_DATA_PACKET_SIZE (2 + 2 + 64 + 2 + 2)
|
||||||
uint16_t g_fsk_tx_timeout_10ms;
|
|
||||||
|
|
||||||
void AIRCOPY_start_FSK_tx(const uint8_t request_packet)
|
// FSK Data Length .. 0xBCDA + 2 byte eeprom address + 2 byte CRC + 0xCDBA
|
||||||
|
#define AIRCOPY_REQ_PACKET_SIZE (2 + 2 + 64 + 2 + 2)
|
||||||
|
|
||||||
|
// **********************
|
||||||
|
|
||||||
|
const unsigned int g_aircopy_block_max = 120;
|
||||||
|
unsigned int g_aircopy_block_number;
|
||||||
|
uint8_t g_aircopy_rx_errors_fsk_crc;
|
||||||
|
uint8_t g_aircopy_rx_errors_magic;
|
||||||
|
uint8_t g_aircopy_rx_errors_crc;
|
||||||
|
aircopy_state_t g_aircopy_state;
|
||||||
|
|
||||||
|
uint16_t g_fsk_buffer[AIRCOPY_DATA_PACKET_SIZE / 2];
|
||||||
|
unsigned int g_fsk_write_index;
|
||||||
|
uint16_t g_fsk_tx_timeout_10ms;
|
||||||
|
|
||||||
|
uint8_t aircopy_send_count_down_10ms;
|
||||||
|
|
||||||
|
void AIRCOPY_init(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
// turn the backlight ON
|
||||||
const uint16_t eeprom_addr = (uint16_t)g_aircopy_block_number * 64;
|
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
|
||||||
|
|
||||||
// will be used to ask the TX/ing radio to resend a missing/corrupted packet
|
RADIO_SetupRegisters(true);
|
||||||
(void)request_packet;
|
|
||||||
|
BK4819_SetupAircopy(AIRCOPY_DATA_PACKET_SIZE);
|
||||||
|
|
||||||
|
BK4819_reset_fsk();
|
||||||
|
|
||||||
|
g_aircopy_state = AIRCOPY_READY;
|
||||||
|
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off
|
||||||
|
BK4819_start_fsk_rx(AIRCOPY_DATA_PACKET_SIZE);
|
||||||
|
|
||||||
|
GUI_SelectNextDisplay(DISPLAY_AIRCOPY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIRCOPY_start_fsk_tx(const int request_block_num)
|
||||||
|
{
|
||||||
|
const unsigned int eeprom_addr = (request_block_num < 0) ? g_aircopy_block_number * 64 : (unsigned int)request_block_num * 64;
|
||||||
|
uint16_t fsk_reg59;
|
||||||
|
unsigned int k;
|
||||||
|
unsigned int tx_size = 0;
|
||||||
|
|
||||||
// *********
|
// *********
|
||||||
|
|
||||||
// packet start
|
// packet start
|
||||||
g_fsk_buffer[0] = AIRCOPY_MAGIC_START;
|
g_fsk_buffer[tx_size++] = (request_block_num < 0) ? AIRCOPY_MAGIC_START : AIRCOPY_MAGIC_START_REQ;
|
||||||
|
|
||||||
// eeprom address
|
// eeprom address
|
||||||
g_fsk_buffer[1] = eeprom_addr;
|
g_fsk_buffer[tx_size++] = eeprom_addr;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
EEPROM_ReadBuffer(eeprom_addr, &g_fsk_buffer[2], 64);
|
if (request_block_num < 0)
|
||||||
|
{
|
||||||
|
EEPROM_ReadBuffer(eeprom_addr, &g_fsk_buffer[tx_size], 64);
|
||||||
|
tx_size += 64 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
// data CRC
|
// data CRC
|
||||||
g_fsk_buffer[34] = CRC_Calculate(&g_fsk_buffer[1], 2 + 64);
|
g_fsk_buffer[tx_size++] = CRC_Calculate(&g_fsk_buffer[1], (request_block_num < 0) ? 2 + 64 : 2);
|
||||||
|
|
||||||
// packet end
|
// packet end
|
||||||
g_fsk_buffer[35] = AIRCOPY_MAGIC_END;
|
g_fsk_buffer[tx_size++] = (request_block_num < 0) ? AIRCOPY_MAGIC_END : AIRCOPY_MAGIC_END_REQ;
|
||||||
|
|
||||||
// *********
|
// *********
|
||||||
|
|
||||||
{ // scramble the packet
|
{ // scramble the packet
|
||||||
//for (i = 0; i < 34; i++)
|
|
||||||
//g_fsk_buffer[1 + i] ^= Obfuscation[i % ARRAY_SIZE(Obfuscation)];
|
|
||||||
|
|
||||||
uint8_t *p = (uint8_t *)&g_fsk_buffer[1];
|
uint8_t *p = (uint8_t *)&g_fsk_buffer[1];
|
||||||
for (i = 0; i < (34 * 2); i++)
|
for (k = 0; k < ((tx_size - 2) * 2); k++)
|
||||||
*p++ ^= obfuscate_array[i % ARRAY_SIZE(obfuscate_array)];
|
*p++ ^= obfuscate_array[k % ARRAY_SIZE(obfuscate_array)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TX the packet
|
g_fsk_tx_timeout_10ms = 1000 / 10; // 1 second timeout
|
||||||
RADIO_SetTxParameters();
|
|
||||||
BK4819_SetupPowerAmplifier(0, g_current_vfo->p_tx->frequency); // VERY low TX power
|
|
||||||
|
|
||||||
// turn the RED LED on
|
// turn the TX on
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true);
|
RADIO_enableTX(true);
|
||||||
|
|
||||||
// start sending the packet
|
// REG_59
|
||||||
|
//
|
||||||
|
// <15> 0 TX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <14> 0 RX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <13> 0 FSK Scramble
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <12> 0 FSK RX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <11> 0 FSK TX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <10> 0 FSK data when RX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <9> 0 FSK data when TX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <8> 0 ???
|
||||||
|
//
|
||||||
|
// <7:4> 0 FSK preamble length selection
|
||||||
|
// 0 = 1 byte
|
||||||
|
// 1 = 2 bytes
|
||||||
|
// 2 = 3 bytes
|
||||||
|
// 15 = 16 bytes
|
||||||
|
//
|
||||||
|
// <3> 0 FSK sync length selection
|
||||||
|
// 0 = 2 bytes (FSK Sync Byte 0, 1)
|
||||||
|
// 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3)
|
||||||
|
//
|
||||||
|
// <2:0> 0 ???
|
||||||
|
//
|
||||||
|
// 0x0068 0000 0000 0110 1000
|
||||||
|
//
|
||||||
|
fsk_reg59 = (0u << 15) | // 0 or 1 1 = clear TX FIFO
|
||||||
|
(0u << 14) | // 0 or 1 1 = clear RX FIFO
|
||||||
|
(0u << 13) | // 0 or 1 1 = scramble
|
||||||
|
(0u << 12) | // 0 or 1 1 = enable RX
|
||||||
|
(0u << 11) | // 0 or 1 1 = enable TX
|
||||||
|
(0u << 10) | // 0 or 1 1 = invert data when RX
|
||||||
|
(0u << 9) | // 0 or 1 1 = invert data when TX
|
||||||
|
(0u << 8) | // 0 or 1 ???
|
||||||
|
(6u << 4) | // 0 ~ 15 preamble Length Selection
|
||||||
|
(1u << 3) | // 0 or 1 sync length selection
|
||||||
|
(0u << 0); // 0 ~ 7 ???
|
||||||
|
|
||||||
// let the TX stabilize
|
// set the packet size
|
||||||
SYSTEM_DelayMs(10);
|
BK4819_WriteRegister(BK4819_REG_5D, (((tx_size * 2) - 1) << 8));
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED);
|
// clear TX fifo
|
||||||
|
BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | fsk_reg59);
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x8068);
|
BK4819_WriteRegister(BK4819_REG_59, fsk_reg59);
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x0068);
|
|
||||||
|
|
||||||
// load the packet
|
// load the packet
|
||||||
for (i = 0; i < 36; i++)
|
for (k = 0; k < tx_size; k++)
|
||||||
BK4819_WriteRegister(BK4819_REG_5F, g_fsk_buffer[i]);
|
BK4819_WriteRegister(BK4819_REG_5F, g_fsk_buffer[k]);
|
||||||
|
|
||||||
// SYSTEM_DelayMs(20);
|
// enable tx interrupt(s)
|
||||||
|
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED);
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x2868);
|
// enable scramble, enable TX
|
||||||
|
BK4819_WriteRegister(BK4819_REG_59, (1u << 13) | (1u << 11) | fsk_reg59);
|
||||||
g_fsk_tx_timeout_10ms = 1000 / 10; // 1 second timeout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIRCOPY_stop_FSK_tx(void)
|
void AIRCOPY_stop_fsk_tx(const bool inc_block)
|
||||||
{
|
{
|
||||||
if (g_aircopy_state != AIRCOPY_TX && g_fsk_tx_timeout_10ms == 0)
|
if (g_aircopy_state != AIRCOPY_TX && g_fsk_tx_timeout_10ms == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_fsk_tx_timeout_10ms = 0;
|
g_fsk_tx_timeout_10ms = 0;
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_02, 0); // disable all interrupts
|
|
||||||
|
|
||||||
// SYSTEM_DelayMs(20);
|
|
||||||
|
|
||||||
BK4819_ResetFSK();
|
|
||||||
|
|
||||||
// disable the TX
|
// disable the TX
|
||||||
BK4819_SetupPowerAmplifier(0, 0);
|
BK4819_SetupPowerAmplifier(0, 0); //
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false);
|
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); // ???
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); // LED off
|
||||||
|
|
||||||
// turn the RED LED off
|
BK4819_reset_fsk();
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false);
|
|
||||||
|
|
||||||
if (++g_aircopy_block_number >= g_aircopy_block_max)
|
if (inc_block)
|
||||||
{ // transfer is complete
|
{
|
||||||
g_aircopy_state = AIRCOPY_TX_COMPLETE;
|
if (++g_aircopy_block_number >= g_aircopy_block_max)
|
||||||
|
{ // transfer is complete
|
||||||
|
g_aircopy_state = AIRCOPY_TX_COMPLETE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // TX pause/gap time till we start the next packet
|
||||||
|
aircopy_send_count_down_10ms = 220 / 10; // 220ms
|
||||||
|
}
|
||||||
|
|
||||||
|
// RX mode
|
||||||
|
BK4819_start_fsk_rx(AIRCOPY_REQ_PACKET_SIZE);
|
||||||
|
|
||||||
|
g_update_display = true;
|
||||||
|
GUI_DisplayScreen();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ // RX mode
|
||||||
// TX pause/gap time till we start the next packet
|
BK4819_start_fsk_rx(AIRCOPY_DATA_PACKET_SIZE);
|
||||||
#if 0
|
|
||||||
aircopy_send_count_down_10ms = 300 / 10; // 300ms
|
|
||||||
#else
|
|
||||||
aircopy_send_count_down_10ms = 10 / 10; // 10ms
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_update_display = true;
|
|
||||||
GUI_DisplayScreen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIRCOPY_process_FSK_tx_10ms(void)
|
void AIRCOPY_process_fsk_tx_10ms(void)
|
||||||
{
|
{
|
||||||
if (g_aircopy_state != AIRCOPY_TX)
|
uint16_t interrupt_bits = 0;
|
||||||
|
|
||||||
|
if (g_aircopy_state != AIRCOPY_TX && g_aircopy_state != AIRCOPY_RX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_fsk_tx_timeout_10ms == 0)
|
if (g_fsk_tx_timeout_10ms == 0)
|
||||||
{ // not currently TX'ing
|
{ // not currently TX'ing
|
||||||
if (g_aircopy_block_number < g_aircopy_block_max)
|
|
||||||
{ // not yet finished the complete transfer
|
|
||||||
if (aircopy_send_count_down_10ms > 0)
|
|
||||||
{ // waiting till it's time to TX next packet
|
|
||||||
if (--aircopy_send_count_down_10ms == 0)
|
|
||||||
{ // start next packet
|
|
||||||
AIRCOPY_start_FSK_tx(0xff);
|
|
||||||
|
|
||||||
g_update_display = true;
|
if (g_aircopy_state == AIRCOPY_TX && g_aircopy_block_number < g_aircopy_block_max)
|
||||||
GUI_DisplayScreen();
|
{ // not yet finished the complete transfer
|
||||||
}
|
|
||||||
}
|
if (aircopy_send_count_down_10ms > 0)
|
||||||
|
if (--aircopy_send_count_down_10ms > 0)
|
||||||
|
return; // not yet time to TX next packet
|
||||||
|
|
||||||
|
if (g_fsk_write_index > 0)
|
||||||
|
return; // currently RX'ing a packet
|
||||||
|
|
||||||
|
// start next TX packet
|
||||||
|
AIRCOPY_start_fsk_tx(-1);
|
||||||
|
|
||||||
|
g_update_display = true;
|
||||||
|
GUI_DisplayScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--g_fsk_tx_timeout_10ms > 0)
|
if (--g_fsk_tx_timeout_10ms > 0)
|
||||||
{ // still TX'ing
|
{ // still TX'ing
|
||||||
if ((BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) == 0)
|
if ((BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) == 0)
|
||||||
return; /// TX not yet finished
|
return;
|
||||||
|
BK4819_WriteRegister(BK4819_REG_02, 0);
|
||||||
|
interrupt_bits = BK4819_ReadRegister(BK4819_REG_02);
|
||||||
|
if ((interrupt_bits & BK4819_REG_02_FSK_TX_FINISHED) == 0)
|
||||||
|
return; // TX not yet finished
|
||||||
}
|
}
|
||||||
|
|
||||||
AIRCOPY_stop_FSK_tx();
|
AIRCOPY_stop_fsk_tx(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIRCOPY_process_FSK_rx_10ms(const uint16_t interrupt_status_bits)
|
void AIRCOPY_process_fsk_rx_10ms(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
const unsigned int block_size = 64;
|
||||||
uint16_t Status;
|
const unsigned int write_size = 8;
|
||||||
|
const unsigned int req_ack_size = 4;
|
||||||
|
uint16_t interrupt_bits;
|
||||||
|
uint16_t status;
|
||||||
|
uint16_t crc1;
|
||||||
|
uint16_t crc2;
|
||||||
|
uint16_t eeprom_addr;
|
||||||
|
uint16_t *data;
|
||||||
|
unsigned int block_num;
|
||||||
|
bool req_ack_packet = false;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (g_aircopy_state != AIRCOPY_RX)
|
// REG_59
|
||||||
|
//
|
||||||
|
// <15> 0 TX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <14> 0 RX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <13> 0 FSK Scramble
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <12> 0 FSK RX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <11> 0 FSK TX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <10> 0 FSK data when RX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <9> 0 FSK data when TX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <8> 0 ???
|
||||||
|
//
|
||||||
|
// <7:4> 0 FSK preamble length selection
|
||||||
|
// 0 = 1 byte
|
||||||
|
// 1 = 2 bytes
|
||||||
|
// 2 = 3 bytes
|
||||||
|
// 15 = 16 bytes
|
||||||
|
//
|
||||||
|
// <3> 0 FSK sync length selection
|
||||||
|
// 0 = 2 bytes (FSK Sync Byte 0, 1)
|
||||||
|
// 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3)
|
||||||
|
//
|
||||||
|
// <2:0> 0 ???
|
||||||
|
//
|
||||||
|
status = BK4819_ReadRegister(BK4819_REG_59);
|
||||||
|
|
||||||
|
if (status & (1u << 11) || g_fsk_tx_timeout_10ms > 0)
|
||||||
|
return; // FSK TX is busy
|
||||||
|
|
||||||
|
if ((status & (1u << 12)) == 0)
|
||||||
|
{ // FSK RX is disabled, enable it
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off
|
||||||
|
BK4819_start_fsk_rx((g_aircopy_state == AIRCOPY_TX) ? AIRCOPY_REQ_PACKET_SIZE : AIRCOPY_DATA_PACKET_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = BK4819_ReadRegister(BK4819_REG_0C);
|
||||||
|
if ((status & (1u << 0)) == 0)
|
||||||
|
return; // no flagged interrupts
|
||||||
|
|
||||||
|
// read the interrupt flags
|
||||||
|
BK4819_WriteRegister(BK4819_REG_02, 0); // clear them
|
||||||
|
interrupt_bits = BK4819_ReadRegister(BK4819_REG_02);
|
||||||
|
|
||||||
|
if (interrupt_bits & BK4819_REG_02_FSK_RX_SYNC)
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); // LED on
|
||||||
|
|
||||||
|
if (interrupt_bits & BK4819_REG_02_FSK_RX_FINISHED)
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off
|
||||||
|
|
||||||
|
if ((interrupt_bits & BK4819_REG_02_FSK_FIFO_ALMOST_FULL) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_FSK_RX_SYNC)
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); // LED on
|
||||||
{
|
|
||||||
// turn the green LED on
|
|
||||||
// BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_FSK_RX_FINISHED)
|
// fetch RX'ed data
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
// turn the green LED off
|
const uint16_t word = BK4819_ReadRegister(BK4819_REG_5F);
|
||||||
// BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_FSK_FIFO_ALMOST_FULL)
|
|
||||||
{
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
g_fsk_buffer[g_fsk_write_index++] = BK4819_ReadRegister(BK4819_REG_5F);
|
|
||||||
|
|
||||||
if (g_fsk_write_index < ARRAY_SIZE(g_fsk_buffer))
|
if (g_fsk_write_index < ARRAY_SIZE(g_fsk_buffer))
|
||||||
{
|
g_fsk_buffer[g_fsk_write_index++] = word;
|
||||||
// turn the green LED on
|
}
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// turn the green LED off
|
// REG_0B read only
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false);
|
//
|
||||||
|
// <15:12> ???
|
||||||
|
//
|
||||||
|
// <11:8> DTMF/5-tone code received
|
||||||
|
//
|
||||||
|
// <7> FSK RX sync negative has been found
|
||||||
|
//
|
||||||
|
// <6> FSK RX sync positive has been found
|
||||||
|
//
|
||||||
|
// <5> ???
|
||||||
|
//
|
||||||
|
// <4> FSK RX CRC indicator
|
||||||
|
// 1 = CRC pass
|
||||||
|
// 0 = CRC fail
|
||||||
|
//
|
||||||
|
// <3:0> ???
|
||||||
|
//
|
||||||
|
status = BK4819_ReadRegister(BK4819_REG_0B);
|
||||||
|
|
||||||
|
// check to see if it's a REQ/ACK packet
|
||||||
|
if (g_fsk_write_index == req_ack_size)
|
||||||
|
req_ack_packet = (g_fsk_buffer[0] == AIRCOPY_MAGIC_START_REQ && g_fsk_buffer[g_fsk_write_index - 1] == AIRCOPY_MAGIC_END_REQ);
|
||||||
|
|
||||||
|
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||||
|
// UART_printf("aircopy rx %04X %u\r\n", interrupt_bits, g_fsk_write_index);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (g_fsk_write_index < ARRAY_SIZE(g_fsk_buffer) && !req_ack_packet)
|
||||||
|
return; // not yet a complete packet
|
||||||
|
|
||||||
|
// restart the RX
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off
|
||||||
|
BK4819_start_fsk_rx((g_aircopy_state == AIRCOPY_TX) ? AIRCOPY_REQ_PACKET_SIZE : AIRCOPY_DATA_PACKET_SIZE);
|
||||||
|
|
||||||
|
g_update_display = true;
|
||||||
|
|
||||||
|
// doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL
|
||||||
|
if ((status & (1u << 4)) != 0)
|
||||||
|
{
|
||||||
|
g_aircopy_rx_errors_fsk_crc++;
|
||||||
|
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||||
|
UART_printf("aircopy status %04X\r\n", status);
|
||||||
|
#endif
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // unscramble the packet
|
||||||
|
uint8_t *p = (uint8_t *)&g_fsk_buffer[1];
|
||||||
|
for (i = 0; i < ((g_fsk_write_index - 2) * 2); i++)
|
||||||
|
*p++ ^= obfuscate_array[i % ARRAY_SIZE(obfuscate_array)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the CRC
|
||||||
|
crc1 = CRC_Calculate(&g_fsk_buffer[1], (g_fsk_write_index - 3) * 2);
|
||||||
|
// fetch the CRC
|
||||||
|
crc2 = g_fsk_buffer[g_fsk_write_index - 2];
|
||||||
|
|
||||||
|
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||||
|
// show the entire packet
|
||||||
|
UART_SendText("aircopy");
|
||||||
|
for (i = 0; i < g_fsk_write_index; i++)
|
||||||
|
UART_printf(" %04X", g_fsk_buffer[i]);
|
||||||
|
UART_printf(" - %04X\r\n", status);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check the CRC
|
||||||
|
if (crc2 != crc1)
|
||||||
|
{ // invalid CRC
|
||||||
|
g_aircopy_rx_errors_crc++;
|
||||||
|
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||||
|
UART_printf("aircopy invalid CRC %04X %04X\r\n", crc2, crc1);
|
||||||
|
#endif
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eeprom_addr = g_fsk_buffer[1];
|
||||||
|
data = &g_fsk_buffer[2];
|
||||||
|
|
||||||
|
block_num = eeprom_addr / block_size;
|
||||||
|
|
||||||
|
if (req_ack_packet)
|
||||||
|
{ // it's a req/ack packet
|
||||||
|
|
||||||
|
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||||
|
UART_printf("aircopy RX req %04X %04X\r\n", block_num * 64, g_aircopy_block_number * 64);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (g_aircopy_state == AIRCOPY_TX)
|
||||||
|
{ // send them the block they want
|
||||||
|
g_aircopy_block_number = block_num; // go to the block number they want
|
||||||
|
aircopy_send_count_down_10ms = 0; // TX asap
|
||||||
|
}
|
||||||
|
|
||||||
g_fsk_write_index = 0;
|
g_fsk_write_index = 0;
|
||||||
g_update_display = true;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Status = BK4819_ReadRegister(BK4819_REG_0B);
|
if (g_aircopy_state != AIRCOPY_RX)
|
||||||
|
{ // not in RX mode .. ignore it
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BK4819_PrepareFSKReceive();
|
if (g_fsk_buffer[0] != AIRCOPY_MAGIC_START || g_fsk_buffer[g_fsk_write_index - 1] != AIRCOPY_MAGIC_END)
|
||||||
|
{ // invalid magics .. ignore it
|
||||||
|
g_aircopy_rx_errors_magic++;
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL
|
if (eeprom_addr != (block_num * block_size))
|
||||||
|
{ // eeprom address not block aligned .. ignore it
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Status & (1u << 4)) == 0 &&
|
if (block_num != g_aircopy_block_number)
|
||||||
g_fsk_buffer[0] == AIRCOPY_MAGIC_START &&
|
{ // not the block number we're expecting .. request the correct block
|
||||||
g_fsk_buffer[35] == AIRCOPY_MAGIC_END)
|
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
|
||||||
|
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||||
|
UART_printf("aircopy TX req %04X %04X\r\n", g_aircopy_block_number * 64, block_num * 64);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// this packet takes 150ms start to finish
|
||||||
|
AIRCOPY_start_fsk_tx(g_aircopy_block_number);
|
||||||
|
g_fsk_tx_timeout_10ms = 200 / 5; // allow up to 200ms for the TX to complete
|
||||||
|
while (g_fsk_tx_timeout_10ms-- > 0)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
SYSTEM_DelayMs(5);
|
||||||
uint16_t CRC;
|
if (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0))
|
||||||
|
{ // we have interrupt flags
|
||||||
{ // unscramble the packet
|
BK4819_WriteRegister(BK4819_REG_02, 0);
|
||||||
uint8_t *p = (uint8_t *)&g_fsk_buffer[1];
|
const uint16_t interrupt_bits = BK4819_ReadRegister(BK4819_REG_02);
|
||||||
for (i = 0; i < (34 * 2); i++)
|
if (interrupt_bits & BK4819_REG_02_FSK_TX_FINISHED)
|
||||||
*p++ ^= obfuscate_array[i % ARRAY_SIZE(obfuscate_array)];
|
g_fsk_tx_timeout_10ms = 0; // TX is complete
|
||||||
}
|
|
||||||
|
|
||||||
CRC = CRC_Calculate(&g_fsk_buffer[1], 2 + 64);
|
|
||||||
|
|
||||||
if (g_fsk_buffer[34] == CRC)
|
|
||||||
{ // CRC is valid
|
|
||||||
uint16_t eeprom_addr = g_fsk_buffer[1];
|
|
||||||
|
|
||||||
if (eeprom_addr == 0)
|
|
||||||
{ // start again
|
|
||||||
g_aircopy_block_number = 0;
|
|
||||||
g_aircopy_rx_errors = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((eeprom_addr + 64) <= AIRCOPY_LAST_EEPROM_ADDR)
|
|
||||||
{ // eeprom block is valid .. write it directly to eeprom
|
|
||||||
|
|
||||||
uint16_t *pData = &g_fsk_buffer[2];
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (eeprom_addr == 0x0E98)
|
|
||||||
{ // power-on password .. wipe it
|
|
||||||
#ifndef ENABLE_PWRON_PASSWORD
|
|
||||||
pData[0] = 0xffff;
|
|
||||||
pData[1] = 0xffff;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (eeprom_addr == 0x0F30)
|
|
||||||
{ // AES key .. wipe it
|
|
||||||
#ifdef ENABLE_RESET_AES_KEY
|
|
||||||
pData[0] = 0xffff;
|
|
||||||
pData[1] = 0xffff;
|
|
||||||
pData[2] = 0xffff;
|
|
||||||
pData[3] = 0xffff;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
EEPROM_WriteBuffer(eeprom_addr, pData); // 8 bytes at a time
|
|
||||||
pData += 4;
|
|
||||||
eeprom_addr += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_aircopy_block_number = eeprom_addr / 64;
|
|
||||||
|
|
||||||
if (eeprom_addr >= AIRCOPY_LAST_EEPROM_ADDR)
|
|
||||||
{ // reached end of eeprom config area
|
|
||||||
g_aircopy_state = AIRCOPY_RX_COMPLETE;
|
|
||||||
|
|
||||||
// turn the green LED off
|
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false);
|
|
||||||
|
|
||||||
g_update_display = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(g_fsk_buffer, 0, sizeof(g_fsk_buffer));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AIRCOPY_stop_fsk_tx(false);
|
||||||
|
|
||||||
g_aircopy_rx_errors++;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((eeprom_addr + block_size) > AIRCOPY_LAST_EEPROM_ADDR)
|
||||||
|
{
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear the error counts
|
||||||
|
g_aircopy_rx_errors_fsk_crc = 0;
|
||||||
|
g_aircopy_rx_errors_magic = 0;
|
||||||
|
g_aircopy_rx_errors_crc = 0;
|
||||||
|
|
||||||
|
// eeprom block appears valid .. write it directly to eeprom
|
||||||
|
|
||||||
|
for (i = 0; i < (block_size / write_size); i++)
|
||||||
|
{
|
||||||
|
if (eeprom_addr == 0x0E98)
|
||||||
|
{ // power-on password .. wipe it
|
||||||
|
//#ifndef ENABLE_PWRON_PASSWORD
|
||||||
|
data[0] = 0xffff;
|
||||||
|
data[1] = 0xffff;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (eeprom_addr == 0x0F30)
|
||||||
|
{ // AES key .. wipe it
|
||||||
|
//#ifdef ENABLE_RESET_AES_KEY
|
||||||
|
data[0] = 0xffff;
|
||||||
|
data[1] = 0xffff;
|
||||||
|
data[2] = 0xffff;
|
||||||
|
data[3] = 0xffff;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
EEPROM_WriteBuffer(eeprom_addr, data); // 8 bytes at a time
|
||||||
|
data += write_size / sizeof(data[0]);
|
||||||
|
eeprom_addr += write_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_aircopy_block_number = block_num + 1;
|
||||||
|
g_fsk_write_index = 0;
|
||||||
|
|
||||||
|
if (eeprom_addr >= AIRCOPY_LAST_EEPROM_ADDR)
|
||||||
|
g_aircopy_state = AIRCOPY_RX_COMPLETE; // reached end of eeprom config area
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
|
static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
|
||||||
@ -307,7 +565,7 @@ static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
|
|||||||
|
|
||||||
if (g_aircopy_state != AIRCOPY_READY)
|
if (g_aircopy_state != AIRCOPY_READY)
|
||||||
{
|
{
|
||||||
AIRCOPY_stop_FSK_tx();
|
AIRCOPY_stop_fsk_tx(false);
|
||||||
|
|
||||||
g_aircopy_state = AIRCOPY_READY;
|
g_aircopy_state = AIRCOPY_READY;
|
||||||
g_update_display = true;
|
g_update_display = true;
|
||||||
@ -359,10 +617,7 @@ static void AIRCOPY_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
|
|||||||
|
|
||||||
g_current_vfo = g_rx_vfo;
|
g_current_vfo = g_rx_vfo;
|
||||||
|
|
||||||
RADIO_SetupRegisters(true);
|
AIRCOPY_init();
|
||||||
BK4819_SetupAircopy();
|
|
||||||
BK4819_ResetFSK();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,7 +638,8 @@ static void AIRCOPY_Key_EXIT(bool key_pressed, bool key_held)
|
|||||||
// turn the green LED off
|
// turn the green LED off
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false);
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false);
|
||||||
|
|
||||||
AIRCOPY_stop_FSK_tx();
|
AIRCOPY_stop_fsk_tx(false);
|
||||||
|
|
||||||
g_input_box_index = 0;
|
g_input_box_index = 0;
|
||||||
g_aircopy_state = AIRCOPY_READY;
|
g_aircopy_state = AIRCOPY_READY;
|
||||||
g_update_display = true;
|
g_update_display = true;
|
||||||
@ -418,12 +674,13 @@ static void AIRCOPY_Key_EXIT(bool key_pressed, bool key_held)
|
|||||||
g_update_display = true;
|
g_update_display = true;
|
||||||
GUI_DisplayScreen();
|
GUI_DisplayScreen();
|
||||||
|
|
||||||
g_fsk_write_index = 0;
|
g_fsk_write_index = 0;
|
||||||
g_aircopy_block_number = 0;
|
g_aircopy_block_number = 0;
|
||||||
g_aircopy_rx_errors = 0;
|
g_aircopy_rx_errors_fsk_crc = 0;
|
||||||
memset(g_fsk_buffer, 0, sizeof(g_fsk_buffer));
|
g_aircopy_rx_errors_magic = 0;
|
||||||
|
g_aircopy_rx_errors_crc = 0;
|
||||||
|
|
||||||
BK4819_PrepareFSKReceive();
|
BK4819_start_fsk_rx(AIRCOPY_DATA_PACKET_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,12 +703,14 @@ static void AIRCOPY_Key_MENU(bool key_pressed, bool key_held)
|
|||||||
|
|
||||||
g_input_box_index = 0;
|
g_input_box_index = 0;
|
||||||
|
|
||||||
g_fsk_write_index = 0;
|
g_fsk_write_index = 0;
|
||||||
g_aircopy_block_number = 0;
|
g_aircopy_block_number = 0;
|
||||||
g_aircopy_rx_errors = 0;
|
g_aircopy_rx_errors_fsk_crc = 0;
|
||||||
|
g_aircopy_rx_errors_magic = 0;
|
||||||
|
g_aircopy_rx_errors_crc = 0;
|
||||||
|
|
||||||
g_fsk_tx_timeout_10ms = 0;
|
g_fsk_tx_timeout_10ms = 0;
|
||||||
aircopy_send_count_down_10ms = 30 / 10; // 30ms
|
aircopy_send_count_down_10ms = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,17 +29,19 @@ enum aircopy_state_e
|
|||||||
};
|
};
|
||||||
typedef enum aircopy_state_e aircopy_state_t;
|
typedef enum aircopy_state_e aircopy_state_t;
|
||||||
|
|
||||||
extern const uint8_t g_aircopy_block_max;
|
extern const unsigned int g_aircopy_block_max;
|
||||||
extern uint8_t g_aircopy_block_number;
|
extern unsigned int g_aircopy_block_number;
|
||||||
extern uint8_t g_aircopy_rx_errors;
|
extern uint8_t g_aircopy_rx_errors_fsk_crc;
|
||||||
extern aircopy_state_t g_aircopy_state;
|
extern uint8_t g_aircopy_rx_errors_magic;
|
||||||
extern uint16_t g_fsk_buffer[36];
|
extern uint8_t g_aircopy_rx_errors_crc;
|
||||||
extern unsigned int g_fsk_write_index;
|
extern aircopy_state_t g_aircopy_state;
|
||||||
extern uint16_t g_fsk_tx_timeout_10ms;
|
extern uint16_t g_fsk_buffer[36];
|
||||||
|
extern unsigned int g_fsk_write_index;
|
||||||
|
extern uint16_t g_fsk_tx_timeout_10ms;
|
||||||
|
|
||||||
void AIRCOPY_process_FSK_tx_10ms(void);
|
void AIRCOPY_init(void);
|
||||||
void AIRCOPY_process_FSK_rx_10ms(const uint16_t interrupt_status_bits);
|
void AIRCOPY_process_fsk_tx_10ms(void);
|
||||||
void AIRCOPY_stop_FSK_tx(void);
|
void AIRCOPY_process_fsk_rx_10ms(void);
|
||||||
void AIRCOPY_ProcessKey(key_code_t key, bool key_pressed, bool key_held);
|
void AIRCOPY_ProcessKey(key_code_t key, bool key_pressed, bool key_held);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
81
app/app.c
81
app/app.c
@ -848,26 +848,13 @@ void APP_CheckRadioInterrupts(void)
|
|||||||
if (g_screen_to_display == DISPLAY_SEARCH)
|
if (g_screen_to_display == DISPLAY_SEARCH)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (BK4819_ReadRegister(BK4819_REG_0C) & 1u)
|
while (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0))
|
||||||
{ // BK chip interrupt request
|
{ // BK chip interrupt request
|
||||||
|
|
||||||
uint16_t interrupt_status_bits;
|
|
||||||
|
|
||||||
// reset the interrupt ?
|
|
||||||
BK4819_WriteRegister(BK4819_REG_02, 0);
|
BK4819_WriteRegister(BK4819_REG_02, 0);
|
||||||
|
const uint16_t interrupt_bits = BK4819_ReadRegister(BK4819_REG_02);
|
||||||
|
|
||||||
// fetch the interrupt status bits
|
if (interrupt_bits & BK4819_REG_02_DTMF_5TONE_FOUND)
|
||||||
interrupt_status_bits = BK4819_ReadRegister(BK4819_REG_02);
|
|
||||||
|
|
||||||
// 0 = no phase shift
|
|
||||||
// 1 = 120deg phase shift
|
|
||||||
// 2 = 180deg phase shift
|
|
||||||
// 3 = 240deg phase shift
|
|
||||||
// const uint8_t ctcss_shift = BK4819_GetCTCShift();
|
|
||||||
// if (ctcss_shift > 0)
|
|
||||||
// g_ctcss_lost = true;
|
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_DTMF_5TONE_FOUND)
|
|
||||||
{ // save the RX'ed DTMF character
|
{ // save the RX'ed DTMF character
|
||||||
const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code());
|
const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code());
|
||||||
if (c != 0xff)
|
if (c != 0xff)
|
||||||
@ -906,26 +893,26 @@ void APP_CheckRadioInterrupts(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_CxCSS_TAIL)
|
if (interrupt_bits & BK4819_REG_02_CxCSS_TAIL)
|
||||||
g_cxcss_tail_found = true;
|
g_cxcss_tail_found = true;
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_CDCSS_LOST)
|
if (interrupt_bits & BK4819_REG_02_CDCSS_LOST)
|
||||||
{
|
{
|
||||||
g_cdcss_lost = true;
|
g_cdcss_lost = true;
|
||||||
g_cdcss_code_type = BK4819_get_CDCSS_code_type();
|
g_cdcss_code_type = BK4819_get_CDCSS_code_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_CDCSS_FOUND)
|
if (interrupt_bits & BK4819_REG_02_CDCSS_FOUND)
|
||||||
g_cdcss_lost = false;
|
g_cdcss_lost = false;
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_CTCSS_LOST)
|
if (interrupt_bits & BK4819_REG_02_CTCSS_LOST)
|
||||||
g_ctcss_lost = true;
|
g_ctcss_lost = true;
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_CTCSS_FOUND)
|
if (interrupt_bits & BK4819_REG_02_CTCSS_FOUND)
|
||||||
g_ctcss_lost = false;
|
g_ctcss_lost = false;
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
#ifdef ENABLE_VOX
|
||||||
if (interrupt_status_bits & BK4819_REG_02_VOX_LOST)
|
if (interrupt_bits & BK4819_REG_02_VOX_LOST)
|
||||||
{
|
{
|
||||||
g_vox_lost = true;
|
g_vox_lost = true;
|
||||||
g_vox_pause_count_down = 10;
|
g_vox_pause_count_down = 10;
|
||||||
@ -951,34 +938,24 @@ void APP_CheckRadioInterrupts(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_VOX_FOUND)
|
if (interrupt_bits & BK4819_REG_02_VOX_FOUND)
|
||||||
{
|
{
|
||||||
g_vox_lost = false;
|
g_vox_lost = false;
|
||||||
g_vox_pause_count_down = 0;
|
g_vox_pause_count_down = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_SQUELCH_LOST)
|
if (interrupt_bits & BK4819_REG_02_SQUELCH_LOST)
|
||||||
{
|
{
|
||||||
g_squelch_lost = true;
|
g_squelch_lost = true;
|
||||||
// turn the LED off
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true); // LED on
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupt_status_bits & BK4819_REG_02_SQUELCH_FOUND)
|
if (interrupt_bits & BK4819_REG_02_SQUELCH_FOUND)
|
||||||
{
|
{
|
||||||
g_squelch_lost = false;
|
g_squelch_lost = false;
|
||||||
// turn the LED on
|
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false); // LED off
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_GREEN, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_AIRCOPY
|
|
||||||
if (g_screen_to_display == DISPLAY_AIRCOPY)
|
|
||||||
{
|
|
||||||
AIRCOPY_process_FSK_rx_10ms(interrupt_status_bits);
|
|
||||||
// AIRCOPY_process_FSK_tx_10ms(interrupt_status_bits);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1625,18 +1602,12 @@ void APP_TimeSlice10ms(void)
|
|||||||
|
|
||||||
#ifdef ENABLE_AIRCOPY
|
#ifdef ENABLE_AIRCOPY
|
||||||
if (g_screen_to_display == DISPLAY_AIRCOPY)
|
if (g_screen_to_display == DISPLAY_AIRCOPY)
|
||||||
{
|
{ // we're in AIRCOPY mode
|
||||||
APP_CheckRadioInterrupts();
|
|
||||||
|
|
||||||
if (g_aircopy_state == AIRCOPY_RX)
|
|
||||||
{ // we're RX'ing
|
|
||||||
//AIRCOPY_process_FSK_rx_10ms(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (g_aircopy_state == AIRCOPY_TX)
|
if (g_aircopy_state == AIRCOPY_TX)
|
||||||
{ // we're TX'ing
|
AIRCOPY_process_fsk_tx_10ms();
|
||||||
AIRCOPY_process_FSK_tx_10ms();
|
|
||||||
}
|
AIRCOPY_process_fsk_rx_10ms();
|
||||||
|
|
||||||
APP_CheckKeys();
|
APP_CheckKeys();
|
||||||
|
|
||||||
@ -1720,9 +1691,9 @@ void APP_TimeSlice10ms(void)
|
|||||||
|
|
||||||
RADIO_EnableCxCSS();
|
RADIO_EnableCxCSS();
|
||||||
BK4819_SetupPowerAmplifier(0, 0);
|
BK4819_SetupPowerAmplifier(0, 0);
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false);
|
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); // ???
|
||||||
BK4819_Enable_AfDac_DiscMode_TxDsp();
|
BK4819_Enable_AfDac_DiscMode_TxDsp();
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false);
|
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); // LED off
|
||||||
|
|
||||||
GUI_DisplayScreen();
|
GUI_DisplayScreen();
|
||||||
}
|
}
|
||||||
@ -1732,13 +1703,12 @@ void APP_TimeSlice10ms(void)
|
|||||||
|
|
||||||
GUI_DisplayScreen();
|
GUI_DisplayScreen();
|
||||||
|
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true);
|
RADIO_enableTX(false);
|
||||||
RADIO_SetTxParameters();
|
|
||||||
BK4819_TransmitTone(true, 500);
|
BK4819_TransmitTone(true, 500);
|
||||||
SYSTEM_DelayMs(2);
|
SYSTEM_DelayMs(2);
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
||||||
|
|
||||||
g_enable_speaker = true;
|
g_enable_speaker = true;
|
||||||
g_alarm_tone_counter = 0;
|
g_alarm_tone_counter = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2087,11 +2057,16 @@ void APP_TimeSlice500ms(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_backlight_count_down > 0 && !g_ask_to_save && g_css_scan_mode == CSS_SCAN_MODE_OFF)
|
if (g_backlight_count_down > 0 &&
|
||||||
|
!g_ask_to_save &&
|
||||||
|
g_css_scan_mode == CSS_SCAN_MODE_OFF &&
|
||||||
|
g_screen_to_display != DISPLAY_AIRCOPY)
|
||||||
|
{
|
||||||
if (g_screen_to_display != DISPLAY_MENU || g_menu_cursor != MENU_ABR) // don't turn off backlight if user is in backlight menu option
|
if (g_screen_to_display != DISPLAY_MENU || g_menu_cursor != MENU_ABR) // don't turn off backlight if user is in backlight menu option
|
||||||
if (--g_backlight_count_down == 0)
|
if (--g_backlight_count_down == 0)
|
||||||
if (g_eeprom.backlight < (ARRAY_SIZE(g_sub_menu_backlight) - 1))
|
if (g_eeprom.backlight < (ARRAY_SIZE(g_sub_menu_backlight) - 1))
|
||||||
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn backlight off
|
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn backlight off
|
||||||
|
}
|
||||||
|
|
||||||
if (g_reduced_service)
|
if (g_reduced_service)
|
||||||
{
|
{
|
||||||
|
549
driver/bk4819.c
549
driver/bk4819.c
@ -27,8 +27,6 @@
|
|||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
|
|
||||||
|
|
||||||
static uint16_t gBK4819_GpioOutState;
|
static uint16_t gBK4819_GpioOutState;
|
||||||
|
|
||||||
bool g_rx_idle_mode;
|
bool g_rx_idle_mode;
|
||||||
@ -700,8 +698,8 @@ void BK4819_SetupPowerAmplifier(const uint8_t bias, const uint32_t frequency)
|
|||||||
// 7 = max
|
// 7 = max
|
||||||
// 0 = min
|
// 0 = min
|
||||||
//
|
//
|
||||||
// 280MHz gain 1 = 1 gain 2 = 0 gain 1 = 4 gain 2 = 2
|
// 280MHz gain 1 = 1 gain 2 = 0 gain 1 = 4 gain 2 = 2
|
||||||
const uint8_t gain = (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0);
|
const uint8_t gain = (frequency == 0) ? 0 : (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0);
|
||||||
const uint8_t enable = 1;
|
const uint8_t enable = 1;
|
||||||
BK4819_WriteRegister(BK4819_REG_36, ((uint16_t)bias << 8) | ((uint16_t)enable << 7) | ((uint16_t)gain << 0));
|
BK4819_WriteRegister(BK4819_REG_36, ((uint16_t)bias << 8) | ((uint16_t)enable << 7) | ((uint16_t)gain << 0));
|
||||||
}
|
}
|
||||||
@ -1040,7 +1038,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
|
|||||||
// BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
|
// BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
|
||||||
}
|
}
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
|
BK4819_WriteRegister(BK4819_REG_70, 0);
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
||||||
BK4819_ExitTxMute();
|
BK4819_ExitTxMute();
|
||||||
}
|
}
|
||||||
@ -1078,39 +1076,9 @@ void BK4819_TurnsOffTones_TurnsOnRX(void)
|
|||||||
BK4819_REG_30_ENABLE_RX_DSP);
|
BK4819_REG_30_ENABLE_RX_DSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_AIRCOPY
|
|
||||||
void BK4819_SetupAircopy(void)
|
|
||||||
{
|
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone2, tuning gain 48
|
|
||||||
BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Tone2 baudrate 1200
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_58, 0x00C1); // FSK Enable
|
|
||||||
// FSK 1.2K RX Bandwidth
|
|
||||||
// Preamble 0xAA or 0x55
|
|
||||||
// RX Gain 0
|
|
||||||
// RX Mode
|
|
||||||
// (FSK1.2K, FSK2.4K Rx and NOAA SAME Rx)
|
|
||||||
// TX Mode FSK 1.2K
|
|
||||||
// FSK 2.4K Tx
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // Enable CRC among other things we don't know yet
|
|
||||||
BK4819_WriteRegister(BK4819_REG_5D, 0x4700); // FSK Data Length 72 Bytes (0xABCD + 2 byte length + 64 byte payload + 2 byte CRC + 0xDCBA)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void BK4819_ResetFSK(void)
|
|
||||||
{
|
|
||||||
BK4819_WriteRegister(BK4819_REG_3F, 0x0000); // Disable interrupts
|
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Sync length 4 bytes, 7 byte preamble
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(30);
|
|
||||||
|
|
||||||
BK4819_Idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BK4819_Idle(void)
|
void BK4819_Idle(void)
|
||||||
{
|
{
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0x0000);
|
BK4819_WriteRegister(BK4819_REG_30, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_ExitBypass(void)
|
void BK4819_ExitBypass(void)
|
||||||
@ -1235,7 +1203,7 @@ void BK4819_ExitDTMF_TX(bool bKeep)
|
|||||||
{
|
{
|
||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
BK4819_SetAF(BK4819_AF_MUTE);
|
BK4819_SetAF(BK4819_AF_MUTE);
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
|
BK4819_WriteRegister(BK4819_REG_70, 0);
|
||||||
BK4819_DisableDTMF();
|
BK4819_DisableDTMF();
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
||||||
if (!bKeep)
|
if (!bKeep)
|
||||||
@ -1262,30 +1230,30 @@ void BK4819_PlayDTMF(char Code)
|
|||||||
uint16_t tone1 = 0;
|
uint16_t tone1 = 0;
|
||||||
uint16_t tone2 = 0;
|
uint16_t tone2 = 0;
|
||||||
|
|
||||||
switch (Code) // Hz Hz
|
switch (Code)
|
||||||
{ //
|
{
|
||||||
case '0': tone1 = 9715; tone2 = 13793; break; // 941 1336
|
case '0': tone1 = 941; tone2 = 1336; break;
|
||||||
case '1': tone1 = 7196; tone2 = 12482; break; // 679 1209
|
case '1': tone1 = 679; tone2 = 1209; break;
|
||||||
case '2': tone1 = 7196; tone2 = 13793; break; // 697 1336
|
case '2': tone1 = 697; tone2 = 1336; break;
|
||||||
case '3': tone1 = 7196; tone2 = 15249; break; // 679 1477
|
case '3': tone1 = 679; tone2 = 1477; break;
|
||||||
case '4': tone1 = 7950; tone2 = 12482; break; // 770 1209
|
case '4': tone1 = 770; tone2 = 1209; break;
|
||||||
case '5': tone1 = 7950; tone2 = 13793; break; // 770 1336
|
case '5': tone1 = 770; tone2 = 1336; break;
|
||||||
case '6': tone1 = 7950; tone2 = 15249; break; // 770 1477
|
case '6': tone1 = 770; tone2 = 1477; break;
|
||||||
case '7': tone1 = 8796; tone2 = 12482; break; // 852 1209
|
case '7': tone1 = 852; tone2 = 1209; break;
|
||||||
case '8': tone1 = 8796; tone2 = 13793; break; // 852 1336
|
case '8': tone1 = 852; tone2 = 1336; break;
|
||||||
case '9': tone1 = 8796; tone2 = 15249; break; // 852 1477
|
case '9': tone1 = 852; tone2 = 1477; break;
|
||||||
case 'A': tone1 = 7196; tone2 = 16860; break; // 679 1633
|
case 'A': tone1 = 679; tone2 = 1633; break;
|
||||||
case 'B': tone1 = 7950; tone2 = 16860; break; // 770 1633
|
case 'B': tone1 = 770; tone2 = 1633; break;
|
||||||
case 'C': tone1 = 8796; tone2 = 16860; break; // 852 1633
|
case 'C': tone1 = 852; tone2 = 1633; break;
|
||||||
case 'D': tone1 = 9715; tone2 = 16860; break; // 941 1633
|
case 'D': tone1 = 941; tone2 = 1633; break;
|
||||||
case '*': tone1 = 9715; tone2 = 12482; break; // 941 1209
|
case '*': tone1 = 941; tone2 = 1209; break;
|
||||||
case '#': tone1 = 9715; tone2 = 15249; break; // 941 1477
|
case '#': tone1 = 941; tone2 = 1477; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tone1 > 0)
|
if (tone1 > 0)
|
||||||
BK4819_WriteRegister(BK4819_REG_71, tone1);
|
BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)tone1 * 103244) + 5000) / 10000); // with rounding
|
||||||
if (tone2 > 0)
|
if (tone2 > 0)
|
||||||
BK4819_WriteRegister(BK4819_REG_72, tone2);
|
BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)tone2 * 103244) + 5000) / 10000); // with rounding
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
|
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
|
||||||
@ -1697,60 +1665,210 @@ uint8_t BK4819_GetCTCType(void)
|
|||||||
{
|
{
|
||||||
return (BK4819_ReadRegister(BK4819_REG_0C) >> 10) & 3u;
|
return (BK4819_ReadRegister(BK4819_REG_0C) >> 10) & 3u;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void BK4819_SendFSKData(uint16_t *pData)
|
#ifdef ENABLE_AIRCOPY
|
||||||
|
void BK4819_SetupAircopy(const unsigned int packet_size)
|
||||||
|
{
|
||||||
|
if (packet_size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// REG_70
|
||||||
|
//
|
||||||
|
// <15> 0 TONE-1
|
||||||
|
// 1 = enable
|
||||||
|
// 0 = disable
|
||||||
|
//
|
||||||
|
// <14:8> 0 TONE-1 gain
|
||||||
|
//
|
||||||
|
// <7> 0 TONE-2
|
||||||
|
// 1 = enable
|
||||||
|
// 0 = disable
|
||||||
|
//
|
||||||
|
// <6:0> 0 TONE-2 / FSK gain
|
||||||
|
// 0 ~ 127
|
||||||
|
//
|
||||||
|
// enable tone-2, set gain
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_70, // 0 0000000 1 1100000
|
||||||
|
( 0u << 15) |
|
||||||
|
( 0u << 8) |
|
||||||
|
( 1u << 7) |
|
||||||
|
(96u << 0));
|
||||||
|
|
||||||
|
// REG_72
|
||||||
|
//
|
||||||
|
// <15:0> 0x2854 TONE2/FSK frequency control word
|
||||||
|
// = freq(Hz) * 10.32444 for XTAL 13M / 26M or
|
||||||
|
// = freq(Hz) * 10.48576 for XTAL 12.8M / 19.2M / 25.6M / 38.4M
|
||||||
|
//
|
||||||
|
// tone-2 = 1200Hz
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_72, ((1200u * 103244) + 5000) / 10000); // with rounding
|
||||||
|
|
||||||
|
// these settings don't match the documentation at all ???
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_58, // 0x00C1); // 000 000 00 11 00 000 1
|
||||||
|
(0u << 13) | // 1 FSK TX mode selection
|
||||||
|
// 0 = FSK 1.2K and FSK 2.4K TX .. no tones, pure data
|
||||||
|
// 1 = FFSK 1200 / 1800 TX
|
||||||
|
// 2 = ???
|
||||||
|
// 3 = FFSK 1200 / 2400 TX
|
||||||
|
// 4 = ???
|
||||||
|
// 5 = NOAA SAME TX
|
||||||
|
// 6 = ???
|
||||||
|
// 7 = ???
|
||||||
|
//
|
||||||
|
(0u << 10) | // 0 FSK RX mode selection
|
||||||
|
// 0 = FSK 1.2K, FSK 2.4K RX and NOAA same RX
|
||||||
|
// 1 = ???
|
||||||
|
// 2 = ???
|
||||||
|
// 3 = ???
|
||||||
|
// 4 = FFSK 1200 / 2400 RX
|
||||||
|
// 5 = ???
|
||||||
|
// 6 = ???
|
||||||
|
// 7 = FFSK 1200 / 1800 RX
|
||||||
|
//
|
||||||
|
(0u << 8) | // 0 FSK RX gain
|
||||||
|
// 0 ~ 3
|
||||||
|
//
|
||||||
|
(3u << 6) | // 0 ???
|
||||||
|
// 0 ~ 3
|
||||||
|
//
|
||||||
|
(0u << 4) | // 0 FSK preamble type selection
|
||||||
|
// 0 = 0xAA or 0x55 due to the MSB of FSK sync byte 0
|
||||||
|
// 1 = ???
|
||||||
|
// 2 = 0x55
|
||||||
|
// 3 = 0xAA
|
||||||
|
//
|
||||||
|
(0u << 1) | // 1 FSK RX bandwidth setting
|
||||||
|
// 0 = FSK 1.2K
|
||||||
|
// 1 = FFSK 1200 / 1800
|
||||||
|
// 2 = NOAA same RX
|
||||||
|
// 3 = ???
|
||||||
|
// 4 = FSK 2.4K and FFSK 1200 / 2400
|
||||||
|
// 5 = ???
|
||||||
|
// 6 = ???
|
||||||
|
// 7 = ???
|
||||||
|
//
|
||||||
|
(1u << 0)); // 1 FSK enable
|
||||||
|
// 0 = disable
|
||||||
|
// 1 = enable
|
||||||
|
|
||||||
|
// REG_5C
|
||||||
|
//
|
||||||
|
// <15:7> ???
|
||||||
|
//
|
||||||
|
// <6> 1 CRC option enable
|
||||||
|
// 0 = disable
|
||||||
|
// 1 = enable
|
||||||
|
//
|
||||||
|
// <5:0> ???
|
||||||
|
//
|
||||||
|
// Enable CRC among other things we don't know yet
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // 010101100 1 100101
|
||||||
|
|
||||||
|
// REG_5D
|
||||||
|
//
|
||||||
|
// <15:8> 15 FSK data length (byte) Low 8 bits (total 11 bits for BK4819v3)
|
||||||
|
// 15 means 16 bytes in length
|
||||||
|
//
|
||||||
|
// <7:5> 0 FSK data
|
||||||
|
//
|
||||||
|
// <4:0> 0 ???
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_5D, ((packet_size - 1) << 8));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void BK4819_reset_fsk(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
BK4819_WriteRegister(BK4819_REG_3F, 0); // disable interrupts
|
||||||
uint8_t Timeout = 1000 / 5; // 1 second
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(20);
|
BK4819_WriteRegister(BK4819_REG_59, // 0x0068); // 0 0 0 0 0 0 0 0 0110 1 000
|
||||||
|
(0u << 15) | // 0 or 1 1 = clear TX FIFO
|
||||||
|
(0u << 14) | // 0 or 1 1 = clear RX FIFO
|
||||||
|
(0u << 13) | // 0 or 1 1 = scramble
|
||||||
|
(0u << 12) | // 0 or 1 1 = enable RX
|
||||||
|
(0u << 11) | // 0 or 1 1 = enable TX
|
||||||
|
(0u << 10) | // 0 or 1 1 = invert data when RX
|
||||||
|
(0u << 9) | // 0 or 1 1 = invert data when TX
|
||||||
|
(0u << 8) | // 0 or 1 ???
|
||||||
|
(6u << 4) | // 0 ~ 15 preamble Length Selection
|
||||||
|
(1u << 3) | // 0 or 1 sync length selection
|
||||||
|
(0u << 0)); // 0 ~ 7 ???
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED);
|
BK4819_Idle();
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x8068);
|
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x0068);
|
|
||||||
|
|
||||||
// load the packet
|
|
||||||
for (i = 0; i < 36; i++)
|
|
||||||
BK4819_WriteRegister(BK4819_REG_5F, pData[i]);
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(20);
|
|
||||||
|
|
||||||
// start sending
|
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x2868);
|
|
||||||
|
|
||||||
// wait till TX is done ?
|
|
||||||
while (Timeout-- && (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) == 0)
|
|
||||||
SYSTEM_DelayMs(5);
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_02, 0); // disable all interrupts
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(20);
|
|
||||||
|
|
||||||
BK4819_ResetFSK();
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
void BK4819_PrepareFSKReceive(void)
|
|
||||||
{
|
|
||||||
BK4819_ResetFSK();
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_02, 0);
|
void BK4819_start_fsk_rx(const unsigned int packet_size)
|
||||||
BK4819_WriteRegister(BK4819_REG_3F, 0);
|
{
|
||||||
|
uint16_t fsk_reg59;
|
||||||
|
|
||||||
|
BK4819_reset_fsk();
|
||||||
|
|
||||||
|
BK4819_WriteRegister(BK4819_REG_02, 0); // clear interrupt flags
|
||||||
|
|
||||||
|
// set the packet size
|
||||||
|
BK4819_WriteRegister(BK4819_REG_5D, ((packet_size - 1) << 8));
|
||||||
|
|
||||||
BK4819_RX_TurnOn();
|
BK4819_RX_TurnOn();
|
||||||
|
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL);
|
||||||
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_SYNC | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL);
|
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_SYNC | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL);
|
||||||
// BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL);
|
|
||||||
|
|
||||||
// Clear RX FIFO
|
// REG_59
|
||||||
// FSK Preamble Length 7 bytes
|
//
|
||||||
// FSK SyncLength Selection
|
// <15> 0 TX FIFO
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x4068);
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <14> 0 RX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <13> 0 FSK Scramble
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <12> 0 FSK RX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <11> 0 FSK TX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <10> 0 FSK data when RX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <9> 0 FSK data when TX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <8> 0 ???
|
||||||
|
//
|
||||||
|
// <7:4> 0 FSK preamble length selection
|
||||||
|
// 0 = 1 byte
|
||||||
|
// 1 = 2 bytes
|
||||||
|
// 2 = 3 bytes
|
||||||
|
// 15 = 16 bytes
|
||||||
|
//
|
||||||
|
// <3> 0 FSK sync length selection
|
||||||
|
// 0 = 2 bytes (FSK Sync Byte 0, 1)
|
||||||
|
// 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3)
|
||||||
|
//
|
||||||
|
// <2:0> 0 ???
|
||||||
|
//
|
||||||
|
fsk_reg59 = (0u << 15) | // 0 or 1 1 = clear TX FIFO
|
||||||
|
(0u << 14) | // 0 or 1 1 = clear RX FIFO
|
||||||
|
(0u << 13) | // 0 or 1 1 = scramble
|
||||||
|
(0u << 12) | // 0 or 1 1 = enable RX
|
||||||
|
(0u << 11) | // 0 or 1 1 = enable TX
|
||||||
|
(0u << 10) | // 0 or 1 1 = invert data when RX
|
||||||
|
(0u << 9) | // 0 or 1 1 = invert data when TX
|
||||||
|
(0u << 8) | // 0 or 1 ???
|
||||||
|
// (6u << 4) | // 0 ~ 15 preamble Length Selection
|
||||||
|
(4u << 4) | // 0 ~ 15 preamble Length Selection .. 1of11 .. a little shorter than the TX length
|
||||||
|
(1u << 3) | // 0 or 1 sync length selection
|
||||||
|
(0u << 0); // 0 ~ 7 ???
|
||||||
|
|
||||||
// Enable FSK Scramble
|
BK4819_WriteRegister(BK4819_REG_59, (1u << 14) | fsk_reg59); // clear RX fifo
|
||||||
// Enable FSK RX
|
BK4819_WriteRegister(BK4819_REG_59, (1u << 13) | (1u << 12) | fsk_reg59); // enable scrambler, enable RX
|
||||||
// FSK Preamble Length 7 bytes
|
|
||||||
// FSK SyncLength Selection
|
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x3068);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PlayRoger(void)
|
void BK4819_PlayRoger(void)
|
||||||
@ -1785,46 +1903,221 @@ void BK4819_PlayRoger(void)
|
|||||||
SYSTEM_DelayMs(80);
|
SYSTEM_DelayMs(80);
|
||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
|
BK4819_WriteRegister(BK4819_REG_70, 0);
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0
|
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PlayRogerMDC(void)
|
void BK4819_PlayRogerMDC1200(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
static const uint8_t MDC1200_DATA[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff,
|
||||||
|
// this needs properly computing for MDC1200
|
||||||
|
0xA2, 0xF1, 0x46, 0x74, 0xA4, 0x61, 0x44, 0x65, 0x8A, 0x4E, 0x44, 0xE0, 0x84, 0xEA
|
||||||
|
};
|
||||||
|
uint16_t fsk_reg59;
|
||||||
|
unsigned int timeout;
|
||||||
|
|
||||||
BK4819_SetAF(BK4819_AF_MUTE);
|
BK4819_SetAF(BK4819_AF_MUTE);
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_58, 0x37C3); // FSK Enable,
|
BK4819_WriteRegister(BK4819_REG_58, // 0x37C3); // 001 101 11 11 00 001 1
|
||||||
// RX Bandwidth FFSK 1200/1800
|
(1u << 13) | // 1 FSK TX mode selection
|
||||||
// 0xAA or 0x55 Preamble
|
// 0 = FSK 1.2K and FSK 2.4K TX .. no tones, pure data
|
||||||
// 11 RX Gain,
|
// 1 = FFSK 1200 / 1800 TX
|
||||||
// 101 RX Mode
|
// 2 = ???
|
||||||
// TX FFSK 1200/1800
|
// 3 = FFSK 1200 / 2400 TX
|
||||||
BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Set Tone-2 to 1200Hz
|
// 4 = ???
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone-2 and Set Tone2 Gain
|
// 5 = NOAA SAME TX
|
||||||
BK4819_WriteRegister(BK4819_REG_5D, 0x0D00); // Set FSK data length to 13 bytes
|
// 6 = ???
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x8068); // 4 byte sync length, 6 byte preamble, clear TX FIFO
|
// 7 = ???
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Same, but clear TX FIFO is now unset (clearing done)
|
//
|
||||||
BK4819_WriteRegister(BK4819_REG_5A, 0x5555); // First two sync bytes
|
(0u << 10) | // 0 FSK RX mode selection
|
||||||
BK4819_WriteRegister(BK4819_REG_5B, 0x55AA); // End of sync bytes. Total 4 bytes: 555555aa
|
// 0 = FSK 1.2K, FSK 2.4K RX and NOAA same RX
|
||||||
BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // Disable CRC
|
// 1 = ???
|
||||||
|
// 2 = ???
|
||||||
|
// 3 = ???
|
||||||
|
// 4 = FFSK 1200 / 2400 RX
|
||||||
|
// 5 = ???
|
||||||
|
// 6 = ???
|
||||||
|
// 7 = FFSK 1200 / 1800 RX
|
||||||
|
//
|
||||||
|
(0u << 8) | // 0 FSK RX gain
|
||||||
|
// 0 ~ 3
|
||||||
|
//
|
||||||
|
(0u << 6) | // 0 ???
|
||||||
|
// 0 ~ 3
|
||||||
|
//
|
||||||
|
(0u << 4) | // 0 FSK preamble type selection
|
||||||
|
// 0 = 0xAA or 0x55 due to the MSB of FSK sync byte 0
|
||||||
|
// 1 = ???
|
||||||
|
// 2 = 0x55
|
||||||
|
// 3 = 0xAA
|
||||||
|
//
|
||||||
|
(1u << 1) | // 1 FSK RX bandwidth setting
|
||||||
|
// 0 = FSK 1.2K
|
||||||
|
// 1 = FFSK 1200 / 1800
|
||||||
|
// 2 = NOAA same RX
|
||||||
|
// 3 = ???
|
||||||
|
// 4 = FSK 2.4K and FFSK 1200 / 2400
|
||||||
|
// 5 = ???
|
||||||
|
// 6 = ???
|
||||||
|
// 7 = ???
|
||||||
|
//
|
||||||
|
(1u << 0)); // 1 FSK enable
|
||||||
|
// 0 = disable
|
||||||
|
// 1 = enable
|
||||||
|
|
||||||
// Send the data from the roger table
|
// REG_72
|
||||||
for (i = 0; i < 7; i++)
|
//
|
||||||
BK4819_WriteRegister(BK4819_REG_5F, FSK_RogerTable[i]);
|
// <15:0> 0x2854 TONE-2 / FSK frequency control word
|
||||||
|
// = freq(Hz) * 10.32444 for XTAL 13M / 26M or
|
||||||
|
// = freq(Hz) * 10.48576 for XTAL 12.8M / 19.2M / 25.6M / 38.4M
|
||||||
|
//
|
||||||
|
// tone-2 = 1200Hz
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_72, ((1200u * 103244) + 5000) / 10000); // with rounding
|
||||||
|
|
||||||
SYSTEM_DelayMs(20);
|
// REG_70
|
||||||
|
//
|
||||||
|
// <15> 0 TONE-1
|
||||||
|
// 1 = enable
|
||||||
|
// 0 = disable
|
||||||
|
//
|
||||||
|
// <14:8> 0 TONE-1 gain
|
||||||
|
//
|
||||||
|
// <7> 0 TONE-2
|
||||||
|
// 1 = enable
|
||||||
|
// 0 = disable
|
||||||
|
//
|
||||||
|
// <6:0> 0 TONE-2 / FSK gain
|
||||||
|
// 0 ~ 127
|
||||||
|
//
|
||||||
|
// enable tone-2, set gain
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_70, // 0 0000000 1 1100000
|
||||||
|
( 0u << 15) |
|
||||||
|
( 0u << 8) |
|
||||||
|
( 1u << 7) |
|
||||||
|
(96u << 0));
|
||||||
|
|
||||||
// 4 sync bytes, 6 byte preamble, Enable FSK TX
|
// Set FSK data length
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x0868);
|
BK4819_WriteRegister(BK4819_REG_5D, ((sizeof(MDC1200_DATA) - 1) << 8));
|
||||||
|
|
||||||
SYSTEM_DelayMs(180);
|
// REG_59
|
||||||
|
//
|
||||||
|
// <15> 0 TX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <14> 0 RX FIFO
|
||||||
|
// 1 = clear
|
||||||
|
//
|
||||||
|
// <13> 0 FSK Scramble
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <12> 0 FSK RX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <11> 0 FSK TX
|
||||||
|
// 1 = Enable
|
||||||
|
//
|
||||||
|
// <10> 0 FSK data when RX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <9> 0 FSK data when TX
|
||||||
|
// 1 = Invert
|
||||||
|
//
|
||||||
|
// <8> 0 ???
|
||||||
|
//
|
||||||
|
// <7:4> 0 FSK preamble length selection
|
||||||
|
// 0 = 1 byte
|
||||||
|
// 1 = 2 bytes
|
||||||
|
// 2 = 3 bytes
|
||||||
|
// 15 = 16 bytes
|
||||||
|
//
|
||||||
|
// <3> 0 FSK sync length selection
|
||||||
|
// 0 = 2 bytes (FSK Sync Byte 0, 1)
|
||||||
|
// 1 = 4 bytes (FSK Sync Byte 0, 1, 2, 3)
|
||||||
|
//
|
||||||
|
// <2:0> 0 ???
|
||||||
|
//
|
||||||
|
fsk_reg59 = (0u << 15) | // 0 or 1 1 = clear TX FIFO
|
||||||
|
(0u << 14) | // 0 or 1 1 = clear RX FIFO
|
||||||
|
(0u << 13) | // 0 or 1 1 = scramble
|
||||||
|
(0u << 12) | // 0 or 1 1 = enable RX
|
||||||
|
(0u << 11) | // 0 or 1 1 = enable TX
|
||||||
|
(0u << 10) | // 0 or 1 1 = invert data when RX
|
||||||
|
(0u << 9) | // 0 or 1 1 = invert data when TX
|
||||||
|
(0u << 8) | // 0 or 1 ???
|
||||||
|
(0u << 4) | // 0 ~ 15 preamble length selection
|
||||||
|
(0u << 3) | // 0 or 1 sync length selection
|
||||||
|
(0u << 0); // 0 ~ 7 ???
|
||||||
|
|
||||||
// Stop FSK TX, reset Tone-2, disable FSK
|
BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | fsk_reg59); // clear TX fifo
|
||||||
BK4819_WriteRegister(BK4819_REG_59, 0x0068);
|
BK4819_WriteRegister(BK4819_REG_59, fsk_reg59);
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
|
|
||||||
BK4819_WriteRegister(BK4819_REG_58, 0x0000);
|
// REG_5A
|
||||||
|
// <15:8> 0x55 FSK Sync Byte 0 (Sync Byte 0 first, then 1,2,3)
|
||||||
|
// <7:0> 0x55 FSK Sync Byte 1
|
||||||
|
//
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_5A, 0x5555);
|
||||||
|
BK4819_WriteRegister(BK4819_REG_5A, 0xAAAA);
|
||||||
|
|
||||||
|
// REG_5B
|
||||||
|
// <15:8> 0x55 FSK Sync Byte 2 (Sync Byte 0 first, then 1,2,3)
|
||||||
|
// <7:0> 0xAA FSK Sync Byte 3
|
||||||
|
//
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_5B, 0x55AA);
|
||||||
|
|
||||||
|
// Enable CRC among other things we don't know yet
|
||||||
|
//
|
||||||
|
// REG_5C
|
||||||
|
//
|
||||||
|
// <15:7> ???
|
||||||
|
//
|
||||||
|
// <6> 1 CRC option enable
|
||||||
|
// 0 = disable
|
||||||
|
// 1 = enable
|
||||||
|
//
|
||||||
|
// <5:0> ???
|
||||||
|
//
|
||||||
|
// disable CRC
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // 101010100 0 110000
|
||||||
|
|
||||||
|
{ // load the packet data
|
||||||
|
unsigned int i;
|
||||||
|
const uint16_t *p = (const uint16_t *)MDC1200_DATA;
|
||||||
|
for (i = 0; i < (sizeof(MDC1200_DATA) / 2); i++)
|
||||||
|
BK4819_WriteRegister(BK4819_REG_5F, p[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable tx interrupt
|
||||||
|
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED);
|
||||||
|
|
||||||
|
// enable TX
|
||||||
|
BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59);
|
||||||
|
|
||||||
|
// packet is 175ms long
|
||||||
|
timeout = 250 / 5; // allow up to 250ms for the TX to complete
|
||||||
|
while (timeout-- > 0)
|
||||||
|
{
|
||||||
|
SYSTEM_DelayMs(5);
|
||||||
|
if (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0))
|
||||||
|
{ // we have interrupt flags
|
||||||
|
uint16_t interrupt_bits;
|
||||||
|
BK4819_WriteRegister(BK4819_REG_02, 0);
|
||||||
|
interrupt_bits = BK4819_ReadRegister(BK4819_REG_02);
|
||||||
|
if (interrupt_bits & BK4819_REG_02_FSK_TX_FINISHED)
|
||||||
|
timeout = 0; // TX is complete
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable TX
|
||||||
|
BK4819_WriteRegister(BK4819_REG_59, fsk_reg59);
|
||||||
|
|
||||||
|
BK4819_WriteRegister(BK4819_REG_3F, 0); // disable interrupts
|
||||||
|
BK4819_WriteRegister(BK4819_REG_70, 0);
|
||||||
|
BK4819_WriteRegister(BK4819_REG_58, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_Enable_AfDac_DiscMode_TxDsp(void)
|
void BK4819_Enable_AfDac_DiscMode_TxDsp(void)
|
||||||
|
@ -105,9 +105,9 @@ void BK4819_ExitTxMute(void);
|
|||||||
void BK4819_Sleep(void);
|
void BK4819_Sleep(void);
|
||||||
void BK4819_TurnsOffTones_TurnsOnRX(void);
|
void BK4819_TurnsOffTones_TurnsOnRX(void);
|
||||||
#ifdef ENABLE_AIRCOPY
|
#ifdef ENABLE_AIRCOPY
|
||||||
void BK4819_SetupAircopy(void);
|
void BK4819_SetupAircopy(const unsigned int packet_size);
|
||||||
#endif
|
#endif
|
||||||
void BK4819_ResetFSK(void);
|
void BK4819_reset_fsk(void);
|
||||||
void BK4819_Idle(void);
|
void BK4819_Idle(void);
|
||||||
void BK4819_ExitBypass(void);
|
void BK4819_ExitBypass(void);
|
||||||
void BK4819_PrepareTransmit(void);
|
void BK4819_PrepareTransmit(void);
|
||||||
@ -151,11 +151,10 @@ uint8_t BK4819_get_CDCSS_code_type(void);
|
|||||||
uint8_t BK4819_GetCTCShift(void);
|
uint8_t BK4819_GetCTCShift(void);
|
||||||
uint8_t BK4819_GetCTCType(void);
|
uint8_t BK4819_GetCTCType(void);
|
||||||
|
|
||||||
//void BK4819_SendFSKData(uint16_t *pData);
|
void BK4819_start_fsk_rx(const unsigned int packet_size);
|
||||||
void BK4819_PrepareFSKReceive(void);
|
|
||||||
|
|
||||||
void BK4819_PlayRoger(void);
|
void BK4819_PlayRoger(void);
|
||||||
void BK4819_PlayRogerMDC(void);
|
void BK4819_PlayRogerMDC1200(void);
|
||||||
|
|
||||||
void BK4819_Enable_AfDac_DiscMode_TxDsp(void);
|
void BK4819_Enable_AfDac_DiscMode_TxDsp(void);
|
||||||
|
|
||||||
|
22
driver/crc.c
22
driver/crc.c
@ -19,32 +19,30 @@
|
|||||||
|
|
||||||
void CRC_Init(void)
|
void CRC_Init(void)
|
||||||
{
|
{
|
||||||
CRC_CR = 0
|
CRC_CR =
|
||||||
| CRC_CR_CRC_EN_BITS_DISABLE
|
CRC_CR_CRC_EN_BITS_DISABLE
|
||||||
| CRC_CR_INPUT_REV_BITS_NORMAL
|
| CRC_CR_INPUT_REV_BITS_NORMAL
|
||||||
| CRC_CR_INPUT_INV_BITS_NORMAL
|
| CRC_CR_INPUT_INV_BITS_NORMAL
|
||||||
| CRC_CR_OUTPUT_REV_BITS_NORMAL
|
| CRC_CR_OUTPUT_REV_BITS_NORMAL
|
||||||
| CRC_CR_OUTPUT_INV_BITS_NORMAL
|
| CRC_CR_OUTPUT_INV_BITS_NORMAL
|
||||||
| CRC_CR_DATA_WIDTH_BITS_8
|
| CRC_CR_DATA_WIDTH_BITS_8
|
||||||
| CRC_CR_CRC_SEL_BITS_CRC_16_CCITT
|
| CRC_CR_CRC_SEL_BITS_CRC_16_CCITT;
|
||||||
;
|
|
||||||
CRC_IV = 0;
|
CRC_IV = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
|
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
|
||||||
{
|
{
|
||||||
const uint8_t *pData = (const uint8_t *)pBuffer;
|
const uint8_t *data = (const uint8_t *)pBuffer;
|
||||||
uint16_t i, Crc;
|
uint16_t i;
|
||||||
|
uint16_t crc;
|
||||||
|
|
||||||
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE;
|
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE;
|
||||||
|
|
||||||
for (i = 0; i < Size; i++) {
|
for (i = 0; i < Size; i++)
|
||||||
CRC_DATAIN = pData[i];
|
CRC_DATAIN = data[i];
|
||||||
}
|
crc = (uint16_t)CRC_DATAOUT;
|
||||||
Crc = (uint16_t)CRC_DATAOUT;
|
|
||||||
|
|
||||||
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE;
|
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE;
|
||||||
|
|
||||||
return Crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
firmware.bin
BIN
firmware.bin
Binary file not shown.
Binary file not shown.
@ -30,24 +30,24 @@ const freq_band_table_t BX4819_BAND2 = {84000000, 130000000};
|
|||||||
|
|
||||||
const freq_band_table_t FREQ_BAND_TABLE[7] =
|
const freq_band_table_t FREQ_BAND_TABLE[7] =
|
||||||
{
|
{
|
||||||
#ifndef ENABLE_WIDE_RX
|
#ifdef ENABLE_WIDE_RX
|
||||||
// QS original
|
|
||||||
{ 5000000, 7600000},
|
|
||||||
{10800000, 13600000},
|
|
||||||
{13600000, 17400000},
|
|
||||||
{17400000, 35000000},
|
|
||||||
{35000000, 40000000},
|
|
||||||
{40000000, 47000000},
|
|
||||||
{47000000, 60000000}
|
|
||||||
#else
|
|
||||||
// extended range
|
// extended range
|
||||||
{ 1800000, 10800000},
|
{ 1800000, 10800000}, // band 1
|
||||||
{10800000, 13600000},
|
{10800000, 13600000}, // band 2
|
||||||
{13600000, 17400000},
|
{13600000, 17400000}, // band 3
|
||||||
{17400000, 35000000},
|
{17400000, 35000000}, // band 4
|
||||||
{35000000, 40000000},
|
{35000000, 40000000}, // band 5
|
||||||
{40000000, 47000000},
|
{40000000, 47000000}, // band 6
|
||||||
{47000000, 130000000}
|
{47000000, 130000000} // band 7
|
||||||
|
#else
|
||||||
|
// QS original
|
||||||
|
{ 5000000, 7600000}, // band 1
|
||||||
|
{10800000, 13600000}, // band 2
|
||||||
|
{13600000, 17400000}, // band 3
|
||||||
|
{17400000, 35000000}, // band 4
|
||||||
|
{35000000, 40000000}, // band 5
|
||||||
|
{40000000, 47000000}, // band 6
|
||||||
|
{47000000, 60000000} // band 7
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -226,10 +226,7 @@ void FUNCTION_Select(function_type_t Function)
|
|||||||
|
|
||||||
GUI_DisplayScreen();
|
GUI_DisplayScreen();
|
||||||
|
|
||||||
RADIO_SetTxParameters();
|
RADIO_enableTX(false);
|
||||||
|
|
||||||
// turn the RED LED on
|
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true);
|
|
||||||
|
|
||||||
DTMF_Reply();
|
DTMF_Reply();
|
||||||
|
|
||||||
|
@ -89,13 +89,7 @@ void BOOT_ProcessMode(boot_mode_t Mode)
|
|||||||
|
|
||||||
g_current_vfo = g_rx_vfo;
|
g_current_vfo = g_rx_vfo;
|
||||||
|
|
||||||
RADIO_SetupRegisters(true);
|
AIRCOPY_init();
|
||||||
BK4819_SetupAircopy();
|
|
||||||
BK4819_ResetFSK();
|
|
||||||
|
|
||||||
g_aircopy_state = AIRCOPY_READY;
|
|
||||||
|
|
||||||
GUI_SelectNextDisplay(DISPLAY_AIRCOPY);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
76
radio.c
76
radio.c
@ -34,6 +34,7 @@
|
|||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
|
||||||
vfo_info_t *g_tx_vfo;
|
vfo_info_t *g_tx_vfo;
|
||||||
vfo_info_t *g_rx_vfo;
|
vfo_info_t *g_rx_vfo;
|
||||||
@ -613,21 +614,19 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
|
|||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false);
|
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, false); // LED off
|
||||||
|
|
||||||
BK4819_SetupPowerAmplifier(0, 0);
|
BK4819_SetupPowerAmplifier(0, 0);
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false); // ???
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, false);
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{ // wait for the interrupt to clear ???
|
||||||
const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C);
|
const uint16_t status_bits = BK4819_ReadRegister(BK4819_REG_0C);
|
||||||
if ((Status & 1u) == 0) // INTERRUPT REQUEST
|
if ((status_bits & (1u << 0)) == 0)
|
||||||
break;
|
break;
|
||||||
|
BK4819_WriteRegister(BK4819_REG_02, 0); // clear the interrupt bits
|
||||||
BK4819_WriteRegister(BK4819_REG_02, 0);
|
|
||||||
SYSTEM_DelayMs(1);
|
SYSTEM_DelayMs(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_3F, 0);
|
BK4819_WriteRegister(BK4819_REG_3F, 0);
|
||||||
|
|
||||||
// mic gain 0.5dB/step 0 to 31
|
// mic gain 0.5dB/step 0 to 31
|
||||||
@ -837,7 +836,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void RADIO_SetTxParameters(void)
|
void RADIO_enableTX(const bool fsk_tx)
|
||||||
{
|
{
|
||||||
BK4819_filter_bandwidth_t Bandwidth = g_current_vfo->channel_bandwidth;
|
BK4819_filter_bandwidth_t Bandwidth = g_current_vfo->channel_bandwidth;
|
||||||
|
|
||||||
@ -845,7 +844,7 @@ void RADIO_SetTxParameters(void)
|
|||||||
|
|
||||||
g_enable_speaker = false;
|
g_enable_speaker = false;
|
||||||
|
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2, false);
|
BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2, false); // ???
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
|
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
|
||||||
@ -868,39 +867,38 @@ void RADIO_SetTxParameters(void)
|
|||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
BK4819_SetFrequency(g_current_vfo->p_tx->frequency);
|
BK4819_SetFrequency(g_current_vfo->p_tx->frequency);
|
||||||
|
BK4819_SetCompander((!fsk_tx && g_rx_vfo->am_mode == 0 && (g_rx_vfo->compander == 1 || g_rx_vfo->compander >= 3)) ? g_rx_vfo->compander : 0);
|
||||||
// TX compressor
|
|
||||||
BK4819_SetCompander((g_rx_vfo->am_mode == 0 && (g_rx_vfo->compander == 1 || g_rx_vfo->compander >= 3)) ? g_rx_vfo->compander : 0);
|
|
||||||
|
|
||||||
BK4819_PrepareTransmit();
|
BK4819_PrepareTransmit();
|
||||||
|
|
||||||
SYSTEM_DelayMs(10);
|
|
||||||
|
|
||||||
BK4819_PickRXFilterPathBasedOnFrequency(g_current_vfo->p_tx->frequency);
|
BK4819_PickRXFilterPathBasedOnFrequency(g_current_vfo->p_tx->frequency);
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, true); // ???
|
||||||
|
if (g_screen_to_display != DISPLAY_AIRCOPY)
|
||||||
|
BK4819_SetupPowerAmplifier(g_current_vfo->txp_calculated_setting, g_current_vfo->p_tx->frequency);
|
||||||
|
else
|
||||||
|
BK4819_SetupPowerAmplifier(0, g_current_vfo->p_tx->frequency); // very low power when in AIRCOPY mode
|
||||||
|
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_RED, true); // turn the RED LED on
|
||||||
|
|
||||||
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1, true);
|
if (fsk_tx)
|
||||||
|
|
||||||
SYSTEM_DelayMs(5);
|
|
||||||
|
|
||||||
BK4819_SetupPowerAmplifier(g_current_vfo->txp_calculated_setting, g_current_vfo->p_tx->frequency);
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(10);
|
|
||||||
|
|
||||||
switch (g_current_vfo->p_tx->code_type)
|
|
||||||
{
|
{
|
||||||
default:
|
BK4819_ExitSubAu();
|
||||||
case CODE_TYPE_NONE:
|
}
|
||||||
BK4819_ExitSubAu();
|
else
|
||||||
break;
|
{
|
||||||
|
switch (g_current_vfo->p_tx->code_type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case CODE_TYPE_NONE:
|
||||||
|
BK4819_ExitSubAu();
|
||||||
|
break;
|
||||||
|
|
||||||
case CODE_TYPE_CONTINUOUS_TONE:
|
case CODE_TYPE_CONTINUOUS_TONE:
|
||||||
BK4819_SetCTCSSFrequency(CTCSS_OPTIONS[g_current_vfo->p_tx->code]);
|
BK4819_SetCTCSSFrequency(CTCSS_OPTIONS[g_current_vfo->p_tx->code]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CODE_TYPE_DIGITAL:
|
case CODE_TYPE_DIGITAL:
|
||||||
case CODE_TYPE_REVERSE_DIGITAL:
|
case CODE_TYPE_REVERSE_DIGITAL:
|
||||||
BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(g_current_vfo->p_tx->code_type, g_current_vfo->p_tx->code));
|
BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(g_current_vfo->p_tx->code_type, g_current_vfo->p_tx->code));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,7 +1087,7 @@ void RADIO_SendEndOfTransmission(void)
|
|||||||
BK4819_PlayRoger();
|
BK4819_PlayRoger();
|
||||||
else
|
else
|
||||||
if (g_eeprom.roger_mode == ROGER_MODE_MDC)
|
if (g_eeprom.roger_mode == ROGER_MODE_MDC)
|
||||||
BK4819_PlayRogerMDC();
|
BK4819_PlayRogerMDC1200();
|
||||||
|
|
||||||
if (g_current_vfo->dtmf_ptt_id_tx_mode == PTT_ID_APOLLO)
|
if (g_current_vfo->dtmf_ptt_id_tx_mode == PTT_ID_APOLLO)
|
||||||
BK4819_PlaySingleTone(APOLLO_TONE2_HZ, APOLLO_TONE_MS, 28, g_eeprom.dtmf_side_tone);
|
BK4819_PlaySingleTone(APOLLO_TONE2_HZ, APOLLO_TONE_MS, 28, g_eeprom.dtmf_side_tone);
|
||||||
|
2
radio.h
2
radio.h
@ -137,7 +137,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0);
|
|||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
void RADIO_ConfigureNOAA(void);
|
void RADIO_ConfigureNOAA(void);
|
||||||
#endif
|
#endif
|
||||||
void RADIO_SetTxParameters(void);
|
void RADIO_enableTX(const bool fsk_tx);
|
||||||
|
|
||||||
void RADIO_Setg_vfo_state(vfo_state_t State);
|
void RADIO_Setg_vfo_state(vfo_state_t State);
|
||||||
void RADIO_PrepareTX(void);
|
void RADIO_PrepareTX(void);
|
||||||
|
20
ui/aircopy.c
20
ui/aircopy.c
@ -24,11 +24,16 @@
|
|||||||
#include "ui/aircopy.h"
|
#include "ui/aircopy.h"
|
||||||
#include "ui/helper.h"
|
#include "ui/helper.h"
|
||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
|
||||||
void UI_DisplayAircopy(void)
|
void UI_DisplayAircopy(void)
|
||||||
{
|
{
|
||||||
|
const uint8_t errors = g_aircopy_rx_errors_fsk_crc + g_aircopy_rx_errors_magic + g_aircopy_rx_errors_crc;
|
||||||
char str[17];
|
char str[17];
|
||||||
|
|
||||||
|
if (g_screen_to_display != DISPLAY_AIRCOPY)
|
||||||
|
return;
|
||||||
|
|
||||||
// clear screen/display buffer
|
// clear screen/display buffer
|
||||||
memset(g_frame_buffer, 0, sizeof(g_frame_buffer));
|
memset(g_frame_buffer, 0, sizeof(g_frame_buffer));
|
||||||
|
|
||||||
@ -78,7 +83,7 @@ void UI_DisplayAircopy(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AIRCOPY_RX_COMPLETE:
|
case AIRCOPY_RX_COMPLETE:
|
||||||
if (g_aircopy_rx_errors == 0)
|
if (errors == 0)
|
||||||
{
|
{
|
||||||
UI_PrintString("RX COMPLETE", 0, LCD_WIDTH - 1, 5, 8);
|
UI_PrintString("RX COMPLETE", 0, LCD_WIDTH - 1, 5, 8);
|
||||||
break;
|
break;
|
||||||
@ -86,8 +91,17 @@ void UI_DisplayAircopy(void)
|
|||||||
|
|
||||||
case AIRCOPY_RX:
|
case AIRCOPY_RX:
|
||||||
sprintf(str, "RX %u.%u", g_aircopy_block_number, g_aircopy_block_max);
|
sprintf(str, "RX %u.%u", g_aircopy_block_number, g_aircopy_block_max);
|
||||||
if (g_aircopy_rx_errors > 0)
|
if (errors > 0)
|
||||||
sprintf(str + strlen(str), " E %u", g_aircopy_rx_errors);
|
{
|
||||||
|
#if 1
|
||||||
|
sprintf(str + strlen(str), " E %u", errors);
|
||||||
|
#else
|
||||||
|
sprintf(str + strlen(str), " E %u %u %u",
|
||||||
|
g_aircopy_rx_errors_fsk_crc,
|
||||||
|
g_aircopy_rx_errors_magic,
|
||||||
|
g_aircopy_rx_errors_crc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
UI_PrintString(str, 0, LCD_WIDTH - 1, 5, 7);
|
UI_PrintString(str, 0, LCD_WIDTH - 1, 5, 7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user