Funktionen SetRatio und Weight getestet. Punkt/Strich Speicher

implementiert und getestet.
main
Tom 9 months ago
parent 74f768a095
commit 75daf456cd

@ -1,2 +1,2 @@
:0F0000000605050C5802001E0000000101005506
:100000000605050C580200321E00000001010055D3
:00000001FF

@ -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
SRC = main.c oled/i2c.c oled/lcd.c oled/font.c encoder.c controls.c functions.c vt100.c
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s

@ -15,7 +15,7 @@ const char IambicB[] = "Iambic B";
const char Ultimatic[] = "Ultimat.";
const char Memory[] = "Memory";
const char Ratio[] = "Ratio";
const char SpeedRatio[] = "SpeedRatio";
const char Weight[] = "Weight";
const char ReverseRL[] = " L - R °";
const char ReverseLR[] = " L ° R -";
const char SideToneOnOff[] = "Mithörton";
@ -38,14 +38,15 @@ void Drehencoder(void)
if(bConfig.WpM != st)
{
bConfig.WpM = st; // neuen Wert in bConfig speichern
bState.WpMChanged = 1; // Status für Timer 0 setzen
bState.WpMChanged = 1; // Status für Timer 0 setzen
bMenuCtrl.Update = 1; // Status 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();
SetRatio(0);
SetRatio();
SetWeight();
}
}
@ -153,6 +154,10 @@ void Drehencoder(void)
bMenuCtrl.SubMenue = 1;
EncoderPosSubConfig = EncoderRead(1);
break;
case M_WEIGHT:
bMenuCtrl.SubMenue = 1;
EncoderPosSubConfig = EncoderRead(1);
break;
case M_MEMORY:
bConfig.Memory = (bConfig.Memory == 1) ? 0 : 1;
bMenuCtrl.m_buttonPressed = 0;
@ -193,14 +198,26 @@ void Drehencoder(void)
switch(bMenuCtrl.CurMenue)
{
case M_RATIO:
EncoderMinMax(15,30);
EncoderMinMax(15,45);
EncoderWrite(bConfig.Ratio);
st = EncoderRead(1);
if(st != bConfig.Ratio)
bMenuCtrl.Update = 1;
bConfig.Ratio = st;
if(bConfig.Ratio > 30) bConfig.Ratio = 30;
if(bConfig.Ratio > 40) bConfig.Ratio = 45;
if(bConfig.Ratio < 15) bConfig.Ratio = 15;
SetRatio();
break;
case M_WEIGHT:
EncoderMinMax (25,75);
EncoderWrite(bConfig.Weight);
st = EncoderRead(1);
if(st != bConfig.Weight)
bMenuCtrl.Update = 1;
bConfig.Weight = st;
if(bConfig.Weight > 75) bConfig.Weight = 75;
if(bConfig.Weight < 25) bConfig.Weight = 25;
SetWeight();
break;
case M_TON_FREQ:
EncoderMinMax(30,100);
@ -313,10 +330,12 @@ void ConfigMenue(void)
break;
case M_RATIO:
lcd_gotoxy(0,3);
if(bConfig.Ratio == 30)
sprintf(line,"%s", "Ratio 3:1");
else
sprintf(line,"%s %.1f", "Ratio", (float)bConfig.Ratio/10);
sprintf(line,"%s %.1f", "Ratio", (float)bConfig.Ratio/10);
lcd_puts(line);
break;
case M_WEIGHT:
lcd_gotoxy(0,3);
sprintf(line,"%s %i",Weight,bConfig.Weight);
lcd_puts(line);
break;
case M_MEMORY:
@ -329,10 +348,7 @@ void ConfigMenue(void)
break;
case M_TON_FREQ:
lcd_gotoxy(0,3);
if(bConfig.SidetoneFreq == 650)
sprintf(line,"%s", "Ton 650Hz");
else
sprintf(line,"%s %uHz", "Ton", bConfig.SidetoneFreq);
sprintf(line,"%s %uHz", "Ton", bConfig.SidetoneFreq);
lcd_puts(line);
break;
case M_TON:
@ -409,7 +425,7 @@ void UpdateDisplay(void)
if(!(bMenuCtrl.Config))
{
lcd_charMode(DOUBLESIZE);
lcd_gotoxy(4,2);
lcd_gotoxy(4,3);
if(bConfig.WpMBpM == 0)
sprintf(line,"%i WpM ",bConfig.WpM);
else
@ -436,20 +452,24 @@ void UpdateDisplay(void)
if(bConfig.SpeedRatioEnabled)
sprintf(line,"Ratio auto.");
else
sprintf(line,"Ratio 1:%.1f", (float)bConfig.Ratio/10);
sprintf(line, "R 1:%.1f",(float)bConfig.Ratio/10);
lcd_puts(line);
lcd_gotoxy(13,6);
lcd_gotoxy(9,6);
sprintf(line, "W %i", bConfig.Weight);
lcd_puts(line);
lcd_gotoxy(14,6);
if(bConfig.Memory)
sprintf(line,"MEM ON ");
sprintf(line,"Mem ON");
else
sprintf(line,"MEM OFF");
sprintf(line,"Mem OFF");
lcd_puts(line);
}
if(bMenuCtrl.Config)
{
ConfigMenue();
}
}
bMenuCtrl.Update = 0;
}

