From 957ac1fa8d8d532ad1ecc0612afc15c97db9b62b Mon Sep 17 00:00:00 2001 From: "Tom, DL7BJ" Date: Sun, 6 Aug 2023 23:11:24 +0200 Subject: [PATCH] Umstrukturierung des Quellcodes in mehr Dateien --- Source/BJ-Keyer.eep | 2 +- Source/Makefile | 3 +- Source/controls.c | 317 +++++++++++++++++++++ Source/controls.h | 26 ++ Source/functions.c | 350 +++++++++++------------ Source/functions.h | 30 +- Source/{bj-keyer.h => globals.h} | 232 ++++++--------- Source/main.c | 466 ++++--------------------------- Source/main.h | 36 +++ 9 files changed, 716 insertions(+), 746 deletions(-) create mode 100644 Source/controls.c create mode 100644 Source/controls.h rename Source/{bj-keyer.h => globals.h} (52%) create mode 100644 Source/main.h diff --git a/Source/BJ-Keyer.eep b/Source/BJ-Keyer.eep index 93aabd0..5da742a 100644 --- a/Source/BJ-Keyer.eep +++ b/Source/BJ-Keyer.eep @@ -1,2 +1,2 @@ -:080000000032005802000C550B +:080000000203005802010C5537 :00000001FF diff --git a/Source/Makefile b/Source/Makefile index 0f88cee..e310153 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 +SRC = main.c oled/i2c.c oled/lcd.c oled/font.c encoder.c controls.c functions.c # List Assembler source files here. # Make them always end in a capital .S. Files ending in a lowercase .s @@ -134,7 +134,6 @@ SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt SCANF_LIB = MATH_LIB = -lm - # External memory options # 64 KB of external RAM, starting after internal RAM (ATmega128!), diff --git a/Source/controls.c b/Source/controls.c new file mode 100644 index 0000000..e147c6f --- /dev/null +++ b/Source/controls.c @@ -0,0 +1,317 @@ +/** @file controls.c + * @brief Display und Bedienelemente + * @author Tom, DL7BJ + */ + +#include "controls.h" + +// Stringkonstanten für das Display +const char CALL[] = " DL7BJ "; +const char PRG[] = " BJ-Keyer "; +const char VER[] = " V1.0 "; +const char Trx1[] = "TRX 1"; +const char Trx2[] = "TRX 2"; +const char IambicA[] = "Iambic A"; +const char IambicB[] = "Iambic B"; +const char Ratio[] = "Ratio"; +const char ReverseRL[] = " L - R °"; +const char ReverseLR[] = " L ° R -"; +const char SideToneOnOff[] = "Mithörton"; +const char SideToneFreq[] = "Frequenz"; +const char RiseTime[] = "Anstieg"; +const char DebounceTime[] = "Entprl."; +const char Yes[] = "J"; +const char No[] = "N"; +const char Hz[] = "Hz"; + +void Drehencoder(void) +{ + int st = 0; + static int last; + + if(!(bMenuCtrl.Config)) + { + EncoderMinMax(5,50); + st = EncoderRead(1); + if(bConfig.WpM != st) + { + bConfig.WpM = st; // neuen Wert in bConfig speichern + bMerker.WpMChanged = 1; // Merker für Timer 0 setzen + bMenuCtrl.Update = 1; // Merker für UpdateDisplay setzen + 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 + sei(); + } + } + + if((bMenuCtrl.buttonPressed == 1) && (bMenuCtrl.Config == 0)) + { + bMenuCtrl.Config = 1; + MenuCtrlTimer = 0; + bMenuCtrl.buttonPressed = 0; + EncoderPos = EncoderRead(1); + bMenuCtrl.CurMenue = EncoderPosConfig; + EncoderWrite(EncoderPosConfig); + bMenuCtrl.Update = 1; + } + + if((bMenuCtrl.buttonPressedLong == 1) && (bMenuCtrl.Config == 1)) + { + bMenuCtrl.Config = 0; + bMenuCtrl.Update = 1; + bMenuCtrl.buttonPressedLong = 0; + bMenuCtrl.buttonPressed = 0; + bMenuCtrl.m_buttonPressed = 0; + MenuCtrlTimer = 0; + EncoderPosConfig = EncoderRead(1); + EncoderWrite(EncoderPos); + bMenuCtrl.ClrScr = 1; + Beep(); + } + + if(bMenuCtrl.Config == 1) + { + if(!bMenuCtrl.buttonPressed) + { + EncoderMinMax(1,M_MAX); + st = EncoderRead(1); + sprintf(sdebug,"Encoder %i\r\n",st); + if(last != st) + { + SendSerialString(sdebug); + bMenuCtrl.CurMenue = st; + bMenuCtrl.Update = 1; + } + last = st; + } + + if(bMenuCtrl.buttonPressed) + { + bMenuCtrl.m_buttonPressed = 1; + bMenuCtrl.buttonPressed = 0; + } + + if(bMenuCtrl.m_buttonPressed == 1) + { + UpdateDisplay(); + switch(bMenuCtrl.CurMenue) + { + case M_TRX1: + if(bConfig.TRX == 2) + bConfig.TRX = 0; + else + bConfig.TRX = 1; + bMenuCtrl.m_buttonPressed = 0; + break; + case M_TRX2: + if(bConfig.TRX == 1) + bConfig.TRX = 0; + else + bConfig.TRX = 2; + bMenuCtrl.m_buttonPressed = 0; + break; + case M_IAMBICA: + bConfig.IambicMode = 1; + bMenuCtrl.m_buttonPressed = 0; + break; + case M_IAMBICB: + bConfig.IambicMode = 2; + bMenuCtrl.m_buttonPressed = 0; + break; + case M_REVERSE: + if(bConfig.Reverse == 1) + bConfig.Reverse = 0; + else + bConfig.Reverse = 1; + bMenuCtrl.m_buttonPressed = 0; + if(bConfig.Reverse == 1) + PaddleMode = PADDLE_REVERSE; + else + PaddleMode = PADDLE_NORMAL; + bMenuCtrl.Update = 1; + break; + case M_RATIO: + EncoderMinMax(15,30); + st = EncoderRead(1); + bConfig.Ratio = st; + if(bConfig.Ratio > 30) bConfig.Ratio = 30; + if(bConfig.Ratio < 15) bConfig.Ratio = 15; + bMenuCtrl.Update = 1; + break; + case M_TON_FREQ: + break; + } + } + } +} + + +void ConfigMenue(void) +{ + char line[22]; + + lcd_charMode(NORMAL); + lcd_gotoxy(0,0); + lcd_puts(CLEARLINE); + lcd_gotoxy(0,0); + sprintf(line,"%s - %i","Einstellungen", bMenuCtrl.CurMenue); + lcd_puts(line); + lcd_charMode(DOUBLESIZE); + lcd_gotoxy(0,3); + lcd_puts(CLEARLINE); + switch(bMenuCtrl.CurMenue) + { + case M_TRX1: + lcd_gotoxy(0,3); + if((bConfig.TRX == 1) || (bConfig.TRX == 0)) + sprintf(line,"[%s]", "TRX 1"); + else + sprintf(line," %s ", "TRX 1"); + lcd_puts(line); + break; + case M_TRX2: + lcd_gotoxy(0,3); + if((bConfig.TRX == 2) || (bConfig.TRX == 0)) + sprintf(line,"[%s]", "TRX 2"); + else + sprintf(line," %s ", "TRX 2"); + lcd_puts(line); + break; + case M_IAMBICA: + lcd_gotoxy(0,3); + if(bConfig.IambicMode == 1) + sprintf(line,"[%s]", IambicA); + else + sprintf(line," %s ", IambicB); + lcd_puts(line); + break; + case M_IAMBICB: + lcd_gotoxy(0,3); + if(bConfig.IambicMode == 2) + sprintf(line,"[%s]", IambicB); + else + sprintf(line," %s ", IambicB); + lcd_puts(line); + break; + case M_REVERSE: + lcd_gotoxy(0,3); + if(bConfig.Reverse == 0) + sprintf(line,"%s", ReverseLR); + else + sprintf(line,"%s", ReverseRL); + lcd_puts(line); + break; + case M_RATIO: + lcd_gotoxy(0,3); + if(bConfig.Ratio == 30) + sprintf(line,"%s", "Ratio 3:1"); + else + sprintf(line,"%s %i:1", "Ratio", bConfig.Ratio/10); + lcd_puts(line); + break; + case M_TON_FREQ: + lcd_gotoxy(0,3); + if(bConfig.FrequencySidetone == 650) + sprintf(line,"%s", "Ton 650Hz"); + else + sprintf(line,"%s %uHz", "Ton", bConfig.FrequencySidetone); + lcd_puts(line); + break; + case M_TON: + lcd_gotoxy(0,3); + if(bConfig.SidetoneEnabled == 1) + sprintf(line,"%s", "Ton an"); + else + sprintf(line,"%s", "Ton aus"); + lcd_puts(line); + break; + case M_WPMBPM: + lcd_gotoxy(0,3); + if(bConfig.WpMBpM == 0) + sprintf(line,"%s", "WpM"); + else + sprintf(line,"%s", "BpM"); + lcd_puts(line); + break; + case M_RISETIME: + lcd_gotoxy(0,3); + sprintf(line,"%s %ims",RiseTime, bConfig.RiseTime); + lcd_puts(line); + break; + case M_DEBOUNCE: + lcd_gotoxy(0,3); + sprintf(line,"%s %ims",DebounceTime, bConfig.DebounceTime); + lcd_puts(line); + break; + } + bMenuCtrl.Update = 0; + lcd_charMode(NORMAL); +} +void DisplayVersion(void) +{ + lcd_init(LCD_DISP_ON); + lcd_charMode(DOUBLESIZE); + lcd_home(); + lcd_puts(PRG); + lcd_gotoxy(1,2); + lcd_puts(VER); + lcd_gotoxy(2,4); + lcd_puts(CALL); + SideToneOff(); + DelayMilliSeconds(1000); +} + +/** \brief UpdateDisplay + * + * Aktualisierung der Anzeigen auf dem Display je nach + * aktueller Funktion. + * + * DOUBLESIZE 4x10 character + * NORMALSIZE 8x21 character +*/ +void UpdateDisplay(void) +{ + char line[22]; + if(bMenuCtrl.Update) + { + if(bMenuCtrl.ClrScr) + { + lcd_clrscr(); + bMenuCtrl.ClrScr = 0; + bMenuCtrl.Update = 1; + } + if(!(bMenuCtrl.Config)) + { + lcd_charMode(DOUBLESIZE); + lcd_gotoxy(4,3); + if(bConfig.WpMBpM) + sprintf(line,"%i WpM ",bConfig.WpM); + else + sprintf(line,"%i BpM ", bConfig.WpM*5); + lcd_puts(line); + lcd_charMode(NORMAL); + lcd_gotoxy(13,0); + if(bConfig.IambicMode == 1) + sprintf(line,"%s", IambicA); + if(bConfig.IambicMode == 2) + sprintf(line,"%s", IambicB); + lcd_puts(line); + lcd_gotoxy(0,0); + if(bConfig.TRX == 1) + sprintf(line, "%s", Trx1); + if(bConfig.TRX == 2) + sprintf(line, "%s", Trx2); + if(bConfig.TRX == 0) + sprintf(line, "%s %s", Trx1, Trx2); + lcd_puts(line); + } + if(bMenuCtrl.Config) + { + ConfigMenue(); + } + bMenuCtrl.Update = 0; + } +} + diff --git a/Source/controls.h b/Source/controls.h new file mode 100644 index 0000000..d566334 --- /dev/null +++ b/Source/controls.h @@ -0,0 +1,26 @@ +/** @file controls.h + * @brief Include Datei für controls.c + * @author Tom, DL7BJ + */ +#ifndef CONTROLS_H_INCLUDED +#define CONTROLS_H_INCLUDED + +#include "globals.h" +#include "encoder.h" + +// Externe Variablen +extern struct Config bConfig; +extern struct MenuCtrl bMenuCtrl; +extern struct Merker bMerker; +extern uint16_t MenuCtrlTimer; +extern uint8_t WpM; +// Externe Funktionen +extern void Boop(void); +extern void Beep(void); + +// Prototypes +void Drehencoder(void); +void ConfigMenue(void); +void UpdateDisplay(void); + +#endif diff --git a/Source/functions.c b/Source/functions.c index b481f7c..963d6bd 100644 --- a/Source/functions.c +++ b/Source/functions.c @@ -1,40 +1,83 @@ +/** @file functions.c + * @brief Diverse Funktionen + * @author Tom, DL7BJ + */ + #include "functions.h" -void delayms(uint16_t ms) -{ - t_wait = 0; - while(t_wait < ms); -} +// EEProm +uint8_t Dummy; +uint8_t ee_Dummy EEMEM = 0x55; // Dummy for Address 0 +uint8_t ee_WpM EEMEM = 12; // WpM +uint8_t ee_Sidetone EEMEM = 1; // Mithörton An (1) oder Aus (0) +uint16_t ee_FrequencySidetone EEMEM = 600; // Frequenz des Mithörtons +uint8_t ee_IambicMode EEMEM = 0; // Iambic Mode A oder B +uint8_t ee_Weight EEMEM = 3; // Dah dit Ratio +uint8_t ee_TRX EEMEM = 2; // TRX 1 (0), TRX 2 (1), Beide (2) -void IntEnable(void) -{ - SREG = sreg_tmp; - sei(); -} +// Stringkonstanten für VT100 Terminals +char CLRSCR[] = "\033[2J"; -void IntDisable(void) +/** @brief Ein paar Millisekunden warten + * + * Dieser Variable muss atomar sein, weil es eine 16Bit Variable ist, + * die im Timer 0 verwendet wird. + * @param Zeit in Millisekunden, die gewartet werden soll + * @return void + */ +void DelayMilliSeconds(uint16_t ms) { - sreg_tmp = SREG; - cli(); + t_delayms = 0; +// ResetMilliSeconds(); + //ATOMIC_BLOCK(ATOMIC_FORCEON) { + while(t_delayms < ms); + //} } -/** \brief MilliSeconds - * - * Get the milliseconds of TIMER 0 - * -*/ -uint32_t MilliSeconds(void) +/** @brief Wert des Zählers für Millisekunden lesen + * + * Dieser Variable muss atomar sein, weil es eine 16Bit Variable ist, + * die im Timer 0 verwendet wird. + * @param none + * @return milliseconds + */ +uint16_t GetMilliSeconds(void) { - uint32_t m; + uint16_t m; ATOMIC_BLOCK(ATOMIC_FORCEON){ - m = ms; + m = t_delayms; } return m; } +/** @brief Setzt den Zähler für Millisekunden auf 0 + * + * Dieser Variable muss atomar sein, weil es eine 16Bit Variable ist, + * die im Timer 0 verwendet wird. + * @param none + * @return none + */ void ResetMilliSeconds(void) { - ATOMIC_BLOCK(ATOMIC_FORCEON){ - ms = 0; - } + //ATOMIC_BLOCK(ATOMIC_FORCEON){ + t_delayms = 0; + //} +} +/** @brief SREG wieder herstellen und Interrupts erlauben + * @param none + * @return none + */ +void IntEnable(void) +{ + SREG = sreg_tmp; + sei(); +} +/** @brief SREG sichern und Interrupts verbieten + * @param none + * @return none + */ +void IntDisable(void) +{ + sreg_tmp = SREG; + cli(); } /** \brief EEPROM schreiben @@ -118,16 +161,18 @@ void SideToneOff(void) StateRiseTimeCounter = 0; } /* - ** TXSidetoneKey + ** TXKey + ** + ** Tastung TRX1, TRX2 oder beide */ -void TXSidetoneKey(uint8_t State, uint8_t SendingType) +void TXKey(uint8_t State, uint8_t SendingType) { if((State) && (KeyState == 0)) { if(KeyTX) { SideToneOn(); - PORTC |= (1< #include @@ -20,7 +19,7 @@ #include #include #include - + #include #include #include @@ -29,48 +28,22 @@ #include #include +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // clear bit +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // set bit + #include "oled/i2c.h" #include "oled/lcd.h" #include "oled/font.h" -#include "encoder.h" -#include "functions.h" - -// Const strings for display -const char CALL[] = " DL7BJ "; -const char PRG[] = " BJ-Keyer "; -const char VER[] = " V1.0 "; -const char Trx1[] = "TRX 1"; -const char Trx2[] = "TRX 2"; -const char IambicA[] = "Iambic A"; -const char IambicB[] = "Iambic B"; -const char Ratio[] = "Ratio"; -const char ReverseRL[] = " L - R °"; -const char ReverseLR[] = " L ° R -"; -const char SideToneOnOff[] = "Mithörton"; -const char SideToneFreq[] = "Frequenz"; -const char RiseTime[] = "Anstieg"; -const char DebounceTime[] = "Entprl."; -const char Yes[] = "J"; -const char No[] = "N"; -const char Hz[] = "Hz"; - -// Const strings for VT100 Terminals -const char CLRSCR[] = "\033[2J"; - #ifndef EEMEM #define EEMEM __attribute__ ((section (".eeprom"))) #endif - + #ifndef NOINIT #define NOINIT __attribute__ ((section (".noinit"))) #endif -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // clear bit -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // set bit - #define L_WAIT 500 // Frequency for debug LED Timer 0 - // Keying states #define NOTHING 0 #define DIT_DAH_OFF 1 @@ -85,20 +58,16 @@ const char CLRSCR[] = "\033[2J"; // Paddle Mode #define PADDLE_NORMAL 0 #define PADDLE_REVERSE 1 -// Machine Mode -#define NORMAL 0 -#define COMMAND 1 + // Sending Mode #define SENDING_NOTHING 0 #define SENDING_DIT 1 #define SENDING_DAH 2 #define SENDING_ELEMENT_SPACE 3 #define SENDING_STRAIGHT 4 -// -#define AUTOMATIC_SENDING 0 -#define AUTOMATIC 0 -#define MANUAL 1 -#define MANUAL_SENDING 1 +// Sending Type +#define AUTO 0 // Automatische Pausen zwischen Elementen +#define MAN 1 // Manuelle Pausen zwischen Elementen // Side Tone #define SIDETONE_OFF 0 #define SIDETONE_ON 1 @@ -121,6 +90,9 @@ const char CLRSCR[] = "\033[2J"; // States #define ON 1 #define OFF 0 +#define NO_KEY_PRESSED 0 +#define KEY_PRESSED_DEBOUNCE 1 +#define KEY_PRESSED 2 // Menue und Drehencoder #define M_TRX1 1 #define M_TRX2 2 @@ -135,38 +107,18 @@ const char CLRSCR[] = "\033[2J"; #define M_DEBOUNCE 11 #define M_MAX 11 // maximale Menuepunke // LCD -#define CLEARLINE " " - -// 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 -}; +#define CLEARLINE " " +#define NORMAL 0 +// Debugausgabe char sdebug[64]; -// Sidetone generation -double FrequencySidetone = 600; -volatile uint8_t icnt; -volatile uint8_t ocr2a; - -// Diverse Zähler für Timer 0 -uint16_t StoreEEprom = 0; // Wartezeit bis EEPROM geschrieben wird -uint16_t MenuCtrlTimer = 0; // Wartezeit bis zur Betriebsanzeige nach Config -volatile uint16_t ms; // Timer 0 max. 65535ms, all purpose timer variable -volatile uint16_t mselement; // Timer 0 max. 65535ms, element length of dit or dah - -int8_t WpM = 12; // Geschwindigkeit in wpm -uint8_t Weight = 50; // Gewichtung Punkt-Strich Verhältnis -uint8_t t_element_length; - -struct Merker +// Structs für Merker, Menü und Einstellungen +struct Merker { uint8_t WpMChanged: 1; uint8_t WriteWpMEEprom: 1; -} bMerker; +}; struct MenuCtrl { @@ -179,61 +131,7 @@ struct MenuCtrl uint8_t WriteEEprom: 1; uint8_t Update: 1; uint8_t CurMenue; -} bMenuCtrl; - -// State Machines -uint8_t MachineMode = NORMAL; -uint8_t PaddleMode = PADDLE_NORMAL; -uint8_t KeyerMode = IAMBIC_A; -uint8_t SidetoneMode = NORMAL; -uint8_t state_sidetoneoff = 0; - -volatile uint8_t Mode = NORMAL; -volatile uint8_t SendStatus = SENDING_NOTHING; -volatile uint8_t LastSendStatus = MANUAL_SENDING; - -// History -uint8_t keyhistory = 0xff; - -uint8_t KeyTX = 1; - -uint8_t DahBuffer = 0; -uint8_t DitBuffer = 0; -uint8_t Weighting = 50; -uint8_t IambicFlag = 0; -uint8_t KeyState = 0; -uint8_t DitCounter = 0; -uint8_t DahCounter = 0; -uint8_t CurrentTRX = TRX1; -uint8_t StateRiseTime = 0; -volatile uint8_t StateRiseTimeCounter = 0; - -// Variablen in Timer 0 -volatile uint16_t l_timer = 0; // counter for LED on -volatile uint8_t t_timer = 0; // Frequency of audio output -volatile uint16_t t_wait = 0; // delayms max. 65535ms -volatile uint8_t t_pwm = 0; -volatile uint16_t t_wait_led = 50; -volatile uint8_t lastButton = 0; // Wert der letzten Buttonabfrage - -// Drehencoder -volatile uint8_t EncoderTimer = 0; // 10ms Timer for Encoder -volatile int8_t EncoderCounter = 0; // Vor/Rück Zähler -volatile int8_t EncoderPos; // Encoderposition für WpM/BpM -volatile int8_t EncoderPosConfig; // Encoderposition für Einstellungen - -volatile uint8_t StateStraightKeyPressed = 0; // Merker für StraightKey betätigt -volatile uint8_t TimerStraightKeyPressed = 0; // Timervariable für Entprellung - -// EEPROM -uint8_t Dummy = 0x55; -uint8_t ee_Dummy EEMEM = 0x55; // Dummy for Address 0 -uint8_t ee_WpM EEMEM = 12; // WpM -uint8_t ee_Sidetone EEMEM = 0; // Mithörton An (1) oder Aus (0) -uint16_t ee_FrequencySidetone EEMEM = 600; // Frequenz des Mithörtons -uint8_t ee_IambicMode EEMEM = 0; // Iambic Mode A oder B -uint8_t ee_Weight EEMEM = 50; // Dah dit Ratio -uint8_t ee_TRX EEMEM = 0; // TRX 1 (0), TRX 2 (1), Beide (2) +}; struct Config { @@ -250,28 +148,62 @@ struct Config uint8_t RiseTimeCounter; // Anzahl Sinusschwingungen für den Anstieg uint8_t DebounceTime; // Entprellzeit für Straight Key Eingang uint8_t WinkeyerEnabled; // Winkeyer2 Emulation -} bConfig; -// Function prototypes -void Init(void); -void InitTimer(void); +}; -void CheckDahPaddle(void); -void CheckDitPaddle(void); -void CheckPaddle(void); -void CheckStraightKey(void); -void SendDit(uint8_t SendingType); -void SendDah(uint8_t SendingType); -void PTTKey(uint8_t State); -void SideToneOff(void); -void SideToneOn(void); -void TXSidetoneKey(uint8_t State, uint8_t SendingType); -void SendChar(uint8_t); -void ChangeSpeed(void); +// Drehencoder +volatile uint8_t EncoderTimer; // 10ms Timer for Encoder +volatile int8_t EncoderCounter; // Vor/Rück Zähler +volatile int8_t EncoderPos; // Encoderposition für WpM/BpM +volatile int8_t EncoderPosConfig; // Encoderposition für Einstellungen + +uint16_t StoreEEprom; -void dah(void); -void dit(void); -void DoMorse(void); +// Globale Variablen für diverse Zwecke +uint8_t WpM; +uint8_t Weight; +uint8_t t_element_length; + +// Diverse Zähler für Timer 0 +uint16_t MenuCtrlTimer; // Wartezeit bis zur Betriebsanzeige nach Config +volatile uint16_t t_delayms; // Timer 0 max. 65535ms, all purpose timer variable +volatile uint16_t mselement; // Timer 0 max. 65535ms, element length of dit or dah + +// State Machines +uint8_t PaddleMode; +uint8_t KeyerMode; +uint8_t state_sidetoneoff; -void SetFrequency(uint16_t f); +volatile uint8_t SendStatus; -#endif // BJ-KEYER_H_INCLUDED +// History +uint8_t keyhistory; +uint8_t KeyTX; +uint8_t DahBuffer; +uint8_t DitBuffer; +uint8_t Weighting; +uint8_t IambicFlag; +uint8_t KeyState; +uint8_t DitCounter; +uint8_t DahCounter; +uint8_t CurrentTRX1; +uint8_t StateRiseTime; +volatile uint8_t StateRiseTimeCounter; + +// Sidetone generation +double FrequencySidetone; +volatile uint8_t icnt; +volatile uint8_t ocr2a; +// Variablen in Timer 0 +volatile uint16_t l_timer; // counter for LED on +volatile uint8_t t_timer; // Frequency of audio output +volatile uint16_t t_wait; // delayms max. 65535ms +volatile uint8_t t_pwm; +volatile uint16_t t_wait_led; +volatile uint8_t lastButton; // Wert der letzten Buttonabfrage + +volatile uint8_t StateStraightKeyPressed; // Merker für StraightKey betätigt +volatile uint8_t TimerStraightKeyPressed; // Timer Variable für Entprellung +volatile uint8_t StatePaddleKeyPressed; // Merker für Paddle betätigt +volatile uint8_t TimerPaddleKeyPressed; // Timer Variable für Entprellung + +#endif diff --git a/Source/main.c b/Source/main.c index 7c3f56c..03d26ad 100644 --- a/Source/main.c +++ b/Source/main.c @@ -57,14 +57,15 @@ @endverbatim */ -#include "bj-keyer.h" -// Additional files -#include "functions.c" +#include "main.h" -#define LENGTH 256 -#define AMP 127 -#define OFFSET 128 -#define PI2 6.283185 +// 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 +}; /** * \brief Initialsieren der Timer @@ -103,7 +104,7 @@ void InitTimer(void) OCR2A = 0x80; sbi(DDRB,PB3); cbi(TIMSK2,OCIE0A); - + // Timer 1 für die Sinus Hüllkurve TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0; // CTC Mode @@ -130,10 +131,7 @@ void InitTimer(void) void Init() { cli(); // disable all interrupts - - MachineMode = NORMAL; SendStatus = SENDING_NOTHING; - // PORTB DDRB = 0x00; // Interne PullUps einschalten @@ -205,18 +203,7 @@ void Init() bConfig.WinkeyerEnabled = 0; sei(); // enable all interrupts } -/** \brief 16 Bit Timer 1A - * - * Timer 1A interrupt - * Overflow interrupt every 64µs - * - */ -//ISR(TIMER1_OVF_vect) -//{ -// //sCurrentTimer += 0xffff; -// PORTD ^= (1< bConfig.DebounceTime) - StateStraightKeyPressed = 2; + StateStraightKeyPressed = KEY_PRESSED; + } + // Softwarentprellung für Paddle + TimerPaddleKeyPressed++; + if(StatePaddleKeyPressed == KEY_PRESSED_DEBOUNCE) + { + if(TimerPaddleKeyPressed > bConfig.DebounceTime) + StatePaddleKeyPressed = KEY_PRESSED; } - - // Konfiguration nach 3 Sekunden verlassen - // if((MenuCtrlTimer > 3000) && (bMenuCtrl.Config == 1)) - // { - // bMenuCtrl.Config = 0; - // bMenuCtrl.Update = 1; - // bMenuCtrl.ClrScr = 1; - // BeepBoop(); - // } } /** \brief 8 Bit Timer 2 @@ -326,12 +309,12 @@ ISR(TIMER0_COMPA_vect) */ ISR(TIMER2_OVF_vect) { -// phaccu = phaccu + tword_m; -// icnt = phaccu >> 24; -// OCR2A = pgm_read_byte_near(sinewave+icnt); - + /* nothing */ } - +/** @brief Interrupt RX serielle Schnittstelle + * @param none + * @return none + */ ISR(USART_RX_vect) { unsigned char data; @@ -339,57 +322,6 @@ ISR(USART_RX_vect) SendSerialChar(data); } -/** \brief ClearSendBuffer - * -*/ -void ClearSendBuffer(void) -{ - // sendbufferbytes = 0; -} - -/** \brief CheckDitPaddle - * - * -*/ -void CheckDitPaddle(void) -{ - uint8_t pinvalue = 0; - uint8_t ditpaddle = 0; - - if(PaddleMode == PADDLE_NORMAL) // no reverse paddle - ditpaddle = LEFT_PADDLE; - else - ditpaddle = RIGHT_PADDLE; // reverse paddle - - pinvalue = ReadKeyPin(ditpaddle); - - if(pinvalue == 0) - DitBuffer = 1; -} -/* - ** CheckDahPaddle - */ -void CheckDahPaddle(void) -{ - uint8_t pinvalue = 0; - uint8_t dahpaddle = 0; - - if(PaddleMode == PADDLE_NORMAL) // no reverse paddle - dahpaddle = RIGHT_PADDLE; - else - dahpaddle = LEFT_PADDLE; // reverse paddle - - pinvalue = ReadKeyPin(dahpaddle); - - if(pinvalue == 0) { - if(DahBuffer == 0) { - DahCounter++; - DitCounter = 0; - } - DahBuffer = 1; - } -} - /* ** DoMorse */ @@ -408,12 +340,12 @@ void DoMorse(void) if(DitBuffer) { DitBuffer = 0; - SendDit(MANUAL_SENDING); + SendDit(MAN); } if(DahBuffer) { DahBuffer = 0; - SendDah(MANUAL_SENDING); + SendDah(MAN); } } } @@ -424,290 +356,37 @@ void DoMorse(void) if(DitBuffer) { DitBuffer = 0; - TXSidetoneKey(1,MANUAL_SENDING); + TXKey(1,MAN); } else { - TXSidetoneKey(0,MANUAL_SENDING); + TXKey(0,MAN); } DitCounter = 0; } } } -void ConfigMenue(void) +void ReStart(void) { - char line[22]; - - lcd_charMode(NORMAL); - lcd_gotoxy(0,0); - lcd_puts(CLEARLINE); - lcd_gotoxy(0,0); - sprintf(line,"%s - %i","Einstellungen", bMenuCtrl.CurMenue); - lcd_puts(line); - lcd_charMode(DOUBLESIZE); - lcd_gotoxy(0,3); - lcd_puts(CLEARLINE); - switch(bMenuCtrl.CurMenue) - { - case M_TRX1: - lcd_gotoxy(0,3); - if((bConfig.TRX == 1) || (bConfig.TRX == 0)) - sprintf(line,"[%s]", "TRX 1"); - else - sprintf(line," %s ", "TRX 1"); - lcd_puts(line); - break; - case M_TRX2: - lcd_gotoxy(0,3); - if((bConfig.TRX == 2) || (bConfig.TRX == 0)) - sprintf(line,"[%s]", "TRX 2"); - else - sprintf(line," %s ", "TRX 2"); - lcd_puts(line); - break; - case M_IAMBICA: - lcd_gotoxy(0,3); - if(bConfig.IambicMode == 1) - sprintf(line,"[%s]", IambicA); - else - sprintf(line," %s ", IambicB); - lcd_puts(line); - break; - case M_IAMBICB: - lcd_gotoxy(0,3); - if(bConfig.IambicMode == 2) - sprintf(line,"[%s]", IambicB); - else - sprintf(line," %s ", IambicB); - lcd_puts(line); - break; - case M_REVERSE: - lcd_gotoxy(0,3); - if(bConfig.Reverse == 0) - sprintf(line,"%s", ReverseLR); - else - sprintf(line,"%s", ReverseRL); - lcd_puts(line); - break; - case M_RATIO: - lcd_gotoxy(0,3); - if(bConfig.Ratio == 30) - sprintf(line,"%s", "Ratio 3:1"); - else - sprintf(line,"%s %i:1", "Ratio", bConfig.Ratio/10); - lcd_puts(line); - break; - case M_TON_FREQ: - lcd_gotoxy(0,3); - if(bConfig.FrequencySidetone == 650) - sprintf(line,"%s", "Ton 650Hz"); - else - sprintf(line,"%s %uHz", "Ton", bConfig.FrequencySidetone); - lcd_puts(line); - break; - case M_TON: - lcd_gotoxy(0,3); - if(bConfig.SidetoneEnabled == 1) - sprintf(line,"%s", "Ton an"); - else - sprintf(line,"%s", "Ton aus"); - lcd_puts(line); - break; - case M_WPMBPM: - lcd_gotoxy(0,3); - if(bConfig.WpMBpM == 0) - sprintf(line,"%s", "WpM"); - else - sprintf(line,"%s", "BpM"); - lcd_puts(line); - break; - case M_RISETIME: - lcd_gotoxy(0,3); - sprintf(line,"%s %ims",RiseTime, bConfig.RiseTime); - lcd_puts(line); - break; - case M_DEBOUNCE: - lcd_gotoxy(0,3); - sprintf(line,"%s %ims",DebounceTime, bConfig.DebounceTime); - lcd_puts(line); - break; - } - bMenuCtrl.Update = 0; - lcd_charMode(NORMAL); -} -/** \brief UpdateDisplay - * - * Aktualisierung der Anzeigen auf dem Display je nach - * aktueller Funktion. - * - * DOUBLESIZE 4x10 character - * NORMALSIZE 8x21 character -*/ -void UpdateDisplay(void) -{ - char line[22]; - if(bMenuCtrl.Update) - { - if(bMenuCtrl.ClrScr) - { - lcd_clrscr(); - bMenuCtrl.ClrScr = 0; - bMenuCtrl.Update = 1; - } - if(!(bMenuCtrl.Config)) - { - lcd_charMode(DOUBLESIZE); - lcd_gotoxy(4,3); - if(bConfig.WpMBpM) - sprintf(line,"%i WpM ",bConfig.WpM); - else - sprintf(line,"%i BpM ", bConfig.WpM*5); - lcd_puts(line); - lcd_charMode(NORMAL); - lcd_gotoxy(13,0); - if(bConfig.IambicMode == 1) - sprintf(line,"%s", IambicA); - if(bConfig.IambicMode == 2) - sprintf(line,"%s", IambicB); - lcd_puts(line); - lcd_gotoxy(0,0); - if(bConfig.TRX == 1) - sprintf(line, "%s", Trx1); - if(bConfig.TRX == 2) - sprintf(line, "%s", Trx2); - if(bConfig.TRX == 0) - sprintf(line, "%s %s", Trx1, Trx2); - lcd_puts(line); - } - if(bMenuCtrl.Config) - { - ConfigMenue(); - } - bMenuCtrl.Update = 0; - } -} -void Drehencoder(void) -{ - int8_t st = 0; - static int8_t last; - - if(!(bMenuCtrl.Config)) - { - EncoderMinMax(5,50); - st = EncoderRead(1); - if(bConfig.WpM != st) - { - bConfig.WpM = st; // neuen Wert in bConfig speichern - bMerker.WpMChanged = 1; // Merker für Timer 0 setzen - bMenuCtrl.Update = 1; // Merker für UpdateDisplay setzen - 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 - sei(); - } - } - - if((bMenuCtrl.buttonPressed == 1) && (bMenuCtrl.Config == 0)) - { - bMenuCtrl.Config = 1; - MenuCtrlTimer = 0; - bMenuCtrl.buttonPressed = 0; - EncoderPos = EncoderRead(1); - bMenuCtrl.CurMenue = EncoderPosConfig; - EncoderWrite(EncoderPosConfig); - bMenuCtrl.Update = 1; - } - - if((bMenuCtrl.buttonPressedLong == 1) && (bMenuCtrl.Config == 1)) - { - bMenuCtrl.Config = 0; - bMenuCtrl.Update = 1; - bMenuCtrl.buttonPressedLong = 0; - bMenuCtrl.buttonPressed = 0; - bMenuCtrl.m_buttonPressed = 0; - MenuCtrlTimer = 0; - EncoderPosConfig = EncoderRead(1); - EncoderWrite(EncoderPos); - bMenuCtrl.ClrScr = 1; - Beep(); - } - - if(bMenuCtrl.Config == 1) - { - if(!bMenuCtrl.buttonPressed) - { - EncoderMinMax(1,M_MAX); - st = EncoderRead(1); - sprintf(sdebug,"Encoder %i\r\n",st); - if(last != st) - { - SendSerialString(sdebug); - bMenuCtrl.CurMenue = st; - bMenuCtrl.Update = 1; - } - last = st; - } - - if(bMenuCtrl.buttonPressed) - { - bMenuCtrl.m_buttonPressed = 1; - bMenuCtrl.buttonPressed = 0; - } + ReadEEpromWpM(); + WpM = bConfig.WpM; + EncoderPos = bConfig.WpM; + EncoderWrite(bConfig.WpM); + EncoderPosConfig = 1; + SetFrequency(600); + MenuCtrlTimer = 0; + t_delayms = 0; + SendStatus = SENDING_NOTHING; + WpM = 15; + Weight = 50; + Init(); + DisplayVersion(); + KeyerMode = IAMBIC_A; + PaddleMode = PADDLE_NORMAL; + KeyTX = 1; + KeyState = 0; - if(bMenuCtrl.m_buttonPressed == 1) - { - UpdateDisplay(); - switch(bMenuCtrl.CurMenue) - { - case M_TRX1: - if(bConfig.TRX == 2) - bConfig.TRX = 0; - else - bConfig.TRX = 1; - bMenuCtrl.m_buttonPressed = 0; - break; - case M_TRX2: - if(bConfig.TRX == 1) - bConfig.TRX = 0; - else - bConfig.TRX = 2; - bMenuCtrl.m_buttonPressed = 0; - break; - case M_IAMBICA: - bConfig.IambicMode = 1; - bMenuCtrl.m_buttonPressed = 0; - break; - case M_IAMBICB: - bConfig.IambicMode = 2; - bMenuCtrl.m_buttonPressed = 0; - break; - case M_REVERSE: - if(bConfig.Reverse == 1) - bConfig.Reverse = 0; - else - bConfig.Reverse = 1; - bMenuCtrl.m_buttonPressed = 0; - if(bConfig.Reverse == 1) - PaddleMode = PADDLE_REVERSE; - else - PaddleMode = PADDLE_NORMAL; - bMenuCtrl.Update = 1; - break; - case M_RATIO: - EncoderMinMax(15,30); - st = EncoderRead(1); - bConfig.Ratio = st; - if(bConfig.Ratio > 30) bConfig.Ratio = 30; - if(bConfig.Ratio < 15) bConfig.Ratio = 15; - bMenuCtrl.Update = 1; - break; - case M_TON_FREQ: - break; - } - } - } } /* @@ -715,58 +394,23 @@ void Drehencoder(void) */ int main(void) { - - Init(); - lcd_init(LCD_DISP_ON); - lcd_charMode(DOUBLESIZE); - lcd_home(); - lcd_puts(PRG); - lcd_gotoxy(1,2); - lcd_puts(VER); - lcd_gotoxy(2,4); - lcd_puts(CALL); - SideToneOff(); - delayms(1000); - - MachineMode = NORMAL; - KeyerMode = IAMBIC_A; - SendSerialString(CLRSCR); - SendSerialString("BJ-Keyer V1.00\r\n"); - SendSerialString("Ready!\r\n"); - - ReadEEpromWpM(); - WpM = bConfig.WpM; - EncoderPos = bConfig.WpM; - EncoderWrite(bConfig.WpM); - EncoderPosConfig = 1; - - SetFrequency(600); - + uint8_t c = 0; + ReStart(); while(1) { Drehencoder(); // Wenn Geschwindigkeit verändert und Zeit abgelaufen, // dann im EEprom speichern und Merker löschen. if(bMerker.WriteWpMEEprom) - { + { sprintf(" %i WpM in EEprom speichern\r\n", bConfig.WpM); WriteEEpromWpM(); bMerker.WriteWpMEEprom = 0; } - UpdateDisplay(); - - if(MachineMode == NORMAL) - { - CheckStraightKey(); - CheckPaddles(); - DoMorse(); - } - - if(MachineMode == COMMAND) - { - - } + CheckStraightKey(); + CheckPaddles(); + DoMorse(); } } diff --git a/Source/main.h b/Source/main.h new file mode 100644 index 0000000..f4312d5 --- /dev/null +++ b/Source/main.h @@ -0,0 +1,36 @@ +/* +* BJ-Keyer +* +* 2023-07-29 Tom, DL7BJ +* +*/ +#ifndef MAIN_H_INCLUDED +#define MAIN_H_INCLUDED + +#include "globals.h" +#include "encoder.h" +#include "functions.h" + +struct Config bConfig; +struct MenuCtrl bMenuCtrl; +struct Merker bMerker; +// Function prototypes +void Init(void); +void InitTimer(void); + +void CheckDahPaddle(void); +void CheckDitPaddle(void); +void CheckPaddle(void); +void CheckStraightKey(void); +void SendDit(uint8_t SendingType); +void SendDah(uint8_t SendingType); +void SideToneOff(void); +void SideToneOn(void); +void TXKey(uint8_t State, uint8_t SendingType); +void SendChar(uint8_t); +void ChangeSpeed(void); +void DoMorse(void); + +void SetFrequency(uint16_t f); + +#endif // BJ-KEYER_H_INCLUDED