Umstrukturierung des Quellcodes in mehr Dateien

main
Tom 2 years ago
parent 2bdecacf56
commit 957ac1fa8d

@ -1,2 +1,2 @@
:080000000032005802000C550B :080000000203005802010C5537
:00000001FF :00000001FF

@ -46,7 +46,7 @@ FORMAT = ihex
TARGET = BJ-Keyer TARGET = BJ-Keyer
# List C source files here. (C dependencies are automatically generated.) # 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. # List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s # 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 = SCANF_LIB =
MATH_LIB = -lm MATH_LIB = -lm
# External memory options # External memory options
# 64 KB of external RAM, starting after internal RAM (ATmega128!), # 64 KB of external RAM, starting after internal RAM (ATmega128!),

@ -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;
}
}

@ -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

@ -1,40 +1,83 @@
/** @file functions.c
* @brief Diverse Funktionen
* @author Tom, DL7BJ
*/
#include "functions.h" #include "functions.h"
void delayms(uint16_t ms) // EEProm
{ uint8_t Dummy;
t_wait = 0; uint8_t ee_Dummy EEMEM = 0x55; // Dummy for Address 0
while(t_wait < ms); 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) // Stringkonstanten für VT100 Terminals
{ char CLRSCR[] = "\033[2J";
SREG = sreg_tmp;
sei();
}
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; t_delayms = 0;
cli(); // ResetMilliSeconds();
//ATOMIC_BLOCK(ATOMIC_FORCEON) {
while(t_delayms < ms);
//}
} }
/** \brief MilliSeconds /** @brief Wert des Zählers für Millisekunden lesen
* *
* Get the milliseconds of TIMER 0 * Dieser Variable muss atomar sein, weil es eine 16Bit Variable ist,
* * die im Timer 0 verwendet wird.
*/ * @param none
uint32_t MilliSeconds(void) * @return milliseconds
*/
uint16_t GetMilliSeconds(void)
{ {
uint32_t m; uint16_t m;
ATOMIC_BLOCK(ATOMIC_FORCEON){ ATOMIC_BLOCK(ATOMIC_FORCEON){
m = ms; m = t_delayms;
} }
return m; 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) void ResetMilliSeconds(void)
{ {
ATOMIC_BLOCK(ATOMIC_FORCEON){ //ATOMIC_BLOCK(ATOMIC_FORCEON){
ms = 0; 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 /** \brief EEPROM schreiben
@ -118,16 +161,18 @@ void SideToneOff(void)
StateRiseTimeCounter = 0; 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((State) && (KeyState == 0))
{ {
if(KeyTX) if(KeyTX)
{ {
SideToneOn(); SideToneOn();
PORTC |= (1<<MORSE_LED); sbi(PORTC,MORSE_LED);
KeyState = 1; KeyState = 1;
} }
} }
@ -138,7 +183,7 @@ void TXSidetoneKey(uint8_t State, uint8_t SendingType)
if(KeyTX) if(KeyTX)
{ {
SideToneOff(); SideToneOff();
PORTC &= ~(1<<MORSE_LED); cbi(PORTC,MORSE_LED);
} }
KeyState = 0; KeyState = 0;
} }
@ -153,7 +198,7 @@ void CheckStraightKey(void)
{ {
if(PIND & (1<<STRAIGHT_KEY)) if(PIND & (1<<STRAIGHT_KEY))
{ {
TXSidetoneKey(0,MANUAL_SENDING); TXKey(0,MAN);
StateStraightKeyPressed = 0; StateStraightKeyPressed = 0;
} else { } else {
if(StateStraightKeyPressed == 0) if(StateStraightKeyPressed == 0)
@ -163,104 +208,69 @@ void CheckStraightKey(void)
} }
if(StateStraightKeyPressed == 2) if(StateStraightKeyPressed == 2)
{ {
TXSidetoneKey(1,MANUAL_SENDING); TXKey(1,MAN);
} }
} }
} }
/** \brief CheckPaddles /** \brief CheckPaddles
* Original code K3NG keyer line 5654 **
*
*/ */
void CheckPaddles(void) void CheckPaddles(void)
{ {
static uint8_t laststate = NOTHING;
CheckDitPaddle(); CheckDitPaddle();
CheckDahPaddle(); CheckDahPaddle();
}
/** \brief CheckDitPaddle
*
*
*/
void CheckDitPaddle(void)
{
uint8_t pinvalue = 0;
uint8_t ditpaddle = 0;
if(KeyerMode == SINGLE_PADDLE) if(PaddleMode == PADDLE_NORMAL) // no reverse paddle
{ ditpaddle = LEFT_PADDLE;
switch(laststate) else
{ ditpaddle = RIGHT_PADDLE; // reverse paddle
case DIT_DAH_OFF:
if(DitBuffer) {
if(DahBuffer)
DahBuffer = 0;
else
laststate = DIT_DAH_OFF;
} else {
if(DahBuffer)
laststate = DAH_DIT_OFF;
else
laststate = NOTHING;
}
break;
case DIT_DAH_ON:
if(DahBuffer) {
if(DitBuffer) {
laststate = DAH_DIT_ON;
DitBuffer = 0;
} else
laststate = DAH_DIT_OFF;
} else {
if(!DitBuffer)
laststate = NOTHING;
}
break;
case DAH_DIT_OFF:
if(DahBuffer) {
if(DitBuffer)
DitBuffer = 0;
else
laststate = DAH_DIT_OFF;
} else {
if(DitBuffer)
laststate = DIT_DAH_OFF;
else
laststate = NOTHING;
}
break;
case DAH_DIT_ON:
if(DitBuffer) {
if(DahBuffer) {
laststate = DIT_DAH_ON;
DahBuffer = 0;
} else
laststate = DIT_DAH_OFF;
} else {
if(!DahBuffer)
laststate = NOTHING;
}
break; pinvalue = ReadKeyPin(ditpaddle);
case NOTHING:
break;
}
}
// service_tx_inhibit_and_pause{}
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
/** \brief ServiceStraightKey pinvalue = ReadKeyPin(dahpaddle);
* Original code K3NG keyer line 2762
*
* ***TODO
*/
long ServiceStraightKey(void)
{
}
if(pinvalue == 0) {
if(DahBuffer == 0) {
DahCounter++;
DitCounter = 0;
}
DahBuffer = 1;
}
}
/** \brief Schleife für die Dauer der Zeichenelemente /** \brief Schleife für die Dauer der Zeichenelemente
** **
** lengths = count of dits * weigthing / 50 ** len = count of dits * weigthing / 50
** additional_time_ms = increase pausing between elements ** AddMiliSeconds = increase pausing between elements
** speed_wpm_in = speed in WpM ** SendingType = AUTO or MAN
** sending_type =
*/ */
void Loop(uint8_t len, uint8_t AddMilliSeconds, uint8_t inWpM, uint8_t SendingType) void ElementLoop(uint8_t len, uint8_t AddMilliSeconds, uint8_t SendingType)
{ {
uint16_t LoE; // lengths of one element in ms uint16_t LoE; // lengths of one element in ms
uint16_t ticks; // lengths of len elements + AddMilliSeconds in ms uint16_t ticks; // lengths of len elements + AddMilliSeconds in ms
@ -268,7 +278,7 @@ void Loop(uint8_t len, uint8_t AddMilliSeconds, uint8_t inWpM, uint8_t SendingTy
if((len == 0) || (len < 0)) if((len == 0) || (len < 0))
return; return;
LoE = 1200/inWpM; LoE = 1200/WpM;
ticks = LoE * len + AddMilliSeconds; ticks = LoE * len + AddMilliSeconds;
mselement = 0; // Reset Timer 0 variable mselement = 0; // Reset Timer 0 variable
while(mselement < ticks) { while(mselement < ticks) {
@ -298,10 +308,10 @@ void Loop(uint8_t len, uint8_t AddMilliSeconds, uint8_t inWpM, uint8_t SendingTy
void SendDit(uint8_t SendingType) void SendDit(uint8_t SendingType)
{ {
SendStatus = SENDING_DIT; SendStatus = SENDING_DIT;
TXSidetoneKey(1,SendingType); TXKey(1,SendingType);
Loop(1,0,WpM,SendingType); ElementLoop(1,0,SendingType);
TXSidetoneKey(0,SendingType); TXKey(0,SendingType);
Loop(1,0,WpM,SendingType); ElementLoop(1,0,SendingType);
} }
/** \brief Send a dah /** \brief Send a dah
** A Dah with weight = 50 has the length of 3 Dits. ** A Dah with weight = 50 has the length of 3 Dits.
@ -309,10 +319,10 @@ void SendDit(uint8_t SendingType)
void SendDah(uint8_t SendingType) void SendDah(uint8_t SendingType)
{ {
SendStatus = SENDING_DAH; SendStatus = SENDING_DAH;
TXSidetoneKey(1,SendingType); TXKey(1,SendingType);
Loop(3,0,WpM,SendingType); ElementLoop(3,0,SendingType);
TXSidetoneKey(0,SendingType); TXKey(0,SendingType);
Loop(1,0,WpM,SendingType); ElementLoop(1,0,SendingType);
} }
/* /*
** Set sidetone frequency ** Set sidetone frequency
@ -331,7 +341,7 @@ void Tone(uint16_t f, uint8_t duration)
{ {
SetFrequency(f); SetFrequency(f);
SideToneOn(); SideToneOn();
delayms(duration); DelayMilliSeconds(duration);
SideToneOff(); SideToneOff();
SetFrequency(bConfig.FrequencySidetone); SetFrequency(bConfig.FrequencySidetone);
} }
@ -346,65 +356,63 @@ void Beep(void)
void BeepBoop(void) void BeepBoop(void)
{ {
sbi(PORTB,AUDIO_EN); sbi(PORTB,AUDIO_EN);
delayms(10); DelayMilliSeconds(10);
Beep(); Beep();
delayms(100); DelayMilliSeconds(100);
Boop(); Boop();
} }
void SendChar(unsigned char c) void SendChar(unsigned char c)
{ {
switch(c) switch(c)
{ {
case 'A': SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; // Buchstaben
case 'B': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'A': SendDit(AUTO); SendDah(AUTO); break;
case 'C': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case 'B': SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case 'D': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'C': SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case 'E': SendDit(AUTOMATIC); break; case 'D': SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case 'F': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'E': SendDit(AUTO); break;
case 'G': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break; case 'F': SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case 'H': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'G': SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); break;
case 'I': SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'H': SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case 'J': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case 'I': SendDit(AUTO); SendDit(AUTO); break;
case 'K': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case 'J': SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case 'L': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'K': SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case 'M': SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case 'L': SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case 'N': SendDah(AUTOMATIC); SendDit(AUTOMATIC); break; case 'M': SendDah(AUTO); SendDah(AUTO); break;
case 'O': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case 'N': SendDah(AUTO); SendDit(AUTO); break;
case 'P': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break; case 'O': SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case 'Q': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case 'P': SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); break;
case 'R': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break; case 'Q': SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case 'S': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case 'R': SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); break;
case 'T': SendDah(AUTOMATIC); break; case 'S': SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case 'U': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case 'T': SendDah(AUTO); break;
case 'V': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case 'U': SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case 'W': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case 'V': SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case 'X': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case 'W': SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case 'Y': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case 'X': SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case 'Z': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case 'Y': SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case 'Z': SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case '0': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; // Zahlen
case '1': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case '0': SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case '2': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case '1': SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case '3': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case '2': SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case '4': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case '3': SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case '5': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case '4': SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case '6': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case '5': SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case '7': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case '6': SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case '8': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case '7': SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case '9': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break; case '8': SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); break;
case '9': SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); break;
case '=': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; // Sonderzeichen
case '/': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break; case '=': SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case '.': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break; case '/': SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); break;
case ',': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break; case '.': SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); break;
case '?': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break; case ',': SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); break;
case '?': SendDit(AUTO); SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); SendDit(AUTO); break;
// ***TODO Umlaute case '@': SendDit(AUTO); SendDah(AUTO); SendDah(AUTO); SendDit(AUTO); SendDah(AUTO); SendDit(AUTO); break;
// ***TODO Sonderzeichen }
ElementLoop(3,0,WpM);
}
Loop(3,0,WpM,AUTOMATIC);
} }

@ -1,8 +1,10 @@
#ifndef FUNCTIONS_H_INCLUDED #ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED #define FUNCTIONS_H_INCLUDED
#define TRUE 0x1 #include "main.h"
#define FALSE 0x0
#define TRUE 0x1
#define FALSE 0x0
#define PI 3.1415926535897932384626433832795 #define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398 #define HALF_PI 1.5707963267948966192313216916398
@ -10,26 +12,32 @@
#define DEG_TO_RAD 0.017453292519943295769236907684886 #define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105 #define RAD_TO_DEG 57.295779513082320876798154814105
uint8_t sreg_tmp; uint8_t sreg_tmp;
// Prototypes // Prototypes
void ElementLoop(uint8_t Len, uint8_t AddMilliSeconds, uint8_t SendingType);
void ElementLoop(float lengths, float additional_time_ms, int speed_wpm_on, uint8_t sending_type); uint8_t ReadKeyPin(uint8_t pin);
void CheckPaddles(void);
// Sidetone
void SideToneOn(void); void SideToneOn(void);
void SideToneOff(void); void SideToneOff(void);
void Tone(uint16_t f, uint8_t duration);
void Boop(void);
void Beep(void);
void BeepBoop(void);
// Interrupt
void IntDisable(void); void IntDisable(void);
void IntEnable(void); void IntEnable(void);
// EEPROM // EEPROM
void WriteEEprom(void); void WriteEEprom(void);
void ReadEEprom(void); void ReadEEprom(void);
void WriteEEpromWpM(void); void WriteEEpromWpM(void);
void ReadEEpromWpM(void); void ReadEEpromWpM(void);
// Serielle Schnittstelle // Serielle Schnittstelle
void SendSerialString(char *s); void SendSerialString(char *s);
void SendSerialChar(unsigned char data);
// Delay Millis
void DelayMilliSeconds(uint16_t ms);
void ResetMilliSeconds(void);
uint16_t GetMilliSeconds(void);
#endif #endif

@ -1,18 +1,17 @@
/* #ifndef GLOBALS_H_INCLUDED
* BJ-Keyer #define GLOBALS_H_INCLUDED
*
* 2023-07-29 Tom, DL7BJ
*
*/
#ifndef BJ-KEYER_H_INCLUDED
#define BJ-KEYER_H_INCLUDED
#define F_CPU 16000000UL #define F_CPU 16000000UL
#define PRESCALER 8 #define PRESCALER 8
#define SINEWAVELENGTH 64 #define SINEWAVELENGTH 64
#define F_CPUPRESIN (F_CPU/(PRESCALER*SINEWAVELENGTH)) #define F_CPUPRESIN (F_CPU/(PRESCALER*SINEWAVELENGTH))
#define USART_BAUDRATE 9600 #define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU/(USART_BAUDRATE*16UL)))-1) #define UBRR_VALUE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
#define LENGTH 256
#define AMP 127
#define OFFSET 128
#define PI2 6.283185
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -20,7 +19,7 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <inttypes.h> #include <inttypes.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/wdt.h> #include <avr/wdt.h>
@ -29,48 +28,22 @@
#include <util/delay.h> #include <util/delay.h>
#include <util/atomic.h> #include <util/atomic.h>
#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/i2c.h"
#include "oled/lcd.h" #include "oled/lcd.h"
#include "oled/font.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 #ifndef EEMEM
#define EEMEM __attribute__ ((section (".eeprom"))) #define EEMEM __attribute__ ((section (".eeprom")))
#endif #endif
#ifndef NOINIT #ifndef NOINIT
#define NOINIT __attribute__ ((section (".noinit"))) #define NOINIT __attribute__ ((section (".noinit")))
#endif #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 #define L_WAIT 500 // Frequency for debug LED Timer 0
// Keying states // Keying states
#define NOTHING 0 #define NOTHING 0
#define DIT_DAH_OFF 1 #define DIT_DAH_OFF 1
@ -85,20 +58,16 @@ const char CLRSCR[] = "\033[2J";
// Paddle Mode // Paddle Mode
#define PADDLE_NORMAL 0 #define PADDLE_NORMAL 0
#define PADDLE_REVERSE 1 #define PADDLE_REVERSE 1
// Machine Mode
#define NORMAL 0
#define COMMAND 1
// Sending Mode // Sending Mode
#define SENDING_NOTHING 0 #define SENDING_NOTHING 0
#define SENDING_DIT 1 #define SENDING_DIT 1
#define SENDING_DAH 2 #define SENDING_DAH 2
#define SENDING_ELEMENT_SPACE 3 #define SENDING_ELEMENT_SPACE 3
#define SENDING_STRAIGHT 4 #define SENDING_STRAIGHT 4
// // Sending Type
#define AUTOMATIC_SENDING 0 #define AUTO 0 // Automatische Pausen zwischen Elementen
#define AUTOMATIC 0 #define MAN 1 // Manuelle Pausen zwischen Elementen
#define MANUAL 1
#define MANUAL_SENDING 1
// Side Tone // Side Tone
#define SIDETONE_OFF 0 #define SIDETONE_OFF 0
#define SIDETONE_ON 1 #define SIDETONE_ON 1
@ -121,6 +90,9 @@ const char CLRSCR[] = "\033[2J";
// States // States
#define ON 1 #define ON 1
#define OFF 0 #define OFF 0
#define NO_KEY_PRESSED 0
#define KEY_PRESSED_DEBOUNCE 1
#define KEY_PRESSED 2
// Menue und Drehencoder // Menue und Drehencoder
#define M_TRX1 1 #define M_TRX1 1
#define M_TRX2 2 #define M_TRX2 2
@ -135,38 +107,18 @@ const char CLRSCR[] = "\033[2J";
#define M_DEBOUNCE 11 #define M_DEBOUNCE 11
#define M_MAX 11 // maximale Menuepunke #define M_MAX 11 // maximale Menuepunke
// LCD // LCD
#define CLEARLINE " " #define CLEARLINE " "
#define NORMAL 0
// 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
};
// Debugausgabe
char sdebug[64]; char sdebug[64];
// Sidetone generation // Structs für Merker, Menü und Einstellungen
double FrequencySidetone = 600; struct Merker
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
{ {
uint8_t WpMChanged: 1; uint8_t WpMChanged: 1;
uint8_t WriteWpMEEprom: 1; uint8_t WriteWpMEEprom: 1;
} bMerker; };
struct MenuCtrl struct MenuCtrl
{ {
@ -179,61 +131,7 @@ struct MenuCtrl
uint8_t WriteEEprom: 1; uint8_t WriteEEprom: 1;
uint8_t Update: 1; uint8_t Update: 1;
uint8_t CurMenue; 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 struct Config
{ {
@ -250,28 +148,62 @@ struct Config
uint8_t RiseTimeCounter; // Anzahl Sinusschwingungen für den Anstieg uint8_t RiseTimeCounter; // Anzahl Sinusschwingungen für den Anstieg
uint8_t DebounceTime; // Entprellzeit für Straight Key Eingang uint8_t DebounceTime; // Entprellzeit für Straight Key Eingang
uint8_t WinkeyerEnabled; // Winkeyer2 Emulation uint8_t WinkeyerEnabled; // Winkeyer2 Emulation
} bConfig; };
// Function prototypes
void Init(void);
void InitTimer(void);
void CheckDahPaddle(void); // Drehencoder
void CheckDitPaddle(void); volatile uint8_t EncoderTimer; // 10ms Timer for Encoder
void CheckPaddle(void); volatile int8_t EncoderCounter; // Vor/Rück Zähler
void CheckStraightKey(void); volatile int8_t EncoderPos; // Encoderposition für WpM/BpM
void SendDit(uint8_t SendingType); volatile int8_t EncoderPosConfig; // Encoderposition für Einstellungen
void SendDah(uint8_t SendingType);
void PTTKey(uint8_t State); uint16_t StoreEEprom;
void SideToneOff(void);
void SideToneOn(void);
void TXSidetoneKey(uint8_t State, uint8_t SendingType);
void SendChar(uint8_t);
void ChangeSpeed(void);
void dah(void); // Globale Variablen für diverse Zwecke
void dit(void); uint8_t WpM;
void DoMorse(void); 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

@ -57,14 +57,15 @@
@endverbatim @endverbatim
*/ */
#include "bj-keyer.h" #include "main.h"
// Additional files
#include "functions.c"
#define LENGTH 256 // Sinustabelle für PWM mit 64 Werten
#define AMP 127 const unsigned char sinewave[] PROGMEM = {
#define OFFSET 128 0x00, 0x01, 0x02, 0x05, 0x0a, 0x0f, 0x15, 0x1d, 0x25, 0x2f, 0x39, 0x43, 0x4f, 0x5a, 0x67, 0x73,
#define PI2 6.283185 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 * \brief Initialsieren der Timer
@ -103,7 +104,7 @@ void InitTimer(void)
OCR2A = 0x80; OCR2A = 0x80;
sbi(DDRB,PB3); sbi(DDRB,PB3);
cbi(TIMSK2,OCIE0A); cbi(TIMSK2,OCIE0A);
// Timer 1 für die Sinus Hüllkurve // Timer 1 für die Sinus Hüllkurve
TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0; TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0;
// CTC Mode // CTC Mode
@ -130,10 +131,7 @@ void InitTimer(void)
void Init() void Init()
{ {
cli(); // disable all interrupts cli(); // disable all interrupts
MachineMode = NORMAL;
SendStatus = SENDING_NOTHING; SendStatus = SENDING_NOTHING;
// PORTB // PORTB
DDRB = 0x00; DDRB = 0x00;
// Interne PullUps einschalten // Interne PullUps einschalten
@ -205,18 +203,7 @@ void Init()
bConfig.WinkeyerEnabled = 0; bConfig.WinkeyerEnabled = 0;
sei(); // enable all interrupts 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<<PD1);
//}
//
ISR(TIMER1_COMPA_vect) ISR(TIMER1_COMPA_vect)
{ {
ocr2a = pgm_read_byte_near(sinewave+icnt); ocr2a = pgm_read_byte_near(sinewave+icnt);
@ -253,16 +240,14 @@ ISR(TIMER1_COMPA_vect)
} }
} }
/** @brief 8 Bit Timer 0 ISR routine
/** \brief 8 Bit Timer 0
* *
* The Timer 0 CTC interrupt * The Timer 0 CTC interrupt will be fired every millisecond
* Dieser Interrupt wird jede Millisekunde erzeugt
* *
*/ */
ISR(TIMER0_COMPA_vect) ISR(TIMER0_COMPA_vect)
{ {
ms++; // allgemeiner Millisekundenzähler t_delayms++; // 16Bit counter for milliseconds
StoreEEprom++; // Zähler für Zeitablauf speichern EEprom StoreEEprom++; // Zähler für Zeitablauf speichern EEprom
MenuCtrlTimer++; // Zähler für Zeitablauf Einstellungen MenuCtrlTimer++; // Zähler für Zeitablauf Einstellungen
EncoderTimer++; // Zähler für 5ms Drehencoder Timer EncoderTimer++; // Zähler für 5ms Drehencoder Timer
@ -301,20 +286,18 @@ ISR(TIMER0_COMPA_vect)
} }
// Softwareentprellung für StraightKey // Softwareentprellung für StraightKey
TimerStraightKeyPressed++; TimerStraightKeyPressed++;
if(StateStraightKeyPressed == 1) if(StateStraightKeyPressed == KEY_PRESSED_DEBOUNCE)
{ {
if(TimerStraightKeyPressed > bConfig.DebounceTime) if(TimerStraightKeyPressed > 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 /** \brief 8 Bit Timer 2
@ -326,12 +309,12 @@ ISR(TIMER0_COMPA_vect)
*/ */
ISR(TIMER2_OVF_vect) ISR(TIMER2_OVF_vect)
{ {
// phaccu = phaccu + tword_m; /* nothing */
// icnt = phaccu >> 24;
// OCR2A = pgm_read_byte_near(sinewave+icnt);
} }
/** @brief Interrupt RX serielle Schnittstelle
* @param none
* @return none
*/
ISR(USART_RX_vect) ISR(USART_RX_vect)
{ {
unsigned char data; unsigned char data;
@ -339,57 +322,6 @@ ISR(USART_RX_vect)
SendSerialChar(data); 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 ** DoMorse
*/ */
@ -408,12 +340,12 @@ void DoMorse(void)
if(DitBuffer) if(DitBuffer)
{ {
DitBuffer = 0; DitBuffer = 0;
SendDit(MANUAL_SENDING); SendDit(MAN);
} }
if(DahBuffer) if(DahBuffer)
{ {
DahBuffer = 0; DahBuffer = 0;
SendDah(MANUAL_SENDING); SendDah(MAN);
} }
} }
} }
@ -424,290 +356,37 @@ void DoMorse(void)
if(DitBuffer) if(DitBuffer)
{ {
DitBuffer = 0; DitBuffer = 0;
TXSidetoneKey(1,MANUAL_SENDING); TXKey(1,MAN);
} }
else else
{ {
TXSidetoneKey(0,MANUAL_SENDING); TXKey(0,MAN);
} }
DitCounter = 0; DitCounter = 0;
} }
} }
} }
void ConfigMenue(void) void ReStart(void)
{ {
char line[22]; ReadEEpromWpM();
WpM = bConfig.WpM;
lcd_charMode(NORMAL); EncoderPos = bConfig.WpM;
lcd_gotoxy(0,0); EncoderWrite(bConfig.WpM);
lcd_puts(CLEARLINE); EncoderPosConfig = 1;
lcd_gotoxy(0,0); SetFrequency(600);
sprintf(line,"%s - %i","Einstellungen", bMenuCtrl.CurMenue); MenuCtrlTimer = 0;
lcd_puts(line); t_delayms = 0;
lcd_charMode(DOUBLESIZE); SendStatus = SENDING_NOTHING;
lcd_gotoxy(0,3); WpM = 15;
lcd_puts(CLEARLINE); Weight = 50;
switch(bMenuCtrl.CurMenue) Init();
{ DisplayVersion();
case M_TRX1: KeyerMode = IAMBIC_A;
lcd_gotoxy(0,3); PaddleMode = PADDLE_NORMAL;
if((bConfig.TRX == 1) || (bConfig.TRX == 0)) KeyTX = 1;
sprintf(line,"[%s]", "TRX 1"); KeyState = 0;
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;
}
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) int main(void)
{ {
uint8_t c = 0;
Init(); ReStart();
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);
while(1) while(1)
{ {
Drehencoder(); Drehencoder();
// Wenn Geschwindigkeit verändert und Zeit abgelaufen, // Wenn Geschwindigkeit verändert und Zeit abgelaufen,
// dann im EEprom speichern und Merker löschen. // dann im EEprom speichern und Merker löschen.
if(bMerker.WriteWpMEEprom) if(bMerker.WriteWpMEEprom)
{ {
sprintf(" %i WpM in EEprom speichern\r\n", bConfig.WpM); sprintf(" %i WpM in EEprom speichern\r\n", bConfig.WpM);
WriteEEpromWpM(); WriteEEpromWpM();
bMerker.WriteWpMEEprom = 0; bMerker.WriteWpMEEprom = 0;
} }
UpdateDisplay(); UpdateDisplay();
CheckStraightKey();
if(MachineMode == NORMAL) CheckPaddles();
{ DoMorse();
CheckStraightKey();
CheckPaddles();
DoMorse();
}
if(MachineMode == COMMAND)
{
}
} }
} }

@ -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
Loading…
Cancel
Save