@ -21,7 +21,7 @@ extern void WriteEEprom(void);
extern void SideToneOff(void);
extern void DelayMilliSeconds(uint16_t t);
extern void Tone(uint16_t f, uint8_t t);
extern void SetRatio(uint8_t WPMCorrectFactor);
extern void SetRatio(void);
extern void SidetoneDisable(void);
extern void SidetoneEnable(void);
extern void SidetoneOff(void);

@ -15,19 +15,19 @@ 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_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
uint16_t ee_SidetoneFreq EEMEM = 600; // Frequenz des Mithörtons
uint8_t ee_WpM EEMEM = 12; // Geschwindigkeit WpM
uint8_t ee_RiseTime EEMEM = 5; // Anstiegszeit Sinuston
uint8_t ee_RiseTimeCounter EEMEM = 5; // Anzahl Sinusschwingungen für den Anstieg
uint8_t ee_DebounceTime EEMEM = 6; // Entprellzeit für Straight Key Eingang
// Stringkonstanten für VT100 Terminals
const char CLRSCR[] = "\033[2J";
/** @brief Ein paar Millisekunden warten
*
* @param Zeit in Millisekunden, die gewartet werden soll
* @return void
//
//
/** @fn void DelayMilliSeconds(uint16_t ms)
* @brief Zeitschleife von 1-65535 Millisekunden
* @param Anzahl Millisekunden
* @return none
*/
void DelayMilliSeconds(uint16_t ms)
{
@ -39,12 +39,13 @@ void DelayMilliSeconds(uint16_t ms)
{
ctr = t_delayms;
}
CheckPaddles();
} while (ctr < ms);
}
/** @brief Wert des Zählers für Millisekunden lesen
*
/** @fn uint16_t GetMilliSeconds(void)
* @brief Zäherwert für Zeitschleifen auslesen
* @param none
* @return milliseconds
* @return Millisekunden
*/
uint16_t GetMilliSeconds(void)
{
@ -55,8 +56,8 @@ uint16_t GetMilliSeconds(void)
}
return ctr;
}
/** @brief Setzt den Zähler für Millisekunden auf 0
*
/** @fn void ResetMilliSeconds(void)
* @brief Setzt den Millisekundenzähler für Zeitschleifen auf 0
* @param none
* @return none
*/
@ -67,7 +68,8 @@ void ResetMilliSeconds(void)
t_delayms = 0;
}
}
/** @brief SREG wieder herstellen und Interrupts erlauben
/** @fn void IntEnable(void)
* @brief Register wieder herstellen und Interrupts erlauben
* @param none
* @return none
*/
@ -76,7 +78,8 @@ void IntEnable(void)
SREG = sreg_tmp;
sei();
}
/** @brief SREG sichern und Interrupts verbieten
/** @fn void IntDisable(void)
* @brief Register sichern und Interrupts verbieten
* @param none
* @return none
*/
@ -85,23 +88,8 @@ void IntDisable(void)
sreg_tmp = SREG;
cli();
}
/** @brief Pin Change Interrupt abschalten
* @param none
* @return none
*/
void DisablePinChangeIRQ(void)
{
cbi(PCICR,PCIE2);
}
/** @brief Pin Change Interrupt einschalten
* @param none
* @return none
*/
void EnablePinChangeIRQ(void)
{
sbi(PCICR,PCIE2);
}
/** @brief EEPROM schreiben
/** @fn void WriteEEprom(void)
* @brief Akt. Einstellungen in EEPROM schreiben
* @param none
* @return none
*/
@ -117,6 +105,7 @@ void WriteEEprom(void)
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_Weight, bConfig.Weight);
eeprom_write_byte(&ee_Ratio, bConfig.Ratio);
eeprom_write_byte(&ee_Memory, bConfig.Memory);
eeprom_write_byte(&ee_RiseTime, bConfig.RiseTime);
@ -124,21 +113,35 @@ void WriteEEprom(void)
eeprom_write_byte(&ee_DebounceTime, bConfig.DebounceTime);
IntEnable();
}
/** @fn void ReadEEpromWpM(void)
* @brief Gespeicherte Einstellung für die Geschwindigkeit aus EEprom lesen
* @param none
* @return none
*/
void ReadEEpromWpM(void)
{
IntDisable();
bConfig.WpM = eeprom_read_byte(&ee_WpM);
IntEnable();
}
/** @fn void WriteEEpromWpM(void)
* @brief Akt. Einstellung für die Geschwindigkeit in EEprom schreiben
* @param none
* @return none
*/
void WriteEEpromWpM(void)
{
IntDisable();
eeprom_write_byte(&ee_WpM, bConfig.WpM);
IntEnable();
}
/** @fn void SetEEprom(void)
/** @brief Standardeinstellungen (bei neuem Controller)
*
* Wird ein neuer Controller verwendet, gibt es keine
* Einstellungswerte im EEprom. Diese Funktion schreibt
* die initialen Werte in das EEprom. Wird sehr selten
* benötigt ;-)
*
* @param none
* @return none
@ -154,6 +157,7 @@ void SetEEprom(void)
bConfig.WpMBpM = 1;
bConfig.Reverse = 0;
bConfig.SpeedRatioEnabled = 0;
bConfig.Weight = 50;
bConfig.Ratio = 30;
bConfig.Memory = 0;
bConfig.RiseTime = 5;
@ -161,7 +165,8 @@ void SetEEprom(void)
bConfig.DebounceTime = 5;
WriteEEprom();
}
/** @brief EEprom lesen
/** @fn void ReadEEprom(void)
* @brief Einstellungen aus dem EEprom lesen
* @param none
* @return none
*/
@ -184,57 +189,15 @@ void ReadEEprom(void)
bConfig.Reverse = eeprom_read_byte(&ee_Reverse);
bConfig.SpeedRatioEnabled = eeprom_read_byte(&ee_SpeedRatioEnabled);
bConfig.Ratio = eeprom_read_byte(&ee_Ratio);
bConfig.Weight = eeprom_read_byte(&ee_Weight);
bConfig.Memory = eeprom_read_byte(&ee_Memory);
bConfig.RiseTime = eeprom_read_byte(&ee_RiseTime);
bConfig.RiseTimeCounter = eeprom_read_byte(&ee_RiseTimeCounter);
bConfig.DebounceTime = eeprom_read_byte(&ee_DebounceTime);
IntEnable();
}
/** @brief Aktuelle Einstellungen über serielle Schnittstelle ausgeben
* @param none
* @return none
*/
void SerialInfo(void)
{
sprintf(sdebug,"WpM : %i\r\n", bConfig.WpM);
SerialWriteString(sdebug);
sprintf(sdebug,"KeyerMode : %i\r\n", bConfig.KeyerMode);
SerialWriteString(sdebug);
sprintf(sdebug,"SidetoneFreq : %u\r\n", bConfig.SidetoneFreq);
SerialWriteString(sdebug);
sprintf(sdebug,"TRX : %i\r\n", bConfig.TRX);
SerialWriteString(sdebug);
sprintf(sdebug,"SidetoneEnabled : %i\r\n", bConfig.SidetoneEnabled);
SerialWriteString(sdebug);
sprintf(sdebug,"Ratio : %i\r\n", bConfig.Ratio);
SerialWriteString(sdebug);
sprintf(sdebug,"WpMBpM : %i\r\n", bConfig.WpMBpM);
SerialWriteString(sdebug);
sprintf(sdebug,"Reverse : %i\r\n", bConfig.Reverse);
SerialWriteString(sdebug);
sprintf(sdebug,"Memory : %i\r\n", bConfig.Memory);
SerialWriteString(sdebug);
sprintf(sdebug,"SpeedRatio : %i\r\n", bConfig.SpeedRatioEnabled);
SerialWriteString(sdebug);
sprintf(sdebug,"RiseTime : %i\r\n", bConfig.RiseTime);
SerialWriteString(sdebug);
sprintf(sdebug,"RiseTimeCounter : %i\r\n", bConfig.RiseTimeCounter);
SerialWriteString(sdebug);
sprintf(sdebug,"DebounceTime : %i\r\n", bConfig.DebounceTime);
SerialWriteString(sdebug);
}
/** @brief Versionsinformation über serielle Schnittstelle ausgeben
* @param none
* @return none
*/
void SerialAbout(void)
{
sprintf(sdebug,"%s", CLRSCR);
SerialWriteString(sdebug);
sprintf(sdebug,"%s %s %s\r\n\r\n", PRG,VER,CALL);
SerialWriteString(sdebug);
}
/** @brief Ein Zeichen über serielle Schnittstelle ausgeben
/** @fn void SerialWriteChar(unsigned char data)
* @brief Ein Zeichen über serielle Schnittstelle ausgeben
* @param Zeichen
* @return none
*/
@ -243,7 +206,8 @@ void SerialWriteChar(unsigned char data)
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}
/** @brief Eine Zeichenkette über serielle Schnittstelle ausgeben
/** @fn void SerialWriteString(unsigned char *s)
* @brief Eine Zeichenkette über serielle Schnittstelle ausgeben
* @param Zeiger auf Zeichenkette, die mit 0x00 abgeschlossen sein muss
* @return none
*/
@ -252,19 +216,8 @@ void SerialWriteString(char *s)
while(*s != 0x00)
SerialWriteChar(*s++);
}
/** @brief Read port pin of morse keys
*
* This function reads the input of
* the Paddle or Straight key.
* @params: Pin to read
* @return: State of pin
*/
uint8_t ReadKeyPin(uint8_t pin)
{
return(PIND & (1<<pin));
}
/** @brief Tonausgabe einschalten
/** @fn void SidetoneOn(void)
* @brief Mithörton einschalten
* @param none
* @return none
*/
@ -276,7 +229,8 @@ void SidetoneOn(void)
icnt = 0;
sbi(TIMSK1,OCIE1A);
}
/** @brief Tonausgabe abschalten
/** @fn void SidetoneOff(void)
* @brief Mithörtone ausschalten
* @param none
* @return none
*/
@ -286,7 +240,8 @@ void SidetoneOff(void)
StateRiseTime = 0;
StateRiseTimeCounter = 0;
}
/** @brief Audioverstärker abschalten
/** @fn void SidetoneDisable(void)
/* @brief Audioverstärker abschalten
* @param none
* @return none
*/
@ -295,7 +250,8 @@ void SidetoneDisable(void)
bConfig.SidetoneEnabled = 0;
cbi(PORTB,AUDIO_EN);
}
/** @brief Audioverstärker einschalten
/** @fn void SidetoneEnable(void)
* @brief Audioverstärker einschalten
* @param none
* @return none
*/
@ -304,11 +260,14 @@ void SidetoneEnable(void)
bConfig.SidetoneEnabled = 1;
sbi(PORTB,AUDIO_EN);
}
/*
** TXKey
**
** Tastung TRX1, TRX2 oder beide
/** @fn void TXKey(uint8_t State)
* @brief Gibt ein Symbol aus
*
* Je nach Einstellung wird ein oder beide Transceiver
* getastet oder nur der Mithörton ausgegeben.
*
* @param State - Bitfeld für Transceiver und Tonausgabe
* @return none
*/
void TXKey(uint8_t State)
{
@ -334,17 +293,19 @@ void TXKey(uint8_t State)
}
}
}
/** \brief StraigtKey
*
* Check Straightkey
*
*/
/** @fn void CheckStraightKey(void)
* @brief Fragt die Handtasteneingänge ab und gibt das
* entsprechende Symbol aus. Bei der Handtaste
* findet über einen Timer noch eine Software
* Entprellung statt
* @param none
* @return none
*/
void CheckStraightKey(void)
{
if(PIND & (1<<STRAIGHT_KEY))
{
if(bState.SendStatus == NOTHING)
if(bState.SendStatus == SENDING_NOTHING)
TXKey(0);
StateStraightKeyPressed = NO_KEY_PRESSED;
} else {
@ -355,40 +316,78 @@ void CheckStraightKey(void)
}
if(StateStraightKeyPressed == KEY_PRESSED)
{
if(bState.SendStatus == NOTHING)
if(bState.SendStatus == SENDING_NOTHING)
TXKey(1);
}
}
}
/** \brief CheckPaddles
**
/** @fn void CheckPaddles(void)
** @brief Diese Funktion prüft, ob ein Paddle betätigt wurde.
**
** Wenn dies der Fall war, ist das jeweilige Statusbit gesetzt
** und die Funktion für die Ausgabe des entsprechendem Symbol
** wird aufgerufen.
**
** @param none
** @return none
*/
void CheckPaddles(void)
{
CheckDitPaddle();
CheckDahPaddle();
// Wenn Paddle betätigt wurde,
if(bState.SendStatus == SENDING_NOTHING)
{
if(bState.DitPressed || bState.DahPressed)
{
if(bState.DitPressed && !bState.DahPressed)
SendDit();
else if(bState.DahPressed && !bState.DitPressed)
SendDah();
else if(bState.DahPressed && bState.DitPressed)
SendIambic();
}
}
}
/** \brief CheckDitPaddle
/** @fn void CheckDitPaddle(void)
* @brief Prüfen, ob das Punkt Paddle betätigt wurde.
*
* Ist dies der Fall, wird das Statusbit gesetzt.Wurde in den
* Einstellungen der Reverse Mode aktiviert, werden in der
* Abfrage die Paddle vertauscht.
*
* @param none
* @return none
*/
void CheckDitPaddle(void)
{
uint8_t pinvalue = 0;
if(PaddleMode == PADDLE_NORMAL) // no reverse paddle
if(PaddleMode == PADDLE_NORMAL)
pinvalue = PIND & (1<<LEFT_PADDLE);
else
pinvalue = PIND & (1<<RIGHT_PADDLE); // reverse paddle
pinvalue = PIND & (1<<RIGHT_PADDLE);
if(pinvalue == 0) // DitPaddle betätigt
if((pinvalue == 0) && ((!(bState.SendStatus == SENDING_DIT)) || (bState.SendStatus == SENDING_NOTHING)))
{
bState.DitPressed = 1;
}
// Wenn Punkt/Strich Speicher aktiviert ist, das Symbol merken, wenn es nicht identisch ist
if((pinvalue == 0) && (!(bState.SendStatus == SENDING_DIT)) && (bConfig.Memory == 1))
bState.DitPressed = 1;
}
/*
** CheckDahPaddle
*/
/** @fn void CheckDahPaddle(void)
* @brief Prüfen, ob das Strich Paddle betätigt wurde.
*
* Ist dies der Fall, wird das Statusbit gesetzt. Wurde in den
* Einstellungen der Reverse Mode aktiviert, werden in der
* Abfrage die Paddle vertauscht.
*
* @param none
* @return none
*/
void CheckDahPaddle(void)
{
uint8_t pinvalue = 0;
@ -398,54 +397,130 @@ void CheckDahPaddle(void)
else
pinvalue = PIND & (1<<LEFT_PADDLE); // reverse paddle
if(pinvalue == 0)
// Das Symbol nur merken, wenn nicht gerade eines ausgegeben wird oder gar nichts ausgegeben wird
if((pinvalue == 0) && ((!(bState.SendStatus == SENDING_DAH)) || (bState.SendStatus == SENDING_NOTHING)))
{
bState.DahPressed = 1;
}
// Wenn Punkt/Strich Speicher aktiviert ist, das Symbol merken, wenn es nicht identisch ist
if((pinvalue == 0) && (!(bState.SendStatus == SENDING_DAH)) && (bConfig.Memory == 1))
bState.DahPressed = 1;
}
void SetRatio(uint8_t WPMCorrectFactor)
/** @fn void SetRatio(void)
* @brief Berechnung der Zeitdauer für Punkt und Strich
*
* Die Länge eines Symbols ist abhängig von der
* eingestellten Geschwindigkeit. Intern wird immer
* mit Wörtern pro Minute gerechnet. Das normale
* Punkt/Strich Verhältnis ist 1:3. Dies kann durch
* den Parameter Ratio in den Einstellungen verändert
* werden. Wird ein Korrekturfaktor angegeben, kann
* das Ratio über eine Tabelle in Abhängigkeit der
* Geschwindigkeit bis zu 1:2.0 verändert werden.
*
* @param none
* @return none
*/
void SetRatio(void)
{
DitMillis = 1200 / WpM;
DahMillis = DitMillis * (float)(bConfig.Ratio/10);
if(bConfig.SpeedRatioEnabled)
DahMillis = DitMillis * (float)(bState.WpMCorrectFactor / 10);
else
DahMillis = DitMillis * (float)(bConfig.Ratio/10);
}
/** @fn void GetWpMCorrectFactor(void)
* @brief Ermittelt den Korrekturfaktor für das Ratio
* param none
* return none
*/
void GetWpMCorrectFactor(void)
{
bState.WpMCorrectFactor = 30;
if(WpM > 20)
bState.WpMCorrectFactor = 28;
/** @brief Symbol senden
}
void SetWeight(void)
{
DitMillis = 1200/WpM;
DahMillis = 3 * DitMillis;
SpcMillis = 1200/WpM;
DitMillis = (bConfig.Weight/50.0) * DitMillis;
DahMillis = (bConfig.Weight/50.0) * DahMillis;
if(bConfig.Weight < 50)
SpcMillis = SpcMillis + (SpcMillis - DitMillis);
else
SpcMillis = SpcMillis - (DitMillis - SpcMillis);
}
/** @fn void SendSymbol(uint8_t Dit)
* @brief Symbol senden
* @param Dit = 1, wenn Symbol ein Punkt ist
* @return none
*/
void SendSymbol(uint8_t Dit)
{
volatile static uint16_t ticks; // Länge des Symbols
static uint16_t ticks; // Länge des Symbols
if(Dit)
ticks = DitMillis;
else
ticks = DahMillis;
t_elementlength = 0;
t_elementlength = 0;
TXKey(1);
DelayMilliSeconds(ticks);
bState.SendStatus = SENDING_SPC;
TXKey(0);
DelayMilliSeconds(DitMillis);
DelayMilliSeconds(SpcMillis);
}
/*
** void SendDit(uint8_t SendingType)
*/
/** @fn void SendDit(void)
* @brief Gibt einen Punkt aus
* @param none
* @return none
*/
void SendDit(void)
{
bState.DitPressed = 0;
SendSymbol(DIT);
bState.LastSymbolWasDit = 1;
if((bState.SendStatus == NOTHING) || (bState.SendStatus == SENDING_DAH))
{
bState.DitPressed = 0;
bState.SendStatus = SENDING_DIT;
SendSymbol(DIT);
bState.SendStatus = SENDING_NOTHING;
bState.LastSymbolWasDit = 1;
}
if(bConfig.Memory == 0)
bState.DitPressed = 0;
}
/** \brief Send a dah
** A Dah with weight = 50 has the length of 3 Dits.
/** @fn void SendDah(void)
* @brief Gibt einen Strich aus
* @param none
* @return none
*/
void SendDah(void)
{
bState.DahPressed = 0;
SendSymbol(DAH);
bState.LastSymbolWasDit = 0;
if((bState.SendStatus == NOTHING) || (bState.SendStatus == SENDING_DIT))
{
bState.DahPressed = 0;
bState.SendStatus = SENDING_DAH;
SendSymbol(DAH);
bState.SendStatus = SENDING_NOTHING;
bState.LastSymbolWasDit = 0;
}
if(bConfig.Memory == 0)
bState.DahPressed = 0;
}
/** @fn void SendIambic(void)
* @brief Wenn beide Paddle betätigt sind, wird alternierend
* ein Punkt und Strich ausgegeben.
*
* Beim Iambic B Mode und Ultimatic Mode wird gegebenenfalls
* noch ein gegensätzliches Zeichen des zuletzt betätigten Paddle
* angefügt. Erläuterung und Timing siehe Dokumentation.
*
* @param none
* @return none
*/
void SendIambic(void)
{
bState.DahPressed = 0;
@ -485,19 +560,27 @@ void SendIambic(void)
}
}
}
/*
** Set sidetone frequency
*/
/** @fn void SetFrequency(uint16_t f)
* @brief Verändert die Frequenz des Mithörtons
*
* Durch die Anpassung des Timers 1 für das
* Laden der Werte der Sinuskurve wird die
* Tonhöhe des Mithörtons verändert.
* @param Frequenz des Mithörtons in Hz
* @return none
*/
void SetFrequency(uint16_t f)
{
IntDisable();
OCR1A = (F_CPUPRESIN / f) - 1;
IntEnable();
}
/*
** Output a tone width frequency f and duration duration
**
*/
/** @fn void Tone(uint16_t f, uint8_t duration)
* @brief Ausgabe eines Tons mit Dauer und Frequenz
* @param f - Frequenz des Tons
* duration - Dauer des Tons
* @return none
*/
void Tone(uint16_t f, uint8_t duration)
{
SetFrequency(f);
@ -506,14 +589,29 @@ void Tone(uint16_t f, uint8_t duration)
SidetoneOff();
SetFrequency(bConfig.SidetoneFreq);
}
/** @fn void Boop(void)
* @brief Boop Ton ausgeben
* @param none
* @return none
*/
void Boop(void)
{
Tone(600,100);
}
/** @fn void Beep(void)
* @brief Beep Ton ausgeben
* @param none
* @return none
*/
void Beep(void)
{
Tone(1200,100);
}
/** @fn void BeepBoop(void)
* @brief BeepBoop Doppelton ausgeben
* @param none
* @return none
*/
void BeepBoop(void)
{
DelayMilliSeconds(10);

@ -16,9 +16,8 @@ uint8_t sreg_tmp;
// Prototypes
void SymbolLoop(uint8_t Len);
uint8_t ReadKeyPin(uint8_t pin);
void CheckPaddles(void);
void SetRatio(uint8_t WpMCorrectFactor);
void SetRatio(void);
void DitDahBuffers(void);
void SendDit(void);
@ -45,8 +44,6 @@ void SetEEprom(void);
// Serielle Schnittstelle
void SerialWriteString(char *s);
void SerialWriteChar(unsigned char data);
void SerialInfo(void);
void SerialAbout(void);
// Delay Millis
void DelayMilliSeconds(uint16_t ms);
void ResetMilliSeconds(void);

@ -43,13 +43,10 @@
#define NOINIT __attribute__ ((section (".noinit")))
#endif
#define L_WAIT 500 // Frequency for debug LED Timer 0
#define CALL " DL7BJ "
#define PRG " BJ-Keyer "
#define VER " V1.00 "
// Keying states
#define NOTHING 0
#define DIT_DAH_OFF 1
@ -69,14 +66,11 @@
#define SENDING_NOTHING 0
#define SENDING_DIT 1
#define SENDING_DAH 2
#define SENDING_ELEMENT_SPACE 3
#define SENDING_SPC 3
#define SENDING_STRAIGHT 4
// 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
// Ports
#define LEFT_PADDLE PD2 // Left Paddle Input
#define RIGHT_PADDLE PD3 // Right Paddle Input
@ -113,10 +107,11 @@
#define M_REVERSE 9
#define M_RATIO 10
#define M_SPEEDRATIO 11
#define M_WPMBPM 12
#define M_RISETIME 13
#define M_DEBOUNCE 14
#define M_MAX 14 // maximale Menuepunke
#define M_WEIGHT 12
#define M_WPMBPM 13
#define M_RISETIME 14
#define M_DEBOUNCE 15
#define M_MAX 15 // maximale Menuepunke
// LCD
#define CLEARLINE " "
#define NORMAL 0
@ -136,7 +131,7 @@ struct State
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
uint8_t Encoder: 1; // Drekencoder wurde betätigt
uint8_t WpMCorrectFactor; // Korrekturfaktor für Ratio
uint8_t KeyState:1; //
uint8_t KeyTX:1;
};
@ -164,6 +159,7 @@ struct Config
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
uint16_t SidetoneFreq; // Frequenz des Mithörtons
uint8_t WpM; // WpM
@ -185,36 +181,19 @@ uint16_t StoreEEprom;
// Globale Variablen für diverse Zwecke
uint8_t WpM;
uint8_t Weight;
uint8_t LengthOfElement;
// State Machines
uint8_t PaddleMode;
uint8_t KeyerMode;
// History
uint8_t keyhistory;
uint8_t KeyTX;
uint8_t DahBuffer;
uint8_t DitBuffer;
uint8_t Weighting;
uint8_t IambicFlag;
uint8_t DitCounter;
uint8_t DahCounter;
uint8_t CurrentTRX1;
// Sidetone generation
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 uint16_t DitMillis;
volatile uint16_t DahMillis;
volatile uint16_t SpcMillis;
// Zähler und Status für Entprellung der Tasteneingänge und Mithörton
volatile uint8_t StateStraightKeyPressed; // Merker für StraightKey betätigt
volatile uint8_t TimerStraightKeyPressed; // Timer Variable für Entprellung

