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.

264 lines
8.5 KiB
C

#ifndef BJ-KEYER_H_INCLUDED
#define BJ-KEYER_H_INCLUDED
#define F_CPU 16000000UL
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <util/atomic.h>
#include "oled/i2c.h"
#include "oled/lcd.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 Trx[] = "Beide TRX";
const char IambicA[] = "Iambic A";
const char IambicB[] = "Iambic B";
const char Ratio[] = "Ratio";
const char Reverse[] = "R";
const char SideToneOnOff[] = "Mithörton";
const char SideToneFreq[] = "Frequenz";
const char Yes[] = "J";
const char No[] = "N";
const char Hz[] = "Hz";
#ifndef EEMEM
#define EEMEM __attribute__ ((section (".eeprom")))
#endif
#ifndef NOINIT
#define NOINIT __attribute__ ((section (".noinit")))
#endif
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // clear bit
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // set bit
// The length of one dit at 1wpm is 1.2s. The timer resolution
// of Timer 1 is set to 64µs, so there are 18750 ticks needed.
#define TICKS_PER_WPM 18750
#define L_WAIT 500 // Frequency for debug LED Timer 0
#define NOTHING 0
#define DIT_DAH_OFF 1
#define DAH_DIT_OFF 2
#define DIT_DAH_ON 3
#define DAH_DIT_ON 4
// Keyer mode
#define STRAIGHT 0
#define IAMBIC_B 1
#define IAMBIC_A 2
#define SINGLE_PADDLE 3
// Paddle Mode
#define PADDLE_NORMAL 0
#define PADDLE_REVERSE 1
// Machine Mode
#define NORMAL 0
#define COMMAND 1
// Sending Mode
#define SENDING_NOTHING 0
#define SENDING_DIT 1
#define SENDING_DAH 2
#define SENDING_ELEMENT_SPACE 3
//
#define AUTOMATIC_SENDING 0
#define AUTOMATIC 0
#define MANUAL 1
#define MANUAL_SENDING 1
// 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
#define STRAIGHT_KEY PD4 // Straight key Input
#define MORSE_LED PC3 // LED Morse Output
#define MEM1 PD5 // Mem 1 Input
#define MEM2 PD6 // Mem 2 Input
#define MEM3 PD7 // Mem 3 Input
#define MEM4 PC0 // Mem 4 Input
#define MEM5 PB5 // Mem 5 Input
#define TRX1 PC1 // TRX1 Output
#define TRX2 PC2 // TRX2 Output
#define AUDIO PB3 // PWM Audio Output
#define AUDIO_EN PB4 // Audio PA Enable
#define SCL PC5 // I²C LC Display
#define SDA PC4 // I²C LC Display
// States
#define ON 1
#define OFF 0
// Menue und Drehencoder
#define M_TRX1 1
#define M_TRX2 2
#define M_IAMBICA 3
#define M_IAMBICB 4
#define M_REVERSE 5
#define M_RATIO 6
#define M_TON_FREQ 7
#define M_TON 8
#define M_WPMBPM 9
#define M_MAX 9 // maximale Menuepunke
// LCD
#define CLEARLINE " "
// Sine wave table for PWM, 256 values
const int sinewave_length=256;
const unsigned char sinewave[] PROGMEM = {
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0X80,0X7C,0X79,0X76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};
// Sidetone generation
double sidetone_f = 650;
const double refclk = 31376.6;
volatile unsigned long tword_m;
volatile unsigned long phaccu;
volatile uint8_t c4ms;
volatile uint8_t icnt;
volatile uint8_t icnt1;
volatile uint16_t idx;
// 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 = 15; // 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 WriteWpMEEProm: 1;
} bMerker;
struct MenuCtrl
{
uint8_t buttonPressed: 1;
uint8_t buttonPressedLong: 1;
uint8_t m_buttonPressed: 1;
uint8_t m_buttonPressedLong: 1;
uint8_t ClrScr: 1;
uint8_t Config: 1;
uint8_t WriteEEProm: 1;
uint8_t Update: 1;
uint8_t CurMenue;
} bMenuCtrl;
// State Machines
uint8_t MachineMode = NORMAL;
uint8_t PaddleMode = PADDLE_NORMAL;
uint8_t KeyerMode = IAMBIC_A;
uint8_t SidetoneMode = NORMAL;
volatile uint8_t Mode = NORMAL;
volatile uint8_t SendStatus = SENDING_NOTHING;
volatile uint8_t LastSendStatus = MANUAL_SENDING;
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 SpeedWpM = 1;
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 encoder_timer = 0; // 10ms Timer for Encoder
volatile int8_t encoder_counter = 0; // Vor/Rück Zähler
// EEPROM
uint8_t dummy = 0x55;
uint8_t ee_dummy EEMEM = 0x55; // Dummy for Address 0
uint8_t ee_wpm EEMEM = 15; // WpM
uint8_t ee_sidetone EEMEM = 0; // Mithörton An (1) oder Aus (0)
uint16_t ee_sidetone_f EEMEM = 650; // Frequenz des Mithörtons
uint8_t ee_iambic 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
{
uint8_t trx;
uint8_t iambic;
uint8_t ratio;
uint16_t sidetone_f;
uint8_t sidetone;
uint8_t wpmbpm;
uint8_t wpm;
uint8_t reverse;
uint8_t weight;
} bConfig;
// Function prototypes
void Init(void);
void InitTimer(void);
void CheckDahPaddle(void);
void CheckDitPaddle(void);
void CheckPaddle(void);
void SendDit(uint8_t SendingType);
void SendDah(uint8_t SendingType);
void PTTKey(uint8_t State);
void SideToneOff(void);
void SideToneOn(void);
void TXSidetoneKey(uint8_t State, uint8_t SendingType);
void TellMode(void);
void SendChar(uint8_t);
void ChangeSpeed(void);
void dah(void);
void dit(void);
void DoMorse(void);
void SetFrequency(double f);
#endif // BJ-KEYER_H_INCLUDED