Merge pull request #362 from markusb/REGA
Rega alarm call functionality
This commit is contained in:
7
Makefile
7
Makefile
@@ -55,6 +55,7 @@ ENABLE_FEAT_F4HWN_RESET_CHANNEL ?= 0
|
|||||||
ENABLE_FEAT_F4HWN_PMR ?= 0
|
ENABLE_FEAT_F4HWN_PMR ?= 0
|
||||||
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS ?= 0
|
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS ?= 0
|
||||||
ENABLE_FEAT_F4HWN_CA ?= 1
|
ENABLE_FEAT_F4HWN_CA ?= 1
|
||||||
|
ENABLE_REGA ?= 1
|
||||||
|
|
||||||
# ---- DEBUGGING ----
|
# ---- DEBUGGING ----
|
||||||
ENABLE_AM_FIX_SHOW_DATA ?= 0
|
ENABLE_AM_FIX_SHOW_DATA ?= 0
|
||||||
@@ -135,6 +136,9 @@ OBJS += app/app.o
|
|||||||
OBJS += app/chFrScanner.o
|
OBJS += app/chFrScanner.o
|
||||||
OBJS += app/common.o
|
OBJS += app/common.o
|
||||||
OBJS += app/dtmf.o
|
OBJS += app/dtmf.o
|
||||||
|
ifeq ($(ENABLE_REGA),1)
|
||||||
|
OBJS += app/rega.o
|
||||||
|
endif
|
||||||
ifeq ($(ENABLE_FLASHLIGHT),1)
|
ifeq ($(ENABLE_FLASHLIGHT),1)
|
||||||
OBJS += app/flashlight.o
|
OBJS += app/flashlight.o
|
||||||
endif
|
endif
|
||||||
@@ -399,6 +403,9 @@ endif
|
|||||||
ifeq ($(ENABLE_DTMF_CALLING),1)
|
ifeq ($(ENABLE_DTMF_CALLING),1)
|
||||||
CFLAGS += -DENABLE_DTMF_CALLING
|
CFLAGS += -DENABLE_DTMF_CALLING
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(ENABLE_REGA),1)
|
||||||
|
CFLAGS += -DENABLE_REGA
|
||||||
|
endif
|
||||||
ifeq ($(ENABLE_AGC_SHOW_DATA),1)
|
ifeq ($(ENABLE_AGC_SHOW_DATA),1)
|
||||||
CFLAGS += -DENABLE_AGC_SHOW_DATA
|
CFLAGS += -DENABLE_AGC_SHOW_DATA
|
||||||
endif
|
endif
|
||||||
|
@@ -42,6 +42,9 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
#include "app/rega.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
|
||||||
#include "screenshot.h"
|
#include "screenshot.h"
|
||||||
@@ -123,6 +126,10 @@ void (*action_opt_table[])(void) = {
|
|||||||
#else
|
#else
|
||||||
[ACTION_OPT_RXMODE] = &FUNCTION_NOP,
|
[ACTION_OPT_RXMODE] = &FUNCTION_NOP,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
[ACTION_OPT_REGA_ALARM] = &ACTION_RegaAlarm,
|
||||||
|
[ACTION_OPT_REGA_TEST] = &ACTION_RegaTest,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(action_opt_table) == ACTION_OPT_LEN);
|
static_assert(ARRAY_SIZE(action_opt_table) == ACTION_OPT_LEN);
|
||||||
|
@@ -96,7 +96,12 @@ void (*ProcessKeysFunctions[])(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
// This is a hack for REGA as I need a special display element only for it with no key
|
||||||
|
static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM-1);
|
||||||
|
#else
|
||||||
static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM);
|
static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void CheckForIncoming(void)
|
static void CheckForIncoming(void)
|
||||||
{
|
{
|
||||||
|
187
app/rega.c
Normal file
187
app/rega.c
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* REGA Alam and Test
|
||||||
|
* ==================
|
||||||
|
*
|
||||||
|
* This bit of code is to implement the REGA test and alarm functions.
|
||||||
|
* This function sends out a fixed ZVEI tone sequence for testing or alarm purposes.
|
||||||
|
* Further information: https://www.rega.ch/en/our-missions/sites-and-infrastructure/emergency-radio
|
||||||
|
*
|
||||||
|
* There are two REGA ACTIONS: Test and Alarm.
|
||||||
|
* The Test action sends out a fixed ZVEI tone sequence for testing purposes.
|
||||||
|
* The Alarm action sends out a fixed ZVEI tone sequence for alarm purposes.
|
||||||
|
*
|
||||||
|
* These actions can be assigned to a key in the settings menu.
|
||||||
|
*
|
||||||
|
* The Test/Alarm function will perform the following actions:
|
||||||
|
* - Set the radio to transmit mode
|
||||||
|
* - Wait 100ms to allow the radio to switch to transmit mode and stabilize the tramsmitter
|
||||||
|
* - Send out the ZVEI tone sequence
|
||||||
|
* - Wait 100ms to allow the radio to finish transmitting
|
||||||
|
* - Set the radio back to receive mode
|
||||||
|
*
|
||||||
|
* The ZVEI tone squence for alarm is: 21414
|
||||||
|
* The ZVEI tone squence for test is: 21301
|
||||||
|
*
|
||||||
|
* To save space the two tone sequences are stored as precalculated register values.
|
||||||
|
* This avoids the need to calculate the register values at runtime.
|
||||||
|
* They are hardcoded as array of 32bit integers in the rega.h file.
|
||||||
|
*
|
||||||
|
* Copyright 2025 Markus Bärtschi
|
||||||
|
* https://github.com/markusb
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "rega.h"
|
||||||
|
#include "radio.h"
|
||||||
|
#include "action.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "driver/bk4819.h"
|
||||||
|
#include "driver/st7565.h"
|
||||||
|
#include "driver/system.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "bsp/dp32g030/gpio.h"
|
||||||
|
#include "ui/helper.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
|
||||||
|
const uint16_t rega_alarm_tones[5] = {
|
||||||
|
1160, // 2 1160Hz
|
||||||
|
1060, // 1 1060Hz
|
||||||
|
1400, // 4 1400Hz
|
||||||
|
1060, // 1 1060Hz
|
||||||
|
1400, // 4 1400Hz
|
||||||
|
};
|
||||||
|
const uint16_t rega_test_tones[5] = {
|
||||||
|
1160, // 2 1160Hz
|
||||||
|
1060, // 1 1060Hz
|
||||||
|
1260, // 3 1260Hz
|
||||||
|
2400, // 0 2400Hz
|
||||||
|
1060, // 1 1060Hz
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global variable to pass the message to the display
|
||||||
|
char rega_message[16];
|
||||||
|
|
||||||
|
// Transmit the ZVEI tone sequence for alarm
|
||||||
|
void ACTION_RegaAlarm()
|
||||||
|
{
|
||||||
|
const char message[16] = "REGA Alarm";
|
||||||
|
REGA_TransmitZvei(rega_alarm_tones,message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tranmit the ZVEI tone sequence for test
|
||||||
|
void ACTION_RegaTest()
|
||||||
|
{
|
||||||
|
const char message[16] = "REGA Test";
|
||||||
|
REGA_TransmitZvei(rega_test_tones,message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the REGA message on the screen
|
||||||
|
void UI_DisplayREGA()
|
||||||
|
{
|
||||||
|
UI_DisplayClear();
|
||||||
|
UI_DisplayPopup(rega_message);
|
||||||
|
ST7565_BlitFullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transmit a ZVEI tone sequence on the REGA frequency
|
||||||
|
// Configures the radio on VFO A with the required parameters
|
||||||
|
// tones: array of 5 ZVEI tones
|
||||||
|
// message: message to display on the screen
|
||||||
|
void REGA_TransmitZvei(const uint16_t tones[],const char message[])
|
||||||
|
{
|
||||||
|
// Copy the message text
|
||||||
|
strncpy(rega_message,message,16);
|
||||||
|
// Trigger the display
|
||||||
|
gScreenToDisplay = DISPLAY_REGA;
|
||||||
|
|
||||||
|
// Flash the green LED twice
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
|
||||||
|
SYSTEM_DelayMs(70);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
|
||||||
|
SYSTEM_DelayMs(50);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
|
||||||
|
SYSTEM_DelayMs(70);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
|
||||||
|
|
||||||
|
// Select VFO A
|
||||||
|
gEeprom.TX_VFO = 0;
|
||||||
|
gEeprom.ScreenChannel[gEeprom.TX_VFO] = gEeprom.FreqChannel[gEeprom.TX_VFO];
|
||||||
|
gRxVfo = gTxVfo;
|
||||||
|
gRequestSaveVFO = true;
|
||||||
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||||
|
|
||||||
|
// Set the REGA frequency, no offset
|
||||||
|
gTxVfo->freq_config_RX.Frequency = REGA_FREQUENCY;
|
||||||
|
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX;
|
||||||
|
gTxVfo->TX_OFFSET_FREQUENCY = 0;
|
||||||
|
|
||||||
|
// Set the modulation to FM narrow
|
||||||
|
gTxVfo->Modulation = MODULATION_FM;
|
||||||
|
gTxVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_NARROW;
|
||||||
|
|
||||||
|
// Set Tx Squelch Tone
|
||||||
|
gTxVfo->freq_config_TX.CodeType = CODE_TYPE_CONTINUOUS_TONE;
|
||||||
|
gTxVfo->freq_config_TX.Code = REGA_CTCSS_FREQ_INDEX;
|
||||||
|
BK4819_SetCTCSSFrequency(CTCSS_Options[gTxVfo->freq_config_TX.Code]);
|
||||||
|
// Turn Rx squelch tone off
|
||||||
|
gTxVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
|
||||||
|
|
||||||
|
// Set the transmit power to high
|
||||||
|
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_HIGH;
|
||||||
|
|
||||||
|
// Lock the keyboard
|
||||||
|
gEeprom.KEY_LOCK = true;
|
||||||
|
|
||||||
|
gRequestSaveChannel = 1;
|
||||||
|
gRequestSaveSettings = true;
|
||||||
|
|
||||||
|
// Configure the receiver
|
||||||
|
BK4819_RX_TurnOn();
|
||||||
|
|
||||||
|
// Set the radio to transmit mode
|
||||||
|
RADIO_PrepareCssTX();
|
||||||
|
FUNCTION_Select(FUNCTION_TRANSMIT);
|
||||||
|
|
||||||
|
// Wait to allow the radio to switch to transmit mode and stabilize the transmitter
|
||||||
|
SYSTEM_DelayMs(ZVEI_PRE_LENGTH_MS);
|
||||||
|
|
||||||
|
// Send out the ZVEI2 tone sequence
|
||||||
|
for (int i = 0; i < ZVEI_NUM_TONES; i++)
|
||||||
|
{
|
||||||
|
BK4819_PlaySingleTone(tones[i], ZVEI_TONE_LENGTH_MS, 100, true);
|
||||||
|
SYSTEM_DelayMs(ZVEI_PAUSE_LENGTH_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait to allow the radio to finish transmitting
|
||||||
|
SYSTEM_DelayMs(ZVEI_POST_LENGTH_MS);
|
||||||
|
|
||||||
|
// Flash the green LED twice
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
|
||||||
|
SYSTEM_DelayMs(70);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
|
||||||
|
SYSTEM_DelayMs(70);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
|
||||||
|
SYSTEM_DelayMs(70);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
|
||||||
|
|
||||||
|
// Display the normal screen
|
||||||
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
|
}
|
65
app/rega.h
Normal file
65
app/rega.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* REGA Alam and Test
|
||||||
|
* ==================
|
||||||
|
*
|
||||||
|
* This function sends out a fixed ZVEI tone sequence for testing or alarm purposes for the Alpine REGA alarm channel.
|
||||||
|
* Further information: https://www.rega.ch/en/our-missions/sites-and-infrastructure/emergency-radio
|
||||||
|
*
|
||||||
|
* There are two REGA ACTIONS: Test and Alarm.
|
||||||
|
* The Test action sends out a fixed ZVEI tone sequence for testing purposes.
|
||||||
|
* The Alarm action sends out a fixed ZVEI tone sequence for alarm purposes.
|
||||||
|
*
|
||||||
|
* These actions can be assigned to a key in the settings menu.
|
||||||
|
*
|
||||||
|
* The Test/Alarm function will perform the following actions:
|
||||||
|
* - Set the radio configuration to the REGA frequency, CTCSS, FM, full power etc.
|
||||||
|
* - Start transmitting
|
||||||
|
* - Wait 100ms to allow the radio to switch to transmit mode and stabilize the transmitter
|
||||||
|
* - Send out the ZVEI tone sequence
|
||||||
|
* - Wait 100ms to allow the radio to finish transmitting
|
||||||
|
* - Set the radio back to receive mode
|
||||||
|
*
|
||||||
|
* The REGA frequency is 161.300 Mhz
|
||||||
|
*
|
||||||
|
* The ZVEI tone squence for alarm is: 21414
|
||||||
|
* The ZVEI tone squence for test is: 21301
|
||||||
|
*
|
||||||
|
* The two tone sequences are hardcoded in two arrays
|
||||||
|
*
|
||||||
|
* Copyright 2025 Markus Bärtschi
|
||||||
|
*
|
||||||
|
* https://github.com/markusb
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGA_H
|
||||||
|
#define REGA_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ZVEI_NUM_TONES 5
|
||||||
|
#define ZVEI_TONE_LENGTH_MS 70 // 70
|
||||||
|
#define ZVEI_PAUSE_LENGTH_MS 10 // 10
|
||||||
|
#define ZVEI_PRE_LENGTH_MS 300
|
||||||
|
#define ZVEI_POST_LENGTH_MS 100
|
||||||
|
#define REGA_CTCSS_FREQ_INDEX 18 // dcs.c: CTCSS_Options[18] = 1230
|
||||||
|
#define REGA_FREQUENCY 16130000 // 43370000 16130000
|
||||||
|
|
||||||
|
void ACTION_RegaAlarm(void);
|
||||||
|
void ACTION_RegaTest(void);
|
||||||
|
void UI_DisplayREGA(void);
|
||||||
|
void REGA_TransmitZvei(const uint16_t[], const char[]);
|
||||||
|
|
||||||
|
#endif
|
@@ -122,6 +122,10 @@ enum ACTION_OPT_t {
|
|||||||
ACTION_OPT_POWER_HIGH,
|
ACTION_OPT_POWER_HIGH,
|
||||||
ACTION_OPT_REMOVE_OFFSET,
|
ACTION_OPT_REMOVE_OFFSET,
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
ACTION_OPT_REGA_ALARM,
|
||||||
|
ACTION_OPT_REGA_TEST,
|
||||||
#endif
|
#endif
|
||||||
ACTION_OPT_LEN
|
ACTION_OPT_LEN
|
||||||
};
|
};
|
||||||
|
@@ -434,6 +434,10 @@ const t_sidefunction gSubMenu_SIDEFUNCTIONS[] =
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_TX1750
|
#ifdef ENABLE_TX1750
|
||||||
{"1750Hz", ACTION_OPT_1750},
|
{"1750Hz", ACTION_OPT_1750},
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
{"REGA\nALARM", ACTION_OPT_REGA_ALARM},
|
||||||
|
{"REGA\nTEST", ACTION_OPT_REGA_TEST},
|
||||||
#endif
|
#endif
|
||||||
{"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK},
|
{"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK},
|
||||||
{"VFO A\nVFO B", ACTION_OPT_A_B},
|
{"VFO A\nVFO B", ACTION_OPT_A_B},
|
||||||
|
7
ui/ui.c
7
ui/ui.c
@@ -30,6 +30,9 @@
|
|||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "ui/fmradio.h"
|
#include "ui/fmradio.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
#include "app/rega.h"
|
||||||
|
#endif
|
||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
#include "ui/main.h"
|
#include "ui/main.h"
|
||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
@@ -57,6 +60,10 @@ void (*UI_DisplayFunctions[])(void) = {
|
|||||||
#ifdef ENABLE_AIRCOPY
|
#ifdef ENABLE_AIRCOPY
|
||||||
[DISPLAY_AIRCOPY] = &UI_DisplayAircopy,
|
[DISPLAY_AIRCOPY] = &UI_DisplayAircopy,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_REGA
|
||||||
|
[DISPLAY_REGA] = &UI_DisplayREGA,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(UI_DisplayFunctions) == DISPLAY_N_ELEM);
|
static_assert(ARRAY_SIZE(UI_DisplayFunctions) == DISPLAY_N_ELEM);
|
||||||
|
Reference in New Issue
Block a user