2023.10.01.1410

FEATURE_DUAL_MODE_KEYER_AND_TINYFSK: eeprom should be working now
      Raspberry Pi Pico now supported for everything except PS2 keyboard and sleep
pull/143/head
k3ng 2023-10-01 10:51:23 -04:00
rodzic 42d20abc1a
commit 587250e9be
6 zmienionych plików z 138 dodań i 65 usunięć

Wyświetl plik

@ -80,9 +80,8 @@ RPI_PICO_Timer FSKTimer(0);
#define R2_FSK_PIN 6
#define R2_PTT_PIN 8
//EEPROM addresses to persist configuration
#define EE_SPEED_ADDR 0
#define EE_POLARITY_ADDR 1
//Special Baudot symbols for shift
#define LTRS_SHIFT 0x1F //baudot letter shift byte
@ -167,6 +166,12 @@ void echo(byte b);
/******************************************************
Variable declarations
*******************************************************/
//EEPROM addresses to persist configuration
int ee_speed_addr;
int ee_polarity_addr;
// Mapping of ascii to baudot symbols. This is the
// translation table that maps an incoming ASCII byte
// on the serial interface to a equivalent (or reasonable
@ -380,14 +385,14 @@ void handleConfigurationCommand(byte oneByte) {
{
mark = HIGH;
space = LOW;
//===== EEPROM.write(EE_POLARITY_ADDR, b);
EEPROM.write(ee_polarity_addr, COMMAND_POLARITY_MARK_HIGH);
break;
}
case (COMMAND_POLARITY_MARK_LOW):
{
mark = LOW;
space = HIGH;
//===== EEPROM.write(EE_POLARITY_ADDR, b);
EEPROM.write(ee_polarity_addr, COMMAND_POLARITY_MARK_LOW);
break;
}
case (COMMAND_45BAUD):
@ -395,7 +400,7 @@ void handleConfigurationCommand(byte oneByte) {
baudrate = 45.45;
FSKTIMER_INTERVAL_US = 11001;
initTimer();
//===== EEPROM.write(EE_SPEED_ADDR, b);
EEPROM.write(ee_speed_addr, COMMAND_45BAUD);
break;
}
case (COMMAND_50BAUD):
@ -403,7 +408,7 @@ void handleConfigurationCommand(byte oneByte) {
baudrate = 50.0;
FSKTIMER_INTERVAL_US = 10000L;
initTimer();
//===== EEPROM.write(EE_SPEED_ADDR, b);
EEPROM.write(ee_speed_addr, COMMAND_50BAUD);
break;
}
case (COMMAND_75BAUD):
@ -411,7 +416,7 @@ void handleConfigurationCommand(byte oneByte) {
baudrate = 75.0;
FSKTIMER_INTERVAL_US = 6666L;
initTimer();
//===== EEPROM.write(EE_SPEED_ADDR, b);
EEPROM.write(ee_speed_addr, COMMAND_75BAUD);
break;
}
case (COMMAND_DUMP_CONFIG):
@ -432,10 +437,9 @@ void handleConfigurationCommand(byte oneByte) {
* Loads speed and polarity from EEPROM
*/
void eeLoad() {
// byte speedChar = EEPROM.read(EE_SPEED_ADDR);
byte speedChar = COMMAND_45BAUD;
// byte polarity = EEPROM.read(EE_POLARITY_ADDR);
byte polarity = COMMAND_POLARITY_MARK_LOW;
byte speedChar = EEPROM.read(ee_speed_addr);
byte polarity = EEPROM.read(ee_polarity_addr);
if (polarity == COMMAND_POLARITY_MARK_LOW) {
mark = LOW;
@ -779,6 +783,34 @@ Main execution
* configuration from EEPROM.
*/
void TinyFSKsetup() { // ==============================================================================================
#ifdef __LGT8FX8P__
/* LGT chip emulates EEPROM at the cost of giving up twice the space in program flash memory.
* Unortunately, the last 4 bytes of every 1KB block are read-only. Therefore
* EEPROM.length() would return 1024 (readable EEPROM size), while EEPROM.size() returns 1020
* (writable EEPROM size). The following line will give the right figure for LGT.
*/
ee_speed_addr = EEPROM.size() - 1;
ee_polarity_addr = EEPROM.size() - 2;
#elif (!defined(ARDUINO_SAM_DUE) && !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO) && !defined(HARDWARE_GENERIC_STM32F103C)) || (defined(ARDUINO_SAM_DUE) && defined(FEATURE_EEPROM_E24C1024))
ee_speed_addr = EEPROM.length() - 1;
ee_polarity_addr = EEPROM.length() - 2;
#elif defined(HARDWARE_GENERIC_STM32F103C)
ee_speed_addr = 252;
ee_polarity_addr = 253;
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_RASPBERRY_PI_PICO)
ee_speed_addr = 4094;
ee_polarity_addr = 4095;
#else
// assume eeprom size of 1024 and hope for the best
ee_speed_addr = 1022;
ee_polarity_addr = 1023;
#endif
Serial.begin(serialSpeed);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only

Wyświetl plik

@ -1381,6 +1381,10 @@ Recent Update History
2023.09.29.2043
FEATURE_WINKEY_EMULATION: corrected pot_full_scale_reading
2023.10.01.1410
FEATURE_DUAL_MODE_KEYER_AND_TINYFSK: eeprom should be working now
Raspberry Pi Pico now supported for everything except PS2 keyboard and sleep
Documentation: https://github.com/k3ng/k3ng_cw_keyer/wiki
Support: https://groups.io/g/radioartisan ( Please do not email K3NG directly for support. Thanks )
@ -1587,7 +1591,7 @@ If you offer a hardware kit using this software, show your appreciation by sendi
#define noTone noNewTone
#endif //FEATURE_SIDETONE_NEWTONE
#if defined(FEATURE_SLEEP)
#if defined(FEATURE_SLEEP) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
#include <avr/sleep.h> // It should be different library for ARM sp5iou
#endif
@ -2394,14 +2398,12 @@ void loop()
// this is where the magic happens
#if defined(FEATURE_DUAL_MODE_KEYER_AND_TINYFSK)
if (runTinyFSK){
TinyFSKloop();
} else {
if (runTinyFSK){
TinyFSKloop();
} else {
#endif
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -2428,7 +2430,7 @@ void loop()
check_serial();
#endif
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif // OPTION_WATCHDOG_TIMER
@ -2499,7 +2501,7 @@ void loop()
update_led_ring();
#endif
#ifdef FEATURE_SLEEP
#if defined(FEATURE_SLEEP) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
check_sleep();
#endif
@ -3457,7 +3459,7 @@ void wakeup() {
#endif //FEATURE_SLEEP
*/
#ifdef FEATURE_SLEEP // Code contributed by Graeme, ZL2APV 2016-01-18
#if defined(FEATURE_SLEEP) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO) // Code contributed by Graeme, ZL2APV 2016-01-18
void wakeup() {
sleep_disable();
detachInterrupt (0);
@ -3514,7 +3516,7 @@ void check_sleep(){
*/
#ifdef FEATURE_SLEEP // Code contributed by Graeme, ZL2APV 2016-01-18
#if defined(FEATURE_SLEEP) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO) // Code contributed by Graeme, ZL2APV 2016-01-18
void check_sleep(){
if ((millis() - last_activity_time) > ((unsigned long)go_to_sleep_inactivity_time*60000)){
@ -7119,7 +7121,7 @@ void loop_element_lengths(float lengths, float additional_time_ms, int speed_wpm
}
#endif //FEATURE_INTERNET_LINK
#if defined(OPTION_WATCHDOG_TIMER)
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -7370,7 +7372,7 @@ long get_cw_input_from_user(unsigned int exit_time_milliseconds) {
while (looping) {
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -7468,7 +7470,7 @@ void command_mode() {
debug_serial_port->println(F("command_mode: entering"));
#endif
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_disable();
#endif //OPTION_WATCHDOG_TIMER
@ -8229,7 +8231,7 @@ void command_mode() {
paddle_echo_buffer = 0;
#endif
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_enable(WDTO_4S);
#endif //OPTION_WATCHDOG_TIMER
@ -8645,7 +8647,7 @@ void command_keying_compensation_adjust() {
}
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -8687,7 +8689,7 @@ void command_dah_to_dit_ratio_adjust() {
}
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -8728,7 +8730,7 @@ void command_weighting_adjust() {
looping = 0;
}
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -8766,7 +8768,7 @@ void command_tuning_mode() {
key_tx = 1;
while (looping) {
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -8898,7 +8900,7 @@ void command_sidetone_freq_adj() {
looping = 0;
}
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -8974,7 +8976,7 @@ void command_speed_mode(byte mode) {
looping = 0;
}
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -9566,7 +9568,7 @@ void send_the_dits_and_dahs(char const * cw_to_send){
#endif
#endif
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -13388,7 +13390,7 @@ void sd_card_clear_log_file(PRIMARY_SERIAL_CLS * port_to_use,String filename) {
sd_card_log_state = SD_CARD_LOG_NOT_OPEN;
if (!sdfile){
port_to_use->println(F("Unable to open file "));
sd_card_state = SD_CARD_ERROR;
sd_card_state = SD_CARD_ERROR_;
sd_card_log_state = SD_CARD_LOG_ERROR;
}
sdlogfile.close();
@ -17632,7 +17634,7 @@ void initialize_pins() {
digitalWrite(compression_detection_pin,LOW);
#endif //FEATURE_COMPETITION_COMPRESSION_DETECTION
#if defined(FEATURE_SLEEP)
#if defined(FEATURE_SLEEP) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
if (keyer_awake){
pinMode(keyer_awake,OUTPUT);
digitalWrite(keyer_awake,KEYER_AWAKE_PIN_AWAKE_STATE);
@ -18138,20 +18140,39 @@ void initialize_keyer_state(){
switch_to_tx_silent(1);
#endif
#ifdef __LGT8FX8P__
/* LGT chip emulates EEPROM at the cost of giving up twice the space in program flash memory.
* Unortunately, the last 4 bytes of every 1KB block are read-only. Therefore
* EEPROM.length() would return 1024 (readable EEPROM size), while EEPROM.size() returns 1020
* (writable EEPROM size). The following line will give the right figure for LGT.
*/
memory_area_end = EEPROM.size() - 1;
#elif (!defined(ARDUINO_SAM_DUE) && !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO) && !defined(HARDWARE_GENERIC_STM32F103C)) || (defined(ARDUINO_SAM_DUE) && defined(FEATURE_EEPROM_E24C1024))
memory_area_end = EEPROM.length() - 1;
#else
#if defined(HARDWARE_GENERIC_STM32F103C)
memory_area_end = 254;
#if !defined(FEATURE_DUAL_MODE_KEYER_AND_TINYFSK)
#ifdef __LGT8FX8P__
/* LGT chip emulates EEPROM at the cost of giving up twice the space in program flash memory.
* Unortunately, the last 4 bytes of every 1KB block are read-only. Therefore
* EEPROM.length() would return 1024 (readable EEPROM size), while EEPROM.size() returns 1020
* (writable EEPROM size). The following line will give the right figure for LGT.
*/
memory_area_end = EEPROM.size() - 1;
#elif (!defined(ARDUINO_SAM_DUE) && !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO) && !defined(HARDWARE_GENERIC_STM32F103C)) || (defined(ARDUINO_SAM_DUE) && defined(FEATURE_EEPROM_E24C1024))
memory_area_end = EEPROM.length() - 1;
#else
memory_area_end = 1024; // not sure if this is a valid assumption
#if defined(HARDWARE_GENERIC_STM32F103C)
memory_area_end = 254;
#else
memory_area_end = 1024; // not sure if this is a valid assumption
#endif
#endif
#else
#ifdef __LGT8FX8P__
/* LGT chip emulates EEPROM at the cost of giving up twice the space in program flash memory.
* Unortunately, the last 4 bytes of every 1KB block are read-only. Therefore
* EEPROM.length() would return 1024 (readable EEPROM size), while EEPROM.size() returns 1020
* (writable EEPROM size). The following line will give the right figure for LGT.
*/
memory_area_end = EEPROM.size() - 1 - 2;
#elif (!defined(ARDUINO_SAM_DUE) && !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO) && !defined(HARDWARE_GENERIC_STM32F103C)) || (defined(ARDUINO_SAM_DUE) && defined(FEATURE_EEPROM_E24C1024))
memory_area_end = EEPROM.length() - 1 - 2;
#else
#if defined(HARDWARE_GENERIC_STM32F103C)
memory_area_end = 254 - 2;
#else
memory_area_end = 1024 - 2; // not sure if 1024 is a valid assumption
#endif
#endif
#endif
@ -18217,7 +18238,7 @@ void initialize_default_modes(){
void initialize_watchdog(){
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_enable(WDTO_4S);
#endif //OPTION_WATCHDOG_TIMER
@ -18594,7 +18615,7 @@ void blink_ptt_dits_and_dahs(char const * cw_to_send){
}
#ifdef OPTION_WATCHDOG_TIMER
#if defined(OPTION_WATCHDOG_TIMER) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
wdt_reset();
#endif //OPTION_WATCHDOG_TIMER
@ -20332,7 +20353,7 @@ void web_print_page_about(EthernetClient client){
web_client_println(client,CODE_VERSION);
web_client_println(client,"<br>");
#if !defined(HARDWARE_GENERIC_STM32F103C)
#if !defined(HARDWARE_GENERIC_STM32F103C) && !defined(ARDUINO_RASPBERRY_PI_PICO_W) && !defined(ARDUINO_RASPBERRY_PI_PICO)
void* HP = malloc(4);
if (HP){
free (HP);
@ -22044,7 +22065,7 @@ void service_sd_card(){
if (sdfile){
sd_card_state = SD_CARD_AVAILABLE_BEACON_FILE_RUNNING;
} else {
sd_card_state = SD_CARD_ERROR;
sd_card_state = SD_CARD_ERROR_;
}
}

Wyświetl plik

@ -227,7 +227,7 @@
#define SD_CARD_AVAILABLE 1
#define SD_CARD_AVAILABLE_BEACON_FILE_FOUND 2
#define SD_CARD_AVAILABLE_BEACON_FILE_RUNNING 3
#define SD_CARD_ERROR 254
#define SD_CARD_ERROR_ 254
#define SD_CARD_LOG_NOT_OPEN 0
#define SD_CARD_LOG_OPEN 1

Wyświetl plik

@ -15,7 +15,7 @@
#define FEATURE_SIDETONE_NEWTONE // Use the NewTone library, ~1k smaller code size than the standard tone library. Uses timer1 (pins 9 or 10) https://bitbucket.org/teckel12/arduino-new-tone/wiki/Home
#define FEATURE_SERIAL_HELP
#define FEATURE_HELL
#define FEATURE_PS2_KEYBOARD // Use a PS2 keyboard to send code - Change keyboard layout (non-US) in K3NG_PS2Keyboard.h. Additional options below.
// #define FEATURE_PS2_KEYBOARD // Use a PS2 keyboard to send code - Change keyboard layout (non-US) in K3NG_PS2Keyboard.h. Additional options below.
// #define FEATURE_USB_KEYBOARD // Use a USB keyboard to send code - Uncomment three lines in k3ng_keyer.ino (search for note_usb_uncomment_lines)
// #define FEATURE_CW_COMPUTER_KEYBOARD // Have an Arduino Due or Leonardo act as a USB HID (Human Interface Device) keyboard and use the paddle to "type" characters on the computer
#define FEATURE_DEAD_OP_WATCHDOG

Wyświetl plik

@ -184,7 +184,7 @@ FEATURE_SIDETONE_SWITCH
#define pin_sending_mode_automatic 0 // goes HIGH when keyer is sending code automatically
#define pin_sending_mode_manual 0 // goes HIGH when keyer is sending code manually (i.e. the paddle or straight key)
#define pin_run_tinyfsk 0
#define pin_run_tinyfsk 0 // assert this pin HIGH at boot up to go into TinyFSK mode
#else

Wyświetl plik

@ -43,15 +43,25 @@
#define so2r_rx_s 10 // Stereo receive selected (optional, set to zero if not used)
#ifdef FEATURE_SO2R_SWITCHES
#define so2r_tx_switch A5 // TX switch, low if TX1, high if TX2
#define so2r_rx1_switch A4 // RX 1 switch, low if RX1, high if RX2 or stereo
#define so2r_rx2_switch A3 // RX 2 switch, low if RX2, high if RX1 or stereo
#if defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_RASPBERRY_PI_PICO)
#define so2r_tx_switch 20 // TX switch, low if TX1, high if TX2
#define so2r_rx1_switch 21 // RX 1 switch, low if RX1, high if RX2 or stereo
#define so2r_rx2_switch 22 // RX 2 switch, low if RX2, high if RX1 or stereo
#else
#define so2r_tx_switch A5 // TX switch, low if TX1, high if TX2
#define so2r_rx1_switch A4 // RX 1 switch, low if RX1, high if RX2 or stereo
#define so2r_rx2_switch A3 // RX 2 switch, low if RX2, high if RX1 or stereo
#endif
#endif
#define potentiometer_enable_pin 0 // if defined, the potentiometer will be enabled only when this pin is held low; set to 0 to ignore this pin
#ifdef FEATURE_BUTTONS
#define analog_buttons_pin A1
#if defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_RASPBERRY_PI_PICO)
#define analog_buttons_pin 28
#else
#define analog_buttons_pin A1
#endif
#define command_mode_active_led 0
#endif //FEATURE_BUTTONS
@ -97,9 +107,15 @@
#endif //FEATURE_ROTARY_ENCODER
#ifdef FEATURE_LED_RING
#define led_ring_sdi A10 //2 //Data
#define led_ring_clk A9 //3 //Clock
#define led_ring_le A8 //4 //Latch
#if defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_RASPBERRY_PI_PICO)
#define led_ring_sdi 24 //Data
#define led_ring_clk 25 //Clock
#define led_ring_le 26 //Latch
#else
#define led_ring_sdi A10 //2 //Data
#define led_ring_clk A9 //3 //Clock
#define led_ring_le A8 //4 //Latch
#endif
#endif //FEATURE_LED_RING
#define correct_answer_led 0
@ -109,8 +125,12 @@
#define ptt_interlock 0 // this pin disables PTT and TX KEY
#endif //FEATURE_PTT_INTERLOCK
#ifdef FEATURE_STRAIGHT_KEY
#define pin_straight_key A5 //52 // pin 52 doesn't work right when FEATURE_WEB_SERVER is active. don't know why 2016-04-26
#if defined(FEATURE_STRAIGHT_KEY)
#if defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_RASPBERRY_PI_PICO)
#define pin_straight_key 15
#else
#define pin_straight_key A5 //52 // pin 52 doesn't work right when FEATURE_WEB_SERVER is active. don't know why 2016-04-26
#endif
#endif //FEATURE_STRAIGHT_KEY
// FEATURE_CW_DECODER & OPTION_CW_DECODER_GOERTZEL_AUDIO_DETECTOR