You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
403 lines
10 KiB
C
403 lines
10 KiB
C
1 year ago
|
#include "functions.h"
|
||
|
|
||
|
void delayms(uint16_t ms)
|
||
|
{
|
||
|
t_wait = 0;
|
||
|
while(t_wait < ms);
|
||
|
}
|
||
|
|
||
|
void IntEnable(void)
|
||
|
{
|
||
|
SREG = sreg_tmp;
|
||
|
sei();
|
||
|
}
|
||
|
|
||
|
void IntDisable(void)
|
||
|
{
|
||
|
sreg_tmp = SREG;
|
||
|
cli();
|
||
|
}
|
||
|
/** \brief MilliSeconds
|
||
|
*
|
||
|
* Get the milliseconds of TIMER 0
|
||
|
*
|
||
|
*/
|
||
|
uint32_t MilliSeconds(void)
|
||
|
{
|
||
|
uint32_t m;
|
||
|
ATOMIC_BLOCK(ATOMIC_FORCEON){
|
||
|
m = ms;
|
||
|
}
|
||
|
return m;
|
||
|
}
|
||
|
void ResetMilliSeconds(void)
|
||
|
{
|
||
|
ATOMIC_BLOCK(ATOMIC_FORCEON){
|
||
|
ms = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** \brief EEPROM schreiben
|
||
|
*/
|
||
|
void WriteEEProm(void)
|
||
|
{
|
||
|
cli();
|
||
|
eeprom_write_byte(&ee_dummy,0x55);
|
||
|
eeprom_write_byte(&ee_wpm, bConfig.wpm);
|
||
|
eeprom_write_byte(&ee_iambic, bConfig.iambic);
|
||
|
eeprom_write_word(&ee_sidetone_f, bConfig.sidetone_f);
|
||
|
eeprom_write_byte(&ee_trx, bConfig.trx);
|
||
|
sei();
|
||
|
}
|
||
|
|
||
|
void ReadEEProm(void)
|
||
|
{
|
||
|
// wpm = eeprom_read_byte(&ee_wpm);
|
||
|
}
|
||
|
|
||
|
void WriteEEProm_WpM(void)
|
||
|
{
|
||
|
cli();
|
||
|
eeprom_write_byte(&ee_wpm, bConfig.wpm);
|
||
|
sei();
|
||
|
}
|
||
|
|
||
|
void ReadEEProm_WpM(void)
|
||
|
{
|
||
|
cli();
|
||
|
bConfig.wpm = eeprom_read_byte(&ee_wpm);
|
||
|
sei();
|
||
|
if(bConfig.wpm > 50) {
|
||
|
bConfig.wpm = 15;
|
||
|
WriteEEProm_WpM();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** \brief Read port pin of morse keys
|
||
|
* This function reads the input of
|
||
|
* the Paddle or Straight key.
|
||
|
*
|
||
|
*/
|
||
|
uint8_t ReadKeyPin(uint8_t pin)
|
||
|
{
|
||
|
return(PIND & (1<<pin));
|
||
|
}
|
||
|
/*
|
||
|
** SideToneOn
|
||
|
*/
|
||
|
void SideToneOn(void)
|
||
|
{
|
||
|
sbi(TIMSK2,TOIE2);
|
||
|
PORTD |= (1<<MORSE_LED);
|
||
|
}
|
||
|
/*
|
||
|
** SideToneOff
|
||
|
*/
|
||
|
void SideToneOff(void)
|
||
|
{
|
||
|
cbi(TIMSK2,TOIE2);
|
||
|
PORTD &= ~(1<<MORSE_LED);
|
||
|
}
|
||
|
/*
|
||
|
** TXSidetoneKey
|
||
|
*/
|
||
|
void TXSidetoneKey(uint8_t State, uint8_t SendingType)
|
||
|
{
|
||
|
if((State) && (KeyState == 0))
|
||
|
{
|
||
|
if(KeyTX)
|
||
|
{
|
||
|
SideToneOn();
|
||
|
KeyState = 1;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if((State == 0) && (KeyState))
|
||
|
{
|
||
|
if(KeyTX)
|
||
|
{
|
||
|
SideToneOff();
|
||
|
}
|
||
|
KeyState = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** \brief CheckPaddles
|
||
|
* Original code K3NG keyer line 5654
|
||
|
*
|
||
|
*/
|
||
|
void CheckPaddles(void)
|
||
|
{
|
||
|
static uint8_t laststate = NOTHING;
|
||
|
|
||
|
CheckDitPaddle();
|
||
|
CheckDahPaddle();
|
||
|
|
||
|
if(KeyerMode == SINGLE_PADDLE)
|
||
|
{
|
||
|
switch(laststate)
|
||
|
{
|
||
|
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;
|
||
|
case NOTHING:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// service_tx_inhibit_and_pause{}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/** \brief ServiceStraightKey
|
||
|
* Original code K3NG keyer line 2762
|
||
|
*
|
||
|
* ***TODO
|
||
|
*/
|
||
|
long ServiceStraightKey(void)
|
||
|
{
|
||
|
long l;
|
||
|
static uint8_t last_straight_key_state = 0;
|
||
|
|
||
|
return l;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/** \brief Schleife für die Dauer der Zeichenelemente
|
||
|
**
|
||
|
** lengths = count of dits * weigthing / 50
|
||
|
** additional_time_ms = increase pausing between elements
|
||
|
** speed_wpm_in = speed in WpM
|
||
|
** sending_type =
|
||
|
*/
|
||
|
void Loop(uint8_t len, uint8_t AddMilliSeconds, uint8_t inWpM, uint8_t SendingType)
|
||
|
{
|
||
|
uint16_t LoE; // lengths of one element in ms
|
||
|
uint16_t ticks; // lengths of len elements + AddMilliSeconds in ms
|
||
|
|
||
|
if((len == 0) || (len < 0))
|
||
|
return;
|
||
|
|
||
|
LoE = 1200/inWpM;
|
||
|
ticks = LoE * len + AddMilliSeconds;
|
||
|
mselement = 0; // Reset Timer 0 variable
|
||
|
while(mselement < ticks) {
|
||
|
|
||
|
if((KeyerMode == IAMBIC_A) && (!(ReadKeyPin(LEFT_PADDLE))) && (!(ReadKeyPin(RIGHT_PADDLE))))
|
||
|
IambicFlag = 1;
|
||
|
|
||
|
if(SendStatus == SENDING_DIT)
|
||
|
CheckDahPaddle();
|
||
|
else if(SendStatus == SENDING_DAH)
|
||
|
CheckDitPaddle();
|
||
|
else {
|
||
|
CheckDahPaddle();
|
||
|
CheckDitPaddle();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if((KeyerMode == IAMBIC_A) && (IambicFlag) && ReadKeyPin(LEFT_PADDLE) && ReadKeyPin(RIGHT_PADDLE)){
|
||
|
IambicFlag = 0;
|
||
|
DitBuffer = 0;
|
||
|
DahBuffer = 0;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
** void SendDit(uint8_t SendingType)
|
||
|
*/
|
||
|
void SendDit(uint8_t SendingType)
|
||
|
{
|
||
|
SendStatus = SENDING_DIT;
|
||
|
TXSidetoneKey(1,SendingType);
|
||
|
Loop(1,0,wpm,SendingType);
|
||
|
TXSidetoneKey(0,SendingType);
|
||
|
Loop(1,0,wpm,SendingType);
|
||
|
}
|
||
|
/** \brief Send a dah
|
||
|
** A Dah with weight = 50 has the length of 3 Dits.
|
||
|
*/
|
||
|
void SendDah(uint8_t SendingType)
|
||
|
{
|
||
|
SendStatus = SENDING_DAH;
|
||
|
TXSidetoneKey(1,SendingType);
|
||
|
Loop(3,0,wpm,SendingType);
|
||
|
TXSidetoneKey(0,SendingType);
|
||
|
Loop(1,0,wpm,SendingType);
|
||
|
}
|
||
|
/*
|
||
|
** set sidetone frequency
|
||
|
*/
|
||
|
void SetFrequency(double f)
|
||
|
{
|
||
|
cbi(TIMSK2,TOIE2);
|
||
|
tword_m = pow(2,32)*f/refclk;
|
||
|
sbi(TIMSK2,TOIE2);
|
||
|
}
|
||
|
/*
|
||
|
** Output a tone width frequency f and duration duration
|
||
|
**
|
||
|
*/
|
||
|
void Tone(uint16_t f, uint8_t duration)
|
||
|
{
|
||
|
SideToneOff();
|
||
|
SetFrequency(f);
|
||
|
SideToneOn();
|
||
|
delayms(duration);
|
||
|
SetFrequency(sidetone_f);
|
||
|
SideToneOff();
|
||
|
}
|
||
|
void Boop(void)
|
||
|
{
|
||
|
Tone(600,100);
|
||
|
}
|
||
|
|
||
|
void Beep(void)
|
||
|
{
|
||
|
Tone(1200,100);
|
||
|
}
|
||
|
|
||
|
void BeepBoop(void)
|
||
|
{
|
||
|
Beep();
|
||
|
delayms(100);
|
||
|
Boop();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
**
|
||
|
** Output the current mode of keyer as CW
|
||
|
**
|
||
|
*/
|
||
|
void TellMode(void)
|
||
|
{
|
||
|
char text[9];
|
||
|
int len = 0;
|
||
|
int i = 0;
|
||
|
switch(KeyerMode)
|
||
|
{
|
||
|
case STRAIGHT: sprintf(text,"STRAIGHT");
|
||
|
break;
|
||
|
case IAMBIC_B: sprintf(text,"IAMBIC B");
|
||
|
break;
|
||
|
case IAMBIC_A: sprintf(text,"IAMBIC A");
|
||
|
break;
|
||
|
}
|
||
|
len = strlen(text);
|
||
|
for(i = 0; i < len; i++)
|
||
|
{
|
||
|
SendChar(text[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SendChar(unsigned char c)
|
||
|
{
|
||
|
switch(c)
|
||
|
{
|
||
|
case 'A': SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'B': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'C': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'D': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'E': SendDit(AUTOMATIC); break;
|
||
|
case 'F': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'G': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'H': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'I': SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'J': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'K': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'L': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'M': SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'N': SendDah(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'O': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'P': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'Q': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'R': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'S': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case 'T': SendDah(AUTOMATIC); break;
|
||
|
case 'U': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'V': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'W': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'X': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'Y': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case 'Z': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
|
||
|
case '0': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '1': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '2': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '3': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '4': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '5': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case '6': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case '7': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case '8': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case '9': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
|
||
|
case '=': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '/': SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
case '.': SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case ',': SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); break;
|
||
|
case '?': SendDit(AUTOMATIC); SendDit(AUTOMATIC); SendDah(AUTOMATIC); SendDah(AUTOMATIC); SendDit(AUTOMATIC); SendDit(AUTOMATIC); break;
|
||
|
|
||
|
// ***TODO Umlaute
|
||
|
// ***TODO Sonderzeichen
|
||
|
|
||
|
}
|
||
|
Loop(3,0,wpm,AUTOMATIC);
|
||
|
}
|
||
|
|
||
|
|
||
|
|