From 554fef71f8195d193aec3abe3bf53878d4f5fa23 Mon Sep 17 00:00:00 2001 From: k3ng Date: Tue, 27 Feb 2024 19:44:36 -0500 Subject: [PATCH] 2024.02.27.2314 HARDWARE_MORTTY_PICO_OVER_USB - Updated for Mortty v5 --- k3ng_keyer/AudioPWMSineWave.h | 270 ++++++++++-------- k3ng_keyer/k3ng_keyer.ino | 80 +++--- k3ng_keyer/keyer_features_and_options.h | 2 +- ...eatures_and_options_mortty_pico_over_usb.h | 1 + k3ng_keyer/keyer_features_and_options_test.h | 4 +- .../keyer_pin_settings_mortty_pico_over_usb.h | 30 +- k3ng_keyer/keyer_pin_settings_test.h | 20 +- .../keyer_settings_mortty_pico_over_usb.h | 9 +- 8 files changed, 227 insertions(+), 189 deletions(-) diff --git a/k3ng_keyer/AudioPWMSineWave.h b/k3ng_keyer/AudioPWMSineWave.h index 3a4e226..7ef4273 100644 --- a/k3ng_keyer/AudioPWMSineWave.h +++ b/k3ng_keyer/AudioPWMSineWave.h @@ -1,83 +1,44 @@ #if !defined(audiopwmsinewave_h) #define audiopwmsinewave_h +// IMPORTANT: MUST INSTALL - Adriono IDE >Tools >Library Manager >RPI_PICO_TimerInterrupt #include "RPi_Pico_TimerInterrupt.h" -#include "RPi_Pico_ISR_Timer.h" +// #include "RPi_Pico_ISR_Timer.h" //- no longer needed +#include "RP2040_PWM.h" /* -Generate a PWM-based sine wave: Mortty_v5 CPU and Sidetone boards, Steve N8AR and Larry K8UT 2023-10-27 +Produce PWM GPIO output for Sinewave IO board on the Mortty_v5 IO and CPU boards, Larry K8UT 2023-12-15 + +PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W +M M OOOOO RRRR TTTTTT TTTTTT Y Y AAAAAA UU UU DDDD IIII OOOOOO +M M M M O O R RR TT TT Y Y AA AA UU UU DD DD II OO OO +M M M O O RRR TT TT YY AAAAAA UU UU DDDDDD II OO OO +M M O O R R TT TT YY AA AA UU UU DD DD II OO OO +M M OOOOO R R TT TT YY AA AA UUUUUU DDDD IIII OOOOOO + +SOURCE: http://www.arduino.cc/en/Tutorial/Blink +SOURCE: https://github.com/earlephilhower/arduino-pico/discussions/184 PWM functions in Arduino IDE +SOURCE: https://registry.platformio.org/libraries/khoih-prog/RP2040_PWM +SOURCE: https://randomnerdtutorials.com/raspberry-pi-pico-pwm-analogwrite-arduino/ +SOURCE: https://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml +This example to demo the new function setPWM_manual(uint8_t pin, uint16_t top, uint8_t div, uint16_t level, bool phaseCorrect = false) +used to generate a waveform. Check https://github.com/khoih-prog/RP2040_PWM/issues/6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software -PIPICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W PICO-W -M M OOOOO RRRR TTTTTT TTTTTT Y Y AAAAAA UU UU DDDD II OOOOO -M M M M O O R RR TT TT Y Y AA AA UU UU DD D II O O -M M M O O RRR TT TT YY AAAAAA UU UU DD DD II O O -M M O O R R TT TT YY AA AA UU UU DD D II O O -M M OOOOO R R TT TT YY AA AA UUUUUU DDDD II OOOOO +// Mortty_v5 PWM Sinewave Generator. Use 20 bits ("sices") in the sidetone array. +// SINE WAVE CALCULATED VALUES from website for 20 slices: MAX=1000, IMPORTANT: adjust MAX element from 1000 to 998 +// NOTE: variables modified from original source using Millisecond integer values rather than microSecond decimal values +// Measured INTERVAL_MS: 20=2500 Hz. 30=1663 Hz, 40=1250 Hz, 50=1000 Hz, 60=833 Hz, 70=714 Hz, 80=624 Hz, 90=556, 100=500 Hz +// Measured INTERVAL_MS: 110=453 Hz. 120=416 Hz, 130=382 Hz, 140=357 Hz, 150=333 Hz +// RTTY Mark/Space frequencies: target MARK=2125 Hz, use 190=2105 Hz -- target SPACE=2295 Hz, use 180=2222 Hz -REFERENCE MATERIAL -Nice PWM Tutorial - VIdeo: https://www.youtube.com/watch?v=Au-oc4hxj-c -Sample code - SOURCE: https://github.com/khoih-prog/RPI_PICO_TimerInterrupt -SineWaveTable - SOURCE: https://forum.arduino.cc/t/create-an-array-of-wave-data-for-wavetable-synth/1030423/13 - -// PWM PulseWidthModulation parms - timer interval must be an Unsigned Long integer "L" -// unsigned long AudioPWMTIMER_INTERVAL_US = 1000L; // this is in MICROSECONDS timer interval in microseconds -// Square wave Scope Trigger frequency -// uint32_t freqTrigger = 1000; // this is in HERTZ - -// const float AudioPWMTIMER_INTERVAL_MS = nL; this is in MICROSECONDS -// /\/\/ <10L + 500000 does not oscillate (?) BUSTED -// 10L + 500000 = 1562.6 Hz 2.4v p-p -// 11L + 500000 = 1420.4 Hz -// 12L + 500000 = 1302.1 Hz -// /\/\/ <12L causes Windows USB fault (?) - BUSTED do not use values below 13nS -// 13L + 500000 = 1201.9 Hz -// 14L + 500000 = 1106.1 Hz -// 15L + 500000 = 1041.7 Hz 2.6v p-p -// 16L + 500000 = 976.5 Hz -// 17L + 500000 = 919.1 Hz -// 18L + 500000 = 868.8 Hz -// 19L + 500000 = 822.5 Hz -// 20L + 500000 = 776.9 Hz 2.8v p-p -// 21L + 500000 = 744.0 Hz -// 22L + 500000 = 710.2 Hz -// 23L + 500000 = 679.4 Hz -// 24L + 500000 = 651.1 Hz -// 25L + 500000 = 624.9 Hz 3.0v p-p -// 26L + 500000 = 600.9 Hz -// 27L + 500000 = 573.6 Hz -// 28L + 500000 = 558.0 Hz -// 29L + 500000 = 538.8 Hz -// 30L + 500000 = 520.8 Hz 3.2v p-p -// 31L + 500000 = 504.0 Hz -// 32L + 500000 = 488.3 Hz -// 33L + 500000 = 473.5 Hz -// 34L + 500000 = 459.5 Hz -// 35L + 500000 = 446.3 Hz -// 36L + 500000 = 433.9 Hz -// 37L + 500000 = 422.2 Hz -// 38L + 500000 = 411.2 Hz -// 39L + 500000 = 400.1 Hz -// 40L + 500000 = 390.6 Hz -// 41L + 500000 = 381.1 Hz -// 42L + 500000 = 372.1 Hz 3.3v p-p - -// Low Frequencies. Do not use for CW Sidetone -// 75L + 500000 = 208.4 Hz -// 100L + 500000 = 156.2 Hz -// 125L + 500000 = 125.0 Hz -// 150L + 500000 = 104.2 Hz -// 156L + 500000 = 100.1 Hz - */ - -// // IMPORTANT: MUST INSTALL - Adriono IDE >Tools >Library Manager >RPI_PICO_TimerInterrupt -// #include "RPi_Pico_TimerInterrupt.h" -// #include "RPi_Pico_ISR_Timer.h" +version 1.0.0 2024/01/01 by k8UT +*/ // VARIABLES ////////////////////////////////////////////////////////////////// @@ -87,74 +48,133 @@ SineWaveTable - SOURCE: https://forum.arduino.cc/t/create-an-array-of-wave-data- // #define TIMER_INTERRUPT_DEBUG 1 // #define _TIMERINTERRUPT_LOGLEVEL_ 4 -void initTimer(); -bool timerISR(struct repeating_timer* t); -void writePWM_Pin(); +// Mortty_v5 Sidetone output PWM pin 16: channel PWM0A (SPI D2) +//#define pin_Sidetone 16 // GP16, PWM channel 0A (spi D2) +//#define pin_Carrier 8 -RPI_PICO_Timer AudioPWMTimer(0); // define the Mortty Audio PWM timer as a RPI_PICO_Timer -RPI_PICO_ISR_Timer AudioPWM_ISR_timer; // define the ISR Interrupt Service Request timer +volatile uint16_t sineWaveArrayPtr = 0; +volatile bool isSidetoneON = true; +volatile float sidetoneAudioHz; +float sidetoneCarrierHz; +byte pin_Sidetone = 16; // GP16, PWM channel 0A (spi D2) +byte pin_Carrier = 8; // testing purposes +volatile uint16_t sidetoneDutyCycle; -const float AudioPWMTIMER_INTERVAL_MS = 16L; // this is in MICROSECONDS timer interval in microseconds -// uint32_t freqTrigger = 500000; // this is in HERTZ. Square wave Scope Trigger frequency +// sineWave definition --------------- +typedef struct +{ + uint16_t top; + uint8_t div; + uint16_t level; +} PWD_Data; -byte pin_PWM_Output = 0; -// NOTE: Radio #1 PTT LED (13) used for scope PWM_Trigger. Do not use for production operation -// #define pin_PWM_Trigger_LED 13 // TEST Mortty R1 PTT - output blink LED at start of each cycle (NOTE: trigger channel on scope) - -// SineWaveTable - SOURCE: https://forum.arduino.cc/t/create-an-array-of-wave-data-for-wavetable-synth/1030423/13 -volatile int arrPtr = 0; // pointer for looping through SineWaveArray -const int sineWaveArray[64] = { - 127, 139, 152, 164, 176, 187, 198, 208, 217, 225, 233, 239, 244, 249, 252, - 253, 254, 253, 252, 249, 244, 239, 233, 225, 217, 208, 198, 187, 176, 164, 152, - 139, 127, 115, 102, 90, 78, 67, 56, 46, 37, 29, 21, 15, 10, 5, 3, 2, 1, 2, 3, - 5, 10, 15, 21, 29, 37, 46, 56, 67, 78, 90, 102, 115 +#define NUM_PWM_POINTS 20 +PWD_Data PWM_SINE_DATA[NUM_PWM_POINTS] = { + { 1000, 10, 0 }, // arrange sinewave array with "0" value first. Audio OFF point with 0 volts output + { 1000, 10, 24 }, + { 1000, 10, 95 }, + { 1000, 10, 206 }, + { 1000, 10, 345 }, + { 1000, 10, 500 }, + { 1000, 10, 655 }, + { 1000, 10, 794 }, + { 1000, 10, 905 }, + { 1000, 10, 976 }, + { 1000, 10, 998 }, // reduce top "1000" to "998" to nearest even integer for cleaner output + { 1000, 10, 976 }, + { 1000, 10, 905 }, + { 1000, 10, 794 }, + { 1000, 10, 655 }, + { 1000, 10, 500 }, + { 1000, 10, 345 }, + { 1000, 10, 206 }, + { 1000, 10, 95 }, + { 1000, 10, 24 } }; +RPI_PICO_Timer timerSidetone(0); //declore timerSidetone as an RPI_PICO_TIMER +RP2040_PWM* PWM_Sidetone; //declore PWM_Sidetone as a PWM output +volatile uint32_t timerSidetone_Milliseconds; // = 0; // CW audio range values from 250 Ms = 333 Hz -to- 20 Ms = 2500 Hz +// PWM_SINE_DATA_idle - sineWaveArray position of 0 volts. Resting point when sidetone == OFF +PWD_Data PWM_SINE_DATA_idle = PWM_SINE_DATA[0]; // ?does this do anything? I don't think so +// end of define variables ------------ +// //////////////////////////////////////////////////////////////////////////// +// ----- procs and functions ////////////////////////////////////////////////// - - -void initTimer() { - // -------------------------------------------------------------------------- - AudioPWMTimer.stopTimer(); // if timer is running, stop it - - if (!AudioPWMTimer.attachInterruptInterval(AudioPWMTIMER_INTERVAL_MS, timerISR)) { // if init fails, print this to console - // Serial.println(F("FAIL init AudioPWMTimer. Select another freq. or timer")); - // } else { - // Serial.println(F("SUCCESS init AudioPWMTimer")); - } -} // ----- end of initTimer() - -bool timerISR(struct repeating_timer* t) { - // ------------------------------------------------------------------------ - (void)t; - writePWM_Pin(); // do this every time the Repeating Timer fires - return true; -} // ----- end of timerISR() AudioPWM Timer Handler - -void writePWM_Pin() { - // ------------------------------------------------------------------------ - // loop through 64 bit (0-63) SineWaveArray - if (arrPtr < 63) { - arrPtr++; +void set_SidetoneOutput(int localPtr) { + // BUSTED do not print here Serial.print("."); + // increment pointer to the sinwWaveArray + if ((sineWaveArrayPtr >= (NUM_PWM_POINTS - 1)) || (!isSidetoneON)) { + sineWaveArrayPtr = 0; } else { - arrPtr = 0; - } - analogWrite(pin_PWM_Output, sineWaveArray[arrPtr]); // PWM output to audio filter -} // ----- end of writePWM+Pin() - -void PWMTone(byte pin, uint32_t hz){ - pin_PWM_Output = pin; - if (pin_PWM_Output > 0){ - analogWriteFreq(hz * 1000); - initTimer(); + sineWaveArrayPtr++; } -} + // set dutyCycle to [array element * 100] for 0->100,000 range required by (PWM_Sidetone->setPWM_Int) + PWM_Sidetone->setPWM_Int(pin_Sidetone, sidetoneCarrierHz, (PWM_SINE_DATA[sineWaveArrayPtr].level) * 100); + return; +} // end of set SidetoneOutput() ------------------------- -void noPWMTone(byte pin){ - if (pin_PWM_Output > 0){ - AudioPWMTimer.stopTimer(); - digitalWrite(pin_PWM_Output,LOW); +bool timerSidetone_Handler(struct repeating_timer* t) { + (void)t; + + set_SidetoneOutput(sineWaveArrayPtr); + // BUSTED do not print here Serial.print("."); + return true; +} // end of timerSidetone_Handler() interrupt ------------ + +// ------------------------------------ +// Interrupts - PWM generator is a repeating timer -------- +// calculate Millisecond interval = 1 / (Targer Audio in Hz ) / (NUM_PWM_POINTS (aka slices) * 1000000) + +void timerSidetone_Init() { // initialize the ISR timer interrupt routine + if (timerSidetone.attachInterruptInterval(timerSidetone_Milliseconds, timerSidetone_Handler)) { + //Serial.print("Starting timerSidetone OK, = "); + // Serial.print(timerSidetone_INTERVAL_MS * 10000); + //Serial.println(" timerSidetone interval in uS"); + } else { + //Serial.println(F("Can't set timerSidetone. Select another Timer, freq. or timer")); } -} + return; +} // end of timerSidetone_Init() ------------------------- +int32_t PWMTone(byte pin, uint32_t hz) { + // called by K3NG_KEYER.INO to start sending sidetone --- + // C++ (float) calculation for calculaint timerSidetone_Milliseconds from Audio Hertz + // = (( (float)1 / (float)Hertz ) / NUM_PWM_POINTS )*1000000 + //=====pin_PWM_Output = pin; + pin_Sidetone = pin; + if (pin == 0) { // pin#0 == sidetoneOFF + isSidetoneON = false; + timerSidetone_Milliseconds = 50; // with sidetone OFF, set timer for 50% duty cycle + } else { + sidetoneAudioHz = hz; + if (hz <= 375) { // low end of Winkeyer sidetone choices = 375 + sidetoneAudioHz = 375; + } else { // high end of PWM generator - ignore Winkey values sidetone frequencies + if (hz >= 1500) { + sidetoneAudioHz = 1500; + } + // enable for RTTY sidetones - standard MARK/SPACE tones + //if ((hz >= 2125) || (hz <= 2295)) { sidetoneAudioHz = hz; } + } + isSidetoneON = true; + timerSidetone_Milliseconds = (((float)1 / (float)sidetoneAudioHz) / NUM_PWM_POINTS) * 1000000; + + timerSidetone.stopTimer(); + timerSidetone_Init(); + } + return timerSidetone_Milliseconds; + delay(10); + +} // end of PWMTone() ------------------------------------ + +void noPWMTone(byte pin) { + // called by K3NG_KEYER.INO. Stop sending sidetone ------ + if (pin_Sidetone > 0) { + isSidetoneON = false; + PWM_Sidetone->setPWM_Int(pin_Sidetone, sidetoneCarrierHz, (PWM_SINE_DATA[0].level) * 100); + } // PWM generator never turns off, but continuously sends the "0" zero elemeent +} // end of noPWMTone() ---------------------------------- +// +// end of procedures and functions ------------------------ #endif \ No newline at end of file diff --git a/k3ng_keyer/k3ng_keyer.ino b/k3ng_keyer/k3ng_keyer.ino index 14e187f..cf2809b 100644 --- a/k3ng_keyer/k3ng_keyer.ino +++ b/k3ng_keyer/k3ng_keyer.ino @@ -1405,6 +1405,9 @@ Recent Update History OPTION_WORDSWORTH_POLISH - Polish CW training text from Piotr, SP2BPD. Thanks! Straight key capability for CW training Piotr, SP2BPD. Thanks! + 2024.02.27.2314 + HARDWARE_MORTTY_PICO_OVER_USB - Updated for Mortty v5 + qwerty Documentation: https://github.com/k3ng/k3ng_cw_keyer/wiki @@ -1435,7 +1438,7 @@ If you offer a hardware kit using this software, show your appreciation by sendi */ -#define CODE_VERSION "2024.02.17.1600" +#define CODE_VERSION "2024.02.27.2314" #define eeprom_magic_number 41 // you can change this number to have the unit re-initialize EEPROM @@ -2380,7 +2383,7 @@ void setup() #if defined(FEATURE_DUAL_MODE_KEYER_AND_TINYFSK) - check_run_tinyfsk_pin(); + check_run_tinyfsk_pin(); // read Mortty+v5 CW<->RTTY slide switch if (runTinyFSK){ TinyFSKsetup(); } else { @@ -2420,6 +2423,9 @@ void setup() } //if (runTinyFSK) #endif + initialize_audiopwmsinewave(); + + } // -------------------------------------------------------------------------------------------- @@ -2609,9 +2615,32 @@ void loop() // Subroutines -------------------------------------------------------------------------------------------- - // Are you a radio artisan ? +void initialize_audiopwmsinewave(){ + + #if defined(FEATURE_AUDIOPWMSINEWAVE) // Raspberry Pi Pico hardware only + // // SIDETONE - define the PWM ouput pin, frequency and dutyCycle + RPI_PICO_Timer timerSidetone(0); + sidetoneCarrierHz = 40000; // frequency in Hz - 1000 = 1 kilohertz. even multiple of 20 slices + sidetoneDutyCycle = 50000; // dutyCycle = real_dutyCycle * 1000, dutyCycle 50% = 50000; USE 5?4? DIGITS: "0000" == zero + PWM_Sidetone = new RP2040_PWM(pin_Sidetone, sidetoneCarrierHz, false); + if (PWM_Sidetone) { + // Serial.print("Defining PWM_Sidetone OK, = "); + // Serial.print(sidetoneCarrierHz); + // Serial.println(" slices per each Sidetone audio cycle"); + PWM_Sidetone->setPWM_Int(pin_Sidetone, sidetoneCarrierHz, sidetoneDutyCycle); + isSidetoneON = false; // launch with sideTone == OFF + } else { + Serial.println("Defining PWM_Sidetone instance FAIL"); + } // end of Sidetone definition --------------- + #endif + +} + +//------------------------------------------------------------------------------------------------------- + + #if defined(FEATURE_DUAL_MODE_KEYER_AND_TINYFSK) void check_run_tinyfsk_pin(){ @@ -2896,9 +2925,10 @@ void service_keypad(){ //------------------------------------------------------------------------------------------------------- -#ifdef FEATURE_STRAIGHT_KEY +#if defined(FEATURE_STRAIGHT_KEY) long service_straight_key(){ + long decode_character = 0; static byte last_straight_key_state = 0; if (digitalRead(pin_straight_key) == STRAIGHT_KEY_ACTIVE_STATE){ @@ -2906,13 +2936,10 @@ void service_keypad(){ sending_mode = MANUAL_SENDING; tx_and_sidetone_key(1); last_straight_key_state = 1; - - #ifdef FEATURE_MEMORIES clear_send_buffer(); repeat_memory = 255; #endif - } } else { if (last_straight_key_state){ @@ -2922,9 +2949,7 @@ void service_keypad(){ } } - #if defined(FEATURE_STRAIGHT_KEY_DECODE) - static unsigned long last_transition_time = 0; static unsigned long last_decode_time = 0; static byte last_state = 0; @@ -2935,10 +2960,8 @@ void service_keypad(){ static int no_tone_count = 0; static int tone_count = 0; byte decode_it_flag = 0; - int element_duration = 0; static float decoder_wpm = configuration.wpm; - long decode_character = 0; static byte space_sent = 0; #if defined(FEATURE_COMMAND_LINE_INTERFACE) && defined(FEATURE_STRAIGHT_KEY_ECHO) static byte screen_column = 0; @@ -2951,12 +2974,10 @@ void service_keypad(){ static byte cw_keyboard_backspace_flag = 0; #endif //defined(FEATURE_CW_COMPUTER_KEYBOARD) - - if (last_transition_time == 0) { + if (last_transition_time == 0){ if (last_straight_key_state == 1) { // is this our first tone? last_transition_time = millis(); last_state = 1; - #ifdef FEATURE_SLEEP last_activity_time = millis(); #endif //FEATURE_SLEEP @@ -2966,7 +2987,7 @@ void service_keypad(){ } else { - if ((last_decode_time > 0) && (!space_sent) && ((millis() - last_decode_time) > ((1200/decoder_wpm)*CW_DECODER_SPACE_PRINT_THRESH))) { // should we send a space? + if ((last_decode_time > 0) && (!space_sent) && ((millis() - last_decode_time) > ((1200/decoder_wpm)*CW_DECODER_SPACE_PRINT_THRESH))){ //should we send a space? #if defined(FEATURE_SERIAL) && defined(FEATURE_STRAIGHT_KEY_ECHO) #ifdef FEATURE_COMMAND_LINE_INTERFACE primary_serial_port->write(32); @@ -2991,7 +3012,7 @@ void service_keypad(){ }// should we send a space? } } else { - if (last_straight_key_state != last_state) { + if (last_straight_key_state != last_state){ // we have a transition element_duration = millis() - last_transition_time; if (element_duration > CW_DECODER_NOISE_FILTER) { // filter out noise @@ -3019,8 +3040,6 @@ void service_keypad(){ last_transition_time = millis(); if (decode_element_pointer == 16) { decode_it_flag = 1; } // if we've filled up the array, go ahead and decode it } - - } else { // no transition element_duration = millis() - last_transition_time; @@ -3034,16 +3053,15 @@ void service_keypad(){ // have we had tone for an outrageous amount of time? } } - } + } - if (decode_it_flag) { // are we ready to decode the element array? + if (decode_it_flag){ // are we ready to decode the element array? // adjust the decoder wpm based on what we got - if ((no_tone_count > 0) && (tone_count > 1)){ // NEW - + if ((no_tone_count > 0) && (tone_count > 1)){ if (decode_element_no_tone_average > 0) { if (abs((1200/decode_element_no_tone_average) - decoder_wpm) < 5) { decoder_wpm = (decoder_wpm + (1200/decode_element_no_tone_average))/2; @@ -3057,12 +3075,10 @@ void service_keypad(){ } } } - - - } // NEW + } #ifdef DEBUG_FEATURE_STRAIGHT_KEY_ECHO - if (abs(decoder_wpm - last_printed_decoder_wpm) > 0.9) { + if (abs(decoder_wpm - last_printed_decoder_wpm) > 0.9){ debug_serial_port->print("<"); debug_serial_port->print(int(decoder_wpm)); debug_serial_port->print(">"); @@ -3308,15 +3324,11 @@ void service_keypad(){ #endif //FEATURE_COMMAND_LINE_INTERFACE #endif //FEATURE_SERIAL - return(decode_character); + #endif //FEATURE_STRAIGHT_KEY_DECODE - - - - - + return(decode_character); } #endif //FEATURE_STRAIGHT_KEY @@ -17714,9 +17726,9 @@ void initialize_pins() { #ifdef FEATURE_STRAIGHT_KEY pinMode(pin_straight_key,INPUT); if (STRAIGHT_KEY_ACTIVE_STATE == HIGH){ - digitalWrite (pin_straight_key, LOW); + digitalWrite(pin_straight_key, LOW); } else { - digitalWrite (pin_straight_key, HIGH); + digitalWrite(pin_straight_key, HIGH); } #endif //FEATURE_STRAIGHT_KEY diff --git a/k3ng_keyer/keyer_features_and_options.h b/k3ng_keyer/keyer_features_and_options.h index 15f29dd..db222bf 100644 --- a/k3ng_keyer/keyer_features_and_options.h +++ b/k3ng_keyer/keyer_features_and_options.h @@ -49,7 +49,7 @@ // #define FEATURE_PTT_INTERLOCK // #define FEATURE_QLF // #define FEATURE_EEPROM_E24C1024 -#define FEATURE_STRAIGHT_KEY +// #define FEATURE_STRAIGHT_KEY // #define FEATURE_DYNAMIC_DAH_TO_DIT_RATIO // #define FEATURE_PADDLE_ECHO // you may also need to comment out line 19 in the file keyer_dependencies.h // #define FEATURE_STRAIGHT_KEY_ECHO diff --git a/k3ng_keyer/keyer_features_and_options_mortty_pico_over_usb.h b/k3ng_keyer/keyer_features_and_options_mortty_pico_over_usb.h index 0c1d813..28a2a73 100644 --- a/k3ng_keyer/keyer_features_and_options_mortty_pico_over_usb.h +++ b/k3ng_keyer/keyer_features_and_options_mortty_pico_over_usb.h @@ -121,3 +121,4 @@ // #define OPTION_BEACON_MODE_PTT_TAIL_TIME // adds the ptt tail time to each playing of memory 1 in beacon mode // #define OPTION_WINKEY_PROSIGN_COMPATIBILITY // Additional character mappings to support K1EL Winkey emulation prosigns +#define FEATURE_DUAL_MODE_KEYER_AND_TINYFSK // Mortty_v5 dual mode (CW Keyer, TinyFSK RTTY) support diff --git a/k3ng_keyer/keyer_features_and_options_test.h b/k3ng_keyer/keyer_features_and_options_test.h index 0d5f285..4b0400c 100644 --- a/k3ng_keyer/keyer_features_and_options_test.h +++ b/k3ng_keyer/keyer_features_and_options_test.h @@ -15,13 +15,13 @@ #define FEATURE_BUTTONS #define FEATURE_COMMAND_MODE -#define FEATURE_COMMAND_LINE_INTERFACE // Command Line Interface functionality +// #define FEATURE_COMMAND_LINE_INTERFACE // Command Line Interface functionality // #define FEATURE_MEMORIES // on the Arduino Due, you must have FEATURE_EEPROM_E24C1024 and E24C1024 EEPROM hardware in order to compile this // #define FEATURE_MEMORY_MACROS #define FEATURE_WINKEY_EMULATION // disabling Automatic Software Reset is highly recommended (see documentation) // #define FEATURE_BEACON // Go into beacon mode if paddle_left pin is LOW at boot up // #define FEATURE_BEACON_SETTING // Go into beacon mode at boot up if EEPROM setting is enabled (\_ CLI Command) -#define FEATURE_TRAINING_COMMAND_LINE_INTERFACE +// #define FEATURE_TRAINING_COMMAND_LINE_INTERFACE // #define FEATURE_POTENTIOMETER // do not enable unless you have a potentiometer connected, otherwise noise will falsely trigger wpm changes // #define FEATURE_SIDETONE_SWITCH // adds switch control for the sidetone output. requires an external toggle switch (assigned to an arduino pin - see keyer_pin_settings.h). // #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 diff --git a/k3ng_keyer/keyer_pin_settings_mortty_pico_over_usb.h b/k3ng_keyer/keyer_pin_settings_mortty_pico_over_usb.h index e4a542e..7ab42c5 100644 --- a/k3ng_keyer/keyer_pin_settings_mortty_pico_over_usb.h +++ b/k3ng_keyer/keyer_pin_settings_mortty_pico_over_usb.h @@ -2,26 +2,31 @@ #ifndef keyer_pin_settings_h #define keyer_pin_settings_h -#define paddle_left 2 -#define paddle_right 5 -#define tx_key_line_1 11 // (high = key down/tx on) -#define tx_key_line_2 12 +#define paddle_left 18 +#define paddle_right 19 +#define tx_key_line_1 12 // (high = key down/tx on) +#define tx_key_line_2 3 #define tx_key_line_3 0 #define tx_key_line_4 0 #define tx_key_line_5 0 #define tx_key_line_6 0 -#define sidetone_line 4 // connect a speaker for sidetone -#define potentiometer 28 // Speed potentiometer (0 to 3.3 V) Use pot from 1k to 10k -#define ptt_tx_1 13 // PTT ("push to talk") lines -#define ptt_tx_2 14 // Can be used for keying fox transmitter, T/R switch, or keying slow boatanchors -#define ptt_tx_3 0 // These are optional - set to 0 if unused +#define sidetone_line 16 // connect a speaker for sidetone. Mortty_v5 PWM output to AudioBoard +#define potentiometer 28 // Speed potentiometer (0 to 3.3 V) Use pot from 1k to 10k +#define ptt_tx_1 13 // PTT ("push to talk") lines +#define ptt_tx_2 4 // Can be used for keying fox transmitter, T/R switch, or keying slow boatanchors +#define ptt_tx_3 0 // These are optional - set to 0 if unused #define ptt_tx_4 0 #define ptt_tx_5 0 #define ptt_tx_6 0 -#define tx_key_dit 0 // if defined, goes active for dit (any transmitter) - customized with tx_key_dit_and_dah_pins_active_state and tx_key_dit_and_dah_pins_inactive_state -#define tx_key_dah 0 // if defined, goes active for dah (any transmitter) - customized with tx_key_dit_and_dah_pins_active_state and tx_key_dit_and_dah_pins_inactive_state +#define tx_key_dit 0 // if defined, goes active for dit (any transmitter) - customized with tx_key_dit_and_dah_pins_active_state and tx_key_dit_and_dah_pins_inactive_state +#define tx_key_dah 0 // if defined, goes active for dah (any transmitter) - customized with tx_key_dit_and_dah_pins_active_state and tx_key_dit_and_dah_pins_inactive_state #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 +#define jackSwitch_paddle 17 // Paddle plug insert detect - Mortty_v5. (pullup input) +#define jackSwitch_R1 15 // Radio1 plug insert detect - Mortty_v5. (pullup input) +#define jackSwitch_R2 6 // Paddle plug insert detect - Mortty_v5. (pullup input) +//NOTE: rtty_tx_1 14 // Radio1 RTTY FSK - used in Mortty_v5 DUAL MODE TinyFSK sketch (output) +//NOTE: rtty_tx_2 5 // Radio2 RTTY FSK - used in MOrtty_v5 DUAL MODE TinyFSK sketch (output) #ifdef FEATURE_BUTTONS #define analog_buttons_pin A1 @@ -155,5 +160,4 @@ FEATURE_SIDETONE_SWITCH #error "Multiple pin_settings.h files included somehow..." -#endif //keyer_pin_settings_h - +#endif //keyer_pin_settings_h \ No newline at end of file diff --git a/k3ng_keyer/keyer_pin_settings_test.h b/k3ng_keyer/keyer_pin_settings_test.h index c6a36b7..e5dee84 100644 --- a/k3ng_keyer/keyer_pin_settings_test.h +++ b/k3ng_keyer/keyer_pin_settings_test.h @@ -14,18 +14,18 @@ // Raspbery Pi Pico: paddle_right = 3 sidetone_line = 6 //Mega test Jig / Standard Pins -// #define paddle_left 2 -// #define paddle_right 5 -// #define sidetone_line 4 -// #define potentiometer A0 -// #define ptt_tx_1 13 // PTT ("push to talk") lines +#define paddle_left 2 +#define paddle_right 5 +#define sidetone_line 4 +#define potentiometer A0 +#define ptt_tx_1 13 // PTT ("push to talk") lines //Raspberry Pi Pico Test Jig -#define paddle_left 2 -#define paddle_right 3 -#define sidetone_line 15 -#define potentiometer 26 -#define ptt_tx_1 0 // PTT ("push to talk") lines +// #define paddle_left 2 +// #define paddle_right 3 +// #define sidetone_line 15 +// #define potentiometer 26 +// #define ptt_tx_1 0 // PTT ("push to talk") lines #define tx_key_line_1 11 // (high = key down/tx on) #define tx_key_line_2 0 diff --git a/k3ng_keyer/keyer_settings_mortty_pico_over_usb.h b/k3ng_keyer/keyer_settings_mortty_pico_over_usb.h index 762f002..3f10345 100644 --- a/k3ng_keyer/keyer_settings_mortty_pico_over_usb.h +++ b/k3ng_keyer/keyer_settings_mortty_pico_over_usb.h @@ -72,10 +72,11 @@ #define serial_program_memory_buffer_size 500 #define eeprom_write_time_ms 30000 -//FEATURE_DUAL_MODE_KEYER_AND_TINYFSK -#define pin_run_tinyfsk 0 // assert this pin HIGH at boot up to go into TinyFSK mode, LOW to go into keyer mode -#define pin_rtty_running 0 // output - goes HIGH when TinyFSK is running -#define pin_keyer_running 0 // output - goes HIGH when Keyer is running +// CW<->RTTY DUAL MODE control - rear-panel slide switch: pin HIGH default = CW mode, LOW = TinyFSK mode +// The "pin_run_tinyfsk" is only queried at boot, selecting the CW Keyer or TinyFSK RTTY sketch to launch +#define pin_run_tinyfsk 20 // HIGH=CW, LOW=RTTY rear-panel mode slide switch (pullup input) +#define pin_keyer_running 1 // HIGH when CW Keyer is running. rear-panel green status LED (output) +#define pin_rtty_running 2 // HIGH when TinyFSK is running. rear-panel yellow status LED (output) #ifdef FEATURE_BUTTONS #define analog_buttons_number_of_buttons 4