From 704eb9faadd3e1e3c2e7e8ac7885bfff0ca1eec7 Mon Sep 17 00:00:00 2001 From: "Tom, DL7BJ" Date: Mon, 4 Sep 2023 00:24:24 +0200 Subject: [PATCH] =?UTF-8?q?Ein=20Taster=20f=C3=BCr=20TRX1/TRX2=20Umschaltu?= =?UTF-8?q?ng=20durch=20Konfiguration=20m=C3=B6glich.=20Speicher-=20und=20?= =?UTF-8?q?Speichertexte=20begonnen.=20Sendefunktionen=20von=20Texten=20hi?= =?UTF-8?q?nzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/#main.c# | 361 +++++++++++++++++++++++++++++++++++++++++++++ Source/Makefile | 2 +- Source/controls.c | 29 ++-- Source/functions.c | 110 +++++++++++--- Source/functions.h | 5 +- Source/globals.h | 34 ++--- Source/main.c | 52 +++---- Source/main.h | 2 + Source/memory.c | 71 +++++++++ Source/vt100.c | 2 +- 10 files changed, 583 insertions(+), 85 deletions(-) create mode 100644 Source/#main.c# create mode 100644 Source/memory.c diff --git a/Source/#main.c# b/Source/#main.c# new file mode 100644 index 0000000..7779521 --- /dev/null +++ b/Source/#main.c# @@ -0,0 +1,361 @@ +/** @brief BJ-Keyer + + Morsekeyer von DL7BJ + tom@dl7bj.de + + OLED functions from https://github.com/Sylaina/oled-display + +@verbatim + History + -------------------------------------------------------------------------- + 2012-05-24 DL7BJ erste Version + 2013-05-10 DL7BJ Generierung des Mithörtons als Sinus mit PWM/DDS + 2013-07-15 DL7BJ Änderungen der Keyerfunktionen + 2013-07-19 DL7BJ Beep/Boop (Spielkram) + 2013-10-20 DL7BJ Änderungen der PWM Funktionen für besseren Sinus + 2022-04-10 DL7BJ erste Leiterplatten für Prototyp (bisher Lochraster) + 2022-09-02 DL7BJ viele Softwareänderungen, neuer Filter für PWM + 2022-09-11 DL7BJ Encoder, LC-Display, Frontplatine "entsorgt" + 2023-06-28 DL7BJ Port Anpassungen an neue Leiterplatte V1.01 + 2023-07-29 DL7BJ Menü für Einstellungen implementiert + 2023-08-06 DL7BJ Quelltexte umstrukturiert, Aufteilung + 2023-08-25 DL7BJ Code dokumentiert und aufgeräumt + + ATMEGA328(P) + ---------- + (PCINT14/_RESET) PC6 -| 1 28|- PC5 (ADC5/SCL/PCINT13) + (PCINT16/RXD) PD0 -| 2 27|- PC4 (ADC4/SDA/PCINT12) + (PCINT17/TXT) PD1 -| 3 26|- PC3 (ADC3/PCINT11) + (PCINT18/INT0) PD2 -| 4 25|- PC2 (ADC2/PCINT10) + (PCINT19/OC2B/INT1) PD3 -| 5 24|- PC1 (ADC1/PCINT9) + (PCINT20/XCK/T0) PD4 -| 6 23|- PC0 (ADC0/PCINT8) + VCC -| 7 22|- GND + GND -| 8 21|- AREF + (PCINT6/XTAL1/TOSC1) PB6 -| 9 20|- AVCC + (PCINT7/XTAL2/TOSC2) PB7 -|10 19|- PB5 (SCK/PCINT5) + (PCINT21/OC0B/T1) PD5 -|11 18|- PB4 (MISO/PCINT4) + (PCINT22/OC0A/AIN0) PD6 -|12 17|- PB3 (MOSI/OC2A/PCINT3) + (PCINT23/AIN1) PD7 -|13 16|- PB2 (SS/OC1B/PCINT2) + (PCINT0/CLK0/ICP1) PB0 -|14 15|- PB1 (OC1A/PCINT1) + ---------- + + Pin 1 - PC6 - Reset Pin 28 - PC5 - SCL Display + Pin 2 - PD0 - RxD Pin 27 - PC4 - SDA Display + Pin 3 - PD1 - TxD Pin 26 - PC3 - LED Key + Pin 4 - PD2 - Left Paddle Pin 25 - PC2 - TRX 2 Out + Pin 5 - PD3 - Right Paddle Pin 24 - PC1 - TRX 1 Out + Pin 6 - PD4 - Straight Key Pin 23 - PC0 - Mem 4 + Pin 19 - PB5 - Mem 5 + Pin 11 - PD5 - Mem 1 Pin 18 - PB4 - _Audio SD + Pin 12 - PD6 - Mem 2 Pin 17 - OC2A - Audio PWM output + Pin 13 - PD7 - Mem 3 Pin 16 - PB2 - Encoder Switch + Pin 14 - PB0 - Encoder A Pin 15 - PB1 - Encoder B + +@endverbatim +*/ + +#include "main.h" + +// Sinustabelle für PWM mit 64 Werten +const unsigned char sinewave[] PROGMEM = { + 0x00, 0x01, 0x02, 0x05, 0x0a, 0x0f, 0x15, 0x1d, 0x25, 0x2f, 0x39, 0x43, 0x4f, 0x5a, 0x67, 0x73, + 0x80, 0x8c, 0x98, 0xa5, 0xb0, 0xbc, 0xc6, 0xd0, 0xda, 0xe2, 0xea, 0xf0, 0xf5, 0xfa, 0xfd, 0xfe, + 0xff, 0xfe, 0xfd, 0xfa, 0xf5, 0xf0, 0xea, 0xe2, 0xda, 0xd0, 0xc6, 0xbc, 0xb0, 0xa5, 0x98, 0x8c, + 0x80, 0x73, 0x67, 0x5a, 0x4f, 0x43, 0x39, 0x2f, 0x25, 0x1d, 0x15, 0x0f, 0x0a, 0x05, 0x02, 0x01 +}; + +/** @fn void InitTimer(void) + * @brief Initialsieren der Timer + * + * Alle Parameter der Timer basieren auf 16MHz Systemtakt. + * + * Timer 0 - 8 Bit timer für 1ms + * Timer 2 - 8 Bit timer für PWM zur Erzeugung des Sinustons + * Timer 1A - 16 Bit timer zur Erzeugung der Hüllkurve + * @param none + * @return none + */ +void InitTimer(void) +{ + cli(); + // Timer 2 PWM + TCCR2A = 0; + TCCR2B = 0; + // No prescaling + sbi(TCCR2B,CS20); + // Clear OC2A on compare match + sbi(TCCR2A,COM2A1); + // Fast PWM Mode + sbi(TCCR2A,WGM20); + sbi(TCCR2A,WGM21); + // Initial value + OCR2A = 0x80; + sbi(DDRB,PB3); + cbi(TIMSK2,OCIE0A); + // Timer 1 für die Sinus Hüllkurve + TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0; + // CTC Mode + sbi(TCCR1B,WGM12); + // Prescaling 8 + sbi(TCCR1B,CS11); + // Output Compare Match Interrupt Enable + OCR1A = 51; // 600Hz + sbi(TIMSK1,OCIE1A); // Timer 1 Sinus Hüllkurve einschalten + // Timer 0 1ms für diverse Zähler + TCCR0A = 0; TCCR0B = 0; TCNT0 = 0; + cbi(TCCR0A,WGM00); + sbi(TCCR0A,WGM01); + cbi(TCCR0B,WGM02); // CTC Mode 2 Immediate + cbi(TCCR0B,CS02); + sbi(TCCR0B,CS01); + sbi(TCCR0B,CS00); // prescaler 64 + OCR0A = 249; // CTC 1ms + sbi(TIMSK0,OCIE0A); // Timer 0 1ms einschalten + sei(); +} +/** @fn void Init(void) + * @brief Initialisierung aller Variablen, Timer + * @param none + * @return none + */ +void Init(void) +{ + cli(); // disable all interrupts + bState.SendStatus = SENDING_NOTHING; + // PORTB + DDRB = 0x00; + // Interne PullUps einschalten + sbi(PORTB,PB0); + sbi(PORTB,PB1); + sbi(PORTB,PB2); + sbi(PORTB,PB3); + // Tasten + sbi(PORTD,MEM1); + sbi(PORTD,MEM2); + sbi(PORTD,MEM3); + sbi(PORTC,MEM4); + sbi(PORTB,MEM5); + + sbi(PORTB,AUDIO_EN); + // Ein- und Ausgänge festlegen + // PORTB Ausgänge + sbi(DDRB,PB3); // PWM + sbi(DDRB,AUDIO_EN); // Audio Verstärker + // PORTC Ausgänge + sbi(DDRC,MORSE_LED); // LED + sbi(DDRC,TRX1); // Transceiver 1 + sbi(DDRC,TRX2); // Transceiver 2 + // PORTD Eingänge + DDRD = 0x00; + // Interne PullUps für die Eingänge abschalten + cbi(PORTD,LEFT_PADDLE); + cbi(PORTD,RIGHT_PADDLE); + cbi(PORTD,STRAIGHT_KEY); + // Serielle Schnittstelle + UBRR0=UBRR_VALUE; // Set baud rate + sbi(UCSR0B,TXEN0); // Enable TX + sbi(UCSR0B,RXEN0); // Enable RX + sbi(UCSR0B,RXCIE0); // RX complete interrupt + sbi(UCSR0C,UCSZ01); // no parity, 1 stop bit + sbi(UCSR0C,UCSZ01); // 8-bit data + + // Alle Timer Variablen rücksetzen + StateRiseTimeCounter = 0; + MenuCtrlTimer = 0; + EncoderTimer = 0; + StoreEEprom = 0; + t_elementlength = 0; + t_delayms = 0; + // Timer initialisieren + InitTimer(); + // Encoder initialisieren + EncoderInit(); + // Initialisierung Menüvariablen + bMenuCtrl.ClrScr = 1; + bMenuCtrl.Update = 1; + bMenuCtrl.Config = 0; + bMenuCtrl.buttonPressed = 0; + bMenuCtrl.buttonPressedLong = 0; + bMenuCtrl.WriteEEprom = 0; + sei(); // enable all interrupts +} +/** @fn ISR(TIMER1_COMPA_vect) + * @brief 8 Bit Timer 1 ISR routine + * + * Der Timer 1 lädt die Sinuswerte für die PWM + * + * params: none + * return: none +*/ +ISR(TIMER1_COMPA_vect) +{ + ocr2a = pgm_read_byte_near(sinewave+icnt); + icnt++; + if(StateRiseTime > 0) + OCR2A = (ocr2a >> StateRiseTime); + else + OCR2A = ocr2a; + + if(icnt == SINEWAVELENGTH) + { + icnt = 0; + if(bState.SidetoneOff == 0) + { + if(StateRiseTime > 0) + { + StateRiseTimeCounter++; + if(StateRiseTimeCounter > bConfig.RiseTimeCounter) + StateRiseTime--; + } + } + if(bState.SidetoneOff == 1) + { + if(StateRiseTime < bConfig.RiseTime) + { + StateRiseTimeCounter++; + if(StateRiseTimeCounter > bConfig.RiseTimeCounter) + StateRiseTime++; + } else { + OCR2A = 0; + cbi(TIMSK1,OCIE1A); + } + } + } +} +/** @fn ISR(TIMER0_COMPA_vect) + * @brief 8 Bit Timer 0 ISR routine + * + * Der Timer 0 mit CTC Interrupt läuft mit einem Takt + * von einer Millisekunde Es werden mehrere Werte innerhalb + * des Timerinterrupts verarbeitet. + * + * params: none + * return: none + */ +ISR(TIMER0_COMPA_vect) +{ + t_delayms++; // 16Bit Zähler für Warteschleifen + t_elementlength++; // Länge eines Symbols + StoreEEprom++; // Zähler für Zeitablauf speichern EEprom + MenuCtrlTimer++; // Zähler für Zeitablauf Einstellungen + EncoderTimer++; // Zähler für 5ms Drehencoder Timer + + // Alle 5ms den Drehencoder abfragen + if(EncoderTimer > 5) + { + EncoderTimer = 0; + EncoderPolling(); + // Schalter vom Drehencoder abfragen + lastButton = EncoderGetButtonState(); + if(lastButton == ButtonPressed_Short) + { + bMenuCtrl.buttonPressed = 1; + } + if(lastButton == ButtonPressed_Long) + { + bMenuCtrl.buttonPressedLong = 1; + if(bMenuCtrl.Config == 1) + bState.WriteEEprom = 1; + } + } + // WpM verändert? Nach 5 Sekunden im EEPROM Speichern + if((StoreEEprom > 1000) && (bState.WpMChanged)) + { + bState.WriteWpMEEprom = 1; + bState.WpMChanged = 0; + } + // Softwareentprellung für StraightKey + TimerStraightKeyPressed++; + if(StateStraightKeyPressed == KEY_PRESSED_DEBOUNCE) + { + if(TimerStraightKeyPressed > bConfig.DebounceTime) + StateStraightKeyPressed = KEY_PRESSED; + } + // Softwarentprellung für Paddle + TimerPaddleDitKeyPressed++; + if(StatePaddleDitKeyPressed == KEY_PRESSED_DEBOUNCE) + { + if(TimerPaddleDitKeyPressed > bConfig.DebounceTime) + StatePaddleDitKeyPressed = KEY_PRESSED; + } + // Softwarentprellung für Paddle + TimerPaddleDahKeyPressed++; + if(StatePaddleDahKeyPressed == KEY_PRESSED_DEBOUNCE) + { + if(TimerPaddleDahKeyPressed > bConfig.DebounceTime) + StatePaddleDahKeyPressed = KEY_PRESSED; + } +} +/** @fn ISR(USART_RX_vect) + * @brief Interrupt RX serielle Schnittstelle + * + * @param none + * @return none + */ +ISR(USART_RX_vect) +{ + unsigned char data; + data = UDR0; + SerialWriteChar(data); +} +/** @fn void ReStart(void) + * @brief Initialisierung bei Reset und Power On + * @param none + * @return none + */ +void ReStart(void) +{ + bState.SendStatus = SENDING_NOTHING; + Init(); + DisplayVersion(); + ReadEEprom(); + WpM = bConfig.WpM; + EncoderPos = bConfig.WpM; + EncoderWrite(bConfig.WpM); + EncoderPosConfig = 1; + SetFrequency(bConfig.SidetoneFreq); + KeyerMode = bConfig.KeyerMode; + PaddleMode = bConfig.Reverse; + bState.KeyTX = 1; + bState.KeyState = 0; + if(bConfig.SidetoneEnabled) + SidetoneEnable(); + else + SidetoneDisable(); + SetRatio(); + SetWeight(); +} +/** @fn int main(void) + * @brief One Infinite Loop + * @param none + * @return none + */ +int main(void) +{ + ReStart(); + SerialAbout(); + SerialMenue(); + while(1) + { + // Wenn Geschwindigkeit verändert und Zeit abgelaufen, + // dann neue Geschwindigkeit im EEprom speichern und + // Merker löschen. + if(bState.WriteWpMEEprom) + { + WriteEEpromWpM(); + bState.WriteWpMEEprom = 0; + } + // Wenn Einstellungen verändert wurde, diese im EEprom + // speichern + if(bState.WriteEEprom) + { + WriteEEprom(); + bState.WriteEEprom = 0; + } + Drehencoder(); // Drehencoder abfragen + UpdateDisplay(); // Display aktualisieren + CheckStraightKey(); // Handtaste auf Betätigung prüfen + CheckPaddles(); // Paddles auf Betätigung prüfen + CheckButtons(); + } +} diff --git a/Source/Makefile b/Source/Makefile index 39eff45..c7c6ac9 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -46,7 +46,7 @@ FORMAT = ihex TARGET = BJ-Keyer # List C source files here. (C dependencies are automatically generated.) -SRC = main.c oled/i2c.c oled/lcd.c oled/font.c encoder.c controls.c functions.c vt100.c +SRC = main.c oled/i2c.c oled/lcd.c oled/font.c encoder.c controls.c functions.c vt100.c memory.c # List Assembler source files here. # Make them always end in a capital .S. Files ending in a lowercase .s diff --git a/Source/controls.c b/Source/controls.c index 854549d..a0d1236 100644 --- a/Source/controls.c +++ b/Source/controls.c @@ -6,8 +6,6 @@ #include "controls.h" // Stringkonstanten für das Display - -// Programm Info const char sTrx1[] = "TRX 1"; const char sTrx2[] = "TRX 2"; const char IambicA[] = "Iambic A"; @@ -43,7 +41,7 @@ void Drehencoder(void) EncoderPos = st; // neuen Werte in EncoderPos speichern WpM = bConfig.WpM; // neuen Wert in WpM übernehmen cli(); - StoreEEprom = 0; // Timer 0 Variable löschen für Update EEprom + StoreEEpromTimer = 0; // Timer 0 Variable löschen für Update EEprom sei(); SetRatio(); SetWeight(); @@ -185,8 +183,8 @@ void Drehencoder(void) bMenuCtrl.SubMenue = 1; EncoderPosSubConfig = EncoderRead(1); break; - case M_SPEEDRATIO: - bConfig.SpeedRatioEnabled = (bConfig.SpeedRatioEnabled == 1) ? 0 : 1; + case M_MEMBUTTONMODE: + bConfig.MemButtonMode = (bConfig.MemButtonMode == 1) ? 0 : 1; bMenuCtrl.m_buttonPressed = 0; break; } @@ -377,12 +375,12 @@ void ConfigMenue(void) sprintf(line,"%s %ims",DebounceTime, bConfig.DebounceTime); lcd_puts(line); break; - case M_SPEEDRATIO: + case M_MEMBUTTONMODE: lcd_gotoxy(0,3); - if(bConfig.SpeedRatioEnabled) - sprintf(line,"[%s]","va.Ratio"); + if(bConfig.MemButtonMode == 1) + sprintf(line,"[%s]","TRX Sw."); else - sprintf(line," %s ","va.Ratio"); + sprintf(line,"[%s]","Textsp."); lcd_puts(line); break; } @@ -443,16 +441,17 @@ void UpdateDisplay(void) lcd_gotoxy(0,0); if(bConfig.Trx1 == 1) sprintf(line, "%s", sTrx1); + else + sprintf(line, " "); + lcd_puts(line); + lcd_gotoxy(6,0); if(bConfig.Trx2 == 1) sprintf(line, "%s", sTrx2); - if((bConfig.Trx1 == 1) && (bConfig.Trx2 == 1)) - sprintf(line, "%s %s", sTrx1, sTrx2); + else + sprintf(line, " "); lcd_puts(line); lcd_gotoxy(0,6); - if(bConfig.SpeedRatioEnabled) - sprintf(line,"Ratio auto."); - else - sprintf(line, "R 1:%.1f",(float)bConfig.Ratio/10); + sprintf(line, "R 1:%.1f",(float)bConfig.Ratio/10); lcd_puts(line); lcd_gotoxy(9,6); sprintf(line, "W %i", bConfig.Weight); diff --git a/Source/functions.c b/Source/functions.c index 89fa0f2..d358cd1 100644 --- a/Source/functions.c +++ b/Source/functions.c @@ -14,7 +14,7 @@ uint8_t ee_KeyerMode EEMEM = 1; // Iambic A, Iambic B oder Ultimati uint8_t ee_SidetoneEnabled EEMEM = 1; // Mithörton eingeschaltet uint8_t ee_WpMBpM EEMEM = 0; // WpM oder BpM Anzeige uint8_t ee_Reverse EEMEM = 0; // linkes/rechtes Paddle vertauschen -uint8_t ee_SpeedRatioEnabled EEMEM = 0; // Ratio von der Geschwindigkeit abhängig +uint8_t ee_MemButtonMode EEMEM = 0; // Ratio von der Geschwindigkeit abhängig uint8_t ee_Ratio EEMEM = 30; // Punkt/Strich Verhältnis 1:3 uint8_t ee_Weight EEMEM = 50; // Punkt/Strich Gewichtung uint8_t ee_Memory EEMEM = 0; // Punkt/Strich Speicher @@ -112,7 +112,7 @@ void WriteEEprom(void) eeprom_write_byte(&ee_SidetoneEnabled, bConfig.SidetoneEnabled); eeprom_write_byte(&ee_WpMBpM, bConfig.WpMBpM); eeprom_write_byte(&ee_Reverse, bConfig.Reverse); - eeprom_write_byte(&ee_SpeedRatioEnabled, bConfig.SpeedRatioEnabled); + eeprom_write_byte(&ee_MemButtonMode, bConfig.MemButtonMode); eeprom_write_byte(&ee_Weight, bConfig.Weight); eeprom_write_byte(&ee_Ratio, bConfig.Ratio); eeprom_write_byte(&ee_Memory, bConfig.Memory); @@ -165,16 +165,14 @@ void SetEEprom(void) bConfig.SidetoneEnabled = 1; bConfig.WpMBpM = 1; bConfig.Reverse = 0; - bConfig.SpeedRatioEnabled = 0; + bConfig.MemButtonMode = 1; bConfig.Weight = 50; bConfig.Ratio = 30; bConfig.Memory = 0; - bConfig.RiseTime = 5; - bConfig.RiseTimeCounter = 5; + bConfig.RiseTime = 6; + bConfig.RiseTimeCounter = 8; bConfig.DebounceTime = 5; WriteEEprom(); - - sprintf(bMessage.Msg1,"CQ CQ CQ DE DL7BJ DL7BJ DL7BJ PSE K\n"); } /** @fn void ReadEEprom(void) * @brief Einstellungen aus dem EEprom lesen @@ -199,7 +197,7 @@ void ReadEEprom(void) bConfig.SidetoneEnabled = eeprom_read_byte(&ee_SidetoneEnabled); bConfig.WpMBpM = eeprom_read_byte(&ee_WpMBpM); bConfig.Reverse = eeprom_read_byte(&ee_Reverse); - bConfig.SpeedRatioEnabled = eeprom_read_byte(&ee_SpeedRatioEnabled); + bConfig.MemButtonMode = eeprom_read_byte(&ee_MemButtonMode); bConfig.Ratio = eeprom_read_byte(&ee_Ratio); bConfig.Weight = eeprom_read_byte(&ee_Weight); bConfig.Memory = eeprom_read_byte(&ee_Memory); @@ -320,8 +318,67 @@ void TXKey(uint8_t State) */ void CheckButtons(void) { + static uint8_t ButtonPressed; + static uint8_t TrxButtonPressed = 0; + ButtonPressed = 0; if(!(PINB & (1< 0) + { + if(StateButtonPressed == NO_KEY_PRESSED) + { + StateButtonPressed = KEY_PRESSED_DEBOUNCE; + TimerButtonPressed = 0; + } + if(StateButtonPressed == KEY_PRESSED) + { + if((bConfig.MemButtonMode) && (ButtonPressed == 5)) + { + if(TrxButtonPressed == 0) + { + bConfig.Trx1 = 1; + bConfig.Trx2 = 0; + } + if(TrxButtonPressed == 1) + { + bConfig.Trx1 = 0; + bConfig.Trx2 = 1; + } + if(TrxButtonPressed == 2) + { + bConfig.Trx1 = 1; + bConfig.Trx2 = 1; + } + if(TrxButtonPressed == 3) + { + bConfig.Trx1 = 0; + bConfig.Trx2 = 0; + } + StateButtonPressed = NO_KEY_PRESSED; + bMenuCtrl.Update = 1; + TrxButtonPressed++; + if(TrxButtonPressed > 3) TrxButtonPressed = 0; + } else { + if(bState.Automatic == 0) + { + bState.Automatic = 1; + StateButtonPressed = NO_KEY_PRESSED; + SendMemory(ButtonPressed); + } else { + StateButtonPressed = NO_KEY_PRESSED; + bState.Automatic = 0; + } + } + } + } } /** @fn void CheckStraightKey(void) * @brief Fragt die Handtasteneingänge ab und gibt das @@ -346,8 +403,11 @@ void CheckStraightKey(void) } if(StateStraightKeyPressed == KEY_PRESSED) { + bState.Automatic = 0; if(bState.SendStatus == SENDING_NOTHING) + { TXKey(1); + } } } } @@ -371,6 +431,7 @@ void CheckPaddles(void) { if(bState.DitPressed || bState.DahPressed) { + bState.Automatic = 0; if(bState.DitPressed && !bState.DahPressed) SendDit(); else if(bState.DahPressed && !bState.DitPressed) @@ -454,10 +515,7 @@ void CheckDahPaddle(void) void SetRatio(void) { DitMillis = 1200 / WpM; - if(bConfig.SpeedRatioEnabled) - DahMillis = DitMillis * (float)(bState.WpMCorrectFactor / 10); - else - DahMillis = DitMillis * (float)(bConfig.Ratio/10); + DahMillis = DitMillis * (float)(bConfig.Ratio/10); } /** @fn void GetWpMCorrectFactor(void) * @brief Ermittelt den Korrekturfaktor für das Ratio @@ -511,7 +569,7 @@ void SendSymbol(uint8_t Dit) */ void SendDit(void) { - if((bState.SendStatus == NOTHING) || (bState.SendStatus == SENDING_DAH)) + if((bState.SendStatus == SENDING_NOTHING) || (bState.SendStatus == SENDING_DAH)) { bState.DitPressed = 0; bState.SendStatus = SENDING_DIT; @@ -529,7 +587,7 @@ void SendDit(void) */ void SendDah(void) { - if((bState.SendStatus == NOTHING) || (bState.SendStatus == SENDING_DIT)) + if((bState.SendStatus == SENDING_NOTHING) || (bState.SendStatus == SENDING_DIT)) { bState.DahPressed = 0; bState.SendStatus = SENDING_DAH; @@ -652,19 +710,25 @@ void BeepBoop(void) void SendString(char *s) { - int c; - while(*s != 0x00) + while((*s != 0x00) && (bState.Automatic == 1)) { - if(*s != 0x20) + if(*s != 0x20) { SendChar(*s); + DelayMilliSeconds(3*DitMillis); + } else if (*s == 0x20) { - DelayMilliSeconds(7*DahMillis); + DelayMilliSeconds(7*DitMillis); } - *s++; + s++; + Drehencoder(); + CheckPaddles(); + CheckButtons(); + CheckStraightKey(); + if(bState.Automatic == 0) break; } + bState.Automatic = 0; } - void SendChar(unsigned char c) { switch(c) @@ -672,10 +736,10 @@ void SendChar(unsigned char c) // Buchstaben case 'A': SendDit(); SendDah(); break; case 'B': SendDah(); SendDit(); SendDit(); SendDit(); break; - case 'C': SendDit(); SendDah(); SendDit(); SendDah(); break; + case 'C': SendDah(); SendDit(); SendDah(); SendDit(); break; case 'D': SendDah(); SendDit(); SendDit(); break; case 'E': SendDit(); break; - case 'F': SendDit(); SendDah(); SendDit(); SendDit(); break; + case 'F': SendDit(); SendDit(); SendDah(); SendDit(); break; case 'G': SendDah(); SendDah(); SendDit(); break; case 'H': SendDit(); SendDit(); SendDit(); SendDit(); break; case 'I': SendDit(); SendDit(); break; diff --git a/Source/functions.h b/Source/functions.h index b844fbe..d8d119e 100644 --- a/Source/functions.h +++ b/Source/functions.h @@ -19,10 +19,11 @@ void SymbolLoop(uint8_t Len); void CheckPaddles(void); void SetRatio(void); void SetWeight(void); - void SendDit(void); void SendDah(void); void SendIambic(void); +void SendChar(unsigned char c); +void SendString(char *s); // Sidetone void SideToneOn(void); void SideToneOff(void); @@ -48,4 +49,6 @@ void SerialWriteChar(unsigned char data); void DelayMilliSeconds(uint16_t ms); void ResetMilliSeconds(void); uint16_t GetMilliSeconds(void); +// Externals +extern void SendMemory(uint8_t ButtonPressed); #endif diff --git a/Source/globals.h b/Source/globals.h index 5e31df0..7ab7345 100644 --- a/Source/globals.h +++ b/Source/globals.h @@ -45,7 +45,7 @@ #define CALL " DL7BJ " #define PRG " BJ-Keyer " -#define VER " V1.00 " +#define VER " V1.02 " // Keying states #define NOTHING 0 @@ -68,6 +68,7 @@ #define SENDING_DAH 2 #define SENDING_SPC 3 #define SENDING_STRAIGHT 4 +#define SENDING_AUTOMATIC 5 // Sending Type #define AUTO 0 // Automatische Pausen zwischen Elementen #define MAN 1 // Manuelle Pausen zwischen Elementen @@ -106,19 +107,15 @@ #define M_MEMORY 8 #define M_REVERSE 9 #define M_RATIO 10 -#define M_SPEEDRATIO 11 -#define M_WEIGHT 12 -#define M_WPMBPM 13 +#define M_WEIGHT 11 +#define M_WPMBPM 12 +#define M_MEMBUTTONMODE 13 #define M_RISETIME 14 #define M_DEBOUNCE 15 #define M_MAX 15 // maximale Menuepunke // LCD #define CLEARLINE " " #define NORMAL 0 -// Texte -#define CQ "CQ" -#define DE "DE" -#define K "PSE K" // Debugausgabe char sdebug[64]; @@ -131,6 +128,7 @@ struct State uint8_t SidetoneOff: 1; // Mithörton an oder aus uint8_t SidetoneEnabled: 1; // Mithörton ein- oder ausgeschaltet uint8_t SendStatus; // Status, ob Symbol gesendet wird + uint8_t Automatic; // Speicher wird gesendet uint8_t LastSymbolWasDit: 1; // letztes Symbol war ein Punkt uint8_t DitPressed: 1; // Dit Hebel betätigt uint8_t DahPressed: 1; // Dah Hebel betätigt @@ -161,10 +159,10 @@ struct Config uint8_t SidetoneEnabled: 1; // Mithörton eingeschaltet uint8_t WpMBpM: 1; // WpM oder BpM Anzeige uint8_t Reverse: 1; // linkes/rechtes Paddle vertauschen - uint8_t SpeedRatioEnabled: 1; // Punkt/Strich Verhältnis Auto uint8_t Ratio; // Punkt/Strich Verhältnis 1:3 uint8_t Weight; // Punkt/Strich Gewichtung uint8_t Memory:1; // Punkt/Strich Speicher + uint8_t MemButtonMode:1; // Button 5 als Umschalter TRX oder Speichertaste uint16_t SidetoneFreq; // Frequenz des Mithörtons uint8_t WpM; // WpM uint8_t RiseTime; // Anstiegszeit Sinuston @@ -173,15 +171,11 @@ struct Config }; struct Message { - char Msg1[100]; - char Msg2[100]; - char Msg3[100]; - char Msg4[100]; - char Msg5[100]; - char Call[16]; - char Locator[6]; - char QTH[32]; - char Name[16]; + char Msg1[80]; + char Msg2[80]; + char Msg3[80]; + char Msg4[80]; + char Msg5[80]; }; // Pin Change Interrupt Merker für Port @@ -194,7 +188,7 @@ volatile int8_t EncoderPos; // Encoderposition für WpM/BpM volatile int8_t EncoderPosConfig; // Encoderposition für Einstellungen volatile int8_t EncoderPosSubConfig; // Encoderposition für Submenues -uint16_t StoreEEprom; +uint16_t StoreEEpromTimer; // Globale Variablen für diverse Zwecke uint8_t WpM; @@ -218,6 +212,8 @@ volatile uint8_t StatePaddleDitKeyPressed; // Merker für Paddle betätigt volatile uint8_t TimerPaddleDitKeyPressed; // Timer Variable für Entprellung volatile uint8_t StatePaddleDahKeyPressed; // Merker für Paddle betätigt volatile uint8_t TimerPaddleDahKeyPressed; // Timer Variable für Entprellung +volatile uint8_t StateButtonPressed; // Merker für Speichertaste betätigt +volatile uint8_t TimerButtonPressed; // Timer Variable für Entprellung volatile uint8_t StateRiseTimeCounter; // Zähler für Anstieg des Mithörtons volatile uint8_t StateRiseTime; volatile uint8_t StateRiseTimeCounter; diff --git a/Source/main.c b/Source/main.c index 7779521..1e93078 100644 --- a/Source/main.c +++ b/Source/main.c @@ -122,35 +122,27 @@ void Init(void) { cli(); // disable all interrupts bState.SendStatus = SENDING_NOTHING; - // PORTB - DDRB = 0x00; + // Alle Ports auf Eingang + DDRB = 0x00; DDRD = 0x00; DDRC = 0x00; // Interne PullUps einschalten - sbi(PORTB,PB0); - sbi(PORTB,PB1); - sbi(PORTB,PB2); - sbi(PORTB,PB3); - // Tasten - sbi(PORTD,MEM1); - sbi(PORTD,MEM2); - sbi(PORTD,MEM3); - sbi(PORTC,MEM4); - sbi(PORTB,MEM5); - - sbi(PORTB,AUDIO_EN); - // Ein- und Ausgänge festlegen + sbi(PORTB,PB0); // Encoder A + sbi(PORTB,PB1); // Encoder B + sbi(PORTB,PB2); // Encoder Switch + // Eingänge für Speichertasten + sbi(PORTD,MEM1); // PD5 + sbi(PORTD,MEM2); // PD6 + sbi(PORTD,MEM3); // PD7 + sbi(PORTC,MEM4); // PC0 + sbi(PORTB,MEM5); // PB5 + // Ausgänge festlegen // PORTB Ausgänge sbi(DDRB,PB3); // PWM sbi(DDRB,AUDIO_EN); // Audio Verstärker + sbi(PORTB,AUDIO_EN); // Audio Verstärker Enable // PORTC Ausgänge sbi(DDRC,MORSE_LED); // LED sbi(DDRC,TRX1); // Transceiver 1 sbi(DDRC,TRX2); // Transceiver 2 - // PORTD Eingänge - DDRD = 0x00; - // Interne PullUps für die Eingänge abschalten - cbi(PORTD,LEFT_PADDLE); - cbi(PORTD,RIGHT_PADDLE); - cbi(PORTD,STRAIGHT_KEY); // Serielle Schnittstelle UBRR0=UBRR_VALUE; // Set baud rate sbi(UCSR0B,TXEN0); // Enable TX @@ -163,7 +155,7 @@ void Init(void) StateRiseTimeCounter = 0; MenuCtrlTimer = 0; EncoderTimer = 0; - StoreEEprom = 0; + StoreEEpromTimer = 0; t_elementlength = 0; t_delayms = 0; // Timer initialisieren @@ -236,7 +228,7 @@ ISR(TIMER0_COMPA_vect) { t_delayms++; // 16Bit Zähler für Warteschleifen t_elementlength++; // Länge eines Symbols - StoreEEprom++; // Zähler für Zeitablauf speichern EEprom + StoreEEpromTimer++; // Zähler für Zeitablauf speichern EEprom MenuCtrlTimer++; // Zähler für Zeitablauf Einstellungen EncoderTimer++; // Zähler für 5ms Drehencoder Timer @@ -259,7 +251,7 @@ ISR(TIMER0_COMPA_vect) } } // WpM verändert? Nach 5 Sekunden im EEPROM Speichern - if((StoreEEprom > 1000) && (bState.WpMChanged)) + if((StoreEEpromTimer > 1000) && (bState.WpMChanged)) { bState.WriteWpMEEprom = 1; bState.WpMChanged = 0; @@ -285,6 +277,14 @@ ISR(TIMER0_COMPA_vect) if(TimerPaddleDahKeyPressed > bConfig.DebounceTime) StatePaddleDahKeyPressed = KEY_PRESSED; } + TimerButtonPressed++; + if(StateButtonPressed == KEY_PRESSED_DEBOUNCE) + { + if(TimerButtonPressed > 250) + { + StateButtonPressed = KEY_PRESSED; + } + } } /** @fn ISR(USART_RX_vect) * @brief Interrupt RX serielle Schnittstelle @@ -318,12 +318,14 @@ void ReStart(void) PaddleMode = bConfig.Reverse; bState.KeyTX = 1; bState.KeyState = 0; + bState.Automatic = 0; if(bConfig.SidetoneEnabled) SidetoneEnable(); else SidetoneDisable(); SetRatio(); SetWeight(); + SetStandardMsg(); } /** @fn int main(void) * @brief One Infinite Loop @@ -345,7 +347,7 @@ int main(void) WriteEEpromWpM(); bState.WriteWpMEEprom = 0; } - // Wenn Einstellungen verändert wurde, diese im EEprom + // Wenn Einstellungen verändert wurden, diese im EEprom // speichern if(bState.WriteEEprom) { diff --git a/Source/main.h b/Source/main.h index 8654d29..43fe57d 100644 --- a/Source/main.h +++ b/Source/main.h @@ -25,8 +25,10 @@ void ReStart(void); extern void CheckDahPaddle(void); extern void CheckDitPaddle(void); extern void CheckStraightKey(void); +extern void CheckButtons(void); extern void SetFrequency(uint16_t f); extern void DitDahBuffers(void); +extern void SetStandardMsg(void); extern void DahPaddle(void); extern void DitPaddle(void); diff --git a/Source/memory.c b/Source/memory.c new file mode 100644 index 0000000..9bb58bc --- /dev/null +++ b/Source/memory.c @@ -0,0 +1,71 @@ +/** @file morse.c + * @brief Funktionen für die Ausgabe von Speichertexten + * @author Tom, DL7BJ + */ + +#include "globals.h" +#include "functions.h" + +extern void SendChar(unsigned char c); +extern void SendString(char *s); + +/** @fn SetStandardMsg(void) + * @brief Schreibt Standardnachrichten in den EEprom Speicher + * wenn dieses leer ist (nach dem Flashen des Controllers) + * @param none + * @return none + */ +void SetStandardMsg(void) +{ +// 1 2 3 4 5 6 7 8 9 +// 123456789012345678901234567890123456789012345678901234567890123456789012345678901235678901234567890 + sprintf(bMessage.Msg4, + "CQ CQ CQ DE DL7BJ DL7BJ DL7BJ PSE K"); + sprintf(bMessage.Msg3, + "NAME IS TOM TOM = QTH NR OLDENBURG OLDENBURG"); + sprintf(bMessage.Msg2, + "QSL VIA BUREAU OK = TNX FER NICE QSO = 73"); + sprintf(bMessage.Msg1, + "CQ RBN TEST CQ RBN TEST CQ RBN TEST DE DL7BJ DL7BJ DL7BJ PSE NO QSO"); +} + +/** @fn endMemory(uint8_t MemoryIndex) + * @brief Sendet den Text eines Speichers + * + * @param Nummer des Speichers + * @return none + */ +void SendMemory(uint8_t MemoryIndex) +{ + switch(MemoryIndex) + { + case 1: + SendString(bMessage.Msg1); + break; + case 2: + SendString(bMessage.Msg2); + break; + case 3: + SendString(bMessage.Msg3); + break; + case 4: + SendString(bMessage.Msg4); + break; + case 5: + SendString(bMessage.Msg5); + break; + } +} + +void ReadTextMsg(unsigned char *s) +{ +} +/** @fn WriteMsg(unsigned char *) + * @brief Textspeicher schreiben + * @param Zeiger auf Zeichenkette + * @return none + */ +void WriteTextMsg(unsigned char *s) +{ + +} diff --git a/Source/vt100.c b/Source/vt100.c index c447230..6fe7f52 100644 --- a/Source/vt100.c +++ b/Source/vt100.c @@ -44,7 +44,7 @@ void SerialSetup(void) SerialWriteString(sdebug); sprintf(sdebug,"Memory : %i\r\n", bConfig.Memory); SerialWriteString(sdebug); - sprintf(sdebug,"SpeedRatio : %i\r\n", bConfig.SpeedRatioEnabled); + sprintf(sdebug,"MemButtonMode : %i\r\n", bConfig.MemButtonMode); SerialWriteString(sdebug); sprintf(sdebug,"RiseTime : %i\r\n", bConfig.RiseTime); SerialWriteString(sdebug);