|
|
|
#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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SendSerialChar(unsigned char data)
|
|
|
|
{
|
|
|
|
while(!(UCSR0A & (1<<UDRE0)));
|
|
|
|
UDR0 = data;
|
|
|
|
}
|
|
|
|
void SendSerialString(char *s)
|
|
|
|
{
|
|
|
|
while(*s != 0x00)
|
|
|
|
SendSerialChar(*s++);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \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)
|
|
|
|
{
|
|
|
|
state_sidetoneoff = 0;
|
|
|
|
sbi(TIMSK1,OCIE1A);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
** SideToneOff
|
|
|
|
*/
|
|
|
|
void SideToneOff(void)
|
|
|
|
{
|
|
|
|
state_sidetoneoff = 1;
|
|
|
|
cbi(TIMSK1,OCIE1A);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
** 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 StraigtKey
|
|
|
|
*
|
|
|
|
* Check Straightkey
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void CheckStraightKey(void)
|
|
|
|
{
|
|
|
|
if(PIND & (1<<STRAIGHT_KEY))
|
|
|
|
TXSidetoneKey(0,MANUAL_SENDING);
|
|
|
|
else
|
|
|
|
TXSidetoneKey(1,MANUAL_SENDING);
|
|
|
|
}
|
|
|
|
/** \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(uint16_t f)
|
|
|
|
{
|
|
|
|
IntDisable();
|
|
|
|
OCR1A = (F_CPUPRESIN / f) - 1;
|
|
|
|
IntEnable();
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
** Output a tone width frequency f and duration duration
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void Tone(uint16_t f, uint8_t duration)
|
|
|
|
{
|
|
|
|
SetFrequency(f);
|
|
|
|
SideToneOn();
|
|
|
|
delayms(duration);
|
|
|
|
SideToneOff();
|
|
|
|
}
|
|
|
|
void Boop(void)
|
|
|
|
{
|
|
|
|
Tone(600,100);
|
|
|
|
}
|
|
|
|
void Beep(void)
|
|
|
|
{
|
|
|
|
Tone(1200,100);
|
|
|
|
}
|
|
|
|
void BeepBoop(void)
|
|
|
|
{
|
|
|
|
sbi(PORTB,AUDIO_EN);
|
|
|
|
delayms(10);
|
|
|
|
Beep();
|
|
|
|
delayms(100);
|
|
|
|
Boop();
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|