mirror of
https://github.com/silenty4ng/uv-k5-firmware-chinese-lts
synced 2025-01-15 14:54:40 +00:00
mdc tx end test
This commit is contained in:
parent
8d67ff068c
commit
9366901ccb
19 changed files with 1533 additions and 84 deletions
|
@ -20,8 +20,26 @@
|
|||
</configurations>
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="cea36e80-e289-4d69-9030-7186d540ac0e" name="更改" comment="修复切换调制模式时亚音消失问题">
|
||||
<list default="true" id="cea36e80-e289-4d69-9030-7186d540ac0e" name="更改" comment="按键锁定改回以前逻辑">
|
||||
<change afterPath="$PROJECT_DIR$/app/mdc1200.c" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/app/mdc1200.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/CMakeLists.txt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Makefile" beforeDir="false" afterPath="$PROJECT_DIR$/Makefile" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/app.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/app.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/spectrum.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/spectrum.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/audio.c" beforeDir="false" afterPath="$PROJECT_DIR$/audio.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/cmake-build-debug/CMakeFiles/clion-Debug-log.txt" beforeDir="false" afterPath="$PROJECT_DIR$/cmake-build-debug/CMakeFiles/clion-Debug-log.txt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/driver/bk4819.c" beforeDir="false" afterPath="$PROJECT_DIR$/driver/bk4819.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/driver/bk4819.h" beforeDir="false" afterPath="$PROJECT_DIR$/driver/bk4819.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/driver/crc.c" beforeDir="false" afterPath="$PROJECT_DIR$/driver/crc.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/driver/crc.h" beforeDir="false" afterPath="$PROJECT_DIR$/driver/crc.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/driver/systick.c" beforeDir="false" afterPath="$PROJECT_DIR$/driver/systick.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/driver/systick.h" beforeDir="false" afterPath="$PROJECT_DIR$/driver/systick.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/radio.c" beforeDir="false" afterPath="$PROJECT_DIR$/radio.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ui/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/main.c" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ui/main.h" beforeDir="false" afterPath="$PROJECT_DIR$/ui/main.h" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/版本说明.txt" beforeDir="false" afterPath="$PROJECT_DIR$/版本说明.txt" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -65,32 +83,38 @@
|
|||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.cidr.known.project.marker": "true",
|
||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"WebServerToolWindowFactoryState": "false",
|
||||
"cf.first.check.clang-format": "false",
|
||||
"cidr.known.project.marker": "true",
|
||||
"last_opened_file_path": "C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "File.Encoding",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.cidr.known.project.marker": "true",
|
||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"WebServerToolWindowFactoryState": "false",
|
||||
"cf.first.check.clang-format": "false",
|
||||
"cidr.known.project.marker": "true",
|
||||
"last_opened_file_path": "C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese/app",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "File.Encoding",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese\app" />
|
||||
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="CLionExternalRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true">
|
||||
<method v="2">
|
||||
<option name="CLION.EXTERNAL.BUILD" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="未命名" type="ShConfigurationType" nameIsGenerated="true">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="false" />
|
||||
|
@ -125,7 +149,7 @@
|
|||
<workItem from="1701325367312" duration="22657000" />
|
||||
<workItem from="1701413653518" duration="3544000" />
|
||||
<workItem from="1701430185864" duration="10115000" />
|
||||
<workItem from="1701559895523" duration="3042000" />
|
||||
<workItem from="1701559895523" duration="12283000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="bug fix">
|
||||
<created>1701136012311</created>
|
||||
|
@ -267,7 +291,14 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1701562094909</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="21" />
|
||||
<task id="LOCAL-00021" summary="按键锁定改回以前逻辑">
|
||||
<created>1701563372624</created>
|
||||
<option name="number" value="00021" />
|
||||
<option name="presentableId" value="LOCAL-00021" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1701563372624</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="22" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
|
@ -291,6 +322,7 @@
|
|||
<MESSAGE value="掃描下翻譯" />
|
||||
<MESSAGE value="fix https://github.com/losehu/uv-k5-firmware-chinese/issues/4" />
|
||||
<MESSAGE value="修复切换调制模式时亚音消失问题" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="修复切换调制模式时亚音消失问题" />
|
||||
<MESSAGE value="按键锁定改回以前逻辑" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="按键锁定改回以前逻辑" />
|
||||
</component>
|
||||
</project>
|
|
@ -816,4 +816,4 @@ add_executable(uv_k5_firmware_custom_0_17
|
|||
sram-overlay.c
|
||||
sram-overlay.h
|
||||
version.c
|
||||
version.h chinese.h)
|
||||
version.h chinese.h app/mdc1200.c app/mdc1200.c)
|
||||
|
|
18
Makefile
18
Makefile
|
@ -45,6 +45,10 @@ ENABLE_REDUCE_LOW_MID_TX_POWER:= 0
|
|||
ENABLE_BYP_RAW_DEMODULATORS := 0
|
||||
ENABLE_BLMIN_TMP_OFF := 0
|
||||
ENABLE_SCAN_RANGES := 1
|
||||
ENABLE_MDC1200 := 1
|
||||
ENABLE_MDC1200_SHOW_OP_ARG := 1
|
||||
ENABLE_MDC1200_SIDE_BEEP := 1
|
||||
|
||||
|
||||
#############################################################
|
||||
|
||||
|
@ -72,7 +76,9 @@ ifeq ($(ENABLE_OVERLAY),1)
|
|||
OBJS += sram-overlay.o
|
||||
endif
|
||||
OBJS += external/printf/printf.o
|
||||
|
||||
ifeq ($(ENABLE_MDC1200),1)
|
||||
OBJS += app/mdc1200.o
|
||||
endif
|
||||
# Drivers
|
||||
OBJS += driver/adc.o
|
||||
ifeq ($(ENABLE_UART),1)
|
||||
|
@ -233,7 +239,15 @@ else
|
|||
# We get most of the space savings if LTO creates problems
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_MDC1200),1)
|
||||
CFLAGS += -DENABLE_MDC1200
|
||||
endif
|
||||
ifeq ($(ENABLE_MDC1200_SHOW_OP_ARG),1)
|
||||
CFLAGS += -DENABLE_MDC1200_SHOW_OP_ARG
|
||||
endif
|
||||
ifeq ($(ENABLE_MDC1200_SIDE_BEEP),1)
|
||||
CFLAGS += -DENABLE_MDC1200_SIDE_BEEP
|
||||
endif
|
||||
# May cause unhelpful build failures
|
||||
#CFLAGS += -Wpadded
|
||||
|
||||
|
|
19
app/app.c
19
app/app.c
|
@ -446,6 +446,7 @@ static void HandleFunction(void)
|
|||
|
||||
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix)
|
||||
{
|
||||
(void)reset_am_fix;
|
||||
const unsigned int chan = gEeprom.RX_VFO;
|
||||
// const unsigned int chan = gRxVfo->CHANNEL_SAVE;
|
||||
|
||||
|
@ -498,31 +499,13 @@ void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix)
|
|||
gUpdateStatus = true;
|
||||
}
|
||||
|
||||
{ // RF RX front end gain
|
||||
// original QS front end register settings
|
||||
// 0x03BE 00000 011 101 11 110
|
||||
const uint8_t orig_lna_short = 3; // 0dB
|
||||
const uint8_t orig_lna = 5; // -4dB
|
||||
const uint8_t orig_mixer = 3; // 0dB
|
||||
const uint8_t orig_pga = 6; // -3dB
|
||||
|
||||
#ifdef ENABLE_AM_FIX
|
||||
BK4819_SetAGC(gRxVfo->Modulation != MODULATION_AM || !gSetting_AM_fix);
|
||||
|
||||
|
||||
if (gRxVfo->Modulation == MODULATION_AM && gSetting_AM_fix) { // AM RX mode
|
||||
if (reset_am_fix)
|
||||
AM_fix_reset(chan); // TODO: only reset it when moving channel/frequency
|
||||
AM_fix_10ms(chan);
|
||||
}
|
||||
else { // FM RX mode
|
||||
BK4819_WriteRegister(BK4819_REG_13, (orig_lna_short << 8) | (orig_lna << 5) | (orig_mixer << 3) | (orig_pga << 0));
|
||||
}
|
||||
#else
|
||||
(void)reset_am_fix;
|
||||
BK4819_WriteRegister(BK4819_REG_13, (orig_lna_short << 8) | (orig_lna << 5) | (orig_mixer << 3) | (orig_pga << 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
// AF gain - original QS values
|
||||
// if (gRxVfo->Modulation != MODULATION_FM){
|
||||
|
|
562
app/mdc1200.c
Normal file
562
app/mdc1200.c
Normal file
|
@ -0,0 +1,562 @@
|
|||
|
||||
#include "driver/bk4819.h"
|
||||
#include "driver/crc.h"
|
||||
|
||||
#include "mdc1200.h"
|
||||
#include "misc.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
const uint8_t mdc1200_pre_amble[] = {0x00, 0x00, 0x00};
|
||||
const uint8_t mdc1200_sync[5] = {0x07, 0x09, 0x2a, 0x44, 0x6f};
|
||||
|
||||
uint8_t mdc1200_sync_suc_xor[sizeof(mdc1200_sync)];
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
uint16_t compute_crc(const void *data, const unsigned int data_len)
|
||||
{ // let the CPU's hardware do some work :)
|
||||
uint16_t crc;
|
||||
CRC_InitReverse();
|
||||
crc = CRC_Calculate(data, data_len);
|
||||
CRC_Init();
|
||||
return crc;
|
||||
}
|
||||
|
||||
#elif 1
|
||||
|
||||
uint16_t compute_crc(const void *data, const unsigned int data_len)
|
||||
{ // using the reverse computation and polynominal avoids having to reverse the bit order during and after
|
||||
unsigned int i;
|
||||
const uint8_t *data8 = (const uint8_t *)data;
|
||||
uint16_t crc = 0;
|
||||
for (i = 0; i < data_len; i++)
|
||||
{
|
||||
unsigned int k;
|
||||
crc ^= data8[i];
|
||||
for (k = 8; k > 0; k--)
|
||||
crc = (crc & 1u) ? (crc >> 1) ^ 0x8408 : crc >> 1;
|
||||
}
|
||||
return crc ^ 0xffff;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
uint16_t compute_crc(const void *data, const unsigned int data_len)
|
||||
{
|
||||
unsigned int i;
|
||||
const uint8_t *data8 = (const uint8_t *)data;
|
||||
uint16_t crc = 0;
|
||||
|
||||
for (i = 0; i < data_len; i++)
|
||||
{
|
||||
uint8_t mask;
|
||||
|
||||
// bit reverse each data byte
|
||||
const uint8_t bits = bit_reverse_8(*data8++);
|
||||
|
||||
for (mask = 0x0080; mask != 0; mask >>= 1)
|
||||
{
|
||||
uint16_t msb = crc & 0x8000;
|
||||
if (bits & mask)
|
||||
msb ^= 0x8000;
|
||||
crc <<= 1;
|
||||
if (msb)
|
||||
crc ^= 0x1021;
|
||||
}
|
||||
}
|
||||
|
||||
// bit reverse and invert the final CRC
|
||||
return bit_reverse_16(crc) ^ 0xffff;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void error_correction(void *data)
|
||||
{ // can correct up to 3 or 4 corrupted bits (I think)
|
||||
|
||||
int i;
|
||||
uint8_t shift_reg;
|
||||
uint8_t syn;
|
||||
uint8_t *data8 = (uint8_t *)data;
|
||||
|
||||
for (i = 0, shift_reg = 0, syn = 0; i < MDC1200_FEC_K; i++)
|
||||
{
|
||||
const uint8_t bi = data8[i];
|
||||
int bit_num;
|
||||
for (bit_num = 0; bit_num < 8; bit_num++)
|
||||
{
|
||||
uint8_t b;
|
||||
unsigned int k = 0;
|
||||
|
||||
shift_reg = (shift_reg << 1) | ((bi >> bit_num) & 1u);
|
||||
b = ((shift_reg >> 6) ^ (shift_reg >> 5) ^ (shift_reg >> 2) ^ (shift_reg >> 0)) & 1u;
|
||||
syn = (syn << 1) | (((b ^ (data8[i + MDC1200_FEC_K] >> bit_num)) & 1u) ? 1u : 0u);
|
||||
|
||||
if (syn & 0x80) k++;
|
||||
if (syn & 0x20) k++;
|
||||
if (syn & 0x04) k++;
|
||||
if (syn & 0x02) k++;
|
||||
|
||||
if (k >= 3)
|
||||
{ // correct a bit error
|
||||
int ii = i;
|
||||
int bn = bit_num - 7;
|
||||
if (bn < 0)
|
||||
{
|
||||
bn += 8;
|
||||
ii--;
|
||||
}
|
||||
if (ii >= 0)
|
||||
data8[ii] ^= 1u << bn; // fix a bit
|
||||
syn ^= 0xA6; // 10100110
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool decode_data(void *data)
|
||||
{
|
||||
uint16_t crc1;
|
||||
uint16_t crc2;
|
||||
uint8_t *data8 = (uint8_t *)data;
|
||||
|
||||
{ // de-interleave
|
||||
|
||||
unsigned int i;
|
||||
unsigned int k;
|
||||
unsigned int m;
|
||||
uint8_t deinterleaved[(MDC1200_FEC_K * 2) * 8]; // temp individual bit storage
|
||||
|
||||
// interleave order
|
||||
// 0, 16, 32, 48, 64, 80, 96,
|
||||
// 1, 17, 33, 49, 65, 81, 97,
|
||||
// 2, 18, 34, 50, 66, 82, 98,
|
||||
// 3, 19, 35, 51, 67, 83, 99,
|
||||
// 4, 20, 36, 52, 68, 84, 100,
|
||||
// 5, 21, 37, 53, 69, 85, 101,
|
||||
// 6, 22, 38, 54, 70, 86, 102,
|
||||
// 7, 23, 39, 55, 71, 87, 103,
|
||||
// 8, 24, 40, 56, 72, 88, 104,
|
||||
// 9, 25, 41, 57, 73, 89, 105,
|
||||
// 10, 26, 42, 58, 74, 90, 106,
|
||||
// 11, 27, 43, 59, 75, 91, 107,
|
||||
// 12, 28, 44, 60, 76, 92, 108,
|
||||
// 13, 29, 45, 61, 77, 93, 109,
|
||||
// 14, 30, 46, 62, 78, 94, 110,
|
||||
// 15, 31, 47, 63, 79, 95, 111
|
||||
|
||||
// de-interleave the received bits
|
||||
for (i = 0, k = 0; i < 16; i++)
|
||||
{
|
||||
for (m = 0; m < MDC1200_FEC_K; m++)
|
||||
{
|
||||
const unsigned int n = (m * 16) + i;
|
||||
deinterleaved[k++] = (data8[n >> 3] >> ((7 - n) & 7u)) & 1u;
|
||||
}
|
||||
}
|
||||
|
||||
// copy the de-interleaved bits back into the data buffer
|
||||
for (i = 0, m = 0; i < (MDC1200_FEC_K * 2); i++)
|
||||
{
|
||||
unsigned int k;
|
||||
uint8_t b = 0;
|
||||
for (k = 0; k < 8; k++)
|
||||
if (deinterleaved[m++])
|
||||
b |= 1u << k;
|
||||
data8[i] = b;
|
||||
}
|
||||
}
|
||||
|
||||
// try to correct the odd corrupted bit
|
||||
error_correction(data);
|
||||
|
||||
// rx'ed de-interleaved data (min 14 bytes) looks like this ..
|
||||
//
|
||||
// OP ARG ID CRC STATUS FEC bits
|
||||
// 01 80 1234 2E3E 00 6580A862DD8808
|
||||
|
||||
crc1 = compute_crc(data, 4);
|
||||
crc2 = ((uint16_t)data8[5] << 8) | (data8[4] << 0);
|
||||
|
||||
return (crc1 == crc2) ? true : false;
|
||||
}
|
||||
|
||||
// **********************************************************
|
||||
// TX
|
||||
|
||||
void xor_modulation(void *data, const unsigned int size)
|
||||
{ // exclusive-or succesive bits - the entire packet
|
||||
unsigned int i;
|
||||
uint8_t *data8 = (uint8_t *)data;
|
||||
uint8_t prev_bit = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int bit_num;
|
||||
uint8_t in = data8[i];
|
||||
uint8_t out = 0;
|
||||
for (bit_num = 7; bit_num >= 0; bit_num--)
|
||||
{
|
||||
const uint8_t new_bit = (in >> bit_num) & 1u;
|
||||
if (new_bit != prev_bit)
|
||||
out |= 1u << bit_num; // previous bit and new bit are different - send a '1'
|
||||
prev_bit = new_bit;
|
||||
}
|
||||
data8[i] = out ^ 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t * encode_data(void *data)
|
||||
{
|
||||
// R=1/2 K=7 convolutional coder
|
||||
//
|
||||
// OP ARG ID CRC STATUS FEC bits
|
||||
// 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 shown above
|
||||
|
||||
uint8_t *data8 = (uint8_t *)data;
|
||||
|
||||
{ // add the FEC bits to the end of the data
|
||||
unsigned int i;
|
||||
uint8_t shift_reg = 0;
|
||||
for (i = 0; i < MDC1200_FEC_K; i++)
|
||||
{
|
||||
unsigned int bit_num;
|
||||
const uint8_t bi = data8[i];
|
||||
uint8_t bo = 0;
|
||||
for (bit_num = 0; bit_num < 8; bit_num++)
|
||||
{
|
||||
shift_reg = (shift_reg << 1) | ((bi >> bit_num) & 1u);
|
||||
bo |= (((shift_reg >> 6) ^ (shift_reg >> 5) ^ (shift_reg >> 2) ^ (shift_reg >> 0)) & 1u) << bit_num;
|
||||
}
|
||||
data8[MDC1200_FEC_K + i] = bo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{ // interleave the bits
|
||||
|
||||
unsigned int i;
|
||||
unsigned int k;
|
||||
uint8_t interleaved[(MDC1200_FEC_K * 2) * 8]; // temp individual bit storage
|
||||
|
||||
// interleave order
|
||||
// 0, 16, 32, 48, 64, 80, 96,
|
||||
// 1, 17, 33, 49, 65, 81, 97,
|
||||
// 2, 18, 34, 50, 66, 82, 98,
|
||||
// 3, 19, 35, 51, 67, 83, 99,
|
||||
// 4, 20, 36, 52, 68, 84, 100,
|
||||
// 5, 21, 37, 53, 69, 85, 101,
|
||||
// 6, 22, 38, 54, 70, 86, 102,
|
||||
// 7, 23, 39, 55, 71, 87, 103,
|
||||
// 8, 24, 40, 56, 72, 88, 104,
|
||||
// 9, 25, 41, 57, 73, 89, 105,
|
||||
// 10, 26, 42, 58, 74, 90, 106,
|
||||
// 11, 27, 43, 59, 75, 91, 107,
|
||||
// 12, 28, 44, 60, 76, 92, 108,
|
||||
// 13, 29, 45, 61, 77, 93, 109,
|
||||
// 14, 30, 46, 62, 78, 94, 110,
|
||||
// 15, 31, 47, 63, 79, 95, 111
|
||||
|
||||
// bit interleaver
|
||||
for (i = 0, k = 0; i < (MDC1200_FEC_K * 2); i++)
|
||||
{
|
||||
unsigned int bit_num;
|
||||
const uint8_t b = data8[i];
|
||||
for (bit_num = 0; bit_num < 8; bit_num++)
|
||||
{
|
||||
interleaved[k] = (b >> bit_num) & 1u;
|
||||
k += 16;
|
||||
if (k >= sizeof(interleaved))
|
||||
k -= sizeof(interleaved) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// copy the interleaved bits back to the data buffer
|
||||
for (i = 0, k = 0; i < (MDC1200_FEC_K * 2); i++)
|
||||
{
|
||||
int bit_num;
|
||||
uint8_t b = 0;
|
||||
for (bit_num = 7; bit_num >= 0; bit_num--)
|
||||
if (interleaved[k++])
|
||||
b |= 1u << bit_num;
|
||||
data8[i] = b;
|
||||
}
|
||||
}
|
||||
|
||||
return data8 + (MDC1200_FEC_K * 2);
|
||||
}
|
||||
|
||||
unsigned int MDC1200_encode_single_packet(void *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id)
|
||||
{
|
||||
unsigned int size;
|
||||
uint16_t crc;
|
||||
uint8_t *p = (uint8_t *)data;
|
||||
|
||||
memcpy(p, mdc1200_pre_amble, sizeof(mdc1200_pre_amble));
|
||||
p += sizeof(mdc1200_pre_amble);
|
||||
memcpy(p, mdc1200_sync, sizeof(mdc1200_sync));
|
||||
p += sizeof(mdc1200_sync);
|
||||
|
||||
p[0] = op;
|
||||
p[1] = arg;
|
||||
p[2] = (unit_id >> 8) & 0x00ff;
|
||||
p[3] = (unit_id >> 0) & 0x00ff;
|
||||
crc = compute_crc(p, 4);
|
||||
p[4] = (crc >> 0) & 0x00ff;
|
||||
p[5] = (crc >> 8) & 0x00ff;
|
||||
p[6] = 0; // unknown field (00 for PTTIDs, 76 for STS and MSG)
|
||||
|
||||
p = encode_data(p);
|
||||
|
||||
size = (unsigned int)(p - (uint8_t *)data);
|
||||
|
||||
xor_modulation(data, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
struct {
|
||||
uint8_t bit;
|
||||
uint8_t prev_bit;
|
||||
uint8_t xor_bit;
|
||||
uint64_t shift_reg;
|
||||
unsigned int bit_count;
|
||||
unsigned int stage;
|
||||
bool inverted_sync;
|
||||
unsigned int data_index;
|
||||
uint8_t data[40];
|
||||
} rx;
|
||||
|
||||
void MDC1200_reset_rx(void)
|
||||
{
|
||||
memset(&rx, 0, sizeof(rx));
|
||||
}
|
||||
|
||||
bool MDC1200_process_rx_data(
|
||||
const void *buffer,
|
||||
const unsigned int size,
|
||||
//const bool inverted,
|
||||
uint8_t *op,
|
||||
uint8_t *arg,
|
||||
uint16_t *unit_id)
|
||||
{
|
||||
const uint8_t *buffer8 = (const uint8_t *)buffer;
|
||||
unsigned int index;
|
||||
|
||||
// 04 8D BF 66 58 sync
|
||||
// FB 72 40 99 A7 inverted sync
|
||||
//
|
||||
// 04 8D BF 66 58 40 C4 B0 32 BA F9 33 18 35 08 83 F6 0C 36 .. 80 87 20 23 2C AE 22 10 26 0F 02 A4 08 24
|
||||
// 04 8D BF 66 58 45 DB 03 07 BC FA 35 2E 33 0E 83 0E 83 69 .. 86 92 02 05 28 AC 26 34 22 0B 02 0B 02 4E
|
||||
|
||||
memset(&rx, 0, sizeof(rx));
|
||||
|
||||
for (index = 0; index < size; index++)
|
||||
{
|
||||
int bit;
|
||||
const uint8_t rx_byte = buffer8[index];
|
||||
|
||||
for (bit = 7; bit >= 0; bit--)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
rx.prev_bit = rx.bit;
|
||||
|
||||
rx.bit = (rx_byte >> bit) & 1u;
|
||||
|
||||
rx.xor_bit = (rx.xor_bit ^ rx.bit) & 1u; // toggle our bit if the rx bit is high
|
||||
|
||||
rx.shift_reg = (rx.shift_reg << 1) | rx.xor_bit;
|
||||
rx.bit_count++;
|
||||
|
||||
// *********
|
||||
|
||||
if (rx.stage == 0)
|
||||
{ // looking for the 40-bit sync pattern
|
||||
|
||||
const unsigned int sync_bit_ok_threshold = 32;
|
||||
|
||||
if (rx.bit_count >= 40)
|
||||
{
|
||||
// 40-bit sync pattern
|
||||
uint64_t sync_nor = 0x07092a446fu; // normal
|
||||
uint64_t sync_inv = 0xffffffffffu ^ sync_nor; // bit inverted
|
||||
|
||||
sync_nor ^= rx.shift_reg;
|
||||
sync_inv ^= rx.shift_reg;
|
||||
|
||||
unsigned int nor_count = 0;
|
||||
unsigned int inv_count = 0;
|
||||
for (i = 40; i > 0; i--, sync_nor >>= 1, sync_inv >>= 1)
|
||||
{
|
||||
nor_count += sync_nor & 1u;
|
||||
inv_count += sync_inv & 1u;
|
||||
}
|
||||
nor_count = 40 - nor_count;
|
||||
inv_count = 40 - inv_count;
|
||||
|
||||
|
||||
|
||||
if (nor_count >= sync_bit_ok_threshold || inv_count >= sync_bit_ok_threshold)
|
||||
{ // good enough
|
||||
|
||||
rx.inverted_sync = (inv_count > nor_count) ? true : false;
|
||||
rx.data_index = 0;
|
||||
rx.bit_count = 0;
|
||||
rx.stage = 1;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rx.bit_count < 8)
|
||||
continue;
|
||||
|
||||
rx.bit_count = 0;
|
||||
|
||||
rx.data[rx.data_index++] = rx.shift_reg & 0xff; // save the last 8 bits
|
||||
|
||||
if (rx.data_index < (MDC1200_FEC_K * 2))
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
if (!decode_data(rx.data))
|
||||
{
|
||||
MDC1200_reset_rx();
|
||||
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// extract the info from the packet
|
||||
*op = rx.data[0];
|
||||
*arg = rx.data[1];
|
||||
*unit_id = ((uint16_t)rx.data[2] << 8) | (rx.data[3] << 0);
|
||||
|
||||
|
||||
// reset the detector
|
||||
MDC1200_reset_rx();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
MDC1200_reset_rx();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t mdc1200_rx_buffer[sizeof(mdc1200_sync_suc_xor) + (MDC1200_FEC_K * 2)];
|
||||
unsigned int mdc1200_rx_buffer_index = 0;
|
||||
|
||||
uint8_t mdc1200_op;
|
||||
uint8_t mdc1200_arg;
|
||||
uint16_t mdc1200_unit_id;
|
||||
uint8_t mdc1200_rx_ready_tick_500ms;
|
||||
|
||||
void MDC1200_process_rx(const uint16_t interrupt_bits)
|
||||
{
|
||||
const uint16_t rx_sync_flags = BK4819_ReadRegister(0x0B);
|
||||
const uint16_t fsk_reg59 = BK4819_ReadRegister(0x59) & ~((1u << 15) | (1u << 14) | (1u << 12) | (1u << 11));
|
||||
|
||||
const bool rx_sync = (interrupt_bits & BK4819_REG_02_FSK_RX_SYNC) ? true : false;
|
||||
const bool rx_sync_neg = (rx_sync_flags & (1u << 7)) ? true : false;
|
||||
const bool rx_fifo_almost_full = (interrupt_bits & BK4819_REG_02_FSK_FIFO_ALMOST_FULL) ? true : false;
|
||||
const bool rx_finished = (interrupt_bits & BK4819_REG_02_FSK_RX_FINISHED) ? true : false;
|
||||
|
||||
|
||||
if (rx_sync)
|
||||
{
|
||||
|
||||
mdc1200_rx_buffer_index = 0;
|
||||
|
||||
{
|
||||
unsigned int i;
|
||||
memset(mdc1200_rx_buffer, 0, sizeof(mdc1200_rx_buffer));
|
||||
for (i = 0; i < sizeof(mdc1200_sync_suc_xor); i++)
|
||||
mdc1200_rx_buffer[mdc1200_rx_buffer_index++] = mdc1200_sync_suc_xor[i] ^ (rx_sync_neg ? 0xFF : 0x00);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (rx_fifo_almost_full)
|
||||
{
|
||||
unsigned int i;
|
||||
const unsigned int count = BK4819_ReadRegister(0x5E) & (7u << 0); // almost full threshold
|
||||
|
||||
|
||||
// fetch received packet data
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
const uint16_t word = BK4819_ReadRegister(0x5F) ^ (rx_sync_neg ? 0xFFFF : 0x0000);
|
||||
|
||||
|
||||
|
||||
if (mdc1200_rx_buffer_index < sizeof(mdc1200_rx_buffer))
|
||||
mdc1200_rx_buffer[mdc1200_rx_buffer_index++] = (word >> 0) & 0xff;
|
||||
|
||||
if (mdc1200_rx_buffer_index < sizeof(mdc1200_rx_buffer))
|
||||
mdc1200_rx_buffer[mdc1200_rx_buffer_index++] = (word >> 8) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
if (mdc1200_rx_buffer_index >= sizeof(mdc1200_rx_buffer))
|
||||
{
|
||||
BK4819_WriteRegister(0x59, (1u << 15) | (1u << 14) | fsk_reg59);
|
||||
BK4819_WriteRegister(0x59, (1u << 12) | fsk_reg59);
|
||||
|
||||
|
||||
if (MDC1200_process_rx_data(
|
||||
mdc1200_rx_buffer,
|
||||
mdc1200_rx_buffer_index,
|
||||
&mdc1200_op,
|
||||
&mdc1200_arg,
|
||||
&mdc1200_unit_id)) {
|
||||
mdc1200_rx_ready_tick_500ms = 2 * 6; // 6 second MDC display time
|
||||
|
||||
gUpdateDisplay = true;
|
||||
|
||||
}
|
||||
|
||||
mdc1200_rx_buffer_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rx_finished)
|
||||
{
|
||||
mdc1200_rx_buffer_index = 0;
|
||||
|
||||
|
||||
BK4819_WriteRegister(0x59, (1u << 15) | (1u << 14) | fsk_reg59);
|
||||
BK4819_WriteRegister(0x59, (1u << 12) | fsk_reg59);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MDC1200_init(void)
|
||||
{
|
||||
memcpy(mdc1200_sync_suc_xor, mdc1200_sync, sizeof(mdc1200_sync));
|
||||
xor_modulation(mdc1200_sync_suc_xor, sizeof(mdc1200_sync_suc_xor));
|
||||
|
||||
MDC1200_reset_rx();
|
||||
}
|
106
app/mdc1200.h
Normal file
106
app/mdc1200.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
|
||||
#ifndef MDC1200H
|
||||
#define MDC1200H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MDC1200_FEC_K 7 // R=1/2 K=7 convolutional coder
|
||||
|
||||
// 0x00 (0x81) emergency alarm
|
||||
// 0x20 (0x00) emergency alarm ack
|
||||
//
|
||||
// 0x01 (0x80) is PTT ID
|
||||
// 0x01 (0x00) is POST ID
|
||||
// 0x11 (0x8A) is REMOTE MONITOR
|
||||
// 0x22 (0x06) is STATUS REQ
|
||||
// 0x2B (0x0C) is RADIO ENABLE
|
||||
// 0x2B (0x00) is RADIO DISABLE
|
||||
// 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,
|
||||
MDC1200_OP_CODE_POST_ID = 0x01,
|
||||
MDC1200_OP_CODE_REMOTE_MONITOR = 0x11,
|
||||
MDC1200_OP_CODE_STATUS_REQ = 0x22,
|
||||
MDC1200_OP_CODE_RADIO_ENABLE = 0x2B,
|
||||
MDC1200_OP_CODE_RADIO_DISABLE = 0x2B,
|
||||
MDC1200_OP_CODE_CALL_ALERT = 0x35,
|
||||
MDC1200_OP_CODE_STS_XX = 0x46,
|
||||
MDC1200_OP_CODE_MSG_XX = 0x47,
|
||||
MDC1200_OP_CODE_RADIO_CHECK = 0x63
|
||||
};
|
||||
typedef enum mdc1200_op_code_e mdc1200_op_code_t;
|
||||
|
||||
extern const uint8_t mdc1200_sync[5];
|
||||
extern uint8_t mdc1200_sync_suc_xor[sizeof(mdc1200_sync)];
|
||||
|
||||
extern uint8_t mdc1200_op;
|
||||
extern uint8_t mdc1200_arg;
|
||||
extern uint16_t mdc1200_unit_id;
|
||||
extern uint8_t mdc1200_rx_ready_tick_500ms;
|
||||
|
||||
unsigned int MDC1200_encode_single_packet(void *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id);
|
||||
//unsigned int MDC1200_encode_double_packet(void *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id, const uint8_t b0, const uint8_t b1, const uint8_t b2, const uint8_t b3);
|
||||
void MDC1200_reset_rx(void);
|
||||
void MDC1200_process_rx(const uint16_t interrupt_bits);
|
||||
void MDC1200_init(void);
|
||||
|
||||
#endif
|
|
@ -18,6 +18,8 @@
|
|||
#include "driver/backlight.h"
|
||||
#include "audio.h"
|
||||
#include "ui/helper.h"
|
||||
#include "am_fix.h"
|
||||
#include "ui/main.h"
|
||||
|
||||
struct FrequencyBandInfo {
|
||||
uint32_t lower;
|
||||
|
@ -30,6 +32,7 @@ struct FrequencyBandInfo {
|
|||
|
||||
const uint16_t RSSI_MAX_VALUE = 65535;
|
||||
|
||||
|
||||
static uint16_t R30, R37, R3D, R43, R47, R48, R7E;
|
||||
static uint32_t initialFreq;
|
||||
static char String[32];
|
||||
|
@ -68,7 +71,7 @@ SpectrumSettings settings = {stepsCount: STEPS_64,
|
|||
uint32_t fMeasure = 0;
|
||||
uint32_t currentFreq, tempFreq;
|
||||
uint16_t rssiHistory[128];
|
||||
|
||||
int vfo;
|
||||
uint8_t freqInputIndex = 0;
|
||||
uint8_t freqInputDotIndex = 0;
|
||||
KEY_Code_t freqInputArr[10];
|
||||
|
@ -99,7 +102,10 @@ static uint8_t DBm2S(int dbm) {
|
|||
return i;
|
||||
}
|
||||
|
||||
static int Rssi2DBm(uint16_t rssi) { return (rssi >> 1) - 160; }
|
||||
static int Rssi2DBm(uint16_t rssi)
|
||||
{
|
||||
return (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band];
|
||||
}
|
||||
|
||||
static uint16_t GetRegMenuValue(uint8_t st) {
|
||||
RegisterSpec s = registerSpecs[st];
|
||||
|
@ -276,7 +282,15 @@ uint16_t GetRssi() {
|
|||
while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255) {
|
||||
SYSTICK_DelayUs(100);
|
||||
}
|
||||
return BK4819_GetRSSI();
|
||||
if(settings.modulationType == MODULATION_AM)
|
||||
{
|
||||
return BK4819_GetRSSI() - rssi_gain_diff[vfo]; //return the corrected RSSI to allow for AM_Fixs AGC action.
|
||||
}
|
||||
else
|
||||
{
|
||||
return BK4819_GetRSSI();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ToggleAudio(bool on) {
|
||||
|
@ -383,7 +397,7 @@ static void Measure() { rssiHistory[scanInfo.i] = scanInfo.rssi = GetRssi(); }
|
|||
|
||||
static uint16_t dbm2rssi(int dBm)
|
||||
{
|
||||
return (dBm + 160)*2;
|
||||
return (dBm + 160 - dBmCorrTable[gRxVfo->Band])*2;
|
||||
}
|
||||
|
||||
static void ClampRssiTriggerLevel()
|
||||
|
@ -475,6 +489,7 @@ static void ToggleModulation() {
|
|||
settings.modulationType = MODULATION_FM;
|
||||
}
|
||||
RADIO_SetModulation(settings.modulationType);
|
||||
RelaunchScan();
|
||||
redrawScreen = true;
|
||||
}
|
||||
|
||||
|
@ -588,7 +603,7 @@ uint8_t Rssi2PX(uint16_t rssi, uint8_t pxMin, uint8_t pxMax) {
|
|||
|
||||
const uint8_t PX_RANGE = pxMax - pxMin;
|
||||
|
||||
int dbm = clamp(rssi - (160 << 1), DB_MIN, DB_MAX);
|
||||
int dbm = clamp(Rssi2DBm(rssi) << 1, DB_MIN, DB_MAX);
|
||||
|
||||
return ((dbm - DB_MIN) * PX_RANGE + DB_RANGE / 2) / DB_RANGE + pxMin;
|
||||
}
|
||||
|
@ -1104,6 +1119,11 @@ static void UpdateListening() {
|
|||
}
|
||||
|
||||
static void Tick() {
|
||||
|
||||
if(settings.modulationType == MODULATION_AM)
|
||||
{
|
||||
AM_fix_10ms(vfo); //allow AM_Fix to apply its AGC action
|
||||
}
|
||||
if (!preventKeypress) {
|
||||
HandleUserInput();
|
||||
}
|
||||
|
@ -1133,8 +1153,9 @@ static void Tick() {
|
|||
|
||||
void APP_RunSpectrum() {
|
||||
// TX here coz it always? set to active VFO
|
||||
currentFreq = initialFreq =
|
||||
gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency;
|
||||
vfo = gEeprom.TX_VFO;
|
||||
//set the current frequency in the middle of the display
|
||||
currentFreq = initialFreq = gEeprom.VfoInfo[vfo].pRX->Frequency - ((GetStepsCount()/2) * GetScanStep());
|
||||
|
||||
BackupRegisters();
|
||||
|
||||
|
@ -1144,7 +1165,7 @@ void APP_RunSpectrum() {
|
|||
newScanStart = true;
|
||||
|
||||
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
|
||||
RADIO_SetModulation(settings.modulationType = MODULATION_FM);
|
||||
RADIO_SetModulation(settings.modulationType = gRxVfo->Modulation);
|
||||
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);
|
||||
|
||||
RelaunchScan();
|
||||
|
|
4
audio.c
4
audio.c
|
@ -192,7 +192,9 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
|||
#endif
|
||||
|
||||
SYSTEM_DelayMs(5);
|
||||
BK4819_TurnsOffTones_TurnsOnRX();
|
||||
//stop tone
|
||||
//BK4819_TurnsOffTones_TurnsOnRX();
|
||||
BK4819_stop_tones(false);
|
||||
SYSTEM_DelayMs(5);
|
||||
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
|
||||
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
"C:\Program Files\JetBrains\CLion 2023.1.1\bin\cmake\win\x64\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=C:/Qt/Qt5.13.1/Tools/mingw730_64/bin/mingw32-make.exe -DCMAKE_C_COMPILER=C:/Qt/Qt5.13.1/Tools/mingw730_64/bin/gcc.exe -DCMAKE_CXX_COMPILER=C:/Qt/Qt5.13.1/Tools/mingw730_64/bin/g++.exe -G "CodeBlocks - MinGW Makefiles" -S C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese -B C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese\cmake-build-debug
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese/cmake-build-debug
|
||||
CMake Error at CMakeLists.txt:122 (add_executable):
|
||||
Cannot find source file:
|
||||
|
||||
external/CMSIS_5/CMSIS/DAP/Firmware/Config/DAP_config.h
|
||||
|
||||
|
||||
CMake Error at CMakeLists.txt:122 (add_executable):
|
||||
No SOURCES given to target: uv_k5_firmware_custom_0_17
|
||||
|
||||
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
|
|
647
driver/bk4819.c
647
driver/bk4819.c
|
@ -23,10 +23,13 @@
|
|||
#include "driver/gpio.h"
|
||||
#include "driver/system.h"
|
||||
#include "driver/systick.h"
|
||||
|
||||
#ifdef ENABLE_MDC1200
|
||||
#include "app/mdc1200.h"
|
||||
#endif
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
BK4819_FilterBandwidth_t m_bandwidth = BK4819_FILTER_BW_NARROW;
|
||||
|
||||
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
|
||||
|
||||
|
@ -164,6 +167,7 @@ uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register)
|
|||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
|
||||
|
||||
return Value;
|
||||
|
||||
}
|
||||
|
||||
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data)
|
||||
|
@ -562,6 +566,7 @@ void BK4819_SetFilterBandwidth(const BK4819_FilterBandwidth_t Bandwidth, const b
|
|||
// <1:0> 0 ???
|
||||
|
||||
uint16_t val;
|
||||
m_bandwidth = Bandwidth;
|
||||
|
||||
switch (Bandwidth)
|
||||
{
|
||||
|
@ -1772,4 +1777,642 @@ void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code)
|
|||
BK4819_PlayDTMF(Code);
|
||||
|
||||
BK4819_ExitTxMute();
|
||||
}
|
||||
}
|
||||
//ENABLE_MDC1200
|
||||
#define h
|
||||
#ifdef h
|
||||
void BK4819_start_tone(const uint16_t frequency, const unsigned int level, const bool tx, const bool tx_mute)
|
||||
{
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
GPIO_ClearBit(&GPIOC->DATA, 4);
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
// mute TX
|
||||
BK4819_WriteRegister(0x50, (1u << 15) | 0x3B20);
|
||||
|
||||
BK4819_WriteRegister(0x70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
|
||||
BK4819_WriteRegister(0x30, 0);
|
||||
|
||||
if (!tx)
|
||||
{
|
||||
BK4819_WriteRegister(0x30,
|
||||
// BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||
// BK4819_REG_30_ENABLE_UNKNOWN |
|
||||
// BK4819_REG_30_ENABLE_RX_LINK |
|
||||
BK4819_REG_30_ENABLE_AF_DAC |
|
||||
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||
// BK4819_REG_30_ENABLE_PLL_VCO |
|
||||
// BK4819_REG_30_ENABLE_PA_GAIN |
|
||||
// BK4819_REG_30_ENABLE_MIC_ADC |
|
||||
BK4819_REG_30_ENABLE_TX_DSP |
|
||||
// BK4819_REG_30_ENABLE_RX_DSP |
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BK4819_WriteRegister(0x30,
|
||||
BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||
BK4819_REG_30_ENABLE_UNKNOWN |
|
||||
// BK4819_REG_30_ENABLE_RX_LINK |
|
||||
BK4819_REG_30_ENABLE_AF_DAC |
|
||||
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||
BK4819_REG_30_ENABLE_PLL_VCO |
|
||||
BK4819_REG_30_ENABLE_PA_GAIN |
|
||||
// BK4819_REG_30_ENABLE_MIC_ADC |
|
||||
BK4819_REG_30_ENABLE_TX_DSP |
|
||||
// BK4819_REG_30_ENABLE_RX_DSP |
|
||||
0);
|
||||
}
|
||||
|
||||
BK4819_WriteRegister(0x71, scale_freq(frequency));
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
// BK4819_SetAF(tx ? BK4819_AF_BEEP : 2);
|
||||
BK4819_SetAF(2); // RX
|
||||
// BK4819_SetAF(BK4819_AF_BEEP); // TX
|
||||
|
||||
if (!tx_mute)
|
||||
BK4819_WriteRegister(0x50, 0x3B20); // 0011 1011 0010 0000
|
||||
|
||||
GPIO_SetBit(&GPIOC->DATA, 4);
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
}
|
||||
|
||||
void BK4819_stop_tones(const bool tx)
|
||||
{
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
GPIO_ClearBit(&GPIOC->DATA, 4);
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
BK4819_SetAF(BK4819_AF_MUTE);
|
||||
|
||||
// BK4819_EnterTxMute();
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
BK4819_WriteRegister(0x70, 0);
|
||||
|
||||
BK4819_WriteRegister(0x30, 0);
|
||||
if (!tx)
|
||||
{
|
||||
BK4819_WriteRegister(0x30,
|
||||
BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||
// BK4819_REG_30_ENABLE_UNKNOWN |
|
||||
BK4819_REG_30_ENABLE_RX_LINK |
|
||||
BK4819_REG_30_ENABLE_AF_DAC |
|
||||
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||
BK4819_REG_30_ENABLE_PLL_VCO |
|
||||
// BK4819_REG_30_ENABLE_PA_GAIN |
|
||||
// BK4819_REG_30_ENABLE_MIC_ADC |
|
||||
// BK4819_REG_30_ENABLE_TX_DSP |
|
||||
BK4819_REG_30_ENABLE_RX_DSP |
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BK4819_WriteRegister(0x30,
|
||||
BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||
BK4819_REG_30_ENABLE_UNKNOWN |
|
||||
// BK4819_REG_30_ENABLE_RX_LINK |
|
||||
BK4819_REG_30_ENABLE_AF_DAC |
|
||||
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||
BK4819_REG_30_ENABLE_PLL_VCO |
|
||||
BK4819_REG_30_ENABLE_PA_GAIN |
|
||||
BK4819_REG_30_ENABLE_MIC_ADC |
|
||||
BK4819_REG_30_ENABLE_TX_DSP |
|
||||
// BK4819_REG_30_ENABLE_RX_DSP |
|
||||
0);
|
||||
}
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
|
||||
BK4819_ExitTxMute();
|
||||
|
||||
SYSTEM_DelayMs(1);
|
||||
}
|
||||
|
||||
void BK4819_enable_mdc1200_rx(const bool enable)
|
||||
{
|
||||
// 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
|
||||
|
||||
// REG_72
|
||||
//
|
||||
// <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
|
||||
|
||||
// REG_58
|
||||
//
|
||||
// <15:13> 1 FSK TX mode selection
|
||||
// 0 = FSK 1.2K and FSK 2.4K TX .. no tones, direct FM
|
||||
// 1 = FFSK 1200 / 1800 TX
|
||||
// 2 = ???
|
||||
// 3 = FFSK 1200 / 2400 TX
|
||||
// 4 = ???
|
||||
// 5 = NOAA SAME TX
|
||||
// 6 = ???
|
||||
// 7 = ???
|
||||
//
|
||||
// <12:10> 0 FSK RX mode selection
|
||||
// 0 = FSK 1.2K, FSK 2.4K RX and NOAA SAME RX .. no tones, direct FM
|
||||
// 1 = ???
|
||||
// 2 = ???
|
||||
// 3 = ???
|
||||
// 4 = FFSK 1200 / 2400 RX
|
||||
// 5 = ???
|
||||
// 6 = ???
|
||||
// 7 = FFSK 1200 / 1800 RX
|
||||
//
|
||||
// <9:8> 0 FSK RX gain
|
||||
// 0 ~ 3
|
||||
//
|
||||
// <7:6> 0 ???
|
||||
// 0 ~ 3
|
||||
//
|
||||
// <5:4> 0 FSK preamble type selection
|
||||
// 0 = 0xAA or 0x55 due to the MSB of FSK sync byte 0
|
||||
// 1 = ???
|
||||
// 2 = 0x55
|
||||
// 3 = 0xAA
|
||||
//
|
||||
// <3:1> 1 FSK RX bandwidth setting
|
||||
// 0 = FSK 1.2K .. no tones, direct FM
|
||||
// 1 = FFSK 1200 / 1800
|
||||
// 2 = NOAA SAME RX
|
||||
// 3 = ???
|
||||
// 4 = FSK 2.4K and FFSK 1200 / 2400
|
||||
// 5 = ???
|
||||
// 6 = ???
|
||||
// 7 = ???
|
||||
//
|
||||
// <0> 1 FSK enable
|
||||
// 0 = disable
|
||||
// 1 = enable
|
||||
|
||||
// REG_5C
|
||||
//
|
||||
// <15:7> ???
|
||||
//
|
||||
// <6> 1 CRC option enable
|
||||
// 0 = disable
|
||||
// 1 = enable
|
||||
//
|
||||
// <5:0> ???
|
||||
//
|
||||
// disable CRC
|
||||
|
||||
// REG_5D
|
||||
//
|
||||
// set the packet size
|
||||
|
||||
if (enable)
|
||||
{
|
||||
const uint16_t fsk_reg59 =
|
||||
(0u << 15) | // 1 = clear TX FIFO
|
||||
(0u << 14) | // 1 = clear RX FIFO
|
||||
(0u << 13) | // 1 = scramble
|
||||
(0u << 12) | // 1 = enable RX
|
||||
(0u << 11) | // 1 = enable TX
|
||||
(0u << 10) | // 1 = invert data when RX
|
||||
(0u << 9) | // 1 = invert data when TX
|
||||
(0u << 8) | // ???
|
||||
(0u << 4) | // 0 ~ 15 preamble length selection .. mdc1200 does not send bit reversals :(
|
||||
(1u << 3) | // 0/1 sync length selection
|
||||
(0u << 0); // 0 ~ 7 ???
|
||||
|
||||
BK4819_WriteRegister(0x70,
|
||||
( 0u << 15) | // 0
|
||||
( 0u << 8) | // 0
|
||||
( 1u << 7) | // 1
|
||||
(96u << 0)); // 96
|
||||
|
||||
BK4819_WriteRegister(0x72, scale_freq(1200));
|
||||
|
||||
BK4819_WriteRegister(0x58,
|
||||
(1u << 13) | // 1 FSK TX mode selection
|
||||
// 0 = FSK 1.2K and FSK 2.4K TX .. no tones, direct FM
|
||||
// 1 = FFSK 1200 / 1800 TX
|
||||
// 2 = ???
|
||||
// 3 = FFSK 1200 / 2400 TX
|
||||
// 4 = ???
|
||||
// 5 = NOAA SAME TX
|
||||
// 6 = ???
|
||||
// 7 = ???
|
||||
//
|
||||
(7u << 10) | // 0 FSK RX mode selection
|
||||
// 0 = FSK 1.2K, FSK 2.4K RX and NOAA SAME RX .. no tones, direct FM
|
||||
// 1 = ???
|
||||
// 2 = ???
|
||||
// 3 = ???
|
||||
// 4 = FFSK 1200 / 2400 RX
|
||||
// 5 = ???
|
||||
// 6 = ???
|
||||
// 7 = FFSK 1200 / 1800 RX
|
||||
//
|
||||
(3u << 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 .. no tones, direct FM
|
||||
// 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_5A .. bytes 0 & 1 sync pattern
|
||||
//
|
||||
// <15:8> sync byte 0
|
||||
// < 7:0> sync byte 1
|
||||
// BK4819_WriteRegister(0x5A, ((uint16_t)mdc1200_sync_suc_xor[0] << 8) | (mdc1200_sync_suc_xor[1] << 0));
|
||||
BK4819_WriteRegister(0x5A, ((uint16_t)mdc1200_sync_suc_xor[1] << 8) | (mdc1200_sync_suc_xor[2] << 0));
|
||||
|
||||
// REG_5B .. bytes 2 & 3 sync pattern
|
||||
//
|
||||
// <15:8> sync byte 2
|
||||
// < 7:0> sync byte 3
|
||||
// BK4819_WriteRegister(0x5B, ((uint16_t)mdc1200_sync_suc_xor[2] << 8) | (mdc1200_sync_suc_xor[3] << 0));
|
||||
BK4819_WriteRegister(0x5B, ((uint16_t)mdc1200_sync_suc_xor[3] << 8) | (mdc1200_sync_suc_xor[4] << 0));
|
||||
|
||||
// disable CRC
|
||||
BK4819_WriteRegister(0x5C, 0x5625); // 01010110 0 0 100101
|
||||
// BK4819_WriteRegister(0x5C, 0xAA30); // 10101010 0 0 110000
|
||||
|
||||
// set the almost full threshold
|
||||
BK4819_WriteRegister(0x5E, (64u << 3) | (1u << 0)); // 0 ~ 127, 0 ~ 7
|
||||
|
||||
{ // packet size .. sync + 14 bytes - size of a single mdc1200 packet
|
||||
// uint16_t size = 1 + (MDC1200_FEC_K * 2);
|
||||
uint16_t size = 0 + (MDC1200_FEC_K * 2);
|
||||
// size -= (fsk_reg59 & (1u << 3)) ? 4 : 2;
|
||||
size = ((size + 1) / 2) * 2; // round up to even, else FSK RX doesn't work
|
||||
BK4819_WriteRegister(0x5D, ((size - 1) << 8));
|
||||
}
|
||||
|
||||
// clear FIFO's then enable RX
|
||||
BK4819_WriteRegister(0x59, (1u << 15) | (1u << 14) | fsk_reg59);
|
||||
BK4819_WriteRegister(0x59, (1u << 12) | fsk_reg59);
|
||||
|
||||
// clear interrupt flags
|
||||
BK4819_WriteRegister(0x02, 0);
|
||||
|
||||
// BK4819_RX_TurnOn();
|
||||
|
||||
// enable interrupts
|
||||
// BK4819_WriteRegister(0x3F, BK4819_ReadRegister(0x3F) | BK4819_REG_3F_FSK_RX_SYNC | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
BK4819_WriteRegister(0x70, 0);
|
||||
BK4819_WriteRegister(0x58, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void BK4819_send_MDC1200(const uint8_t op, const uint8_t arg, const uint16_t id, const bool long_preamble)
|
||||
{
|
||||
uint16_t fsk_reg59;
|
||||
uint8_t packet[42];
|
||||
|
||||
// create the MDC1200 packet
|
||||
const unsigned int size = MDC1200_encode_single_packet(packet, op, arg, id);
|
||||
|
||||
//BK4819_ExitTxMute();
|
||||
BK4819_WriteRegister(0x50, 0x3B20); // 0011 1011 0010 0000
|
||||
|
||||
BK4819_WriteRegister(0x30,
|
||||
BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||
BK4819_REG_30_ENABLE_UNKNOWN |
|
||||
// BK4819_REG_30_ENABLE_RX_LINK |
|
||||
BK4819_REG_30_ENABLE_AF_DAC |
|
||||
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||
BK4819_REG_30_ENABLE_PLL_VCO |
|
||||
BK4819_REG_30_ENABLE_PA_GAIN |
|
||||
// BK4819_REG_30_ENABLE_MIC_ADC |
|
||||
BK4819_REG_30_ENABLE_TX_DSP |
|
||||
// BK4819_REG_30_ENABLE_RX_DSP |
|
||||
0);
|
||||
|
||||
#if 1
|
||||
GPIO_ClearBit(&GPIOC->DATA, 4);
|
||||
BK4819_SetAF(BK4819_AF_MUTE);
|
||||
#else
|
||||
// let the user hear the FSK being sent
|
||||
BK4819_SetAF(BK4819_AF_BEEP);
|
||||
GPIO_SetBit(&GPIOC->DATA, 4);
|
||||
#endif
|
||||
// SYSTEM_DelayMs(2);
|
||||
|
||||
// REG_51
|
||||
//
|
||||
// <15> TxCTCSS/CDCSS 0 = disable 1 = Enable
|
||||
//
|
||||
// turn off CTCSS/CDCSS during FFSK
|
||||
const uint16_t css_val = BK4819_ReadRegister(0x51);
|
||||
BK4819_WriteRegister(0x51, 0);
|
||||
|
||||
// set the FM deviation level
|
||||
const uint16_t dev_val = BK4819_ReadRegister(0x40);
|
||||
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
|
||||
// UART_printf("tx dev %04X\r\n", dev_val);
|
||||
#endif
|
||||
{
|
||||
uint16_t deviation = 850;
|
||||
switch (m_bandwidth)
|
||||
{
|
||||
case BK4819_FILTER_BW_WIDE: deviation = 1050; break;
|
||||
case BK4819_FILTER_BW_NARROW: deviation = 850; break;
|
||||
case BK4819_FILTER_BW_NARROWER: deviation = 750; break;
|
||||
}
|
||||
//BK4819_WriteRegister(0x40, (3u << 12) | (deviation & 0xfff));
|
||||
BK4819_WriteRegister(0x40, (dev_val & 0xf000) | (deviation & 0xfff));
|
||||
}
|
||||
|
||||
// REG_2B 0
|
||||
//
|
||||
// <15> 1 Enable CTCSS/CDCSS DC cancellation after FM Demodulation 1 = enable 0 = disable
|
||||
// <14> 1 Enable AF DC cancellation after FM Demodulation 1 = enable 0 = disable
|
||||
// <10> 0 AF RX HPF 300Hz filter 0 = enable 1 = disable
|
||||
// <9> 0 AF RX LPF 3kHz filter 0 = enable 1 = disable
|
||||
// <8> 0 AF RX de-emphasis filter 0 = enable 1 = disable
|
||||
// <2> 0 AF TX HPF 300Hz filter 0 = enable 1 = disable
|
||||
// <1> 0 AF TX LPF filter 0 = enable 1 = disable
|
||||
// <0> 0 AF TX pre-emphasis filter 0 = enable 1 = disable
|
||||
//
|
||||
// disable the 300Hz HPF and FM pre-emphasis filter
|
||||
//
|
||||
const uint16_t filt_val = BK4819_ReadRegister(0x2B);
|
||||
BK4819_WriteRegister(0x2B, (1u << 2) | (1u << 0));
|
||||
|
||||
// *******************************************
|
||||
// setup the FFSK modem as best we can for MDC1200
|
||||
|
||||
// MDC1200 uses 1200/1800 Hz FSK tone frequencies 1200 bits/s
|
||||
//
|
||||
BK4819_WriteRegister(0x58, // 0x37C3); // 001 101 11 11 00 001 1
|
||||
(1u << 13) | // 1 FSK TX mode selection
|
||||
// 0 = FSK 1.2K and FSK 2.4K TX .. no tones, direct FM
|
||||
// 1 = FFSK 1200/1800 TX
|
||||
// 2 = ???
|
||||
// 3 = FFSK 1200/2400 TX
|
||||
// 4 = ???
|
||||
// 5 = NOAA SAME TX
|
||||
// 6 = ???
|
||||
// 7 = ???
|
||||
//
|
||||
(7u << 10) | // 0 FSK RX mode selection
|
||||
// 0 = FSK 1.2K, FSK 2.4K RX and NOAA SAME RX .. no tones, direct FM
|
||||
// 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 .. no tones, direct FM
|
||||
// 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_72
|
||||
//
|
||||
// <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(0x72, scale_freq(1200));
|
||||
|
||||
// REG_70
|
||||
//
|
||||
// <15> 0 TONE-1
|
||||
// 1 = enable
|
||||
// 0 = disable
|
||||
//
|
||||
// <14:8> 0 TONE-1 tuning
|
||||
//
|
||||
// <7> 0 TONE-2
|
||||
// 1 = enable
|
||||
// 0 = disable
|
||||
//
|
||||
// <6:0> 0 TONE-2 / FSK tuning
|
||||
// 0 ~ 127
|
||||
//
|
||||
// enable tone-2, set gain
|
||||
//
|
||||
BK4819_WriteRegister(0x70, // 0 0000000 1 1100000
|
||||
( 0u << 15) | // 0
|
||||
( 0u << 8) | // 0
|
||||
( 1u << 7) | // 1
|
||||
(96u << 0)); // 96
|
||||
// (127u << 0));
|
||||
|
||||
// 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/1 1 = clear TX FIFO
|
||||
(0u << 14) | // 0/1 1 = clear RX FIFO
|
||||
(0u << 13) | // 0/1 1 = scramble
|
||||
(0u << 12) | // 0/1 1 = enable RX
|
||||
(0u << 11) | // 0/1 1 = enable TX
|
||||
(0u << 10) | // 0/1 1 = invert data when RX
|
||||
(0u << 9) | // 0/1 1 = invert data when TX
|
||||
(0u << 8) | // 0/1 ???
|
||||
(0u << 4) | // 0 ~ 15 preamble length .. bit toggling
|
||||
(1u << 3) | // 0/1 sync length
|
||||
(0u << 0); // 0 ~ 7 ???
|
||||
fsk_reg59 |= long_preamble ? 15u << 4 : 3u << 4;
|
||||
|
||||
// Set packet length (not including pre-amble and sync bytes that we can't seem to disable)
|
||||
BK4819_WriteRegister(0x5D, ((size - 1) << 8));
|
||||
|
||||
// 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(0x5A, 0x0000); // bytes 1 & 2
|
||||
|
||||
// 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(0x5B, 0x0000); // bytes 2 & 3
|
||||
|
||||
// CRC setting (plus other stuff we don't know what)
|
||||
//
|
||||
// REG_5C
|
||||
//
|
||||
// <15:7> ???
|
||||
//
|
||||
// <6> 1 CRC option enable 0 = disable 1 = enable
|
||||
//
|
||||
// <5:0> ???
|
||||
//
|
||||
// disable CRC
|
||||
//
|
||||
// NB, this also affects TX pre-amble in some way
|
||||
//
|
||||
BK4819_WriteRegister(0x5C, 0x5625); // 010101100 0 100101
|
||||
// BK4819_WriteRegister(0x5C, 0xAA30); // 101010100 0 110000
|
||||
// BK4819_WriteRegister(0x5C, 0x0030); // 000000000 0 110000
|
||||
|
||||
BK4819_WriteRegister(0x59, (1u << 15) | (1u << 14) | fsk_reg59); // clear FIFO's
|
||||
BK4819_WriteRegister(0x59, fsk_reg59); // release the FIFO reset
|
||||
|
||||
{ // load the entire packet data into the TX FIFO buffer
|
||||
unsigned int i;
|
||||
const uint16_t *p = (const uint16_t *)packet;
|
||||
for (i = 0; i < (size / sizeof(p[0])); i++)
|
||||
BK4819_WriteRegister(0x5F, p[i]); // load 16-bits at a time
|
||||
}
|
||||
|
||||
// enable tx interrupt
|
||||
BK4819_WriteRegister(0x3F, BK4819_REG_3F_FSK_TX_FINISHED);
|
||||
|
||||
// enable FSK TX
|
||||
BK4819_WriteRegister(0x59, (1u << 11) | fsk_reg59);
|
||||
|
||||
{ // packet time is ..
|
||||
// 173ms for PTT ID, acks, emergency
|
||||
// 266ms for call alert and sel-calls
|
||||
|
||||
// allow up to 310ms for the TX to complete
|
||||
// if it takes any longer then somethings gone wrong, we shut the TX down
|
||||
unsigned int timeout = 300 / 4;
|
||||
|
||||
while (timeout-- > 0)
|
||||
{
|
||||
SYSTEM_DelayMs(4);
|
||||
if (BK4819_ReadRegister(0x0C) & (1u << 0))
|
||||
{ // we have interrupt flags
|
||||
BK4819_WriteRegister(0x02, 0);
|
||||
if (BK4819_ReadRegister(0x02) & BK4819_REG_02_FSK_TX_FINISHED)
|
||||
timeout = 0; // TX is complete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_ClearBit(&GPIOC->DATA, 4);
|
||||
|
||||
// disable FSK
|
||||
BK4819_WriteRegister(0x59, fsk_reg59);
|
||||
|
||||
BK4819_WriteRegister(0x3F, 0); // disable interrupts
|
||||
BK4819_WriteRegister(0x70, 0);
|
||||
BK4819_WriteRegister(0x58, 0);
|
||||
|
||||
// restore FM deviation level
|
||||
BK4819_WriteRegister(0x40, dev_val);
|
||||
|
||||
// restore TX/RX filtering
|
||||
BK4819_WriteRegister(0x2B, filt_val);
|
||||
|
||||
// restore the CTCSS/CDCSS setting
|
||||
BK4819_WriteRegister(0x51, css_val);
|
||||
|
||||
//BK4819_EnterTxMute();
|
||||
BK4819_WriteRegister(0x50, 0xBB20); // 1011 1011 0010 0000
|
||||
|
||||
//BK4819_SetAF(BK4819_AF_MUTE);
|
||||
BK4819_WriteRegister(0x47, (1u << 14) | (1u << 13) | (BK4819_AF_MUTE << 8) | (1u << 6));
|
||||
|
||||
BK4819_WriteRegister(0x30,
|
||||
BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||
BK4819_REG_30_ENABLE_UNKNOWN |
|
||||
// BK4819_REG_30_ENABLE_RX_LINK |
|
||||
// BK4819_REG_30_ENABLE_AF_DAC |
|
||||
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||
BK4819_REG_30_ENABLE_PLL_VCO |
|
||||
BK4819_REG_30_ENABLE_PA_GAIN |
|
||||
BK4819_REG_30_ENABLE_MIC_ADC |
|
||||
BK4819_REG_30_ENABLE_TX_DSP |
|
||||
// BK4819_REG_30_ENABLE_RX_DSP |
|
||||
0);
|
||||
|
||||
//BK4819_ExitTxMute();
|
||||
BK4819_WriteRegister(0x50, 0x3B20); // 0011 1011 0010 0000
|
||||
}
|
||||
#endif
|
|
@ -66,6 +66,7 @@ typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
|
|||
extern bool gRxIdleMode;
|
||||
|
||||
void BK4819_Init(void);
|
||||
|
||||
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
|
||||
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
|
||||
void BK4819_SetRegValue(RegisterSpec s, uint16_t v);
|
||||
|
@ -168,6 +169,10 @@ void BK4819_Enable_AfDac_DiscMode_TxDsp(void);
|
|||
void BK4819_GetVoxAmp(uint16_t *pResult);
|
||||
void BK4819_SetScrambleFrequencyControlWord(uint32_t Frequency);
|
||||
void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code);
|
||||
void BK4819_send_MDC1200(const uint8_t op, const uint8_t arg, const uint16_t id, const bool long_preamble);
|
||||
|
||||
void BK4819_stop_tones(const bool tx);
|
||||
void BK4819_start_tone(const uint16_t frequency, const unsigned int level, const bool tx, const bool tx_mute);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
36
driver/crc.c
36
driver/crc.c
|
@ -19,18 +19,34 @@
|
|||
|
||||
void CRC_Init(void)
|
||||
{
|
||||
CRC_CR = 0
|
||||
| CRC_CR_CRC_EN_BITS_DISABLE
|
||||
| CRC_CR_INPUT_REV_BITS_NORMAL
|
||||
| CRC_CR_INPUT_INV_BITS_NORMAL
|
||||
| CRC_CR_OUTPUT_REV_BITS_NORMAL
|
||||
| CRC_CR_OUTPUT_INV_BITS_NORMAL
|
||||
| CRC_CR_DATA_WIDTH_BITS_8
|
||||
| CRC_CR_CRC_SEL_BITS_CRC_16_CCITT
|
||||
;
|
||||
CRC_IV = 0;
|
||||
CRC_CR =
|
||||
CRC_CR_CRC_EN_BITS_DISABLE |
|
||||
CRC_CR_INPUT_REV_BITS_NORMAL |
|
||||
CRC_CR_INPUT_INV_BITS_BIT_INVERTED |
|
||||
CRC_CR_OUTPUT_REV_BITS_REVERSED |
|
||||
CRC_CR_OUTPUT_INV_BITS_BIT_INVERTED |
|
||||
CRC_CR_DATA_WIDTH_BITS_8 |
|
||||
CRC_CR_CRC_SEL_BITS_CRC_16_CCITT;
|
||||
|
||||
CRC_IV = 0;
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MDC1200
|
||||
void CRC_InitReverse(void)
|
||||
{
|
||||
CRC_CR =
|
||||
CRC_CR_CRC_EN_BITS_DISABLE |
|
||||
CRC_CR_INPUT_REV_BITS_NORMAL |
|
||||
CRC_CR_INPUT_INV_BITS_BIT_INVERTED |
|
||||
CRC_CR_OUTPUT_REV_BITS_REVERSED |
|
||||
CRC_CR_OUTPUT_INV_BITS_BIT_INVERTED |
|
||||
CRC_CR_DATA_WIDTH_BITS_8 |
|
||||
CRC_CR_CRC_SEL_BITS_CRC_16_CCITT;
|
||||
|
||||
CRC_IV = 0;
|
||||
}
|
||||
#endif
|
||||
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
|
||||
{
|
||||
const uint8_t *pData = (const uint8_t *)pBuffer;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
void CRC_Init(void);
|
||||
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size);
|
||||
void CRC_InitReverse(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,3 +43,23 @@ void SYSTICK_DelayUs(uint32_t Delay)
|
|||
} while (i < ticks);
|
||||
}
|
||||
|
||||
void SYSTICK_Delay250ns(const uint32_t Delay)
|
||||
{
|
||||
const uint32_t ticks = (Delay * gTickMultiplier) >> 2;
|
||||
uint32_t i = 0;
|
||||
uint32_t Start = SysTick->LOAD;
|
||||
uint32_t Previous = SysTick->VAL;
|
||||
|
||||
do {
|
||||
uint32_t Delta;
|
||||
uint32_t Current;
|
||||
|
||||
do Current = SysTick->VAL;
|
||||
while (Current == Previous);
|
||||
|
||||
Delta = (Current < Previous) ? -Current : Start - Current;
|
||||
i += Delta + Previous;
|
||||
Previous = Current;
|
||||
|
||||
} while (i < ticks);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
void SYSTICK_Init(void);
|
||||
void SYSTICK_DelayUs(uint32_t Delay);
|
||||
void SYSTICK_Delay250ns(const uint32_t Delay);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
29
radio.c
29
radio.c
|
@ -13,7 +13,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "driver/bk4819.h"
|
||||
|
||||
#include "app/mdc1200.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "app/dtmf.h"
|
||||
|
@ -904,6 +906,7 @@ void RADIO_SetTxParameters(void)
|
|||
|
||||
void RADIO_SetModulation(ModulationMode_t modulation)
|
||||
{
|
||||
static ModulationMode_t m = MODULATION_UKNOWN;
|
||||
BK4819_AF_Type_t mod;
|
||||
switch(modulation) {
|
||||
default:
|
||||
|
@ -928,9 +931,16 @@ void RADIO_SetModulation(ModulationMode_t modulation)
|
|||
}
|
||||
|
||||
BK4819_SetAF(mod);
|
||||
BK4819_SetRegValue(afDacGainRegSpec, 0xF);
|
||||
BK4819_WriteRegister(BK4819_REG_3D, modulation == MODULATION_USB ? 0 : 0x2AAB);
|
||||
BK4819_SetRegValue(afcDisableRegSpec, modulation != MODULATION_FM);
|
||||
if(m != modulation) {
|
||||
m = modulation;
|
||||
BK4819_SetRegValue(afDacGainRegSpec, 0xF);
|
||||
BK4819_WriteRegister(BK4819_REG_3D, modulation == MODULATION_USB ? 0 : 0x2AAB);
|
||||
BK4819_SetRegValue(afcDisableRegSpec, modulation != MODULATION_FM);
|
||||
#ifdef ENABLE_AM_FIX
|
||||
BK4819_SetAGC(gRxVfo->Modulation != MODULATION_AM || !gSetting_AM_fix);
|
||||
BK4819_InitAGC();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void RADIO_SetVfoState(VfoState_t State)
|
||||
|
@ -1113,12 +1123,19 @@ void RADIO_SendEndOfTransmission(void)
|
|||
if (gEeprom.ROGER == ROGER_MODE_ROGER)
|
||||
BK4819_PlayRoger();
|
||||
else
|
||||
if (gEeprom.ROGER == ROGER_MODE_MDC)
|
||||
BK4819_PlayRogerMDC();
|
||||
if (gEeprom.ROGER == ROGER_MODE_MDC) {
|
||||
BK4819_send_MDC1200(MDC1200_OP_CODE_POST_ID, 0x00, 12, false);
|
||||
|
||||
#ifdef ENABLE_MDC1200_SIDE_BEEP
|
||||
BK4819_start_tone(880, 10, true, true);
|
||||
SYSTEM_DelayMs(120);
|
||||
BK4819_stop_tones(true);
|
||||
#endif
|
||||
}
|
||||
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO)
|
||||
BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE);
|
||||
{ BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE);
|
||||
|
||||
}
|
||||
if (
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
gDTMF_CallState == DTMF_CALL_STATE_NONE &&
|
||||
|
|
20
ui/main.c
20
ui/main.c
|
@ -38,7 +38,15 @@
|
|||
#include "ui/ui.h"
|
||||
|
||||
center_line_t center_line = CENTER_LINE_NONE;
|
||||
|
||||
const int8_t dBmCorrTable[7] = {
|
||||
-15, // band 1
|
||||
-25, // band 2
|
||||
-20, // band 3
|
||||
-4, // band 4
|
||||
-7, // band 5
|
||||
-6, // band 6
|
||||
-1 // band 7
|
||||
};
|
||||
// ***************************************************************************
|
||||
|
||||
static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level)
|
||||
|
@ -175,15 +183,7 @@ static void DisplayRSSIBar(const int16_t rssi, const bool now)
|
|||
if (now)
|
||||
memset(p_line, 0, LCD_WIDTH);
|
||||
|
||||
const int8_t dBmCorrTable[7] = {
|
||||
-15, // band 1
|
||||
-25, // band 2
|
||||
-20, // band 3
|
||||
-4, // band 4
|
||||
-7, // band 5
|
||||
-6, // band 6
|
||||
-1 // band 7
|
||||
};
|
||||
|
||||
const int16_t s0_dBm = -130; // S0 .. base level
|
||||
// const int16_t rssi_dBm = (rssi / 2) - 160;
|
||||
const int16_t rssi_dBm = (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band];
|
||||
|
|
|
@ -33,6 +33,6 @@ extern center_line_t center_line;
|
|||
void UI_DisplayAudioBar(void);
|
||||
void UI_UpdateRSSI(const int16_t rssi, const int vfo);
|
||||
void UI_DisplayMain(void);
|
||||
|
||||
extern const int8_t dBmCorrTable[7];
|
||||
#endif
|
||||
|
||||
|
|
17
版本说明.txt
17
版本说明.txt
|
@ -1,3 +1,20 @@
|
|||
#0.10.4
|
||||
修复开机显示问题
|
||||
修复宽窄带开机后失效问题
|
||||
频谱图增加AM-FIX
|
||||
增加MDC1200信令
|
||||
#0.10.3
|
||||
修复“长按菜单切换调制模式(AM/FM/USB)再切回FM亚音消失问题”
|
||||
锁定按键改成原来的逻辑,以后这种操作逻辑相关的都不来改了,众口难调
|
||||
#0.10.2
|
||||
修复命名信道时频率会变化的bug
|
||||
锁定按键时只允许发射/接收按键,与官方中文版逻辑一致
|
||||
#0.10.1
|
||||
重构代码,菜单名使用中文(是的,中文宏定义,感谢现代编译器,中文见/ui/menu.c)
|
||||
优化代码,节省了1.4KB
|
||||
修复扫描时“频差”翻译错误,纠正为“频率”
|
||||
修复开机显示菜单选项错误问题
|
||||
(哥们比较空,所以更新的快,其实不用天天升级,跟着大版本升级就好了)
|
||||
# 0.10
|
||||
* 版本为egcn变种,旨在精简固件植入更多功能,如MDC1200信令
|
||||
* egcn更新至191,结束:https://github.com/losehu/uv-k5-firmware-egcn/tree/main
|
||||
|
|
Loading…
Reference in a new issue