mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +00:00
Increase FM broadcast channels, memory channels and scan lists
- Increase FM broadcast memory channels from 20 to 48 - Increase memory channels from 200 to 768 - Increase scan lists from 3 to 10 - Update internal limits, mappings and related logic accordingly - Minor cleanups and adjustments related to these changes
This commit is contained in:
1 parent
8bb2915446
commit
e5ca2265e4
33 files changed
+1018
-794
No files matched your search
+1
-1
@@ -199,7 +199,7 @@ enable_feature(ENABLE_FEAT_F4HWN_INV)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_CTR)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_RESCUE_OPS)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_VOL)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_RESET_CHANNEL)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_RESET_VFO)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_PMR)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_GMRS_FRS_MURS)
|
||||
enable_feature(ENABLE_FEAT_F4HWN_CA)
|
||||
|
||||
+2
-1
@@ -230,7 +230,8 @@ void ACTION_Scan(bool bRestart)
|
||||
}
|
||||
|
||||
// channel mode. Keep scanning but toggle between scan lists
|
||||
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 6;
|
||||
gEeprom.SCAN_LIST_DEFAULT = ((gEeprom.SCAN_LIST_DEFAULT + 1) % (MR_CHANNELS_LIST + 2)) ?: 1;
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
SETTINGS_WriteCurrentState();
|
||||
#endif
|
||||
|
||||
+235
-37
@@ -16,10 +16,6 @@
|
||||
|
||||
#ifdef ENABLE_AIRCOPY
|
||||
|
||||
//#if !defined(ENABLE_OVERLAY)
|
||||
// #include "ARMCM0.h"
|
||||
//#endif
|
||||
|
||||
#include "app/aircopy.h"
|
||||
#include "audio.h"
|
||||
#include "driver/bk4819.h"
|
||||
@@ -31,6 +27,7 @@
|
||||
#include "ui/helper.h"
|
||||
#include "ui/inputbox.h"
|
||||
#include "ui/ui.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
||||
#include "screenshot.h"
|
||||
@@ -45,14 +42,92 @@ uint8_t gAirCopyIsSendMode;
|
||||
|
||||
uint16_t g_FSK_Buffer[36];
|
||||
|
||||
static uint16_t AIRCOPY_BlockToOffset(const uint16_t block)
|
||||
{
|
||||
if (block < AIRCOPY_MAIN_BLOCKS) {
|
||||
return (uint16_t)(block * AIRCOPY_BLOCK_SIZE);
|
||||
}
|
||||
// ============================================================================
|
||||
// Transfer Maps Definition
|
||||
// ============================================================================
|
||||
|
||||
const uint16_t extraBlock = (uint16_t)(block - AIRCOPY_MAIN_BLOCKS);
|
||||
return (uint16_t)(AIRCOPY_EXTRA_START + (extraBlock * AIRCOPY_BLOCK_SIZE));
|
||||
#define AIRCOPY_BANK_SEGMENTS(bank) \
|
||||
{ \
|
||||
{ 0x0000 + (bank)*0x0800, 0x0000 + (bank)*0x0800 + 0x0800, AIRCOPY_WRITE_STRUCT }, \
|
||||
{ 0x4000 + (bank)*0x0800, 0x4000 + (bank)*0x0800 + 0x0800, AIRCOPY_WRITE_STRUCT }, \
|
||||
{ 0x8000 + (bank)*0x0100, 0x8000 + (bank)*0x0100 + 0x0100, AIRCOPY_WRITE_BYTES }, \
|
||||
}
|
||||
|
||||
#define AIRCOPY_STD_MAP(seg_array) \
|
||||
{ \
|
||||
.segments = seg_array, \
|
||||
.num_segments = 3, \
|
||||
.total_blocks = 68 \
|
||||
}
|
||||
|
||||
// total_blocks = 68 (blocs of 64 bytes) because (16 bytes + 16 bytes + 2 bytes) * 128 = 4352 / 64 = 68
|
||||
|
||||
#define DECLARE_AIRCOPY_BANK(n) \
|
||||
static const AIRCOPY_Segment_t AIRCOPY_Segments_Bank##n[] = \
|
||||
AIRCOPY_BANK_SEGMENTS(n); \
|
||||
\
|
||||
static const AIRCOPY_TransferMap_t AIRCOPY_Map_Bank##n = \
|
||||
AIRCOPY_STD_MAP(AIRCOPY_Segments_Bank##n);
|
||||
|
||||
DECLARE_AIRCOPY_BANK(0)
|
||||
DECLARE_AIRCOPY_BANK(1)
|
||||
#if AIRCOPY_NUM_BANKS >= 4 // if 512 MR CHANNEL
|
||||
DECLARE_AIRCOPY_BANK(2)
|
||||
DECLARE_AIRCOPY_BANK(3)
|
||||
#endif
|
||||
#if AIRCOPY_NUM_BANKS >= 6 // if 758 MR CHANNEL
|
||||
DECLARE_AIRCOPY_BANK(4)
|
||||
DECLARE_AIRCOPY_BANK(5)
|
||||
#endif
|
||||
#if AIRCOPY_NUM_BANKS >= 8 // if 1024 MR CHANNEL
|
||||
DECLARE_AIRCOPY_BANK(6)
|
||||
DECLARE_AIRCOPY_BANK(7)
|
||||
#endif
|
||||
|
||||
// For settings only
|
||||
|
||||
static const AIRCOPY_Segment_t AIRCOPY_Segments_Settings[] = {
|
||||
{ 0xA000, 0xA160, AIRCOPY_WRITE_BYTES },
|
||||
};
|
||||
|
||||
static const AIRCOPY_TransferMap_t AIRCOPY_Map_Settings = {
|
||||
.segments = AIRCOPY_Segments_Settings,
|
||||
.num_segments = 1,
|
||||
.total_blocks = 6
|
||||
};
|
||||
|
||||
// Finally
|
||||
|
||||
static const AIRCOPY_TransferMap_t *AIRCOPY_AvailableMaps[] = {
|
||||
&AIRCOPY_Map_Bank0,
|
||||
&AIRCOPY_Map_Bank1,
|
||||
#if AIRCOPY_NUM_BANKS >= 4 // if 512 MR CHANNEL
|
||||
&AIRCOPY_Map_Bank2,
|
||||
&AIRCOPY_Map_Bank3,
|
||||
#endif
|
||||
#if AIRCOPY_NUM_BANKS >= 6 // if 758 MR CHANNEL
|
||||
&AIRCOPY_Map_Bank4,
|
||||
&AIRCOPY_Map_Bank5,
|
||||
#endif
|
||||
#if AIRCOPY_NUM_BANKS >= 8 // if 1024 MR CHANNEL
|
||||
&AIRCOPY_Map_Bank6,
|
||||
&AIRCOPY_Map_Bank7,
|
||||
#endif
|
||||
&AIRCOPY_Map_Settings,
|
||||
};
|
||||
|
||||
#define AIRCOPY_NUM_MAPS (sizeof(AIRCOPY_AvailableMaps) / sizeof(AIRCOPY_AvailableMaps[0]))
|
||||
|
||||
// ============================================================================
|
||||
// Helper Functions
|
||||
// ============================================================================
|
||||
|
||||
const AIRCOPY_TransferMap_t* AIRCOPY_GetCurrentMap(void)
|
||||
{
|
||||
if (gAircopyCurrentMapIndex >= AIRCOPY_NUM_MAPS) {
|
||||
gAircopyCurrentMapIndex = 0;
|
||||
}
|
||||
return AIRCOPY_AvailableMaps[gAircopyCurrentMapIndex];
|
||||
}
|
||||
|
||||
static void AIRCOPY_clear()
|
||||
@@ -66,9 +141,44 @@ static void AIRCOPY_clear()
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline const AIRCOPY_Segment_t *AIRCOPY_FindSegmentForOffset(uint16_t off)
|
||||
{
|
||||
const AIRCOPY_TransferMap_t *map = AIRCOPY_GetCurrentMap();
|
||||
|
||||
for (uint16_t i = 0; i < map->num_segments; i++)
|
||||
{
|
||||
const AIRCOPY_Segment_t *seg = &map->segments[i];
|
||||
|
||||
if (off >= seg->start_offset && off < seg->end_offset)
|
||||
return seg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void AIRCOPY_CheckComplete(void)
|
||||
{
|
||||
const AIRCOPY_TransferMap_t *map = AIRCOPY_GetCurrentMap();
|
||||
uint16_t done = gAirCopyBlockNumber + gErrorsDuringAirCopy;
|
||||
|
||||
if (done >= map->total_blocks)
|
||||
{
|
||||
gAircopyState = AIRCOPY_COMPLETE;
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
||||
getScreenShot(false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Send/Receive Functions
|
||||
// ============================================================================
|
||||
|
||||
bool AIRCOPY_SendMessage(void)
|
||||
{
|
||||
static uint8_t gAircopySendCountdown = 1;
|
||||
static uint16_t CurrentOffset = 0;
|
||||
static uint16_t CurrentSegmentIndex = 0;
|
||||
|
||||
if (gAircopyState != AIRCOPY_TRANSFER) {
|
||||
return 1;
|
||||
@@ -78,9 +188,36 @@ bool AIRCOPY_SendMessage(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_FSK_Buffer[1] = AIRCOPY_BlockToOffset(gAirCopyBlockNumber);
|
||||
const AIRCOPY_TransferMap_t *map = AIRCOPY_GetCurrentMap();
|
||||
|
||||
EEPROM_ReadBuffer(g_FSK_Buffer[1], &g_FSK_Buffer[2], 64);
|
||||
// Initialize on first call
|
||||
if (gAirCopyBlockNumber == 0) {
|
||||
CurrentSegmentIndex = 0;
|
||||
CurrentOffset = map->segments[0].start_offset;
|
||||
}
|
||||
|
||||
// Advance to next segment if current is done
|
||||
while (CurrentSegmentIndex < map->num_segments &&
|
||||
CurrentOffset >= map->segments[CurrentSegmentIndex].end_offset)
|
||||
{
|
||||
CurrentSegmentIndex++;
|
||||
if (CurrentSegmentIndex < map->num_segments) {
|
||||
CurrentOffset = map->segments[CurrentSegmentIndex].start_offset;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if transfer is complete
|
||||
if (CurrentSegmentIndex >= map->num_segments) {
|
||||
gAircopyState = AIRCOPY_COMPLETE;
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
||||
getScreenShot(false);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send data from current offset
|
||||
g_FSK_Buffer[1] = CurrentOffset;
|
||||
EEPROM_ReadBuffer(CurrentOffset, &g_FSK_Buffer[2], 64);
|
||||
|
||||
g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
|
||||
|
||||
@@ -88,20 +225,14 @@ bool AIRCOPY_SendMessage(void)
|
||||
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
|
||||
}
|
||||
|
||||
if (++gAirCopyBlockNumber >= AIRCOPY_TOTAL_BLOCKS) {
|
||||
gAircopyState = AIRCOPY_COMPLETE;
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
||||
getScreenShot(false);
|
||||
#endif
|
||||
//NVIC_SystemReset();
|
||||
}
|
||||
|
||||
RADIO_SetTxParameters();
|
||||
|
||||
BK4819_SendFSKData(g_FSK_Buffer);
|
||||
BK4819_SetupPowerAmplifier(0, 0);
|
||||
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
||||
|
||||
CurrentOffset += 64;
|
||||
gAirCopyBlockNumber++;
|
||||
gAircopySendCountdown = 30;
|
||||
|
||||
return 0;
|
||||
@@ -118,10 +249,13 @@ void AIRCOPY_StorePacket(void)
|
||||
uint16_t Status = BK4819_ReadRegister(BK4819_REG_0B);
|
||||
BK4819_PrepareFSKReceive();
|
||||
|
||||
// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL.
|
||||
|
||||
if ((Status & 0x0010U) != 0 || g_FSK_Buffer[0] != 0xABCD || g_FSK_Buffer[35] != 0xDCBA) {
|
||||
gErrorsDuringAirCopy++;
|
||||
|
||||
BK4819_ResetFSK(); // <- important
|
||||
BK4819_PrepareFSKReceive(); // <- re-arm proprement
|
||||
|
||||
AIRCOPY_CheckComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,36 +266,67 @@ void AIRCOPY_StorePacket(void)
|
||||
uint16_t Crc = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
|
||||
if (g_FSK_Buffer[34] != Crc) {
|
||||
gErrorsDuringAirCopy++;
|
||||
AIRCOPY_CheckComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t Offset = g_FSK_Buffer[1];
|
||||
const AIRCOPY_TransferMap_t *map = AIRCOPY_GetCurrentMap();
|
||||
|
||||
const bool in_main = (Offset < AIRCOPY_MAIN_END);
|
||||
const bool in_extra = (Offset >= AIRCOPY_EXTRA_START && Offset < AIRCOPY_EXTRA_END);
|
||||
// Validate offset is in the map
|
||||
bool validOffset = false;
|
||||
for (uint16_t i = 0; i < map->num_segments; i++) {
|
||||
if (Offset >= map->segments[i].start_offset && Offset < map->segments[i].end_offset) {
|
||||
validOffset = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_main && !in_extra) {
|
||||
if (!validOffset) {
|
||||
gErrorsDuringAirCopy++;
|
||||
AIRCOPY_CheckComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t *pData = &g_FSK_Buffer[2];
|
||||
for (unsigned int i = 0; i < 8; i++) {
|
||||
EEPROM_WriteBuffer(Offset, pData);
|
||||
pData += 4;
|
||||
Offset += 8;
|
||||
const AIRCOPY_Segment_t *seg = AIRCOPY_FindSegmentForOffset(Offset);
|
||||
|
||||
if (seg == NULL) {
|
||||
gErrorsDuringAirCopy++;
|
||||
AIRCOPY_CheckComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Offset == AIRCOPY_EXTRA_END) {
|
||||
gAircopyState = AIRCOPY_COMPLETE;
|
||||
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
||||
getScreenShot(false);
|
||||
#endif
|
||||
if (seg->write_mode == AIRCOPY_WRITE_BYTES)
|
||||
{
|
||||
/* Raw bytes stream, written in 8-byte EEPROM chunks */
|
||||
const uint8_t *p8 = (const uint8_t *)&g_FSK_Buffer[2];
|
||||
|
||||
for (unsigned int i = 0; i < 8; i++)
|
||||
{
|
||||
EEPROM_WriteBuffer(Offset + (i * 8), p8 + (i * 8));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Structured data path (kept as-is) */
|
||||
const uint16_t *pData = &g_FSK_Buffer[2];
|
||||
|
||||
for (unsigned int i = 0; i < 8; i++)
|
||||
{
|
||||
EEPROM_WriteBuffer(Offset, pData);
|
||||
pData += 4;
|
||||
Offset += 8;
|
||||
}
|
||||
}
|
||||
|
||||
gAirCopyBlockNumber++;
|
||||
AIRCOPY_CheckComplete();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Key Processing
|
||||
// ============================================================================
|
||||
|
||||
static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
{
|
||||
if (bKeyHeld || !bKeyPressed) {
|
||||
@@ -258,6 +423,25 @@ static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
||||
gAircopyState = AIRCOPY_TRANSFER;
|
||||
}
|
||||
|
||||
static void AIRCOPY_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
||||
{
|
||||
if (bKeyHeld || !bKeyPressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(Direction)
|
||||
{
|
||||
case 1:
|
||||
gAircopyCurrentMapIndex = (gAircopyCurrentMapIndex + 1) % AIRCOPY_NUM_MAPS;
|
||||
break;
|
||||
case -1:
|
||||
gAircopyCurrentMapIndex = (gAircopyCurrentMapIndex + AIRCOPY_NUM_MAPS - 1) % AIRCOPY_NUM_MAPS;
|
||||
break;
|
||||
}
|
||||
|
||||
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
||||
}
|
||||
|
||||
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
{
|
||||
switch (Key) {
|
||||
@@ -279,9 +463,23 @@ void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
case KEY_EXIT:
|
||||
AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld);
|
||||
break;
|
||||
case KEY_UP:
|
||||
#ifdef ENABLE_NAVIG_LEFT_RIGHT
|
||||
AIRCOPY_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
|
||||
#else
|
||||
AIRCOPY_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
|
||||
#endif
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
#ifdef ENABLE_NAVIG_LEFT_RIGHT
|
||||
AIRCOPY_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
|
||||
#else
|
||||
AIRCOPY_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+69
-15
@@ -21,24 +21,73 @@
|
||||
|
||||
#include "driver/keyboard.h"
|
||||
|
||||
// Extended AirCopy: after 0x0000..0x1E00, also send 0x2000..0x2080 (2 blocks)
|
||||
#define AIRCOPY_MAIN_END 0x1E00u
|
||||
#define AIRCOPY_EXTRA_START 0x2000u
|
||||
#define AIRCOPY_EXTRA_END 0x2080u
|
||||
#define AIRCOPY_BLOCK_SIZE 0x0040u // 64 bytes
|
||||
#define AIRCOPY_MAIN_BLOCKS (AIRCOPY_MAIN_END / AIRCOPY_BLOCK_SIZE) // 0x78
|
||||
#define AIRCOPY_EXTRA_BLOCKS ((AIRCOPY_EXTRA_END - AIRCOPY_EXTRA_START) / AIRCOPY_BLOCK_SIZE) // 2
|
||||
#define AIRCOPY_TOTAL_BLOCKS (AIRCOPY_MAIN_BLOCKS + AIRCOPY_EXTRA_BLOCKS)
|
||||
#define AIRCOPY_BAR_WIDTH 120 // Visible width of the progress gauge for UI
|
||||
// ============================================================================
|
||||
// General definitions
|
||||
// ============================================================================
|
||||
|
||||
enum AIRCOPY_State_t
|
||||
{
|
||||
#define AIRCOPY_BLOCK_SIZE 0x0040u // 64 bytes per AirCopy block
|
||||
#define AIRCOPY_CHANNELS_PER_BANK 128
|
||||
#define AIRCOPY_NUM_BANKS MR_CHANNELS_MAX / AIRCOPY_CHANNELS_PER_BANK
|
||||
#define AIRCOPY_CHANNEL_SIZE 16 // bytes per channel (freq/name)
|
||||
#define AIRCOPY_BANK_SIZE_BYTES 0x1080u // 0x800 (Freq) + 0x800 (Name) + 0x80 (Attr)
|
||||
#define AIRCOPY_BAR_WIDTH 120 // Visible width of the progress gauge
|
||||
|
||||
// ============================================================================
|
||||
// Segment write mode
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
* Defines how a segment must be written to EEPROM.
|
||||
*
|
||||
* - STRUCT: structured data (frequencies, names)
|
||||
* - BYTES : raw byte stream (attributes, settings, etc.)
|
||||
*/
|
||||
typedef enum {
|
||||
AIRCOPY_WRITE_STRUCT = 0,
|
||||
AIRCOPY_WRITE_BYTES = 1,
|
||||
} AIRCOPY_WriteMode_t;
|
||||
|
||||
// ============================================================================
|
||||
// Transfer segment structure
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
* Describes a contiguous EEPROM region involved in AirCopy.
|
||||
* The write_mode defines how the RX side must write the data.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t start_offset;
|
||||
uint16_t end_offset;
|
||||
AIRCOPY_WriteMode_t write_mode;
|
||||
} AIRCOPY_Segment_t;
|
||||
|
||||
// ============================================================================
|
||||
// Transfer map structure
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
* A transfer map is a collection of segments describing
|
||||
* one complete AirCopy operation (bank, settings, etc.).
|
||||
*/
|
||||
typedef struct {
|
||||
const AIRCOPY_Segment_t *segments;
|
||||
uint16_t num_segments;
|
||||
uint16_t total_blocks;
|
||||
} AIRCOPY_TransferMap_t;
|
||||
|
||||
// ============================================================================
|
||||
// AirCopy state
|
||||
// ============================================================================
|
||||
|
||||
typedef enum {
|
||||
AIRCOPY_READY = 0,
|
||||
AIRCOPY_TRANSFER,
|
||||
AIRCOPY_COMPLETE
|
||||
};
|
||||
} AIRCOPY_State_t;
|
||||
|
||||
typedef enum AIRCOPY_State_t AIRCOPY_State_t;
|
||||
// ============================================================================
|
||||
// Globals
|
||||
// ============================================================================
|
||||
|
||||
extern AIRCOPY_State_t gAircopyState;
|
||||
extern uint16_t gAirCopyBlockNumber;
|
||||
@@ -47,10 +96,15 @@ extern uint8_t gAirCopyIsSendMode;
|
||||
|
||||
extern uint16_t g_FSK_Buffer[36];
|
||||
|
||||
// ============================================================================
|
||||
// API
|
||||
// ============================================================================
|
||||
|
||||
bool AIRCOPY_SendMessage(void);
|
||||
void AIRCOPY_StorePacket(void);
|
||||
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
||||
|
||||
#endif
|
||||
const AIRCOPY_TransferMap_t* AIRCOPY_GetCurrentMap(void);
|
||||
|
||||
#endif
|
||||
#endif // ENABLE_AIRCOPY
|
||||
#endif // APP_AIRCOPY_H
|
||||
@@ -249,12 +249,12 @@ static void NextFreqChannel(void)
|
||||
|
||||
static void NextMemChannel(void)
|
||||
{
|
||||
static unsigned int prev_mr_chan = 0;
|
||||
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT - 1] : true;
|
||||
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT - 1] : -1;
|
||||
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT - 1] : -1;
|
||||
const unsigned int prev_chan = gNextMrChannel;
|
||||
unsigned int chan = 0;
|
||||
static uint16_t prev_mr_chan = 0;
|
||||
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < MR_CHANNELS_LIST + 1) ? gEeprom.SCAN_LIST_ENABLED[0] : true;
|
||||
const int16_t chan1 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < MR_CHANNELS_LIST + 1 && gEeprom.SCANLIST_PRIORITY_CH[0] != MR_CHANNELS_MAX) ? gEeprom.SCANLIST_PRIORITY_CH[0] : -1;
|
||||
const int16_t chan2 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < MR_CHANNELS_LIST + 1 && gEeprom.SCANLIST_PRIORITY_CH[1] != MR_CHANNELS_MAX) ? gEeprom.SCANLIST_PRIORITY_CH[1] : -1;
|
||||
const uint16_t prev_chan = gNextMrChannel;
|
||||
uint16_t chan = 0;
|
||||
|
||||
//char str[64] = "";
|
||||
|
||||
@@ -327,15 +327,15 @@ static void NextMemChannel(void)
|
||||
case SCAN_NEXT_CHAN_MR:
|
||||
currentScanList = SCAN_NEXT_CHAN_MR;
|
||||
gNextMrChannel = prev_mr_chan;
|
||||
chan = 0xff;
|
||||
chan = 0xFFFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!enabled || chan == 0xff)
|
||||
if (!enabled || chan == 0xFFFF)
|
||||
{
|
||||
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, true, gEeprom.SCAN_LIST_DEFAULT);
|
||||
if (chan == 0xFF)
|
||||
if (chan == 0xFFFF)
|
||||
{ // no valid channel found
|
||||
chan = MR_CHANNEL_FIRST;
|
||||
}
|
||||
|
||||
+2
-2
@@ -60,8 +60,8 @@ void COMMON_SwitchVFOMode()
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
|
||||
if (Channel != 0xFF)
|
||||
uint16_t Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
|
||||
if (Channel != 0xFFFF)
|
||||
{ // swap to channel mode
|
||||
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
|
||||
#ifdef ENABLE_VOICE
|
||||
|
||||
+23
-15
@@ -63,20 +63,21 @@ static void toggle_chan_scanlist(void)
|
||||
return;
|
||||
}
|
||||
|
||||
ChannelAttributes_t *att = &gMR_ChannelAttributes[gTxVfo->CHANNEL_SAVE];
|
||||
|
||||
// Remove exclude
|
||||
if(gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] == true)
|
||||
if(att->exclude == true)
|
||||
{
|
||||
gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = false;
|
||||
att->exclude = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t scanTmp = gTxVfo->SCANLIST1_PARTICIPATION | (gTxVfo->SCANLIST2_PARTICIPATION << 1) | (gTxVfo->SCANLIST3_PARTICIPATION << 2);
|
||||
uint8_t scanlist = gTxVfo->SCANLIST_PARTICIPATION;
|
||||
|
||||
scanTmp = (scanTmp++ < 7) ? scanTmp: 0;
|
||||
if (scanlist > MR_CHANNELS_LIST + 1)
|
||||
scanlist = 0;
|
||||
|
||||
gTxVfo->SCANLIST1_PARTICIPATION = (scanTmp >> 0) & 0x01;
|
||||
gTxVfo->SCANLIST2_PARTICIPATION = (scanTmp >> 1) & 0x01;
|
||||
gTxVfo->SCANLIST3_PARTICIPATION = (scanTmp >> 2) & 0x01;
|
||||
gTxVfo->SCANLIST_PARTICIPATION = scanlist;
|
||||
|
||||
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, true, true);
|
||||
|
||||
@@ -348,8 +349,8 @@ void channelMove(uint16_t Channel)
|
||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||
#endif
|
||||
|
||||
gEeprom.MrChannel[Vfo] = (uint8_t)Channel;
|
||||
gEeprom.ScreenChannel[Vfo] = (uint8_t)Channel;
|
||||
gEeprom.MrChannel[Vfo] = (uint16_t)Channel;
|
||||
gEeprom.ScreenChannel[Vfo] = (uint16_t)Channel;
|
||||
//gRequestSaveVFO = true;
|
||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||
|
||||
@@ -433,7 +434,13 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
|
||||
if (gScanStateDir != SCAN_OFF){
|
||||
switch(Key) {
|
||||
case KEY_0...KEY_5:
|
||||
case KEY_0:
|
||||
gEeprom.SCAN_LIST_DEFAULT = MR_CHANNELS_LIST + 1;
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
SETTINGS_WriteCurrentState();
|
||||
#endif
|
||||
break;
|
||||
case KEY_1...KEY_9:
|
||||
gEeprom.SCAN_LIST_DEFAULT = Key;
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
SETTINGS_WriteCurrentState();
|
||||
@@ -673,12 +680,13 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
||||
if (bKeyPressed) { // long press MENU key
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
// Exclude work with list 1, 2, 3 or all list
|
||||
// Exclude channel
|
||||
if(gScanStateDir != SCAN_OFF)
|
||||
{
|
||||
if(FUNCTION_IsRx() || gScanPauseDelayIn_10ms > 9)
|
||||
{
|
||||
gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true;
|
||||
ChannelAttributes_t *att = &gMR_ChannelAttributes[lastFoundFrqOrChan];
|
||||
att->exclude = true;
|
||||
|
||||
gVfoConfigureMode = VFO_CONFIGURE;
|
||||
gFlagResetVfos = true;
|
||||
@@ -855,7 +863,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
||||
gPowerHigh = false;
|
||||
#endif
|
||||
|
||||
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
|
||||
uint16_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
|
||||
|
||||
if (bKeyHeld || !bKeyPressed) { // key held or released
|
||||
if (gInputBoxIndex > 0)
|
||||
@@ -885,7 +893,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
||||
if (!IS_NOAA_CHANNEL(Channel))
|
||||
#endif
|
||||
{
|
||||
uint8_t Next;
|
||||
uint16_t Next;
|
||||
if (IS_FREQ_CHANNEL(Channel)) { // step/down in frequency
|
||||
const uint32_t frequency = APP_SetFrequencyByStep(gTxVfo, Direction);
|
||||
|
||||
@@ -901,7 +909,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
||||
}
|
||||
|
||||
Next = RADIO_FindNextChannel(Channel + Direction, Direction, false, 0);
|
||||
if (Next == 0xFF)
|
||||
if (Next == 0xFFFF)
|
||||
return;
|
||||
if (Channel == Next)
|
||||
return;
|
||||
|
||||
+87
-60
@@ -34,6 +34,7 @@
|
||||
#include "helper/battery.h"
|
||||
#include "misc.h"
|
||||
#include "settings.h"
|
||||
#include "../driver/st7565.h"
|
||||
#if defined(ENABLE_OVERLAY)
|
||||
#include "sram-overlay.h"
|
||||
#endif
|
||||
@@ -234,9 +235,6 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
|
||||
#endif
|
||||
case MENU_BCL:
|
||||
case MENU_BEEP:
|
||||
case MENU_S_ADD1:
|
||||
case MENU_S_ADD2:
|
||||
case MENU_S_ADD3:
|
||||
case MENU_STE:
|
||||
case MENU_D_ST:
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
@@ -257,6 +255,7 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
|
||||
#endif
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
case MENU_SET_TMR:
|
||||
case MENU_S_PRI:
|
||||
#endif
|
||||
//*pMin = 0;
|
||||
*pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1;
|
||||
@@ -299,11 +298,10 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
|
||||
*pMax = MR_CHANNEL_LAST;
|
||||
break;
|
||||
|
||||
case MENU_SLIST1:
|
||||
case MENU_SLIST2:
|
||||
case MENU_SLIST3:
|
||||
*pMin = -1;
|
||||
*pMax = MR_CHANNEL_LAST;
|
||||
case MENU_S_PRI_CH_1:
|
||||
case MENU_S_PRI_CH_2:
|
||||
//*pMin = 0;
|
||||
*pMax = MR_CHANNEL_LAST + 2;
|
||||
break;
|
||||
|
||||
case MENU_SAVE:
|
||||
@@ -316,9 +314,14 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
|
||||
*pMax = 4;
|
||||
break;
|
||||
|
||||
case MENU_S_LIST:
|
||||
case MENU_LIST_CH:
|
||||
//*pMin = 0;
|
||||
*pMax = 5;
|
||||
*pMax = MR_CHANNELS_LIST + 1;
|
||||
break;
|
||||
|
||||
case MENU_S_LIST:
|
||||
*pMin = 1;
|
||||
*pMax = MR_CHANNELS_LIST + 1;
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
@@ -583,6 +586,14 @@ void MENU_AcceptSetting(void)
|
||||
SETTINGS_SaveChannelName(gSubMenuSelection, edit);
|
||||
return;
|
||||
|
||||
case MENU_S_PRI_CH_1:
|
||||
gEeprom.SCANLIST_PRIORITY_CH[0] = gSubMenuSelection;
|
||||
break;
|
||||
|
||||
case MENU_S_PRI_CH_2:
|
||||
gEeprom.SCANLIST_PRIORITY_CH[1] = gSubMenuSelection;
|
||||
break;
|
||||
|
||||
case MENU_SAVE:
|
||||
gEeprom.BATTERY_SAVE = gSubMenuSelection;
|
||||
break;
|
||||
@@ -661,22 +672,8 @@ void MENU_AcceptSetting(void)
|
||||
gKeyLockCountdown = gEeprom.AUTO_KEYPAD_LOCK * 30; // 15 seconds step
|
||||
break;
|
||||
|
||||
case MENU_S_ADD1:
|
||||
gTxVfo->SCANLIST1_PARTICIPATION = gSubMenuSelection;
|
||||
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true);
|
||||
gVfoConfigureMode = VFO_CONFIGURE;
|
||||
gFlagResetVfos = true;
|
||||
return;
|
||||
|
||||
case MENU_S_ADD2:
|
||||
gTxVfo->SCANLIST2_PARTICIPATION = gSubMenuSelection;
|
||||
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true);
|
||||
gVfoConfigureMode = VFO_CONFIGURE;
|
||||
gFlagResetVfos = true;
|
||||
return;
|
||||
|
||||
case MENU_S_ADD3:
|
||||
gTxVfo->SCANLIST3_PARTICIPATION = gSubMenuSelection;
|
||||
case MENU_LIST_CH:
|
||||
gTxVfo->SCANLIST_PARTICIPATION = gSubMenuSelection;
|
||||
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true);
|
||||
gVfoConfigureMode = VFO_CONFIGURE;
|
||||
gFlagResetVfos = true;
|
||||
@@ -718,6 +715,10 @@ void MENU_AcceptSetting(void)
|
||||
gEeprom.SCAN_LIST_DEFAULT = gSubMenuSelection;
|
||||
break;
|
||||
|
||||
case MENU_S_PRI:
|
||||
gEeprom.SCAN_LIST_ENABLED[0] = gSubMenuSelection;
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ALARM
|
||||
case MENU_AL_MOD:
|
||||
gEeprom.ALARM_MODE = gSubMenuSelection;
|
||||
@@ -877,11 +878,11 @@ void MENU_AcceptSetting(void)
|
||||
#endif
|
||||
|
||||
case MENU_BATCAL:
|
||||
{ // voltages are averages between discharge curves of 1600 and 2200 mAh
|
||||
{ // voltages are averages between discharge curves of 1600 and 2200 mAh
|
||||
// gBatteryCalibration[0] = (520ul * gSubMenuSelection) / 760; // 5.20V empty, blinking above this value, reduced functionality below
|
||||
// gBatteryCalibration[1] = (689ul * gSubMenuSelection) / 760; // 6.89V, ~5%, 1 bars above this value
|
||||
// gBatteryCalibration[2] = (724ul * gSubMenuSelection) / 760; // 7.24V, ~17%, 2 bars above this value
|
||||
gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value
|
||||
gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value
|
||||
// gBatteryCalibration[4] = (771ul * gSubMenuSelection) / 760; // 7.71V, ~65%, 4 bars above this value
|
||||
// gBatteryCalibration[5] = 2300;
|
||||
SETTINGS_SaveBatteryCalibration(gBatteryCalibration);
|
||||
@@ -1163,16 +1164,8 @@ void MENU_ShowCurrentSetting(void)
|
||||
gSubMenuSelection = gEeprom.AUTO_KEYPAD_LOCK;
|
||||
break;
|
||||
|
||||
case MENU_S_ADD1:
|
||||
gSubMenuSelection = gTxVfo->SCANLIST1_PARTICIPATION;
|
||||
break;
|
||||
|
||||
case MENU_S_ADD2:
|
||||
gSubMenuSelection = gTxVfo->SCANLIST2_PARTICIPATION;
|
||||
break;
|
||||
|
||||
case MENU_S_ADD3:
|
||||
gSubMenuSelection = gTxVfo->SCANLIST3_PARTICIPATION;
|
||||
case MENU_LIST_CH:
|
||||
gSubMenuSelection = gTxVfo->SCANLIST_PARTICIPATION;
|
||||
break;
|
||||
|
||||
case MENU_STE:
|
||||
@@ -1205,10 +1198,16 @@ void MENU_ShowCurrentSetting(void)
|
||||
gSubMenuSelection = gEeprom.SCAN_LIST_DEFAULT;
|
||||
break;
|
||||
|
||||
case MENU_SLIST1:
|
||||
case MENU_SLIST2:
|
||||
case MENU_SLIST3:
|
||||
gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, UI_MENU_GetCurrentMenuId() - MENU_SLIST1 + 1);
|
||||
case MENU_S_PRI:
|
||||
gSubMenuSelection = gEeprom.SCAN_LIST_ENABLED[0];
|
||||
break;
|
||||
|
||||
case MENU_S_PRI_CH_1:
|
||||
gSubMenuSelection = gEeprom.SCANLIST_PRIORITY_CH[0];
|
||||
break;
|
||||
|
||||
case MENU_S_PRI_CH_2:
|
||||
gSubMenuSelection = gEeprom.SCANLIST_PRIORITY_CH[1];
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ALARM
|
||||
@@ -1524,6 +1523,8 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
|
||||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
|
||||
UI_MENU_GetCurrentMenuId() == MENU_1_CALL ||
|
||||
UI_MENU_GetCurrentMenuId() == MENU_S_PRI_CH_1 ||
|
||||
UI_MENU_GetCurrentMenuId() == MENU_S_PRI_CH_2 ||
|
||||
UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
|
||||
{ // enter 3-digit channel number
|
||||
|
||||
@@ -1842,7 +1843,7 @@ static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld)
|
||||
static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
||||
{
|
||||
uint8_t VFO;
|
||||
uint8_t Channel;
|
||||
uint16_t Channel;
|
||||
bool bCheckScanList;
|
||||
|
||||
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0)
|
||||
@@ -1925,34 +1926,60 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
||||
{
|
||||
case MENU_DEL_CH:
|
||||
case MENU_1_CALL:
|
||||
case MENU_S_PRI_CH_1:
|
||||
case MENU_S_PRI_CH_2:
|
||||
case MENU_MEM_NAME:
|
||||
bCheckScanList = false;
|
||||
break;
|
||||
|
||||
case MENU_SLIST3:
|
||||
bCheckScanList = true;
|
||||
VFO = 3;
|
||||
break;
|
||||
case MENU_SLIST2:
|
||||
bCheckScanList = true;
|
||||
VFO = 2;
|
||||
break;
|
||||
case MENU_SLIST1:
|
||||
bCheckScanList = true;
|
||||
VFO = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
MENU_ClampSelection(Direction);
|
||||
gRequestDisplayScreen = DISPLAY_MENU;
|
||||
return;
|
||||
}
|
||||
|
||||
Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO);
|
||||
if (Channel != 0xFF)
|
||||
gSubMenuSelection = Channel;
|
||||
if(UI_MENU_GetCurrentMenuId() == MENU_S_PRI_CH_1 || UI_MENU_GetCurrentMenuId() == MENU_S_PRI_CH_2)
|
||||
{
|
||||
static int16_t last;
|
||||
|
||||
gRequestDisplayScreen = DISPLAY_MENU;
|
||||
if(Direction > 0 && gSubMenuSelection == MR_CHANNELS_MAX)
|
||||
{
|
||||
gSubMenuSelection = -1;
|
||||
last = -1;
|
||||
}
|
||||
else if(Direction < 0 && gSubMenuSelection == MR_CHANNELS_MAX)
|
||||
{
|
||||
gSubMenuSelection = MR_CHANNELS_MAX;
|
||||
last = MR_CHANNELS_MAX;
|
||||
}
|
||||
|
||||
Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO);
|
||||
if (Channel != 0xFFFF)
|
||||
gSubMenuSelection = Channel;
|
||||
|
||||
if(Direction > 0 && gSubMenuSelection < last)
|
||||
{
|
||||
gSubMenuSelection = MR_CHANNELS_MAX;
|
||||
}
|
||||
else if(Direction < 0 && gSubMenuSelection > last)
|
||||
{
|
||||
gSubMenuSelection = MR_CHANNELS_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
last = Channel;
|
||||
}
|
||||
|
||||
gRequestDisplayScreen = DISPLAY_MENU;
|
||||
}
|
||||
else
|
||||
{
|
||||
Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO);
|
||||
if (Channel != 0xFFFF)
|
||||
gSubMenuSelection = Channel;
|
||||
|
||||
gRequestDisplayScreen = DISPLAY_MENU;
|
||||
}
|
||||
}
|
||||
|
||||
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
|
||||
+3
-3
@@ -121,7 +121,7 @@ uint16_t statuslineUpdateTimer = 0;
|
||||
static void LoadSettings()
|
||||
{
|
||||
uint8_t Data[8] = {0};
|
||||
PY25Q16_ReadBuffer(0x00c000, Data, sizeof(Data));
|
||||
PY25Q16_ReadBuffer(0x00A158, Data, sizeof(Data));
|
||||
|
||||
settings.scanStepIndex = ((Data[3] & 0xF0) >> 4);
|
||||
|
||||
@@ -148,11 +148,11 @@ static void LoadSettings()
|
||||
static void SaveSettings()
|
||||
{
|
||||
uint8_t Data[8] = {0};
|
||||
PY25Q16_ReadBuffer(0x00c000, Data, sizeof(Data));
|
||||
PY25Q16_ReadBuffer(0x00A158, Data, sizeof(Data));
|
||||
|
||||
Data[3] = (settings.scanStepIndex << 4) | (settings.stepsCount << 2) | settings.listenBw;
|
||||
|
||||
PY25Q16_WriteBuffer(0x00c000, Data, sizeof(Data), true);
|
||||
PY25Q16_WriteBuffer(0x00A158, Data, sizeof(Data), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
-103
@@ -199,109 +199,6 @@ const uint8_t BITMAP_VFO_NotDefault[7] =
|
||||
0b00001000
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanList0[7] =
|
||||
{ // '0' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01000011,
|
||||
0b01011101,
|
||||
0b01100001,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanList1[7] =
|
||||
{ // '1' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111011,
|
||||
0b01000001,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanList2[7] =
|
||||
{ // '2' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01001101,
|
||||
0b01010101,
|
||||
0b01011011,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanList3[7] =
|
||||
{ // '3' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01011101,
|
||||
0b01010101,
|
||||
0b01101011,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanListE[7] =
|
||||
{ // 'E' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01000001,
|
||||
0b01010101,
|
||||
0b01010101,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanList123[19] =
|
||||
{
|
||||
// '123' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111011,
|
||||
0b01000001,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01001101,
|
||||
0b01010101,
|
||||
0b01011011,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01011101,
|
||||
0b01010101,
|
||||
0b01101011,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_ScanListAll[19] =
|
||||
{
|
||||
// 'All' symbol
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01000011,
|
||||
0b01110101,
|
||||
0b01000011,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01000001,
|
||||
0b01011111,
|
||||
0b01011111,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01111111,
|
||||
0b01000001,
|
||||
0b01011111,
|
||||
0b01011111,
|
||||
0b01111111,
|
||||
0b01111111
|
||||
};
|
||||
|
||||
const uint8_t BITMAP_compand[6] =
|
||||
{
|
||||
0b00000000,
|
||||
|
||||
@@ -39,13 +39,6 @@ extern const uint8_t BITMAP_Antenna[5];
|
||||
extern const uint8_t BITMAP_VFO_Default[7];
|
||||
extern const uint8_t BITMAP_VFO_NotDefault[7];
|
||||
extern const uint8_t BITMAP_VFO_Lock[7];
|
||||
extern const uint8_t BITMAP_ScanList0[7];
|
||||
extern const uint8_t BITMAP_ScanList1[7];
|
||||
extern const uint8_t BITMAP_ScanList2[7];
|
||||
extern const uint8_t BITMAP_ScanList3[7];
|
||||
extern const uint8_t BITMAP_ScanList123[19];
|
||||
extern const uint8_t BITMAP_ScanListAll[19];
|
||||
extern const uint8_t BITMAP_ScanListE[7];
|
||||
extern const uint8_t BITMAP_PowerUser[3];
|
||||
extern const uint8_t BITMAP_compand[6];
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "misc.h"
|
||||
#endif
|
||||
|
||||
#define PWM_FREQ 240
|
||||
#define PWM_FREQ 320
|
||||
#define DUTY_CYCLE_LEVELS 64
|
||||
|
||||
#define DUTY_CYCLE_ON_VALUE GPIO_PIN_MASK(GPIO_PIN_BACKLIGHT)
|
||||
|
||||
+26
-23
@@ -38,29 +38,32 @@ typedef struct
|
||||
#define _MK_MAPPING(PY25Q16_Addr, EEPROM_From, EEPROM_To) {PY25Q16_Addr, EEPROM_From, EEPROM_To - EEPROM_From}
|
||||
|
||||
static const AddrMapping_t ADDR_MAPPINGS[] = {
|
||||
// Sorted by EEPROM addr
|
||||
_MK_MAPPING(0x000000, 0x0000, 0x0c80), //
|
||||
_MK_MAPPING(0x001000, 0x0c80, 0x0d60), //
|
||||
_MK_MAPPING(0x002000, 0x0d60, 0x0e30), //
|
||||
_MK_MAPPING(HOLE_ADDR, 0x0e30, 0x0e70), //
|
||||
_MK_MAPPING(0x004000, 0x0e70, 0x0e80), //
|
||||
_MK_MAPPING(0x005000, 0x0e80, 0x0e88), //
|
||||
_MK_MAPPING(0x006000, 0x0e88, 0x0e90), //
|
||||
_MK_MAPPING(0x007000, 0x0e90, 0x0ee0), //
|
||||
_MK_MAPPING(0x008000, 0x0ee0, 0x0f18), //
|
||||
_MK_MAPPING(0x009000, 0x0f18, 0x0f20), //
|
||||
_MK_MAPPING(HOLE_ADDR, 0x0f20, 0x0f30), //
|
||||
_MK_MAPPING(0x00a000, 0x0f30, 0x0f40), //
|
||||
_MK_MAPPING(0x00b000, 0x0f40, 0x0f48), //
|
||||
_MK_MAPPING(HOLE_ADDR, 0x0f48, 0x0f50), //
|
||||
_MK_MAPPING(0x00e000, 0x0f50, 0x1bd0), //
|
||||
_MK_MAPPING(HOLE_ADDR, 0x1bd0, 0x1c00), //
|
||||
_MK_MAPPING(0x00f000, 0x1c00, 0x1d00), //
|
||||
_MK_MAPPING(HOLE_ADDR, 0x1d00, 0x1e00), //
|
||||
_MK_MAPPING(0x010000, 0x1e00, 0x1f90), //
|
||||
_MK_MAPPING(HOLE_ADDR, 0x1f90, 0x1ff0), //
|
||||
_MK_MAPPING(0x00c000, 0x1ff0, 0x2000), //
|
||||
_MK_MAPPING(0x003000, 0x2000, 0x2080), //
|
||||
_MK_MAPPING(0x000000, 0x000000, 0x001000), // 256 MR Freq * 16 Bytes (ex 0x000000)
|
||||
_MK_MAPPING(0x001000, 0x001000, 0x002000), // 256 MR Freq * 16 Bytes
|
||||
_MK_MAPPING(0x002000, 0x002000, 0x003000), // 256 MR Freq * 16 Bytes
|
||||
_MK_MAPPING(0x003000, 0x003000, 0x004000), // 256 MR Freq * 16 Bytes
|
||||
|
||||
_MK_MAPPING(0x004000, 0x004000, 0x005000), // 256 MR Name * 16 Bytes (ex 0x00e000)
|
||||
_MK_MAPPING(0x005000, 0x005000, 0x006000), // 256 MR Name * 16 Bytes
|
||||
_MK_MAPPING(0x006000, 0x006000, 0x007000), // 256 MR Name * 16 Bytes
|
||||
_MK_MAPPING(0x007000, 0x007000, 0x008000), // 256 MR Name * 16 Bytes
|
||||
|
||||
_MK_MAPPING(0x008000, 0x008000, 0x00880E), // 1024 MR + 7 VFO Attributes * 2 Bytes (ex 0x002000)
|
||||
|
||||
_MK_MAPPING(0x009000, 0x009000, 0x0090D6), // 14 VFO * 16 Bytes (ex 0x001000)
|
||||
|
||||
_MK_MAPPING(0x00A000, 0x00A000, 0x00A160), // Settings * 16 Bytes (ex 0x004000) 0x00A000 -> 0x00A010
|
||||
// Settings * 16 Bytes (ex 0x005000) 0x00A010 -> 0x00A020
|
||||
// Settings FM * 8 Bytes (0x006000) 0x00A020 -> 0x00A028
|
||||
// MR FM * 128 Bytes (0x003000) 0x00A028 -> 0x00A0A8
|
||||
// Settings * 80 Bytes (0x007000) 0x00A0A8 -> 0x00A0F8
|
||||
// Settings * 56 Bytes (0x008000) 0x00A0F8 -> 0x00A130
|
||||
// Settings Scanlist * 8 Bytes (0x009000) 0x00A130 -> 0x00A140
|
||||
// Settings AES * 16 Bytes (0x00A000) 0x00A140 -> 0x00A150
|
||||
// Settings * 8 Bytes (0x00B000) 0x00A150 -> 0x00A158
|
||||
// Settings F4HWN * 8 Bytes (0x00C000) 0x00A158 -> 0x00A160
|
||||
|
||||
_MK_MAPPING(0x010000, 0x00B000, 0x00B200), // Calibration 512 Bytes!!!
|
||||
};
|
||||
|
||||
static void AddrTranslate(uint16_t EEPROM_Addr, uint16_t Size, uint32_t *PY25Q16_Addr_out, uint16_t *Size_out, bool *End_out);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define _1GHz_in_KHz 100000000
|
||||
#define DEFAULT_FREQ 43450000 // Use for Reset and Aircopy
|
||||
|
||||
typedef struct {
|
||||
const uint32_t lower;
|
||||
|
||||
+4
-2
@@ -61,8 +61,10 @@ BOOT_Mode_t BOOT_GetMode(void)
|
||||
return BOOT_MODE_F_LOCK;
|
||||
|
||||
#ifdef ENABLE_AIRCOPY
|
||||
if (Keys[0] == KEY_SIDE2)
|
||||
if (Keys[0] == KEY_SIDE2) {
|
||||
gAirCopyBootMode = true;
|
||||
return BOOT_MODE_AIRCOPY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
|
||||
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
||||
gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
||||
|
||||
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 43400000); // LPD
|
||||
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, DEFAULT_FREQ); // LPD
|
||||
|
||||
gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW;
|
||||
gRxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1;
|
||||
|
||||
+3
-10
@@ -157,18 +157,11 @@ void Main(void)
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
gEeprom.KEY_LOCK = 0;
|
||||
SETTINGS_SaveSettings();
|
||||
#ifndef ENABLE_VOX
|
||||
gMenuCursor = 67; // move to hidden section, fix me if change... !!! Remove VOX and Mic Bar
|
||||
#else
|
||||
gMenuCursor = 68; // move to hidden section, fix me if change... !!!
|
||||
#endif
|
||||
|
||||
gMenuCursor = MENU_ITEMS;
|
||||
|
||||
#ifdef ENABLE_NOAA
|
||||
gMenuCursor += 1; // move to hidden section, fix me if change... !!!
|
||||
#endif
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
gMenuCursor += 1; // move to hidden section, fix me if change... !!!
|
||||
#endif
|
||||
gSubMenuSelection = gSetting_F_LOCK;
|
||||
#endif
|
||||
}
|
||||
@@ -262,7 +255,7 @@ void Main(void)
|
||||
|
||||
#ifdef ENABLE_VOICE
|
||||
{
|
||||
uint8_t Channel;
|
||||
uint16_t Channel;
|
||||
|
||||
AUDIO_SetVoiceID(0, VOICE_ID_WELCOME);
|
||||
|
||||
|
||||
+6
-5
@@ -131,7 +131,7 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
|
||||
bool gSetting_set_tmr = 0;
|
||||
bool gSetting_set_ptt_session;
|
||||
#ifdef ENABLE_FEAT_F4HWN_DEBUG
|
||||
uint8_t gDebug;
|
||||
uint16_t gDebug;
|
||||
#endif
|
||||
uint8_t gDW = 0;
|
||||
uint8_t gCB = 0;
|
||||
@@ -139,6 +139,8 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
|
||||
uint8_t crc[15] = { 0 };
|
||||
uint8_t lErrorsDuringAirCopy = 0;
|
||||
uint8_t gAircopyStep = 0;
|
||||
uint8_t gAircopyCurrentMapIndex = 0;
|
||||
bool gAirCopyBootMode = 0;
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
bool gPowerHigh = false;
|
||||
bool gRemoveOffset = false;
|
||||
@@ -164,7 +166,6 @@ uint16_t gEEPROM_1F8A;
|
||||
uint16_t gEEPROM_1F8C;
|
||||
|
||||
ChannelAttributes_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
|
||||
bool gMR_ChannelExclude[FREQ_CHANNEL_LAST + 1];
|
||||
|
||||
volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;
|
||||
|
||||
@@ -234,7 +235,7 @@ bool gFlagReconfigureVfos;
|
||||
uint8_t gVfoConfigureMode;
|
||||
bool gFlagResetVfos;
|
||||
bool gRequestSaveVFO;
|
||||
uint8_t gRequestSaveChannel;
|
||||
uint16_t gRequestSaveChannel;
|
||||
bool gRequestSaveSettings;
|
||||
#ifdef ENABLE_FMRADIO
|
||||
bool gRequestSaveFM;
|
||||
@@ -262,7 +263,7 @@ bool g_SquelchLost;
|
||||
volatile uint16_t gFlashLightBlinkCounter;
|
||||
|
||||
bool gFlagEndTransmission;
|
||||
uint8_t gNextMrChannel;
|
||||
uint16_t gNextMrChannel;
|
||||
ReceptionMode_t gRxReceptionMode;
|
||||
|
||||
bool gRxVfoIsActive;
|
||||
@@ -280,7 +281,7 @@ uint8_t gFSKWriteIndex;
|
||||
|
||||
#ifdef ENABLE_NOAA
|
||||
bool gIsNoaaMode;
|
||||
uint8_t gNoaaChannel;
|
||||
uint16_t gNoaaChannel;
|
||||
#endif
|
||||
|
||||
bool gUpdateDisplay;
|
||||
|
||||
+24
-18
@@ -36,20 +36,24 @@
|
||||
#define SWAP(a, b) ({ __typeof__ (a) _c = (a); a = b; b = _c; })
|
||||
#endif
|
||||
|
||||
#define FM_CHANNELS_MAX 64
|
||||
#define FM_CHANNELS_MAX 48
|
||||
#define MR_CHANNELS_MAX 768
|
||||
#define MR_CHANNELS_LIST 9
|
||||
#define MENU_ITEMS 67
|
||||
|
||||
#define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
|
||||
|
||||
#define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST)
|
||||
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
|
||||
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
|
||||
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
|
||||
|
||||
enum {
|
||||
MR_CHANNEL_FIRST = 0,
|
||||
MR_CHANNEL_LAST = 199u,
|
||||
FREQ_CHANNEL_FIRST = 200u,
|
||||
FREQ_CHANNEL_LAST = 206u,
|
||||
NOAA_CHANNEL_FIRST = 207u,
|
||||
NOAA_CHANNEL_LAST = 216u,
|
||||
MR_CHANNEL_LAST = MR_CHANNELS_MAX - 1,
|
||||
FREQ_CHANNEL_FIRST = MR_CHANNELS_MAX,
|
||||
FREQ_CHANNEL_LAST = MR_CHANNELS_MAX + 6,
|
||||
NOAA_CHANNEL_FIRST = MR_CHANNELS_MAX + 7,
|
||||
NOAA_CHANNEL_LAST = MR_CHANNELS_MAX + 16,
|
||||
LAST_CHANNEL
|
||||
};
|
||||
|
||||
@@ -186,7 +190,7 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
|
||||
extern bool gSetting_set_tmr;
|
||||
extern bool gSetting_set_ptt_session;
|
||||
#ifdef ENABLE_FEAT_F4HWN_DEBUG
|
||||
extern uint8_t gDebug;
|
||||
extern uint16_t gDebug;
|
||||
#endif
|
||||
extern uint8_t gDW;
|
||||
extern uint8_t gCB;
|
||||
@@ -194,6 +198,8 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
|
||||
extern uint8_t crc[15];
|
||||
extern uint8_t lErrorsDuringAirCopy;
|
||||
extern uint8_t gAircopyStep;
|
||||
extern uint8_t gAircopyCurrentMapIndex;
|
||||
extern bool gAirCopyBootMode;
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
extern bool gPowerHigh;
|
||||
extern bool gRemoveOffset;
|
||||
@@ -221,18 +227,18 @@ extern uint16_t gEEPROM_1F8C;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t
|
||||
band : 3,
|
||||
uint16_t
|
||||
band : 3,
|
||||
compander : 2,
|
||||
scanlist1 : 1,
|
||||
scanlist2 : 1,
|
||||
scanlist3 : 1;
|
||||
unused_1 : 1,
|
||||
unused_2 : 1,
|
||||
exclude : 1,
|
||||
scanlist : 8;
|
||||
};
|
||||
uint8_t __val;
|
||||
uint16_t __val;
|
||||
} ChannelAttributes_t;
|
||||
|
||||
extern ChannelAttributes_t gMR_ChannelAttributes[207];
|
||||
extern bool gMR_ChannelExclude[207];
|
||||
extern ChannelAttributes_t gMR_ChannelAttributes[MR_CHANNELS_MAX + 7];
|
||||
|
||||
extern volatile uint16_t gBatterySaveCountdown_10ms;
|
||||
|
||||
@@ -307,7 +313,7 @@ extern bool gFlagReconfigureVfos;
|
||||
extern uint8_t gVfoConfigureMode;
|
||||
extern bool gFlagResetVfos;
|
||||
extern bool gRequestSaveVFO;
|
||||
extern uint8_t gRequestSaveChannel;
|
||||
extern uint16_t gRequestSaveChannel;
|
||||
extern bool gRequestSaveSettings;
|
||||
#ifdef ENABLE_FMRADIO
|
||||
extern bool gRequestSaveFM;
|
||||
@@ -338,7 +344,7 @@ extern bool g_SquelchLost;
|
||||
extern volatile uint16_t gFlashLightBlinkCounter;
|
||||
|
||||
extern bool gFlagEndTransmission;
|
||||
extern uint8_t gNextMrChannel;
|
||||
extern uint16_t gNextMrChannel;
|
||||
extern ReceptionMode_t gRxReceptionMode;
|
||||
|
||||
//TRUE when dual watch is momentarly suspended and RX_VFO is locked to either last TX or RX
|
||||
|
||||
+21
-57
@@ -61,43 +61,17 @@ bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanL
|
||||
|
||||
const ChannelAttributes_t att = gMR_ChannelAttributes[channel];
|
||||
|
||||
if (checkScanList && gMR_ChannelExclude[channel] == true)
|
||||
if (checkScanList && att.exclude == true)
|
||||
return false;
|
||||
|
||||
if (att.band > BAND7_470MHz)
|
||||
return false;
|
||||
|
||||
if (!checkScanList || scanList > 4)
|
||||
//if (!checkScanList || scanList > 4)
|
||||
if (!checkScanList || scanList > MR_CHANNELS_LIST)
|
||||
return true;
|
||||
|
||||
/*
|
||||
if(scanList == 0 && (att.scanlist1 == 1 || att.scanlist2 == 1 || att.scanlist3 == 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(scanList == 1 && att.scanlist1 != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(scanList == 2 && att.scanlist2 != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(scanList == 3 && att.scanlist3 != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(scanList == 4 && (att.scanlist1 == 0 && att.scanlist2 == 0 && att.scanlist3 == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
if ((scanList == 0 && (att.scanlist1 == 1 || att.scanlist2 == 1 || att.scanlist3 == 1)) ||
|
||||
(scanList == 1 && att.scanlist1 != 1) ||
|
||||
(scanList == 2 && att.scanlist2 != 1) ||
|
||||
(scanList == 3 && att.scanlist3 != 1) ||
|
||||
(scanList == 4 && (att.scanlist1 == 0 && att.scanlist2 == 0 && att.scanlist3 == 0))) {
|
||||
if ((scanList == 0) || (scanList != att.scanlist)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,16 +79,16 @@ bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanL
|
||||
|
||||
// I don't understand what this code is for...
|
||||
|
||||
const uint8_t PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[scanList - 1];
|
||||
const uint8_t PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[scanList - 1];
|
||||
const uint16_t PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH[0];
|
||||
const uint16_t PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH[1];
|
||||
|
||||
return PriorityCh1 != channel && PriorityCh2 != channel;
|
||||
}
|
||||
|
||||
uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO)
|
||||
uint16_t RADIO_FindNextChannel(uint16_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO)
|
||||
{
|
||||
for (unsigned int i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) {
|
||||
if (Channel == 0xFF) {
|
||||
for (uint16_t i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) {
|
||||
if (Channel == 0xFFFF) {
|
||||
Channel = MR_CHANNEL_LAST;
|
||||
} else if (!IS_MR_CHANNEL(Channel)) {
|
||||
Channel = MR_CHANNEL_FIRST;
|
||||
@@ -125,17 +99,15 @@ uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScan
|
||||
}
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency)
|
||||
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint16_t ChannelSave, const uint32_t Frequency)
|
||||
{
|
||||
memset(pInfo, 0, sizeof(*pInfo));
|
||||
|
||||
pInfo->Band = FREQUENCY_GetBand(Frequency);
|
||||
pInfo->SCANLIST1_PARTICIPATION = false;
|
||||
pInfo->SCANLIST2_PARTICIPATION = false;
|
||||
pInfo->SCANLIST3_PARTICIPATION = false;
|
||||
pInfo->SCANLIST_PARTICIPATION = 0;
|
||||
pInfo->STEP_SETTING = STEP_12_5kHz;
|
||||
pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING];
|
||||
pInfo->CHANNEL_SAVE = ChannelSave;
|
||||
@@ -168,7 +140,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
|
||||
gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
||||
}
|
||||
|
||||
uint8_t channel = gEeprom.ScreenChannel[VFO];
|
||||
uint16_t channel = gEeprom.ScreenChannel[VFO];
|
||||
|
||||
if (IS_VALID_CHANNEL(channel)) {
|
||||
#ifdef ENABLE_NOAA
|
||||
@@ -188,7 +160,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
|
||||
|
||||
if (IS_MR_CHANNEL(channel)) {
|
||||
channel = RADIO_FindNextChannel(channel, RADIO_CHANNEL_UP, false, VFO);
|
||||
if (channel == 0xFF) {
|
||||
if (channel == 0xFFFF) {
|
||||
channel = gEeprom.FreqChannel[VFO];
|
||||
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
|
||||
}
|
||||
@@ -202,13 +174,13 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
|
||||
channel = FREQ_CHANNEL_LAST - 1;
|
||||
|
||||
ChannelAttributes_t att = gMR_ChannelAttributes[channel];
|
||||
if (att.__val == 0xFF) { // invalid/unused channel
|
||||
if (att.__val == 0xFFFF) { // invalid/unused channel
|
||||
if (IS_MR_CHANNEL(channel)) {
|
||||
channel = gEeprom.FreqChannel[VFO];
|
||||
gEeprom.ScreenChannel[VFO] = channel;
|
||||
}
|
||||
|
||||
uint8_t bandIdx = channel - FREQ_CHANNEL_FIRST;
|
||||
uint16_t bandIdx = channel - FREQ_CHANNEL_FIRST;
|
||||
RADIO_InitInfo(pVfo, channel, frequencyBandTable[bandIdx].lower);
|
||||
return;
|
||||
}
|
||||
@@ -218,33 +190,25 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
|
||||
band = BAND6_400MHz;
|
||||
}
|
||||
|
||||
bool bParticipation1;
|
||||
bool bParticipation2;
|
||||
bool bParticipation3;
|
||||
uint8_t bParticipation;
|
||||
|
||||
if (IS_MR_CHANNEL(channel)) {
|
||||
bParticipation1 = att.scanlist1;
|
||||
bParticipation2 = att.scanlist2;
|
||||
bParticipation3 = att.scanlist3;
|
||||
bParticipation = att.scanlist;
|
||||
}
|
||||
else {
|
||||
band = channel - FREQ_CHANNEL_FIRST;
|
||||
bParticipation1 = true;
|
||||
bParticipation2 = true;
|
||||
bParticipation3 = true;
|
||||
bParticipation = MR_CHANNELS_LIST + 1;
|
||||
}
|
||||
|
||||
pVfo->Band = band;
|
||||
pVfo->SCANLIST1_PARTICIPATION = bParticipation1;
|
||||
pVfo->SCANLIST2_PARTICIPATION = bParticipation2;
|
||||
pVfo->SCANLIST3_PARTICIPATION = bParticipation3;
|
||||
pVfo->SCANLIST_PARTICIPATION = bParticipation;
|
||||
pVfo->CHANNEL_SAVE = channel;
|
||||
|
||||
uint32_t base;
|
||||
if (IS_MR_CHANNEL(channel))
|
||||
base = channel * 16;
|
||||
else
|
||||
base = 0x001000 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
|
||||
base = 0x009000 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
|
||||
|
||||
if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel))
|
||||
{
|
||||
|
||||
+5
-7
@@ -95,7 +95,7 @@ typedef struct VFO_Info_t
|
||||
uint32_t TX_OFFSET_FREQUENCY;
|
||||
uint16_t StepFrequency;
|
||||
|
||||
uint8_t CHANNEL_SAVE;
|
||||
uint16_t CHANNEL_SAVE;
|
||||
|
||||
uint8_t TX_OFFSET_FREQUENCY_DIRECTION;
|
||||
|
||||
@@ -115,11 +115,9 @@ typedef struct VFO_Info_t
|
||||
uint8_t SCRAMBLING_TYPE;
|
||||
uint8_t CHANNEL_BANDWIDTH;
|
||||
|
||||
uint8_t SCANLIST1_PARTICIPATION;
|
||||
uint8_t SCANLIST2_PARTICIPATION;
|
||||
uint8_t SCANLIST3_PARTICIPATION;
|
||||
uint8_t SCANLIST_PARTICIPATION;
|
||||
|
||||
uint8_t Band;
|
||||
uint16_t Band;
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
uint8_t DTMF_DECODING_ENABLE;
|
||||
#endif
|
||||
@@ -151,8 +149,8 @@ extern DCS_CodeType_t gCurrentCodeType;
|
||||
extern VfoState_t VfoState[2];
|
||||
|
||||
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList);
|
||||
uint8_t RADIO_FindNextChannel(uint8_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
|
||||
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency);
|
||||
uint16_t RADIO_FindNextChannel(uint16_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
|
||||
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint16_t ChannelSave, const uint32_t Frequency);
|
||||
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure);
|
||||
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
|
||||
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
|
||||
|
||||
+47
-21
@@ -18,16 +18,20 @@
|
||||
#include "driver/st7565.h"
|
||||
#include "screenshot.h"
|
||||
#include "misc.h"
|
||||
#include <string.h>
|
||||
|
||||
// RAM optimization: Only keep previousFrame static (1024 bytes)
|
||||
// Build currentFrame on-the-fly and send delta blocks immediately
|
||||
// SRAM optimization: minimize static allocations
|
||||
// - previousFrame: 1024 bytes (REQUIRED - need to compare for delta)
|
||||
// - No currentFrame or deltaFrame static buffers
|
||||
static uint8_t previousFrame[1024] = {0};
|
||||
static uint8_t forcedBlock = 0;
|
||||
static uint8_t keepAlive = 10;
|
||||
|
||||
void getScreenShot(bool force)
|
||||
{
|
||||
static uint8_t currentFrame[1024]; // Reused static buffer
|
||||
// Build frame in a temporary stack buffer
|
||||
// This is 1024 bytes but it's temporary and gets freed after the function
|
||||
uint8_t frameBuffer[1024];
|
||||
uint16_t index = 0;
|
||||
uint8_t acc = 0;
|
||||
uint8_t bitCount = 0;
|
||||
@@ -47,14 +51,14 @@ void getScreenShot(bool force)
|
||||
return;
|
||||
}
|
||||
|
||||
// ==== Build currentFrame (exact same logic as original) ====
|
||||
// ==== BUILD FRAME ONCE ====
|
||||
// Status line: 8 bit layers × 128 columns
|
||||
for (uint8_t b = 0; b < 8; b++) {
|
||||
for (uint8_t i = 0; i < 128; i++) {
|
||||
uint8_t bit = (gStatusLine[i] >> b) & 0x01;
|
||||
acc |= (bit << bitCount++);
|
||||
if (bitCount == 8) {
|
||||
currentFrame[index++] = acc;
|
||||
frameBuffer[index++] = acc;
|
||||
acc = 0;
|
||||
bitCount = 0;
|
||||
}
|
||||
@@ -68,7 +72,7 @@ void getScreenShot(bool force)
|
||||
uint8_t bit = (gFrameBuffer[l][i] >> b) & 0x01;
|
||||
acc |= (bit << bitCount++);
|
||||
if (bitCount == 8) {
|
||||
currentFrame[index++] = acc;
|
||||
frameBuffer[index++] = acc;
|
||||
acc = 0;
|
||||
bitCount = 0;
|
||||
}
|
||||
@@ -77,37 +81,42 @@ void getScreenShot(bool force)
|
||||
}
|
||||
|
||||
if (bitCount > 0)
|
||||
currentFrame[index++] = acc;
|
||||
frameBuffer[index++] = acc;
|
||||
|
||||
if (index != 1024)
|
||||
return; // Frame size mismatch, abort
|
||||
return;
|
||||
|
||||
// ==== Generate delta frame ====
|
||||
// ==== FIRST PASS: Count changed chunks ====
|
||||
uint16_t deltaLen = 0;
|
||||
uint8_t deltaFrame[128 * 9]; // Worst case: all 128 blocks changed
|
||||
uint8_t changedChunks[128]; // List of changed chunk indices
|
||||
uint8_t changedCount = 0;
|
||||
|
||||
for (uint8_t block = 0; block < 128; block++) {
|
||||
uint8_t *cur = ¤tFrame[block * 8];
|
||||
uint8_t *prev = &previousFrame[block * 8];
|
||||
for (uint8_t chunk = 0; chunk < 128; chunk++) {
|
||||
uint8_t *cur = &frameBuffer[chunk * 8];
|
||||
uint8_t *prev = &previousFrame[chunk * 8];
|
||||
|
||||
bool changed = memcmp(cur, prev, 8) != 0;
|
||||
bool isForced = (block == forcedBlock);
|
||||
bool isForced = (chunk == forcedBlock);
|
||||
bool fullUpdate = force;
|
||||
|
||||
if (changed || isForced || fullUpdate) {
|
||||
deltaFrame[deltaLen++] = block;
|
||||
memcpy(&deltaFrame[deltaLen], cur, 8);
|
||||
deltaLen += 8;
|
||||
memcpy(prev, cur, 8); // Update stored frame
|
||||
changedChunks[changedCount++] = chunk;
|
||||
deltaLen += 9;
|
||||
}
|
||||
}
|
||||
|
||||
forcedBlock = (forcedBlock + 1) % 128;
|
||||
|
||||
if (deltaLen == 0)
|
||||
return; // No update needed
|
||||
return;
|
||||
|
||||
// ==== Send frame ====
|
||||
// ==== Send version marker (for backward compatibility detection) ====
|
||||
// New format: sends 0xFF before header
|
||||
// Old format: doesn't exist, so viewers can differentiate
|
||||
uint8_t versionMarker = 0xFF;
|
||||
UART_Send(&versionMarker, 1);
|
||||
|
||||
// ==== Send header ====
|
||||
uint8_t header[5] = {
|
||||
0xAA, 0x55, 0x02,
|
||||
(uint8_t)(deltaLen >> 8),
|
||||
@@ -115,7 +124,24 @@ void getScreenShot(bool force)
|
||||
};
|
||||
|
||||
UART_Send(header, 5);
|
||||
UART_Send(deltaFrame, deltaLen);
|
||||
|
||||
// ==== SECOND PASS: Send only changed chunks ====
|
||||
uint8_t chunk[9];
|
||||
|
||||
for (uint8_t i = 0; i < changedCount; i++) {
|
||||
uint8_t chunkIdx = changedChunks[i];
|
||||
uint8_t *cur = &frameBuffer[chunkIdx * 8];
|
||||
uint8_t *prev = &previousFrame[chunkIdx * 8];
|
||||
|
||||
chunk[0] = chunkIdx;
|
||||
memcpy(&chunk[1], cur, 8);
|
||||
|
||||
UART_Send(chunk, 9);
|
||||
|
||||
// Update previousFrame for next comparison
|
||||
memcpy(prev, cur, 8);
|
||||
}
|
||||
|
||||
uint8_t end = 0x0A;
|
||||
UART_Send(&end, 1);
|
||||
}
|
||||
+194
-200
@@ -28,23 +28,13 @@
|
||||
#include "settings.h"
|
||||
#include "ui/menu.h"
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL
|
||||
static const uint32_t gDefaultFrequencyTable[] =
|
||||
{
|
||||
14550000, //
|
||||
43350000, //
|
||||
44608125, //
|
||||
12150000, //
|
||||
};
|
||||
#endif
|
||||
|
||||
EEPROM_Config_t gEeprom = { 0 };
|
||||
|
||||
void SETTINGS_InitEEPROM(void)
|
||||
{
|
||||
uint8_t Data[16] = {0};
|
||||
// 0E70..0E77
|
||||
PY25Q16_ReadBuffer(0x004000, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A000, Data, 8);
|
||||
gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST;
|
||||
gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1;
|
||||
gEeprom.TX_TIMEOUT_TIMER = (Data[2] > 4 && Data[2] < 180) ? Data[2] : 11;
|
||||
@@ -65,7 +55,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4;
|
||||
|
||||
// 0E78..0E7F
|
||||
PY25Q16_ReadBuffer(0x004008, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A008, Data, 8);
|
||||
gEeprom.BACKLIGHT_MAX = (Data[0] & 0xF) <= 10 ? (Data[0] & 0xF) : 10;
|
||||
gEeprom.BACKLIGHT_MIN = (Data[0] >> 4) < gEeprom.BACKLIGHT_MAX ? (Data[0] >> 4) : 0;
|
||||
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||
@@ -86,13 +76,14 @@ void SETTINGS_InitEEPROM(void)
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
gEeprom.VFO_OPEN = Data[7] & 0x01;
|
||||
gEeprom.CURRENT_STATE = (Data[7] >> 1) & 0x07;
|
||||
gEeprom.CURRENT_LIST = (Data[7] >> 4) & 0x07;
|
||||
gEeprom.CURRENT_LIST = (Data[7] >> 4) & 0x0F;
|
||||
#else
|
||||
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
|
||||
#endif
|
||||
|
||||
// 0E80..0E87
|
||||
PY25Q16_ReadBuffer(0x005000, Data, 8);
|
||||
/*
|
||||
PY25Q16_ReadBuffer(0x00A010, Data, 8);
|
||||
gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data[0]) ? Data[0] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||
gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data[3]) ? Data[3] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||
gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data[1]) ? Data[1] : MR_CHANNEL_FIRST;
|
||||
@@ -103,6 +94,24 @@ void SETTINGS_InitEEPROM(void)
|
||||
gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data[6]) ? Data[6] : NOAA_CHANNEL_FIRST;
|
||||
gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data[7]) ? Data[7] : NOAA_CHANNEL_FIRST;
|
||||
#endif
|
||||
*/
|
||||
|
||||
// 0x00A010 .. 0x00A01F
|
||||
uint16_t Data16[8];
|
||||
|
||||
PY25Q16_ReadBuffer(0x00A010, Data16, sizeof(Data16));
|
||||
|
||||
gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data16[0]) ? Data16[0] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||
gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data16[1]) ? Data16[1] : MR_CHANNEL_FIRST;
|
||||
gEeprom.FreqChannel[0] = IS_FREQ_CHANNEL(Data16[2]) ? Data16[2] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||
gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data16[3]) ? Data16[3] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||
gEeprom.MrChannel[1] = IS_MR_CHANNEL(Data16[4]) ? Data16[4] : MR_CHANNEL_FIRST;
|
||||
gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data16[5]) ? Data16[5] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||
|
||||
#ifdef ENABLE_NOAA
|
||||
gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data16[6]) ? Data16[6] : NOAA_CHANNEL_FIRST;
|
||||
gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data16[7]) ? Data16[7] : NOAA_CHANNEL_FIRST;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FMRADIO
|
||||
{ // 0E88..0E8F
|
||||
@@ -114,7 +123,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
uint8_t band:2;
|
||||
//uint8_t space:2;
|
||||
} __attribute__((packed)) fmCfg;
|
||||
PY25Q16_ReadBuffer(0x006000, &fmCfg, 4);
|
||||
PY25Q16_ReadBuffer(0x00A020, &fmCfg, 4);
|
||||
|
||||
gEeprom.FM_Band = fmCfg.band;
|
||||
//gEeprom.FM_Space = fmCfg.space;
|
||||
@@ -127,12 +136,12 @@ void SETTINGS_InitEEPROM(void)
|
||||
}
|
||||
|
||||
// 0E40..0E67
|
||||
PY25Q16_ReadBuffer(0x003000, gFM_Channels, sizeof(gFM_Channels));
|
||||
PY25Q16_ReadBuffer(0x00A028, gFM_Channels, sizeof(gFM_Channels));
|
||||
FM_ConfigureChannelState();
|
||||
#endif
|
||||
|
||||
// 0E90..0E97
|
||||
PY25Q16_ReadBuffer(0x007000, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A0A8, Data, 8);
|
||||
gEeprom.BEEP_CONTROL = Data[0] & 1;
|
||||
gEeprom.KEY_M_LONG_PRESS_ACTION = ((Data[0] >> 1) < ACTION_OPT_LEN) ? (Data[0] >> 1) : ACTION_OPT_NONE;
|
||||
gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR;
|
||||
@@ -149,12 +158,12 @@ void SETTINGS_InitEEPROM(void)
|
||||
|
||||
// 0E98..0E9F
|
||||
#ifdef ENABLE_PWRON_PASSWORD
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x8, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A0A8 + 0x8, Data, 8);
|
||||
memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4);
|
||||
#endif
|
||||
|
||||
// 0EA0..0EA7
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x10, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A0A8 + 0x10, Data, 8);
|
||||
#ifdef ENABLE_VOICE
|
||||
gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH;
|
||||
#endif
|
||||
@@ -170,7 +179,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
#endif
|
||||
|
||||
// 0EA8..0EAF
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x18, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A0A8 + 0x18, Data, 8);
|
||||
#ifdef ENABLE_ALARM
|
||||
gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true;
|
||||
#endif
|
||||
@@ -180,7 +189,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
gEeprom.BATTERY_TYPE = (Data[4] < BATTERY_TYPE_UNKNOWN) ? Data[4] : BATTERY_TYPE_1600_MAH;
|
||||
|
||||
// 0ED0..0ED7
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x40, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A0A8 + 0x40, Data, 8);
|
||||
gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true;
|
||||
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
@@ -194,7 +203,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100;
|
||||
|
||||
// 0ED8..0EDF
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x48, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A0A8 + 0x48, Data, 8);
|
||||
gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100;
|
||||
gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100;
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
@@ -202,7 +211,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
|
||||
// 0EE0..0EE7
|
||||
|
||||
PY25Q16_ReadBuffer(0x008000, Data, sizeof(gEeprom.ANI_DTMF_ID));
|
||||
PY25Q16_ReadBuffer(0x00A0F8, Data, sizeof(gEeprom.ANI_DTMF_ID));
|
||||
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.ANI_DTMF_ID))) {
|
||||
memcpy(gEeprom.ANI_DTMF_ID, Data, sizeof(gEeprom.ANI_DTMF_ID));
|
||||
} else {
|
||||
@@ -211,7 +220,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
|
||||
|
||||
// 0EE8..0EEF
|
||||
PY25Q16_ReadBuffer(0x008000 + 0x8, Data, sizeof(gEeprom.KILL_CODE));
|
||||
PY25Q16_ReadBuffer(0x00A0F8 + 0x8, Data, sizeof(gEeprom.KILL_CODE));
|
||||
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.KILL_CODE))) {
|
||||
memcpy(gEeprom.KILL_CODE, Data, sizeof(gEeprom.KILL_CODE));
|
||||
} else {
|
||||
@@ -219,7 +228,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
}
|
||||
|
||||
// 0EF0..0EF7
|
||||
PY25Q16_ReadBuffer(0x008000 + 0x10, Data, sizeof(gEeprom.REVIVE_CODE));
|
||||
PY25Q16_ReadBuffer(0x00A0F8 + 0x10, Data, sizeof(gEeprom.REVIVE_CODE));
|
||||
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.REVIVE_CODE))) {
|
||||
memcpy(gEeprom.REVIVE_CODE, Data, sizeof(gEeprom.REVIVE_CODE));
|
||||
} else {
|
||||
@@ -228,7 +237,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
#endif
|
||||
|
||||
// 0EF8..0F07
|
||||
PY25Q16_ReadBuffer(0x008000 + 0x18, Data, sizeof(gEeprom.DTMF_UP_CODE));
|
||||
PY25Q16_ReadBuffer(0x00A0F8 + 0x18, Data, sizeof(gEeprom.DTMF_UP_CODE));
|
||||
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_UP_CODE))) {
|
||||
memcpy(gEeprom.DTMF_UP_CODE, Data, sizeof(gEeprom.DTMF_UP_CODE));
|
||||
} else {
|
||||
@@ -236,7 +245,7 @@ void SETTINGS_InitEEPROM(void)
|
||||
}
|
||||
|
||||
// 0F08..0F17
|
||||
PY25Q16_ReadBuffer(0x008000 + 0x28, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
|
||||
PY25Q16_ReadBuffer(0x00A0F8 + 0x28, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
|
||||
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_DOWN_CODE))) {
|
||||
memcpy(gEeprom.DTMF_DOWN_CODE, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
|
||||
} else {
|
||||
@@ -244,8 +253,8 @@ void SETTINGS_InitEEPROM(void)
|
||||
}
|
||||
|
||||
// 0F18..0F1F
|
||||
PY25Q16_ReadBuffer(0x009000, Data, 8);
|
||||
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 6) ? Data[0] : 0; // we now have 'all' channel scan option
|
||||
PY25Q16_ReadBuffer(0x00A130, Data, 8);
|
||||
gEeprom.SCAN_LIST_DEFAULT = (Data[0] <= (MR_CHANNELS_LIST + 1)) ? Data[0] : 0; // we now have 'all' channel scan option
|
||||
|
||||
// Fake data
|
||||
/*
|
||||
@@ -253,14 +262,14 @@ void SETTINGS_InitEEPROM(void)
|
||||
gEeprom.SCAN_LIST_ENABLED[1] = 0;
|
||||
gEeprom.SCAN_LIST_ENABLED[2] = 0;
|
||||
|
||||
gEeprom.SCANLIST_PRIORITY_CH1[0] = 0;
|
||||
gEeprom.SCANLIST_PRIORITY_CH2[0] = 2;
|
||||
gEeprom.SCANLIST_PRIORITY_CH[0] = 0;
|
||||
gEeprom.SCANLIST_PRIORITY_CH[1] = 2;
|
||||
|
||||
gEeprom.SCANLIST_PRIORITY_CH1[1] = 14;
|
||||
gEeprom.SCANLIST_PRIORITY_CH2[1] = 15;
|
||||
gEeprom.SCANLIST_PRIORITY_CH[2] = 14;
|
||||
gEeprom.SCANLIST_PRIORITY_CH[3] = 15;
|
||||
|
||||
gEeprom.SCANLIST_PRIORITY_CH1[2] = 40;
|
||||
gEeprom.SCANLIST_PRIORITY_CH2[2] = 41;
|
||||
gEeprom.SCANLIST_PRIORITY_CH[4] = 40;
|
||||
gEeprom.SCANLIST_PRIORITY_CH[5] = 41;
|
||||
*/
|
||||
|
||||
// Fix me probably after Chirp update...
|
||||
@@ -269,15 +278,15 @@ void SETTINGS_InitEEPROM(void)
|
||||
gEeprom.SCAN_LIST_ENABLED[i] = (Data[1] >> i) & 1;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 3; i++)
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
const unsigned int j = 1 + (i * 2);
|
||||
gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1];
|
||||
gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2];
|
||||
gEeprom.SCANLIST_PRIORITY_CH[i] =
|
||||
(uint16_t)Data[2 + (i * 2)] |
|
||||
((uint16_t)Data[2 + (i * 2) + 1] << 8);
|
||||
}
|
||||
|
||||
// 0F40..0F47
|
||||
PY25Q16_ReadBuffer(0x00b000, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A150, Data, 8);
|
||||
gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF;
|
||||
#ifndef ENABLE_FEAT_F4HWN
|
||||
gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
|
||||
@@ -316,34 +325,40 @@ void SETTINGS_InitEEPROM(void)
|
||||
}
|
||||
|
||||
// 0D60..0E27
|
||||
PY25Q16_ReadBuffer(0x002000, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
|
||||
for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) {
|
||||
PY25Q16_ReadBuffer(0x008000, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
|
||||
uint16_t count = ARRAY_SIZE(gMR_ChannelAttributes);
|
||||
|
||||
for (uint16_t i = 0; i < count; i++) {
|
||||
ChannelAttributes_t *att = &gMR_ChannelAttributes[i];
|
||||
if(att->__val == 0xff){
|
||||
|
||||
if (att->__val == 0xFFFF) {
|
||||
att->__val = 0;
|
||||
att->band = 0x7;
|
||||
}
|
||||
gMR_ChannelExclude[i] = false;
|
||||
else
|
||||
{
|
||||
att->exclude = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 0F30..0F3F
|
||||
PY25Q16_ReadBuffer(0x00a000, gCustomAesKey, sizeof(gCustomAesKey));
|
||||
bHasCustomAesKey = false;
|
||||
#ifndef ENABLE_FEAT_F4HWN
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++)
|
||||
// 0F30..0F3F
|
||||
PY25Q16_ReadBuffer(0x00A138, gCustomAesKey, sizeof(gCustomAesKey));
|
||||
bHasCustomAesKey = false;
|
||||
#ifndef ENABLE_FEAT_F4HWN
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++)
|
||||
{
|
||||
if (gCustomAesKey[i] != 0xFFFFFFFFu)
|
||||
{
|
||||
if (gCustomAesKey[i] != 0xFFFFFFFFu)
|
||||
{
|
||||
bHasCustomAesKey = true;
|
||||
return;
|
||||
}
|
||||
bHasCustomAesKey = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
// 1FF0..0x1FF7
|
||||
// TODO: address TBD
|
||||
PY25Q16_ReadBuffer(0x00c000, Data, 8);
|
||||
PY25Q16_ReadBuffer(0x00A158, Data, 8);
|
||||
gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0;
|
||||
gSetting_set_ptt = (((Data[7] & 0x0F)) < 2) ? ((Data[7] & 0x0F)) : 0;
|
||||
|
||||
@@ -460,7 +475,7 @@ void SETTINGS_LoadCalibration(void)
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t SETTINGS_FetchChannelFrequency(const int channel)
|
||||
uint32_t SETTINGS_FetchChannelFrequency(const uint16_t channel)
|
||||
{
|
||||
struct
|
||||
{
|
||||
@@ -473,7 +488,7 @@ uint32_t SETTINGS_FetchChannelFrequency(const int channel)
|
||||
return info.frequency;
|
||||
}
|
||||
|
||||
void SETTINGS_FetchChannelName(char *s, const int channel)
|
||||
void SETTINGS_FetchChannelName(char *s, const uint16_t channel)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
@@ -487,7 +502,7 @@ void SETTINGS_FetchChannelName(char *s, const int channel)
|
||||
return;
|
||||
|
||||
// 0x0F50
|
||||
PY25Q16_ReadBuffer(0x00e000 + (channel * 16), s, 10);
|
||||
PY25Q16_ReadBuffer(0x004000 + (channel * 16), s, 10);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10; i++)
|
||||
@@ -502,92 +517,57 @@ void SETTINGS_FetchChannelName(char *s, const int channel)
|
||||
|
||||
void SETTINGS_FactoryReset(bool bIsAll)
|
||||
{
|
||||
// 0000 - 0c80
|
||||
PY25Q16_SectorErase(0);
|
||||
// 0c80 - 0d60
|
||||
PY25Q16_SectorErase(0x000000);
|
||||
PY25Q16_SectorErase(0x001000);
|
||||
PY25Q16_SectorErase(0x003000);
|
||||
PY25Q16_SectorErase(0x004000);
|
||||
PY25Q16_SectorErase(0x005000);
|
||||
PY25Q16_SectorErase(0x006000);
|
||||
PY25Q16_SectorErase(0x007000);
|
||||
PY25Q16_SectorErase(0x008000);
|
||||
PY25Q16_SectorErase(0x009000);
|
||||
|
||||
// 0d60 - 0e30
|
||||
if (bIsAll)
|
||||
{
|
||||
PY25Q16_SectorErase(0x002000);
|
||||
}
|
||||
// 0e40 - 0e68
|
||||
if (bIsAll)
|
||||
{
|
||||
PY25Q16_SectorErase(0x003000);
|
||||
}
|
||||
// 0e70 - 0e80
|
||||
PY25Q16_SectorErase(0x004000);
|
||||
// 0e80 - 0e88
|
||||
PY25Q16_SectorErase(0x005000);
|
||||
// 0e88 - 0e90
|
||||
if (bIsAll)
|
||||
{
|
||||
PY25Q16_SectorErase(0x006000);
|
||||
}
|
||||
// 0e90 - 0ee0
|
||||
do
|
||||
{
|
||||
uint8_t Buf[0x50];
|
||||
memset(Buf, 0xff, 0x50);
|
||||
// 0EA0 - 0EA8 : keep
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x10, Buf + 0x10, 8);
|
||||
// 0EB0 - 0ED0 : keep
|
||||
PY25Q16_ReadBuffer(0x007000 + 0x20, Buf + 0x20, 0x20);
|
||||
PY25Q16_WriteBuffer(0x007000, Buf, 0x50, true);
|
||||
} while (0);
|
||||
// 0ee0 - 0f18 : keep
|
||||
// 0f18 - 0f20
|
||||
if (bIsAll)
|
||||
{
|
||||
PY25Q16_SectorErase(0x009000);
|
||||
}
|
||||
// 0f30 - 0f40 : keep
|
||||
// 0f40 - 0f48 : keep
|
||||
// 0f50 - 1bd0
|
||||
if (bIsAll)
|
||||
{
|
||||
PY25Q16_SectorErase(0x00e000);
|
||||
}
|
||||
// 1c00 - 1d00 : keep
|
||||
|
||||
if (bIsAll)
|
||||
{
|
||||
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL
|
||||
// set the first few memory channels
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++)
|
||||
{
|
||||
const uint32_t Frequency = gDefaultFrequencyTable[i];
|
||||
gRxVfo->freq_config_RX.Frequency = Frequency;
|
||||
gRxVfo->freq_config_TX.Frequency = Frequency;
|
||||
gRxVfo->Band = FREQUENCY_GetBand(Frequency);
|
||||
SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
PY25Q16_SectorErase(0x00c000);
|
||||
#endif
|
||||
PY25Q16_SectorErase(0x00A000);
|
||||
}
|
||||
|
||||
// Prevent reset to restart in RO mode...
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
{
|
||||
uint8_t buf[0x10];
|
||||
// Bloc 0x0E70..0x0E7F -> offset 0x00A000
|
||||
uint8_t Data8[0x10];
|
||||
PY25Q16_ReadBuffer(0x00A000, Data8, sizeof(Data8));
|
||||
|
||||
// Bloc 0x0E70..0x0E7F -> offset 0x004000
|
||||
PY25Q16_ReadBuffer(0x004000, buf, sizeof(buf));
|
||||
// MENU_LOCK & KEY_LOCK to 0
|
||||
|
||||
// bit 1 = MENU_LOCK => on le force à 0
|
||||
buf[4] &= (uint8_t)~0x02;
|
||||
Data8[4] &= (uint8_t)~0x01;
|
||||
Data8[4] &= (uint8_t)~0x02;
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESET_VFO
|
||||
Data8[7] = (1 & 0x01);
|
||||
#endif
|
||||
|
||||
PY25Q16_WriteBuffer(0x004000, buf, sizeof(buf), true);
|
||||
PY25Q16_WriteBuffer(0x00A000, Data8, sizeof(Data8), false);
|
||||
|
||||
// cohérence RAM
|
||||
gEeprom.MENU_LOCK = 0;
|
||||
}
|
||||
// cohérence RAM
|
||||
gEeprom.MENU_LOCK = 0;
|
||||
#endif
|
||||
|
||||
// Reset VFO for the first time...
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESET_VFO
|
||||
RADIO_InitInfo(&gEeprom.VfoInfo[0], FREQ_CHANNEL_FIRST + BAND3_137MHz, 14550000);
|
||||
RADIO_InitInfo(&gEeprom.VfoInfo[1], FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
|
||||
|
||||
gEeprom.ScreenChannel[0] = FREQ_CHANNEL_FIRST + BAND3_137MHz;
|
||||
gEeprom.ScreenChannel[1] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
||||
gEeprom.MrChannel[0] = MR_CHANNEL_FIRST;
|
||||
gEeprom.MrChannel[1] = MR_CHANNEL_FIRST;
|
||||
gEeprom.FreqChannel[0] = FREQ_CHANNEL_FIRST + BAND3_137MHz;
|
||||
gEeprom.FreqChannel[1] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
||||
|
||||
SETTINGS_SaveVfoIndices();
|
||||
SETTINGS_SaveChannel(FREQ_CHANNEL_FIRST + BAND3_137MHz, 0, &gEeprom.VfoInfo[0], 2);
|
||||
SETTINGS_SaveChannel(FREQ_CHANNEL_FIRST + BAND6_400MHz, 1, &gEeprom.VfoInfo[1], 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -612,37 +592,37 @@ void SETTINGS_SaveFM(void)
|
||||
fmCfg.band = gEeprom.FM_Band;
|
||||
// fmCfg.space = gEeprom.FM_Space;
|
||||
// 0E88
|
||||
PY25Q16_WriteBuffer(0x006000, fmCfg.__raw, 8, true);
|
||||
PY25Q16_WriteBuffer(0x00A020, fmCfg.__raw, 8, false);
|
||||
|
||||
// 0E40
|
||||
PY25Q16_WriteBuffer(0x003000, gFM_Channels, sizeof(gFM_Channels), true);
|
||||
PY25Q16_WriteBuffer(0x00A028, gFM_Channels, sizeof(gFM_Channels), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
void SETTINGS_SaveVfoIndices(void)
|
||||
{
|
||||
uint8_t State[8];
|
||||
uint16_t Data16[8];
|
||||
|
||||
#ifndef ENABLE_NOAA
|
||||
// 0x0E80
|
||||
PY25Q16_ReadBuffer(0x005000, State, sizeof(State));
|
||||
PY25Q16_ReadBuffer(0x00A010, Data16, sizeof(Data16));
|
||||
#endif
|
||||
|
||||
State[0] = gEeprom.ScreenChannel[0];
|
||||
State[1] = gEeprom.MrChannel[0];
|
||||
State[2] = gEeprom.FreqChannel[0];
|
||||
State[3] = gEeprom.ScreenChannel[1];
|
||||
State[4] = gEeprom.MrChannel[1];
|
||||
State[5] = gEeprom.FreqChannel[1];
|
||||
#ifdef ENABLE_NOAA
|
||||
State[6] = gEeprom.NoaaChannel[0];
|
||||
State[7] = gEeprom.NoaaChannel[1];
|
||||
#endif
|
||||
Data16[0] = gEeprom.ScreenChannel[0];
|
||||
Data16[1] = gEeprom.MrChannel[0];
|
||||
Data16[2] = gEeprom.FreqChannel[0];
|
||||
Data16[3] = gEeprom.ScreenChannel[1];
|
||||
Data16[4] = gEeprom.MrChannel[1];
|
||||
Data16[5] = gEeprom.FreqChannel[1];
|
||||
|
||||
// 0x0E80
|
||||
PY25Q16_WriteBuffer(0x005000, State, 8, true);
|
||||
#ifdef ENABLE_NOAA
|
||||
Data16[6] = gEeprom.NoaaChannel[0];
|
||||
Data16[7] = gEeprom.NoaaChannel[1];
|
||||
#endif
|
||||
|
||||
PY25Q16_WriteBuffer(0x00A010, Data16, sizeof(Data16), false);
|
||||
}
|
||||
|
||||
|
||||
void SETTINGS_SaveSettings(void)
|
||||
{
|
||||
uint8_t *State;
|
||||
@@ -713,18 +693,18 @@ void SETTINGS_SaveSettings(void)
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4);
|
||||
State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x0F) << 4);
|
||||
#else
|
||||
State[7] = gEeprom.VFO_OPEN;
|
||||
#endif
|
||||
|
||||
PY25Q16_WriteBuffer(0x004000, SecBuf, 0x10, true);
|
||||
PY25Q16_WriteBuffer(0x00A000, SecBuf, 0x10, false);
|
||||
|
||||
// -------------------------
|
||||
// 0e90 - 0ee0
|
||||
|
||||
// memset(SecBuf, 0xff, 0x50);
|
||||
PY25Q16_ReadBuffer(0x007000, SecBuf, 0x50);
|
||||
PY25Q16_ReadBuffer(0x00A0A8, SecBuf, 0x50);
|
||||
|
||||
// 0x0E90
|
||||
State = SecBuf;
|
||||
@@ -787,12 +767,12 @@ void SETTINGS_SaveSettings(void)
|
||||
State[2] = gEeprom.PERMIT_REMOTE_KILL;
|
||||
#endif
|
||||
|
||||
PY25Q16_WriteBuffer(0x007000, SecBuf, 0x50, true);
|
||||
PY25Q16_WriteBuffer(0x00A0A8, SecBuf, 0x50, false);
|
||||
|
||||
// -------------------------
|
||||
// 0f18 - 0f20
|
||||
|
||||
memset(SecBuf, 0xff, 0x8);
|
||||
memset(SecBuf, 0xff, 0x10);
|
||||
|
||||
// 0x0F18
|
||||
State = SecBuf;
|
||||
@@ -808,14 +788,16 @@ void SETTINGS_SaveSettings(void)
|
||||
tmp = tmp | (1 << 2);
|
||||
|
||||
State[1] = tmp;
|
||||
State[2] = gEeprom.SCANLIST_PRIORITY_CH1[0];
|
||||
State[3] = gEeprom.SCANLIST_PRIORITY_CH2[0];
|
||||
State[4] = gEeprom.SCANLIST_PRIORITY_CH1[1];
|
||||
State[5] = gEeprom.SCANLIST_PRIORITY_CH2[1];
|
||||
State[6] = gEeprom.SCANLIST_PRIORITY_CH1[2];
|
||||
State[7] = gEeprom.SCANLIST_PRIORITY_CH2[2];
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
uint16_t v = gEeprom.SCANLIST_PRIORITY_CH[i];
|
||||
|
||||
PY25Q16_WriteBuffer(0x009000, SecBuf, 8, true);
|
||||
State[2 + (i * 2) + 0] = (uint8_t)(v & 0xFF);
|
||||
State[2 + (i * 2) + 1] = (uint8_t)(v >> 8);
|
||||
}
|
||||
|
||||
PY25Q16_WriteBuffer(0x00A130, SecBuf, 0x10, false);
|
||||
|
||||
// ---------------------
|
||||
// 0f40 - 0f48
|
||||
@@ -855,7 +837,7 @@ void SETTINGS_SaveSettings(void)
|
||||
#endif
|
||||
State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6);
|
||||
|
||||
PY25Q16_WriteBuffer(0x00b000, SecBuf, 8, true);
|
||||
PY25Q16_WriteBuffer(0x00A150, SecBuf, 8, false);
|
||||
|
||||
// ------------------
|
||||
|
||||
@@ -863,7 +845,7 @@ void SETTINGS_SaveSettings(void)
|
||||
// 0x1FF0
|
||||
State = SecBuf;
|
||||
// TODO: TBD
|
||||
PY25Q16_ReadBuffer(0x00c000, State, 8);
|
||||
PY25Q16_ReadBuffer(0x00A158, State, 8);
|
||||
|
||||
//memset(State, 0xFF, sizeof(State));
|
||||
|
||||
@@ -904,7 +886,7 @@ void SETTINGS_SaveSettings(void)
|
||||
|
||||
gEeprom.KEY_LOCK_PTT = gSetting_set_lck;
|
||||
|
||||
PY25Q16_WriteBuffer(0x00c000, SecBuf, 8, true);
|
||||
PY25Q16_WriteBuffer(0x00A158, SecBuf, 8, false);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_VOL
|
||||
@@ -912,7 +894,7 @@ void SETTINGS_SaveSettings(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
|
||||
void SETTINGS_SaveChannel(uint16_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
|
||||
{
|
||||
#ifdef ENABLE_NOAA
|
||||
if (IS_NOAA_CHANNEL(Channel))
|
||||
@@ -924,7 +906,7 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
|
||||
|
||||
if (IS_FREQ_CHANNEL(Channel)) { // it's a VFO, not a channel
|
||||
// 0x0C80
|
||||
OffsetVFO = (VFO == 0) ? 0x001000 : 0x001010;
|
||||
OffsetVFO = (VFO == 0) ? 0x009000 : 0x009010;
|
||||
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
|
||||
}
|
||||
|
||||
@@ -989,16 +971,16 @@ void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
|
||||
PY25Q16_WriteBuffer(0x010000 + 0x140, batteryCalibration, 12, false);
|
||||
}
|
||||
|
||||
void SETTINGS_SaveChannelName(uint8_t channel, const char * name)
|
||||
void SETTINGS_SaveChannelName(uint16_t channel, const char * name)
|
||||
{
|
||||
uint16_t offset = channel * 16;
|
||||
uint8_t buf[16] = {0};
|
||||
memcpy(buf, name, MIN(strlen(name), 10u));
|
||||
// 0x0F50
|
||||
PY25Q16_WriteBuffer(0x00e000 + offset, buf, 0x10, false);
|
||||
PY25Q16_WriteBuffer(0x004000 + offset, buf, 0x10, false);
|
||||
}
|
||||
|
||||
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save)
|
||||
void SETTINGS_UpdateChannel(uint16_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save)
|
||||
{
|
||||
#ifdef ENABLE_NOAA
|
||||
if (!IS_NOAA_CHANNEL(channel))
|
||||
@@ -1008,20 +990,22 @@ void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep,
|
||||
ChannelAttributes_t att = {
|
||||
.band = 0x7,
|
||||
.compander = 0,
|
||||
.scanlist1 = 0,
|
||||
.scanlist2 = 0,
|
||||
.scanlist3 = 0,
|
||||
.unused_1 = 0,
|
||||
.unused_2 = 0,
|
||||
.exclude = 0,
|
||||
.scanlist = 0,
|
||||
}; // default attributes
|
||||
|
||||
// 0x0D60
|
||||
PY25Q16_ReadBuffer(0x002000 + channel, &state, 1);
|
||||
PY25Q16_ReadBuffer(0x008000 + channel, &state, 1);
|
||||
|
||||
if (keep) {
|
||||
att.band = pVFO->Band;
|
||||
att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION;
|
||||
att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION;
|
||||
att.scanlist3 = pVFO->SCANLIST3_PARTICIPATION;
|
||||
att.compander = pVFO->Compander;
|
||||
att.unused_1 = 0;
|
||||
att.unused_2 = 0;
|
||||
att.exclude = 0;
|
||||
att.scanlist = pVFO->SCANLIST_PARTICIPATION;
|
||||
if (check && state.__val == att.__val)
|
||||
return; // no change in the attributes
|
||||
}
|
||||
@@ -1033,10 +1017,10 @@ void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep,
|
||||
#endif
|
||||
if(save)
|
||||
{
|
||||
uint8_t buf[224];
|
||||
PY25Q16_ReadBuffer(0x002000, buf, sizeof(buf));
|
||||
uint16_t buf[MR_CHANNELS_MAX + 24];
|
||||
PY25Q16_ReadBuffer(0x008000, buf, sizeof(buf));
|
||||
buf[channel] = state.__val;
|
||||
PY25Q16_WriteBuffer(0x002000, buf, sizeof(buf), true);
|
||||
PY25Q16_WriteBuffer(0x008000, buf, sizeof(buf), false);
|
||||
}
|
||||
|
||||
gMR_ChannelAttributes[channel] = att;
|
||||
@@ -1056,7 +1040,7 @@ void SETTINGS_WriteBuildOptions(void)
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
// 0x1FF0
|
||||
PY25Q16_ReadBuffer(0x00c000, State, sizeof(State));
|
||||
PY25Q16_ReadBuffer(0x00A158, State, sizeof(State));
|
||||
#endif
|
||||
|
||||
State[0] = 0
|
||||
@@ -1109,7 +1093,7 @@ State[1] = 0
|
||||
| (1 << 6)
|
||||
#endif
|
||||
;
|
||||
PY25Q16_WriteBuffer(0x00c000, State, sizeof(State), true);
|
||||
PY25Q16_WriteBuffer(0x00A158, State, sizeof(State), false);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
@@ -1117,10 +1101,11 @@ State[1] = 0
|
||||
{
|
||||
uint8_t State[0x10];
|
||||
// 0x0E78
|
||||
PY25Q16_ReadBuffer(0x004000, State, sizeof(State));
|
||||
PY25Q16_ReadBuffer(0x00A000, State, sizeof(State));
|
||||
//State[11] = (gEeprom.CURRENT_STATE << 4) | (gEeprom.BATTERY_SAVE & 0x0F);
|
||||
State[15] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4);
|
||||
PY25Q16_WriteBuffer(0x004000, State, sizeof(State), true);
|
||||
//State[15] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4);
|
||||
State[15] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x0F) << 4);
|
||||
PY25Q16_WriteBuffer(0x00A000, State, sizeof(State), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1136,32 +1121,41 @@ State[1] = 0
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
|
||||
void SETTINGS_ResetTxLock(void)
|
||||
{
|
||||
// TODO: This is expensive operation!
|
||||
// This is an expensive operation: full scan of all MR channels
|
||||
|
||||
#define SETTINGS_ResetTxLock_BATCH 10
|
||||
#define CHANNEL_SIZE 16
|
||||
#define TXLOCK_BYTE_OFFSET 4
|
||||
#define TXLOCK_BIT 6
|
||||
#define SETTINGS_ResetTxLock_BATCH 16
|
||||
|
||||
uint8_t Buf[0xc80 / SETTINGS_ResetTxLock_BATCH];
|
||||
const uint32_t BatchSize = 0xc80 / SETTINGS_ResetTxLock_BATCH;
|
||||
const uint32_t BatchChCnt = BatchSize / 0x10;
|
||||
const uint32_t TotalBytes = MR_CHANNELS_MAX * CHANNEL_SIZE; // 512 * 16 = 8192
|
||||
const uint32_t BatchSize = TotalBytes / SETTINGS_ResetTxLock_BATCH; // 8192 / 16 = 512
|
||||
const uint32_t BatchChCnt = BatchSize / CHANNEL_SIZE; // 32 channels per batch
|
||||
|
||||
for (uint32_t i = 0; i < SETTINGS_ResetTxLock_BATCH; i++)
|
||||
uint8_t Buf[BatchSize];
|
||||
|
||||
for (uint32_t batch = 0; batch < SETTINGS_ResetTxLock_BATCH; batch++)
|
||||
{
|
||||
uint32_t Offset = i * BatchSize;
|
||||
PY25Q16_ReadBuffer(0 + Offset, Buf, sizeof(Buf));
|
||||
uint32_t Offset = batch * BatchSize;
|
||||
|
||||
uint8_t *State;
|
||||
for (uint8_t channel = 0; channel < BatchChCnt; channel++)
|
||||
PY25Q16_ReadBuffer(Offset, Buf, BatchSize);
|
||||
|
||||
for (uint32_t ch = 0; ch < BatchChCnt; ch++)
|
||||
{
|
||||
uint16_t OffsetVFO = channel * 16;
|
||||
State = Buf + OffsetVFO;
|
||||
State[4] |= (1 << 6);
|
||||
uint32_t off = ch * CHANNEL_SIZE;
|
||||
Buf[off + TXLOCK_BYTE_OFFSET] |= (1 << TXLOCK_BIT);
|
||||
}
|
||||
|
||||
PY25Q16_WriteBuffer(0 + Offset, Buf, sizeof(Buf), false);
|
||||
PY25Q16_WriteBuffer(Offset, Buf, BatchSize, false);
|
||||
}
|
||||
|
||||
#undef SETTINGS_ResetTxLock_BATCH
|
||||
#undef SETTINGS_ResetTxLock_BATCH
|
||||
#undef CHANNEL_SIZE
|
||||
#undef TXLOCK_BYTE_OFFSET
|
||||
#undef TXLOCK_BIT
|
||||
}
|
||||
|
||||
#endif
|
||||
+10
-11
@@ -162,11 +162,11 @@ enum CHANNEL_DisplayMode_t {
|
||||
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
|
||||
uint8_t FreqChannel[2]; // last frequency channels used
|
||||
uint8_t MrChannel[2]; // last memory channels used
|
||||
uint16_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
|
||||
uint16_t FreqChannel[2]; // last frequency channels used
|
||||
uint16_t MrChannel[2]; // last memory channels used
|
||||
#ifdef ENABLE_NOAA
|
||||
uint8_t NoaaChannel[2];
|
||||
uint16_t NoaaChannel[2];
|
||||
#endif
|
||||
|
||||
// The actual VFO index (0-upper/1-lower) that is now used for RX,
|
||||
@@ -215,8 +215,7 @@ typedef struct {
|
||||
uint8_t SCAN_RESUME_MODE;
|
||||
uint8_t SCAN_LIST_DEFAULT;
|
||||
bool SCAN_LIST_ENABLED[3];
|
||||
uint8_t SCANLIST_PRIORITY_CH1[3];
|
||||
uint8_t SCANLIST_PRIORITY_CH2[3];
|
||||
uint16_t SCANLIST_PRIORITY_CH[6];
|
||||
//#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE // Fix me !!! What the hell is this?
|
||||
uint8_t CURRENT_STATE;
|
||||
uint8_t CURRENT_LIST;
|
||||
@@ -308,18 +307,18 @@ extern EEPROM_Config_t gEeprom;
|
||||
|
||||
void SETTINGS_InitEEPROM(void);
|
||||
void SETTINGS_LoadCalibration(void);
|
||||
uint32_t SETTINGS_FetchChannelFrequency(const int channel);
|
||||
void SETTINGS_FetchChannelName(char *s, const int channel);
|
||||
uint32_t SETTINGS_FetchChannelFrequency(const uint16_t channel);
|
||||
void SETTINGS_FetchChannelName(char *s, const uint16_t channel);
|
||||
void SETTINGS_FactoryReset(bool bIsAll);
|
||||
#ifdef ENABLE_FMRADIO
|
||||
void SETTINGS_SaveFM(void);
|
||||
#endif
|
||||
void SETTINGS_SaveVfoIndices(void);
|
||||
void SETTINGS_SaveSettings(void);
|
||||
void SETTINGS_SaveChannelName(uint8_t channel, const char * name);
|
||||
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
|
||||
void SETTINGS_SaveChannelName(uint16_t channel, const char * name);
|
||||
void SETTINGS_SaveChannel(uint16_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
|
||||
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
|
||||
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save);
|
||||
void SETTINGS_UpdateChannel(uint16_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save);
|
||||
void SETTINGS_WriteBuildOptions(void);
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
|
||||
void SETTINGS_WriteCurrentState(void);
|
||||
|
||||
+44
-34
@@ -70,7 +70,15 @@ void UI_DisplayAircopy(void)
|
||||
|
||||
memset(String, 0, sizeof(String));
|
||||
|
||||
percent = (gAirCopyBlockNumber * 10000) / AIRCOPY_TOTAL_BLOCKS;
|
||||
// Get the current map and calculate percentage based on its total blocks
|
||||
const AIRCOPY_TransferMap_t *currentMap = AIRCOPY_GetCurrentMap();
|
||||
|
||||
uint16_t doneBlocks = gAirCopyBlockNumber + gErrorsDuringAirCopy;
|
||||
|
||||
if (doneBlocks > currentMap->total_blocks)
|
||||
doneBlocks = currentMap->total_blocks;
|
||||
|
||||
percent = (doneBlocks * 10000) / currentMap->total_blocks;
|
||||
|
||||
if (gAirCopyIsSendMode == 0) {
|
||||
sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy);
|
||||
@@ -94,8 +102,24 @@ void UI_DisplayAircopy(void)
|
||||
gFrameBuffer[4][125] = 0x42;
|
||||
gFrameBuffer[4][126] = 0x3c;
|
||||
}
|
||||
|
||||
// Draw memory selection
|
||||
if(gAircopyState == AIRCOPY_READY)
|
||||
{
|
||||
doneBlocks = 0;
|
||||
|
||||
uint16_t doneBlocks = gAirCopyBlockNumber + gErrorsDuringAirCopy;
|
||||
memset(gFrameBuffer[5], 0, 128);
|
||||
memset(gFrameBuffer[6], 0, 128);
|
||||
|
||||
if(gAircopyCurrentMapIndex < AIRCOPY_NUM_BANKS) {
|
||||
sprintf(String, "MEM %03u - %03u%", (gAircopyCurrentMapIndex * 128) + 1, (gAircopyCurrentMapIndex + 1) * 128);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(String, "Settings");
|
||||
}
|
||||
UI_PrintString(String, 2, 127, 5, 8);
|
||||
}
|
||||
|
||||
if (doneBlocks > 0)
|
||||
{
|
||||
@@ -107,46 +131,32 @@ void UI_DisplayAircopy(void)
|
||||
lErrorsDuringAirCopy = gErrorsDuringAirCopy;
|
||||
}
|
||||
|
||||
// Project real blocks onto a fixed-width progress bar
|
||||
const AIRCOPY_TransferMap_t *currentMap = AIRCOPY_GetCurrentMap();
|
||||
|
||||
uint16_t total = currentMap->total_blocks;
|
||||
uint16_t done = gAirCopyBlockNumber + gErrorsDuringAirCopy;
|
||||
|
||||
if (done > total) done = total;
|
||||
|
||||
for (uint8_t col = 0; col < AIRCOPY_BAR_WIDTH; col++)
|
||||
{
|
||||
// Determine the range of blocks represented by this column
|
||||
uint16_t block_start = (col * AIRCOPY_TOTAL_BLOCKS) / AIRCOPY_BAR_WIDTH;
|
||||
uint16_t block_end = ((col + 1) * AIRCOPY_TOTAL_BLOCKS) / AIRCOPY_BAR_WIDTH;
|
||||
/* Map column [0..BAR_WIDTH-1] to block [0..total-1] */
|
||||
uint16_t b = (uint16_t)((col * (uint32_t)total) / AIRCOPY_BAR_WIDTH);
|
||||
|
||||
bool has_data = false;
|
||||
bool has_error = false;
|
||||
bool processed = (b < done);
|
||||
bool error = processed && get_bit(crc, b);
|
||||
|
||||
// Scan the block range mapped to this column
|
||||
for (uint16_t b = block_start; b < block_end; b++)
|
||||
{
|
||||
if (b < doneBlocks)
|
||||
has_data = true;
|
||||
|
||||
if (get_bit(crc, b))
|
||||
has_error = true;
|
||||
}
|
||||
|
||||
// Render the column
|
||||
if (has_error)
|
||||
{
|
||||
// Error blocks are rendered as empty gaps
|
||||
gFrameBuffer[4][col + 4] = 0x81; // error
|
||||
}
|
||||
else if (has_data)
|
||||
{
|
||||
// Successfully transferred blocks
|
||||
gFrameBuffer[4][col + 4] = 0xbd; // full block
|
||||
}
|
||||
if (!processed)
|
||||
gFrameBuffer[4][col + 4] = 0x81; // not yet processed
|
||||
else if (error)
|
||||
gFrameBuffer[4][col + 4] = 0x81; // error gap (intentional hole)
|
||||
else
|
||||
{
|
||||
// Not yet transferred
|
||||
gFrameBuffer[4][col + 4] = 0x81; // empty
|
||||
}
|
||||
gFrameBuffer[4][col + 4] = 0xBD; // ok filled
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ST7565_BlitFullScreen();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+1
-1
@@ -68,7 +68,7 @@ void UI_DisplayFM(void)
|
||||
}
|
||||
}
|
||||
} else if (gFM_AutoScan) {
|
||||
sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition + 1);
|
||||
sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition);
|
||||
pPrintStr = String;
|
||||
} else {
|
||||
pPrintStr = "M-SCAN";
|
||||
|
||||
+58
-3
@@ -27,7 +27,7 @@
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
void UI_GenerateChannelString(char *pString, const uint8_t Channel)
|
||||
void UI_GenerateChannelString(char *pString, const uint16_t Channel)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -44,7 +44,7 @@ void UI_GenerateChannelString(char *pString, const uint8_t Channel)
|
||||
pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
|
||||
}
|
||||
|
||||
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber)
|
||||
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint16_t ChannelNumber)
|
||||
{
|
||||
if (gInputBoxIndex > 0) {
|
||||
for (unsigned int i = 0; i < 3; i++) {
|
||||
@@ -58,7 +58,9 @@ void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uin
|
||||
if (bShowPrefix) {
|
||||
// BUG here? Prefixed NULLs are allowed
|
||||
sprintf(pString, "CH-%03u", ChannelNumber + 1);
|
||||
} else if (ChannelNumber == 0xFF) {
|
||||
} else if (ChannelNumber == MR_CHANNEL_LAST + 1) {
|
||||
strcpy(pString, "None");
|
||||
} else if (ChannelNumber == 0xFFFF) {
|
||||
strcpy(pString, "NULL");
|
||||
} else {
|
||||
sprintf(pString, "%03u", ChannelNumber + 1);
|
||||
@@ -116,6 +118,35 @@ void UI_PrintStringSmallNormal(const char *pString, uint8_t Start, uint8_t End,
|
||||
UI_PrintStringSmall(pString, Start, End, Line, ARRAY_SIZE(gFontSmall[0]), (const uint8_t *)gFontSmall);
|
||||
}
|
||||
|
||||
void UI_PrintStringSmallNormalInverse(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
|
||||
{
|
||||
// First draw the string normally
|
||||
UI_PrintStringSmallNormal(pString, Start, End, Line);
|
||||
|
||||
// Now invert the framebuffer bits for the rendered area
|
||||
uint8_t len = strlen(pString);
|
||||
uint8_t char_width = 7; // small font is typically 6px wide
|
||||
|
||||
uint8_t x_start = Start;
|
||||
uint8_t x_end = Start + (len * char_width) + 1;
|
||||
|
||||
if (End != 0 && x_end > End)
|
||||
x_end = End;
|
||||
|
||||
gFrameBuffer[Line][x_start - 3] ^= 0x3E;
|
||||
gFrameBuffer[Line][x_start - 2] ^= 0x7F;
|
||||
gFrameBuffer[Line][x_start - 1] ^= 0xFF;
|
||||
for (uint8_t x = x_start; x < x_end; x++)
|
||||
{
|
||||
gFrameBuffer[Line][x] ^= 0xFF;
|
||||
gFrameBuffer[Line - 1][x] ^= 0x80;
|
||||
}
|
||||
gFrameBuffer[Line][x_end + 0] ^= 0xFF;
|
||||
gFrameBuffer[Line][x_end + 1] ^= 0x7F;
|
||||
gFrameBuffer[Line][x_end + 2] ^= 0x3E;
|
||||
}
|
||||
|
||||
|
||||
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
|
||||
{
|
||||
#ifdef ENABLE_SMALL_BOLD
|
||||
@@ -129,6 +160,30 @@ void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, ui
|
||||
UI_PrintStringSmall(pString, Start, End, Line, char_width, font);
|
||||
}
|
||||
|
||||
void UI_PrintStringSmallBoldInverse(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
|
||||
{
|
||||
// First draw the string normally
|
||||
UI_PrintStringSmallBold(pString, Start, End, Line);
|
||||
|
||||
// Now invert the framebuffer bits for the rendered area
|
||||
uint8_t len = strlen(pString);
|
||||
uint8_t char_width = 7; // small font is typically 6px wide
|
||||
|
||||
uint8_t x_start = Start;
|
||||
uint8_t x_end = Start + (len * char_width);
|
||||
|
||||
if (End != 0 && x_end > End)
|
||||
x_end = End;
|
||||
|
||||
gFrameBuffer[Line][x_start] ^= 0x7F;
|
||||
for (uint8_t x = x_start + 1; x < x_end; x++)
|
||||
{
|
||||
gFrameBuffer[Line][x] ^= 0x41;
|
||||
}
|
||||
gFrameBuffer[Line][x_end + 1] ^= 0x7F;
|
||||
}
|
||||
|
||||
|
||||
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t * buffer)
|
||||
{
|
||||
UI_PrintStringBuffer(pString, buffer, ARRAY_SIZE(gFontSmall[0]), (uint8_t *)gFontSmall);
|
||||
|
||||
+4
-2
@@ -20,11 +20,13 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void UI_GenerateChannelString(char *pString, const uint8_t Channel);
|
||||
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber);
|
||||
void UI_GenerateChannelString(char *pString, const uint16_t Channel);
|
||||
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint16_t ChannelNumber);
|
||||
void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t Width);
|
||||
void UI_PrintStringSmallNormal(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
|
||||
void UI_PrintStringSmallNormalInverse(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
|
||||
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
|
||||
void UI_PrintStringSmallBoldInverse(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
|
||||
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t *buffer);
|
||||
void UI_PrintStringSmallBufferBold(const char *pString, uint8_t * buffer);
|
||||
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
|
||||
|
||||
+48
-33
@@ -272,10 +272,13 @@ void DisplayRSSIBar(const bool now)
|
||||
//sprintf(String, "%d", RxBlink);
|
||||
//UI_PrintStringSmallBold(String, 80, 0, RxLine);
|
||||
|
||||
/*
|
||||
if(RxLine >= 0 && center_line != CENTER_LINE_IN_USE)
|
||||
{
|
||||
if (RxBlink == 0 || RxBlink == 1) {
|
||||
UI_PrintStringSmallBold("RX", 8, 0, RxLine);
|
||||
//GUI_DisplaySmallest("RX", 10, (RxLine * 8) + 1, false, true);
|
||||
|
||||
if (RxBlink == 1) RxBlink = 2;
|
||||
} else {
|
||||
for (uint8_t i = 8; i < 24; i++)
|
||||
@@ -286,6 +289,7 @@ void DisplayRSSIBar(const bool now)
|
||||
}
|
||||
ST7565_BlitLine(RxLine);
|
||||
}
|
||||
*/
|
||||
#else
|
||||
const unsigned int line = 3;
|
||||
#endif
|
||||
@@ -778,6 +782,10 @@ void UI_DisplayMain(void)
|
||||
{
|
||||
RxBlink = 0;
|
||||
}
|
||||
|
||||
if (RxBlink == 0 || RxBlink == 1) {
|
||||
UI_PrintStringSmallBold("RX", 8, 0, RxLine);
|
||||
}
|
||||
#else
|
||||
UI_PrintStringSmallBold("RX", 8, 0, line);
|
||||
#endif
|
||||
@@ -799,13 +807,13 @@ void UI_DisplayMain(void)
|
||||
|
||||
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
|
||||
{ // channel mode
|
||||
const unsigned int x = 2;
|
||||
const unsigned int x = 3;
|
||||
const bool inputting = gInputBoxIndex != 0 && gEeprom.TX_VFO == vfo_num;
|
||||
if (!inputting)
|
||||
sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1);
|
||||
sprintf(String, "M%03u", gEeprom.ScreenChannel[vfo_num] + 1);
|
||||
else
|
||||
sprintf(String, "M%.3s", INPUTBOX_GetAscii()); // show the input text
|
||||
UI_PrintStringSmallNormal(String, x, 0, line + 1);
|
||||
UI_PrintStringSmallNormalInverse(String, x, 0, line + 1);
|
||||
}
|
||||
else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
|
||||
{ // frequency mode
|
||||
@@ -843,7 +851,7 @@ void UI_DisplayMain(void)
|
||||
if (state != VFO_STATE_NORMAL)
|
||||
{
|
||||
if (state < ARRAY_SIZE(VfoStateStr))
|
||||
UI_PrintString(VfoStateStr[state], 31, 0, line, 8);
|
||||
UI_PrintString(VfoStateStr[state], 35, 0, line, 8);
|
||||
}
|
||||
else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num)
|
||||
{ // user entering a frequency
|
||||
@@ -881,43 +889,48 @@ void UI_DisplayMain(void)
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
if(gEeprom.MENU_LOCK == false) {
|
||||
#endif
|
||||
uint8_t countList = 0;
|
||||
uint8_t shiftList = 0;
|
||||
|
||||
if(gMR_ChannelExclude[gEeprom.ScreenChannel[vfo_num]] == false)
|
||||
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
|
||||
|
||||
|
||||
if(att.exclude == false)
|
||||
{
|
||||
// show the scan list assigment symbols
|
||||
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
|
||||
|
||||
countList = att.scanlist1 + att.scanlist2 + att.scanlist3;
|
||||
|
||||
if(countList == 0)
|
||||
{
|
||||
memcpy(p_line0 + 127 - (1 * 6), BITMAP_ScanList0, sizeof(BITMAP_ScanList0));
|
||||
uint8_t countList = att.scanlist;
|
||||
if(countList > MR_CHANNELS_LIST + 1) {
|
||||
countList = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftList = countList;
|
||||
|
||||
if (att.scanlist1)
|
||||
{
|
||||
memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
|
||||
shiftList--;
|
||||
}
|
||||
if (att.scanlist2)
|
||||
{
|
||||
memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
|
||||
shiftList--;
|
||||
}
|
||||
if (att.scanlist3)
|
||||
{
|
||||
memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList3, sizeof(BITMAP_ScanList3));
|
||||
}
|
||||
const char *displayStr = (countList == MR_CHANNELS_LIST + 1) ? "ALL" :
|
||||
(countList == 0) ? "OFF" : String;
|
||||
uint8_t xStart = (countList > 0 && countList != MR_CHANNELS_LIST + 1) ? 117 : 113;
|
||||
uint8_t xDisplay = (countList > 0 && countList != MR_CHANNELS_LIST + 1) ? 119 : 115;
|
||||
|
||||
if(countList > 0 && countList != MR_CHANNELS_LIST + 1) {
|
||||
sprintf(String, "%02d", countList);
|
||||
}
|
||||
|
||||
GUI_DisplaySmallest(displayStr, xDisplay, line == 0 ? 2 : 34, false, true);
|
||||
|
||||
for (uint8_t x = xStart; x < 128; x++) {
|
||||
gFrameBuffer[line][x] ^= 0xFE;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(p_line0 + 127 - (1 * 6), BITMAP_ScanListE, sizeof(BITMAP_ScanListE));
|
||||
const char *displayStr = "EX";
|
||||
|
||||
uint8_t xStart = 117;
|
||||
uint8_t xDisplay = 119;
|
||||
|
||||
GUI_DisplaySmallest(displayStr, xDisplay, line == 0 ? 2 : 34, false, true);
|
||||
|
||||
for (uint8_t x = xStart; x < 128; x++) {
|
||||
gFrameBuffer[line][x] ^= 0xFE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
@@ -957,7 +970,7 @@ void UI_DisplayMain(void)
|
||||
|
||||
case MDF_CHANNEL: // show the channel number
|
||||
sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1);
|
||||
UI_PrintString(String, 32, 0, line, 8);
|
||||
UI_PrintString(String, 36, 0, line, 8);
|
||||
break;
|
||||
|
||||
case MDF_NAME: // show the channel name
|
||||
@@ -970,13 +983,15 @@ void UI_DisplayMain(void)
|
||||
}
|
||||
|
||||
if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) {
|
||||
UI_PrintString(String, 32, 0, line, 8);
|
||||
String[9] = 0;
|
||||
UI_PrintString(String, 36, 0, line, 8);
|
||||
}
|
||||
else {
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
if (isMainOnly())
|
||||
{
|
||||
UI_PrintString(String, 32, 0, line, 8);
|
||||
String[9] = 0;
|
||||
UI_PrintString(String, 36, 0, line, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+36
-78
@@ -63,17 +63,15 @@ const t_menu_item MenuList[] =
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
{"TXLock", MENU_TX_LOCK },
|
||||
#endif
|
||||
{"ScAdd1", MENU_S_ADD1 },
|
||||
{"ScAdd2", MENU_S_ADD2 },
|
||||
{"ScAdd3", MENU_S_ADD3 },
|
||||
{"ChList", MENU_LIST_CH },
|
||||
{"ChSave", MENU_MEM_CH }, // was "MEM-CH"
|
||||
{"ChDele", MENU_DEL_CH }, // was "DEL-CH"
|
||||
{"ChName", MENU_MEM_NAME },
|
||||
|
||||
{"SList", MENU_S_LIST },
|
||||
{"SList1", MENU_SLIST1 },
|
||||
{"SList2", MENU_SLIST2 },
|
||||
{"SList3", MENU_SLIST3 },
|
||||
{"ScList", MENU_S_LIST },
|
||||
{"ScPri", MENU_S_PRI },
|
||||
{"PriCh1", MENU_S_PRI_CH_1 },
|
||||
{"PriCh2", MENU_S_PRI_CH_2 },
|
||||
{"ScnRev", MENU_SC_REV },
|
||||
#ifndef ENABLE_FEAT_F4HWN
|
||||
#ifdef ENABLE_NOAA
|
||||
@@ -787,9 +785,6 @@ void UI_DisplayMenu(void)
|
||||
#endif
|
||||
case MENU_BCL:
|
||||
case MENU_BEEP:
|
||||
case MENU_S_ADD1:
|
||||
case MENU_S_ADD2:
|
||||
case MENU_S_ADD3:
|
||||
case MENU_STE:
|
||||
case MENU_D_ST:
|
||||
#ifdef ENABLE_DTMF_CALLING
|
||||
@@ -810,6 +805,7 @@ void UI_DisplayMenu(void)
|
||||
#endif
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
case MENU_SET_TMR:
|
||||
case MENU_S_PRI:
|
||||
#endif
|
||||
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
|
||||
break;
|
||||
@@ -817,23 +813,34 @@ void UI_DisplayMenu(void)
|
||||
case MENU_MEM_CH:
|
||||
case MENU_1_CALL:
|
||||
case MENU_DEL_CH:
|
||||
case MENU_S_PRI_CH_1:
|
||||
case MENU_S_PRI_CH_2:
|
||||
{
|
||||
const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0);
|
||||
|
||||
UI_GenerateChannelStringEx(String, valid, gSubMenuSelection);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
|
||||
|
||||
if (valid && !gAskForConfirmation)
|
||||
{ // show the frequency so that the user knows the channels frequency
|
||||
const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
|
||||
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
|
||||
if(gSubMenuSelection == MR_CHANNELS_MAX)
|
||||
{
|
||||
UI_PrintString("None", menu_item_x1, menu_item_x2, 2, 8);
|
||||
already_printed = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0);
|
||||
|
||||
SETTINGS_FetchChannelName(String, gSubMenuSelection);
|
||||
UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2, 8);
|
||||
already_printed = true;
|
||||
break;
|
||||
UI_GenerateChannelStringEx(String, valid, gSubMenuSelection);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
|
||||
|
||||
if (valid && !gAskForConfirmation)
|
||||
{ // show the frequency so that the user knows the channels frequency
|
||||
const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
|
||||
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
|
||||
}
|
||||
|
||||
SETTINGS_FetchChannelName(String, gSubMenuSelection);
|
||||
UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2, 8);
|
||||
already_printed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case MENU_MEM_NAME:
|
||||
@@ -935,15 +942,12 @@ void UI_DisplayMenu(void)
|
||||
sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "%u*100ms", gSubMenuSelection);
|
||||
break;
|
||||
|
||||
case MENU_LIST_CH:
|
||||
case MENU_S_LIST:
|
||||
if (gSubMenuSelection == 0)
|
||||
strcpy(String, "LIST [0]\nNO LIST");
|
||||
else if (gSubMenuSelection < 4)
|
||||
sprintf(String, "LIST [%u]", gSubMenuSelection);
|
||||
else if (gSubMenuSelection == 4)
|
||||
strcpy(String, "LISTS\n[1, 2, 3]");
|
||||
else if (gSubMenuSelection == 5)
|
||||
if (gSubMenuSelection == MR_CHANNELS_LIST + 1)
|
||||
strcpy(String, "ALL");
|
||||
else
|
||||
sprintf(String, "%u", gSubMenuSelection);
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ALARM
|
||||
@@ -1260,55 +1264,9 @@ void UI_DisplayMenu(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2 || UI_MENU_GetCurrentMenuId() == MENU_SLIST3)
|
||||
if (UI_MENU_GetCurrentMenuId() == MENU_S_PRI_CH_1 || UI_MENU_GetCurrentMenuId() == MENU_S_PRI_CH_2)
|
||||
{
|
||||
i = UI_MENU_GetCurrentMenuId() - MENU_SLIST1;
|
||||
|
||||
char *pPrintStr = String;
|
||||
|
||||
if (gSubMenuSelection < 0) {
|
||||
pPrintStr = "NULL";
|
||||
} else {
|
||||
UI_GenerateChannelStringEx(String, true, gSubMenuSelection);
|
||||
pPrintStr = String;
|
||||
}
|
||||
|
||||
// channel number
|
||||
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 0, 8);
|
||||
|
||||
SETTINGS_FetchChannelName(String, gSubMenuSelection);
|
||||
pPrintStr = String[0] ? String : "--";
|
||||
|
||||
// channel name and scan-list
|
||||
if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) {
|
||||
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8);
|
||||
} else {
|
||||
/*
|
||||
UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2);
|
||||
|
||||
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) {
|
||||
sprintf(String, "PRI%d:%u", 1, gEeprom.SCANLIST_PRIORITY_CH1[i] + 1);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 3, 8);
|
||||
}
|
||||
|
||||
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) {
|
||||
sprintf(String, "PRI%d:%u", 2, gEeprom.SCANLIST_PRIORITY_CH2[i] + 1);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
|
||||
}
|
||||
*/
|
||||
|
||||
UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2);
|
||||
|
||||
for (uint8_t pri = 1; pri <= 2; pri++) {
|
||||
uint8_t channel = (pri == 1) ? gEeprom.SCANLIST_PRIORITY_CH1[i] : gEeprom.SCANLIST_PRIORITY_CH2[i];
|
||||
|
||||
if (IS_MR_CHANNEL(channel)) {
|
||||
sprintf(String, "PRI%d:%u", pri, channel + 1);
|
||||
UI_PrintString(String, menu_item_x1, menu_item_x2, pri * 2 + 1, 8);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan)
|
||||
|
||||
+4
-6
@@ -65,9 +65,7 @@ enum
|
||||
#endif
|
||||
MENU_SC_REV,
|
||||
MENU_AUTOLK,
|
||||
MENU_S_ADD1,
|
||||
MENU_S_ADD2,
|
||||
MENU_S_ADD3,
|
||||
MENU_LIST_CH,
|
||||
MENU_STE,
|
||||
MENU_RP_STE,
|
||||
MENU_MIC,
|
||||
@@ -75,9 +73,9 @@ enum
|
||||
MENU_COMPAND,
|
||||
MENU_1_CALL,
|
||||
MENU_S_LIST,
|
||||
MENU_SLIST1,
|
||||
MENU_SLIST2,
|
||||
MENU_SLIST3,
|
||||
MENU_S_PRI,
|
||||
MENU_S_PRI_CH_1,
|
||||
MENU_S_PRI_CH_2,
|
||||
#ifdef ENABLE_ALARM
|
||||
MENU_AL_MOD,
|
||||
#endif
|
||||
|
||||
+46
-25
@@ -94,26 +94,44 @@ void UI_DisplayStatus()
|
||||
{ // SCAN indicator
|
||||
if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) {
|
||||
if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode
|
||||
|
||||
if(gEeprom.SCAN_LIST_DEFAULT == MR_CHANNELS_LIST + 1)
|
||||
{
|
||||
sprintf(str, "%s", "ALL");
|
||||
GUI_DisplaySmallest(str, 2, 1, true, true);
|
||||
for (uint8_t x = 0; x < 15; x++)
|
||||
{
|
||||
gStatusLine[x] ^= 0x7F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t end = 0;
|
||||
if(gEeprom.SCAN_LIST_ENABLED[0]==1) {
|
||||
sprintf(str, "%02d+", gEeprom.SCAN_LIST_DEFAULT);
|
||||
end = 15;
|
||||
}
|
||||
else {
|
||||
sprintf(str, "%02d", gEeprom.SCAN_LIST_DEFAULT);
|
||||
end = 11;
|
||||
}
|
||||
GUI_DisplaySmallest(str, 2, 1, true, true);
|
||||
for (uint8_t x = 0; x < end; x++)
|
||||
{
|
||||
gStatusLine[x] ^= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
switch(gEeprom.SCAN_LIST_DEFAULT) {
|
||||
case 0:
|
||||
memcpy(line + 0, BITMAP_ScanList0, sizeof(BITMAP_ScanList0));
|
||||
break;
|
||||
case 1:
|
||||
memcpy(line + 0, BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
|
||||
break;
|
||||
case 2:
|
||||
memcpy(line + 0, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
|
||||
break;
|
||||
case 3:
|
||||
memcpy(line + 0, BITMAP_ScanList3, sizeof(BITMAP_ScanList3));
|
||||
break;
|
||||
case 4:
|
||||
memcpy(line + 0, BITMAP_ScanList123, sizeof(BITMAP_ScanList123));
|
||||
break;
|
||||
case 5:
|
||||
case MR_CHANNELS_LIST + 1:
|
||||
memcpy(line + 0, BITMAP_ScanListAll, sizeof(BITMAP_ScanListAll));
|
||||
break;
|
||||
default:
|
||||
sprintf(str, "%02d", gEeprom.SCAN_LIST_DEFAULT);
|
||||
UI_PrintStringSmallBufferNormal(str, line + 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else { // frequency mode
|
||||
memcpy(line + x + 1, gFontS, sizeof(gFontS));
|
||||
@@ -174,7 +192,8 @@ void UI_DisplayStatus()
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(line + x + 2, gFontMO, sizeof(gFontMO));
|
||||
if(!gAirCopyBootMode)
|
||||
memcpy(line + x + 2, gFontMO, sizeof(gFontMO));
|
||||
}
|
||||
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
|
||||
}
|
||||
@@ -195,14 +214,16 @@ void UI_DisplayStatus()
|
||||
|
||||
#ifdef ENABLE_FEAT_F4HWN
|
||||
// PTT indicator
|
||||
if (gSetting_set_ptt_session) {
|
||||
memcpy(line + x, gFontPttOnePush, sizeof(gFontPttOnePush));
|
||||
x1 = x + sizeof(gFontPttOnePush) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(line + x, gFontPttClassic, sizeof(gFontPttClassic));
|
||||
x1 = x + sizeof(gFontPttClassic) + 1;
|
||||
if(!gAirCopyBootMode) {
|
||||
if (gSetting_set_ptt_session) {
|
||||
memcpy(line + x, gFontPttOnePush, sizeof(gFontPttOnePush));
|
||||
x1 = x + sizeof(gFontPttOnePush) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(line + x, gFontPttClassic, sizeof(gFontPttClassic));
|
||||
x1 = x + sizeof(gFontPttClassic) + 1;
|
||||
}
|
||||
}
|
||||
x += sizeof(gFontPttClassic) + 3;
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -76,9 +76,9 @@ void UI_DisplayWelcome(void)
|
||||
memset(WelcomeString1, 0, sizeof(WelcomeString1));
|
||||
|
||||
// 0x0EB0
|
||||
PY25Q16_ReadBuffer(0x007020, WelcomeString0, 16);
|
||||
PY25Q16_ReadBuffer(0x00A0C8, WelcomeString0, 16);
|
||||
// 0x0EC0
|
||||
PY25Q16_ReadBuffer(0x007030, WelcomeString1, 16);
|
||||
PY25Q16_ReadBuffer(0x00A0D8, WelcomeString1, 16);
|
||||
|
||||
sprintf(WelcomeString2, "%u.%02uV %u%%",
|
||||
gBatteryVoltageAverage / 100,
|
||||
|
||||
+2
-2
@@ -59,7 +59,7 @@
|
||||
"ENABLE_FEAT_F4HWN_CTR": true,
|
||||
"ENABLE_FEAT_F4HWN_RESCUE_OPS": false,
|
||||
"ENABLE_FEAT_F4HWN_VOL": false,
|
||||
"ENABLE_FEAT_F4HWN_RESET_CHANNEL": true,
|
||||
"ENABLE_FEAT_F4HWN_RESET_VFO": true,
|
||||
"ENABLE_FEAT_F4HWN_PMR": false,
|
||||
"ENABLE_FEAT_F4HWN_GMRS_FRS_MURS": false,
|
||||
"ENABLE_FEAT_F4HWN_CA": true,
|
||||
@@ -70,7 +70,7 @@
|
||||
"ENABLE_NAVIG_LEFT_RIGHT": true,
|
||||
"ENABLE_SWD": false,
|
||||
"VERSION_STRING_1": "v0.22",
|
||||
"VERSION_STRING_2": "v4.3.3"
|
||||
"VERSION_STRING_2": "v5.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user