@ -19,6 +19,7 @@
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)
----------
@ -50,10 +51,6 @@
Pin 13 - PD7 - Mem 3 Pin 16 - PB2 - Encoder Switch
Pin 14 - PB0 - Encoder A Pin 15 - PB1 - Encoder B
Value 1 2 4 8 32 64 128 255
Bit 1 2 3 4 5 6 7 8
Pin 0 1 2 3 4 5 6 7
@endverbatim
*/
@ -67,23 +64,17 @@ const unsigned char sinewave[] PROGMEM = {
0x80, 0x73, 0x67, 0x5a, 0x4f, 0x43, 0x39, 0x2f, 0x25, 0x1d, 0x15, 0x0f, 0x0a, 0x05, 0x02, 0x01
};
/**
* \brief Initialsieren der Timer
*
* Alle Parameter der Timer basieren auf 16MHz Systemtakt.
/** @fn void InitTimer(void)
* @brief Initialsieren der Timer
*
* 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
* Timer 1B - 16 Bit timer wird nicht benutzt
* Alle Parameter der Timer basieren auf 16MHz Systemtakt.
*
* T - dot duration
* wpm - Words per Minute based on PARIS
* Formula T = 1200 / wpm
* Minimum speed 10 wpm - dot duration 120ms
* Maximum speed 99 wpm - dot duration 12ms
*
*/
* 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();
@ -97,14 +88,10 @@ void InitTimer(void)
// Fast PWM Mode
sbi(TCCR2A,WGM20);
sbi(TCCR2A,WGM21);
// Phase Correct PWM
//sbi(TCCR2A,WGM22);
//sbi(TCCR2A,WGM20);
// 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
@ -114,7 +101,6 @@ void InitTimer(void)
// 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);
@ -127,8 +113,12 @@ void InitTimer(void)
sbi(TIMSK0,OCIE0A); // Timer 0 1ms einschalten
sei();
}
void Init()
/** @fn void Init(void)
* @brief Initialisierung aller Variablen, Timer
* @param none
* @return none
*/
void Init(void)
{
cli(); // disable all interrupts
bState.SendStatus = SENDING_NOTHING;
@ -153,23 +143,6 @@ void Init()
cbi(PORTD,LEFT_PADDLE);
cbi(PORTD,RIGHT_PADDLE);
cbi(PORTD,STRAIGHT_KEY);
LengthOfElement = (uint16_t)1200/bConfig.WpM;
// Pin Change Interrupts Port D - Keys
// Alle Pins liegen im PCINT2 Vektor
// PD4 - StraightKey - PCINT20 - Pin Change Interrupt 20
// PD3 - Right Paddle - PCINT19 - Pin Change Interrupt 19
// PD2 - Left Paddle - PCINT18 - Pin Change Interrupt 18
sbi(PCICR,PCIE2);
// sbi(PCMSK2,PCINT18);
// sbi(PCMSK2,PCINT19);
// sbi(PCMSK2,PCINT20);
sbi(PCICR,PCIE0);
sbi(PCMSK0,PCINT0);
sbi(PCMSK0,PCINT1);
sbi(PCMSK0,PCINT2);
// Init serial
UBRR0=UBRR_VALUE; // Set baud rate
sbi(UCSR0B,TXEN0); // Enable TX
@ -180,7 +153,6 @@ void Init()
InitTimer();
EncoderInit();
// Initialisierung Menüvariablen
bMenuCtrl.ClrScr = 1;
bMenuCtrl.Update = 1;
@ -190,7 +162,14 @@ void Init()
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);
@ -226,30 +205,24 @@ ISR(TIMER1_COMPA_vect)
}
}
}
/** @brief 8 Bit Timer 0 ISR routine
/** @fn ISR(TIMER0_COMPA_vect)
* @brief 8 Bit Timer 0 ISR routine
*
* The Timer 0 CTC interrupt will be fired every millisecond and
* has a bundle of counter variables for different timings.
* 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 counter for milliseconds
t_elementlength++; // Length of element dit/dah
t_wait++;
t_timer++;
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
if(t_timer >= L_WAIT)
{
t_timer = 0;
}
// Alle 5ms den Drehencoder abfragen
if(EncoderTimer > 5)
{
@ -295,21 +268,10 @@ ISR(TIMER0_COMPA_vect)
if(TimerPaddleDahKeyPressed > bConfig.DebounceTime)
StatePaddleDahKeyPressed = KEY_PRESSED;
}
}
/** \brief 8 Bit Timer 2
/** @fn ISR(USART_RX_vect)
* @brief Interrupt RX serielle Schnittstelle
*
* Timer 2 overflow interrupt
* Mit diesem Interrupt wird der nächste Wert für die
* Erzeugung des Sinus für den Mithörton geladen.
*
*/
ISR(TIMER2_OVF_vect)
{
/* nothing */
}
/** @brief Interrupt RX serielle Schnittstelle
* @param none
* @return none
*/
@ -319,34 +281,17 @@ ISR(USART_RX_vect)
data = UDR0;
SerialWriteChar(data);
}
/** @brief Pin Change Interrupt PORT C
* @param none
* @return none
*/
ISR(PCINT2_vect)
{
}
/** @brief Pin Change Interrupt PORT B
* @param none
* @return none
*/
ISR(PCINT0_vect)
{
SerialWriteChar("Encoder\r\n");
bState.Encoder = 1;
}
/** @brief Initialisierung bei Reset und Neustart
/** @fn void ReStart(void)
* @brief Initialisierung bei Reset und Power On
* @param none
* @return none
*/
void ReStart(void)
{
MenuCtrlTimer = 0;
t_delayms = 0;
bState.SendStatus = SENDING_NOTHING;
Init();
Init();
DisplayVersion();
ReadEEprom();
WpM = bConfig.WpM;
@ -354,7 +299,6 @@ void ReStart(void)
EncoderWrite(bConfig.WpM);
EncoderPosConfig = 1;
SetFrequency(bConfig.SidetoneFreq);
SetRatio(0);
KeyerMode = bConfig.KeyerMode;
PaddleMode = bConfig.Reverse;
bState.KeyTX = 1;
@ -363,9 +307,11 @@ void ReStart(void)
SidetoneEnable();
else
SidetoneDisable();
LastPINDState = 0xff;
SetRatio();
SetWeight();
}
/** @brief main()
/** @fn int main(void)
* @brief One Infinite Loop
* @param none
* @return none
*/
@ -373,37 +319,27 @@ int main(void)
{
ReStart();
SerialAbout();
SerialInfo();
SerialMenue();
while(1)
{
// Wenn Geschwindigkeit verändert und Zeit abgelaufen,
// dann im EEprom speichern und Merker löschen.
// 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();
UpdateDisplay();
CheckStraightKey();
CheckPaddles();
if(bState.DitPressed || bState.DahPressed)
{
if(bState.DitPressed && !bState.DahPressed)
SendDit();
else if(bState.DahPressed && !bState.DitPressed)
SendDah();
else if(bState.DahPressed && bState.DitPressed)
SendIambic();
}
}
Drehencoder(); // Drehencoder abfragen
UpdateDisplay(); // Display aktualisieren
CheckStraightKey(); // Handtaste auf Betätigung prüfen
CheckPaddles(); // Paddles auf Betätigung prüfen
}
}

