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.
635 lines
16 KiB
C
635 lines
16 KiB
C
1 year ago
|
/** \brief BJ-Keyer
|
||
|
|
||
|
Morsekeyer von DL7BJ
|
||
|
tom@dl7bj.de
|
||
|
|
||
|
OLED functions from https://github.com/Sylaina/oled-display
|
||
|
|
||
|
@verbatim
|
||
|
History
|
||
|
--------------------------------------------------------------------------
|
||
|
2012-05-24 DL7BJ erste Version
|
||
|
2013-05-10 DL7BJ Generierung des Mithörtons als Sinus mit PWM/DDS
|
||
|
2013-07-15 DL7BJ Änderungen der Keyerfunktionen
|
||
|
2013-07-19 DL7BJ Beep/Boop (Spielkram)
|
||
|
2013-10-20 DL7BJ Änderungen der PWM Funktionen für besseren Sinus
|
||
|
2022-04-10 DL7BJ erste Leiterplatten für Prototyp (bisher Lochraster)
|
||
|
2022-09-02 DL7BJ viele Softwareänderungen, neuer Filter für PWM
|
||
|
2022-09-11 DL7BJ Encoder, LC-Display, Frontplatine "entsorgt"
|
||
|
2023-06-28 DL7BJ Port Anpassungen an neue Leiterplatte V1.01
|
||
|
|
||
|
ATMEGA328(P)
|
||
|
----------
|
||
|
(PCINT14/_RESET) PC6 -| 1 28|- PC5 (ADC5/SCL/PCINT13)
|
||
|
(PCINT16/RXD) PD0 -| 2 27|- PC4 (ADC4/SDA/PCINT12)
|
||
|
(PCINT17/TXT) PD1 -| 3 26|- PC3 (ADC3/PCINT11)
|
||
|
(PCINT18/INT0) PD2 -| 4 25|- PC2 (ADC2/PCINT10)
|
||
|
(PCINT19/OC2B/INT1) PD3 -| 5 24|- PC1 (ADC1/PCINT9)
|
||
|
(PCINT20/XCK/T0) PD4 -| 6 23|- PC0 (ADC0/PCINT8)
|
||
|
VCC -| 7 22|- GND
|
||
|
GND -| 8 21|- AREF
|
||
|
(PCINT6/XTAL1/TOSC1) PB6 -| 9 20|- AVCC
|
||
|
(PCINT7/XTAL2/TOSC2) PB7 -|10 19|- PB5 (SCK/PCINT5)
|
||
|
(PCINT21/OC0B/T1) PD5 -|11 18|- PB4 (MISO/PCINT4)
|
||
|
(PCINT22/OC0A/AIN0) PD6 -|12 17|- PB3 (MOSI/OC2A/PCINT3)
|
||
|
(PCINT23/AIN1) PD7 -|13 16|- PB2 (SS/OC1B/PCINT2)
|
||
|
(PCINT0/CLK0/ICP1) PB0 -|14 15|- PB1 (OC1A/PCINT1)
|
||
|
----------
|
||
|
|
||
|
Pin 1 - PC6 - Reset Pin 28 - PC5 - SCL Display
|
||
|
Pin 2 - PD0 - RxD Pin 27 - PC4 - SDA Display
|
||
|
Pin 3 - PD1 - TxD Pin 26 - PC3 - LED Key
|
||
|
Pin 4 - PD2 - Left Paddle Pin 25 - PC2 - TRX 2 Out
|
||
|
Pin 5 - PD3 - Right Paddle Pin 24 - PC1 - TRX 1 Out
|
||
|
Pin 6 - PD4 - Straight Key Pin 23 - PC0 - Mem 4
|
||
|
Pin 19 - PB5 - Mem 5
|
||
|
Pin 11 - PD5 - Mem 1 Pin 18 - PB4 - _Audio SD
|
||
|
Pin 12 - PD6 - Mem 2 Pin 17 - OC2A - Audio PWM output
|
||
|
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
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "bj-keyer.h"
|
||
|
// Additional files
|
||
|
#include "functions.c"
|
||
|
|
||
|
/**
|
||
|
* \brief Initialsieren der Timer
|
||
|
*
|
||
|
* Alle Parameter der Timer basieren auf 16MHz Systemtakt.
|
||
|
*
|
||
|
* 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 für CW Elemente und Pausen
|
||
|
* Timer 1B - 16 Bit timer nicht benutzt
|
||
|
*
|
||
|
* 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 with 1ms interrupt
|
||
|
* Timer 1A with 64µs interrupt
|
||
|
* Timer 2B with 20ms interrupt
|
||
|
* Timer 2 is used to generate a sine wave with PWM.
|
||
|
*
|
||
|
*/
|
||
|
void InitTimer(void)
|
||
|
{
|
||
|
cli();
|
||
|
// Timer 2
|
||
|
// prescaler to 1 => foc2apwm = fclk_I/O / 256 = 15.625Hz (p.149)
|
||
|
// PWM mode to phase correct PWM, 16.000.000MHz / 510 = 31372.55Hz
|
||
|
// (p.150)
|
||
|
sbi(TCCR2B,CS20);
|
||
|
cbi(TCCR2B,CS21);
|
||
|
cbi(TCCR2B,CS22);
|
||
|
// Clear OC2A on compare match
|
||
|
cbi(TCCR2A,COM2A0);
|
||
|
sbi(TCCR2A,COM2A1);
|
||
|
// Phase correct PWM Mode 1
|
||
|
sbi(TCCR2A,WGM20);
|
||
|
cbi(TCCR2A,WGM21);
|
||
|
cbi(TCCR2A,WGM22);
|
||
|
|
||
|
// Timer 1
|
||
|
// 16MHz / (65535 * 1024) = 238.42Hz
|
||
|
// T = 1 / 238.42Hz = 4.19ms
|
||
|
// Timertick = 64µs
|
||
|
TCCR1A = 0; TCCR1B = 0; TCCR1C = 0; TCNT1 = 0;
|
||
|
sbi(TCCR1B,CS12);
|
||
|
cbi(TCCR1B,CS11);
|
||
|
sbi(TCCR1B,CS10); // prescaler 1024 (p.135)
|
||
|
sbi(TIMSK1,TOIE1); // Enable Overflow Interrupt
|
||
|
|
||
|
// Timer 0
|
||
|
// 16MHz / 64 = 250kHz
|
||
|
// Timertick T = 1 / 250kHz = 4µs
|
||
|
// CTC 250 x 4µs = 1ms
|
||
|
TCCR0A = 0; TCCR0B = 0; TCNT0 = 0;
|
||
|
cbi(TCCR0A,WGM00);
|
||
|
sbi(TCCR0A,WGM01);
|
||
|
cbi(TCCR0B,WGM02); // CTC Mode 2 Immediate
|
||
|
cbi(TCCR0B,CS02);
|
||
|
sbi(TCCR0B,CS01);
|
||
|
sbi(TCCR0B,CS00); // prescaler 64
|
||
|
OCR0A = 249; // CTC 1ms
|
||
|
sbi(TIMSK0,OCIE0A); // Enable Timer 0 CTC
|
||
|
sei();
|
||
|
}
|
||
|
|
||
|
void Init()
|
||
|
{
|
||
|
|
||
|
cli(); // disable all interrupts
|
||
|
|
||
|
MachineMode = NORMAL;
|
||
|
SendStatus = SENDING_NOTHING;
|
||
|
|
||
|
// PORTB
|
||
|
PORTB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | 1<<(PB4) | (1<<PB5); // Pullup enabled
|
||
|
DDRB = (1<<PB3); // PB1, PB3 Output
|
||
|
|
||
|
// PORTD
|
||
|
DDRD = 0x00;
|
||
|
DDRD = (1<<PD0) | (1<<PD1) | (1<<PD6) | (1<<PD7); // PD7 Output LED Morsecode, PD6 Output LED_RES
|
||
|
PORTD |= (1<<PD6) | (1<<PD7); // Alle LED aus
|
||
|
|
||
|
// PD4,PD5 paddle input
|
||
|
// switch of internal pullups
|
||
|
cbi(PORTD,PD4);
|
||
|
cbi(PORTD,PD5);
|
||
|
t_element_length = (uint16_t)1200/bConfig.wpm;
|
||
|
InitTimer();
|
||
|
|
||
|
EncoderInit();
|
||
|
|
||
|
// Initialisierung Menüvariablen
|
||
|
bMenuCtrl.ClrScr = 1;
|
||
|
bMenuCtrl.Update = 1;
|
||
|
bMenuCtrl.Config = 0;
|
||
|
bMenuCtrl.buttonPressed = 0;
|
||
|
bMenuCtrl.WriteEEProm = 0;
|
||
|
bMenuCtrl.buttonPressedLong = 0;
|
||
|
// Initialisierung Konfiguration
|
||
|
bConfig.iambic = 1;
|
||
|
bConfig.sidetone_f = 650;
|
||
|
bConfig.sidetone = 1;
|
||
|
bConfig.trx = 0;
|
||
|
bConfig.weight = 50;
|
||
|
bConfig.wpmbpm = 1;
|
||
|
bConfig.wpm = 15;
|
||
|
bConfig.ratio = 30;
|
||
|
bConfig.reverse = 0;
|
||
|
sei(); // enable all interrupts
|
||
|
}
|
||
|
/** \brief 16 Bit Timer 1A
|
||
|
*
|
||
|
* Timer 1A interrupt
|
||
|
* Overflow interrupt every 64µs
|
||
|
*
|
||
|
*/
|
||
|
ISR(TIMER1_OVF_vect)
|
||
|
{
|
||
|
//sCurrentTimer += 0xffff;
|
||
|
PORTD ^= (1<<PD1);
|
||
|
}
|
||
|
/** \brief 8 Bit Timer 0
|
||
|
*
|
||
|
* The Timer 0 CTC interrupt
|
||
|
* Dieser Interrupt wird alle 1ms erzeugt
|
||
|
*
|
||
|
*/
|
||
|
ISR(TIMER0_COMPA_vect)
|
||
|
{
|
||
|
ms++;
|
||
|
StoreEEprom++;
|
||
|
MenuCtrlTimer++;
|
||
|
|
||
|
mselement++; // element length of dit or dat
|
||
|
|
||
|
t_wait++;
|
||
|
l_timer++;
|
||
|
encoder_timer++;
|
||
|
|
||
|
if(l_timer >= L_WAIT){
|
||
|
PORTD ^= (PD7);
|
||
|
l_timer = 0;
|
||
|
}
|
||
|
// Alle 5ms den Drehencoder abfragen
|
||
|
if(encoder_timer > 5) {
|
||
|
EncoderPolling();
|
||
|
// Schalter vom Drehencoder abfragen
|
||
|
if(EncoderGetButtonState() == ButtonPressed_Short)
|
||
|
bMenuCtrl.buttonPressed = 1;
|
||
|
if(EncoderGetButtonState() == ButtonPressed_Long)
|
||
|
bMenuCtrl.buttonPressedLong = 1;
|
||
|
}
|
||
|
// Wpm verändert?
|
||
|
if((StoreEEprom > 1000) && (bMerker.WpMChanged))
|
||
|
{
|
||
|
StoreEEprom = 0;
|
||
|
bMerker.WriteWpMEEProm = 1;
|
||
|
bMerker.WpMChanged = 0;
|
||
|
}
|
||
|
if((MenuCtrlTimer > 3000) && (bMenuCtrl.Config == 1))
|
||
|
{
|
||
|
bMenuCtrl.Config = 0;
|
||
|
bMenuCtrl.Update = 1;
|
||
|
bMenuCtrl.ClrScr = 1;
|
||
|
BeepBoop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** \brief 8 Bit Timer 2
|
||
|
*
|
||
|
* 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)
|
||
|
{
|
||
|
phaccu = phaccu + tword_m;
|
||
|
icnt = phaccu >> 24;
|
||
|
OCR2A = pgm_read_byte_near(sinewave+icnt);
|
||
|
}
|
||
|
/** \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
|
||
|
*/
|
||
|
void DoMorse(void)
|
||
|
{
|
||
|
if((KeyerMode == IAMBIC_A) || (KeyerMode == IAMBIC_B) || KeyerMode == SINGLE_PADDLE)
|
||
|
{
|
||
|
if((KeyerMode == IAMBIC_A) && (IambicFlag) && (ReadKeyPin(LEFT_PADDLE)))
|
||
|
{
|
||
|
IambicFlag = 0;
|
||
|
DitBuffer = 0;
|
||
|
DahBuffer = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(DitBuffer)
|
||
|
{
|
||
|
DitBuffer = 0;
|
||
|
SendDit(MANUAL_SENDING);
|
||
|
}
|
||
|
if(DahBuffer)
|
||
|
{
|
||
|
DahBuffer = 0;
|
||
|
SendDah(MANUAL_SENDING);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(KeyerMode == STRAIGHT)
|
||
|
{
|
||
|
if(DitBuffer)
|
||
|
{
|
||
|
DitBuffer = 0;
|
||
|
TXSidetoneKey(1,MANUAL_SENDING);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TXSidetoneKey(0,MANUAL_SENDING);
|
||
|
}
|
||
|
DitCounter = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConfigMenue(void)
|
||
|
{
|
||
|
char line[22];
|
||
|
|
||
|
lcd_charMode(NORMAL);
|
||
|
lcd_gotoxy(0,0);
|
||
|
sprintf(line,"%s - %i","Konfiguration", 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.iambic == 1)
|
||
|
sprintf(line,"[%s]", "Iambic A");
|
||
|
else
|
||
|
sprintf(line,"%s", "Iambic A");
|
||
|
lcd_puts(line);
|
||
|
break;
|
||
|
case M_IAMBICB:
|
||
|
lcd_gotoxy(0,3);
|
||
|
if(bConfig.iambic == 2)
|
||
|
sprintf(line,"[%s]", "Iambic B");
|
||
|
else
|
||
|
sprintf(line,"%s", "Iambic B");
|
||
|
lcd_puts(line);
|
||
|
break;
|
||
|
case M_REVERSE:
|
||
|
lcd_gotoxy(0,3);
|
||
|
if(bConfig.reverse == 0)
|
||
|
sprintf(line,"%s", "L . R -");
|
||
|
else
|
||
|
sprintf(line,"%s", "L - R .");
|
||
|
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 %f:1", "Ratio", bConfig.ratio/10);
|
||
|
lcd_puts(line);
|
||
|
break;
|
||
|
case M_TON_FREQ:
|
||
|
lcd_gotoxy(0,3);
|
||
|
if(bConfig.sidetone_f == 650)
|
||
|
sprintf(line,"%s", "Ton 650Hz");
|
||
|
else
|
||
|
sprintf(line,"%s %uHz", "Ton", bConfig.sidetone_f);
|
||
|
lcd_puts(line);
|
||
|
break;
|
||
|
case M_TON:
|
||
|
lcd_gotoxy(0,3);
|
||
|
if(bConfig.ratio == 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;
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
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.iambic == 1)
|
||
|
sprintf(line,"%s", IambicA);
|
||
|
if(bConfig.iambic == 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;
|
||
|
bMerker.WpMChanged = 1;
|
||
|
bMenuCtrl.Update = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if((bMenuCtrl.buttonPressed == 1) && (bMenuCtrl.Config == 0))
|
||
|
{
|
||
|
bMenuCtrl.Config = 1;
|
||
|
MenuCtrlTimer = 0;
|
||
|
bMenuCtrl.buttonPressed = 0;
|
||
|
}
|
||
|
|
||
|
if((bMenuCtrl.buttonPressedLong == 1) && (bMenuCtrl.Config == 1))
|
||
|
{
|
||
|
bMenuCtrl.Config = 0;
|
||
|
bMenuCtrl.Update = 1;
|
||
|
bMenuCtrl.buttonPressedLong = 0;
|
||
|
bMenuCtrl.buttonPressed = 0;
|
||
|
bMenuCtrl.m_buttonPressed = 0;
|
||
|
bMenuCtrl.m_buttonPressed = 0;
|
||
|
MenuCtrlTimer = 0;
|
||
|
}
|
||
|
|
||
|
if(bMenuCtrl.Config == 1)
|
||
|
{
|
||
|
if(!bMenuCtrl.buttonPressed)
|
||
|
{
|
||
|
EncoderMinMax(1,M_MAX);
|
||
|
st = EncoderRead(1);
|
||
|
if(last != st)
|
||
|
{
|
||
|
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.iambic = 1;
|
||
|
bMenuCtrl.m_buttonPressed = 0;
|
||
|
break;
|
||
|
case M_IAMBICB:
|
||
|
bConfig.iambic = 2;
|
||
|
bMenuCtrl.m_buttonPressed = 0;
|
||
|
break;
|
||
|
case M_REVERSE:
|
||
|
if(bConfig.reverse == 1)
|
||
|
bConfig.reverse = 0;
|
||
|
else
|
||
|
bConfig.reverse = 1;
|
||
|
bMenuCtrl.m_buttonPressed = 0;
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** main
|
||
|
*/
|
||
|
int main(void)
|
||
|
{
|
||
|
Init();
|
||
|
SetFrequency(650);
|
||
|
SideToneOff();
|
||
|
|
||
|
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);
|
||
|
delayms(1000);
|
||
|
|
||
|
BeepBoop();
|
||
|
MachineMode = NORMAL;
|
||
|
KeyerMode = IAMBIC_A;
|
||
|
ReadEEProm_WpM();
|
||
|
|
||
|
EncoderWrite(bConfig.wpm);
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
Drehencoder();
|
||
|
|
||
|
if(bMerker.WriteWpMEEProm)
|
||
|
WriteEEProm_WpM();
|
||
|
|
||
|
UpdateDisplay();
|
||
|
|
||
|
if(MachineMode == NORMAL)
|
||
|
{
|
||
|
CheckPaddles();
|
||
|
DoMorse();
|
||
|
}
|
||
|
|
||
|
if(MachineMode == COMMAND)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|