@ -11,6 +11,7 @@
#include "encoder.h"
#include "functions.h"
#include "controls.h"
#include "vt100.h"
struct Config bConfig;
struct MenuCtrl bMenuCtrl;

@ -0,0 +1,65 @@
/** @file vt100.c
* @brief VT100 Termial
* @author Tom, DL7BJ
*/
#include "vt100.h"
/** @brief Auswahlmenue über serielle Schnittstelle ausgeben
* @param none
* @return none
*/
void SerialMenue(void)
{
SerialWriteString("(1) Einstellungen anzeigen\r\n");
SerialWriteString("(2) Einstellungen ändern\r\n");
SerialWriteString("(3) Texte anzeigen\r\n");
SerialWriteString("(4) Texte ändern\r\n");
SerialWriteString("(5) Texte anhören\r\n");
SerialWriteString("\r\nEingabe: ");
}
/** @brief Aktuelle Einstellungen über serielle Schnittstelle ausgeben
* @param none
* @return none
*/
void SerialSetup(void)
{
sprintf(sdebug,"WpM : %i\r\n", bConfig.WpM);
SerialWriteString(sdebug);
sprintf(sdebug,"KeyerMode : %i\r\n", bConfig.KeyerMode);
SerialWriteString(sdebug);
sprintf(sdebug,"SidetoneFreq : %u\r\n", bConfig.SidetoneFreq);
SerialWriteString(sdebug);
sprintf(sdebug,"TRX : %i\r\n", bConfig.TRX);
SerialWriteString(sdebug);
sprintf(sdebug,"SidetoneEnabled : %i\r\n", bConfig.SidetoneEnabled);
SerialWriteString(sdebug);
sprintf(sdebug,"Ratio : %i\r\n", bConfig.Ratio);
SerialWriteString(sdebug);
sprintf(sdebug,"WpMBpM : %i\r\n", bConfig.WpMBpM);
SerialWriteString(sdebug);
sprintf(sdebug,"Reverse : %i\r\n", bConfig.Reverse);
SerialWriteString(sdebug);
sprintf(sdebug,"Memory : %i\r\n", bConfig.Memory);
SerialWriteString(sdebug);
sprintf(sdebug,"SpeedRatio : %i\r\n", bConfig.SpeedRatioEnabled);
SerialWriteString(sdebug);
sprintf(sdebug,"RiseTime : %i\r\n", bConfig.RiseTime);
SerialWriteString(sdebug);
sprintf(sdebug,"RiseTimeCounter : %i\r\n", bConfig.RiseTimeCounter);
SerialWriteString(sdebug);
sprintf(sdebug,"DebounceTime : %i\r\n", bConfig.DebounceTime);
SerialWriteString(sdebug);
}
/** @brief Versionsinformation über serielle Schnittstelle ausgeben
* @param none
* @return none
*/
void SerialAbout(void)
{
sprintf(sdebug,"%s", CLRSCR);
SerialWriteString(sdebug);
sprintf(sdebug,"%s %s %s\r\n\r\n",PRG,VER,CALL);
SerialWriteString(sdebug);
}

@ -0,0 +1,22 @@
/** @file vt100.h
* @brief VT100 Termial
* @author Tom, DL7BJ
*/
#ifndef VT100_H_INCLUDED
#define VT100_H_INCLUDED
#include "functions.h"
void SerialInfo(void);
void SerialAbout(void);
void SerialSetup(void);
void SerialMenue(void);
// Stringkonstanten für VT100 Terminals
static const char* const CLRSCR = "\033[2J";
unsigned char line[64];
#endif
Loading…
Cancel
Save