Compare commits

..

25 Commits

Author SHA1 Message Date
phdlee
b153a305d6 Merge branch 'master' into version0.29 2018-01-25 22:25:35 +09:00
phdlee
e61e45d3dd Update README.md 2018-01-22 18:26:22 +09:00
phdlee
a1f941f965 Update README.md 2018-01-22 18:25:41 +09:00
phdlee
d1e72b3bd5 Update README.md 2018-01-22 18:24:29 +09:00
phdlee
032e7f919f Update README.md 2018-01-22 18:21:55 +09:00
phdlee
b6bc264332 Update README.md 2018-01-22 18:11:15 +09:00
phdlee
b1cc5eb98a Update README.md 2018-01-22 02:11:35 +09:00
phdlee
2fe1662d67 Merge pull request #8 from qiwenmin/master
Fixed most compilation warnings and a delay issue
2018-01-20 21:24:15 +09:00
phdlee
ebbc5aae5e Merge pull request #9 from phdlee/version0.28
change delaytimes via cat
2018-01-18 11:47:21 +09:00
Qi Wenmin
209cd3a49c Fixed most compilation warnings and a delay issue
* Fixed most compilation warnings (Compiler warning level: All)
* Fixed a delay issue in enc_read function.
2018-01-17 14:42:15 +08:00
phdlee
95e5c1dfe5 Update README.md 2018-01-14 14:53:28 +09:00
phdlee
45a8479061 Update README.md 2018-01-14 14:52:58 +09:00
phdlee
a6ad381c24 Update README.md 2018-01-14 14:52:22 +09:00
phdlee
bcf80f851d Update README.md 2018-01-14 14:51:46 +09:00
phdlee
16304efacd Update README.md 2018-01-14 14:51:23 +09:00
phdlee
968024ab73 Merge pull request #7 from phdlee/beta0.26
Beta0.26
2018-01-14 14:19:53 +09:00
phdlee
3e60728727 Update README.md 2018-01-13 22:27:23 +09:00
phdlee
9781ef086b Update README.md 2018-01-13 10:58:47 +09:00
phdlee
f27f504ea4 Merge pull request #6 from phdlee/beta0.26
Beta0.26
2018-01-12 20:19:09 +09:00
phdlee
2b08a76fbf Update README.md 2018-01-12 10:16:59 +09:00
phdlee
90655e03b8 Update README.md
add status of project
2018-01-12 09:51:58 +09:00
phdlee
8551ff1b68 Update README.md 2018-01-11 17:40:00 +09:00
phdlee
5ce94e8e49 Merge pull request #5 from qiwenmin/master
Fix the delay condition bug when overflow
2018-01-10 13:51:59 +09:00
Qi Wenmin
7ef9c29fa8 Fix the delay condition bug when overflow
The original expression will cause bug when overflow.
2018-01-10 12:00:53 +08:00
phdlee
fda398046e Merge pull request #4 from phdlee/beta0.25
beta 0.25 commit
2018-01-10 11:39:15 +09:00
10 changed files with 455 additions and 1572 deletions

View File

@@ -1,7 +1,21 @@
#IMPORTANT INFORMATION
----------------------------------------------------------------------------
- Beta 0.26 and Beta 0.261, Beta 0.262, Beta 0.27 is complete test
- You can download and use it.
-Working on version 0.29 now. Download the source from the release section rather than the master branch version.
Master version is working now.
- Beta 0.26 and Beta 0.261, Beta 0.262,0.27 is complete test, 0.28 is tested.
- You can download and use it (Release section).
# Current work list (for Version 0.29)
1 Testing CAT Control with Software using hamlib on Linux
2 BFO setting based on current value - complete
3 Select Tune Step - Testing
4 Change Tune control type, Do not keep the original source - Complete
- Coded differently after clearing the original source
- Prevent malfunction by applying threshold
5 stabilize and remove many warning messages - by Pullrequest and merge
6 Study on improvement method for cw keying - need idea
- set ADC Range value
#NOTICE
----------------------------------------------------------------------------
@@ -46,6 +60,10 @@ Prepared or finished tasks for the next version
----------------------------------------------------------------------------
## REVISION RECORD
0.28
- Fixed CAT problem with hamlib on Linux
- restore Protocol autorecovery logic
0.27
(First alpha test version, This will be renamed to the major version 1.0)
- Dual VFO Dial Lock (vfoA Dial lock)

View File

@@ -1,5 +1,4 @@
/*************************************************************************
KD8CEC's CAT Library for uBITX and HAM
This source code is written for uBITX, but it can also be used on other radios.
The CAT protocol is used by many radios to provide remote control to comptuers through
@@ -109,8 +108,7 @@ void CatSetFreq(byte fromType)
//#define BCD_LEN 9
//PROTOCOL : 0x03
//Computer <-(frequency)-> TRCV CAT_BUFF
//void CatGetFreqMode(unsigned long freq, byte fromType)
void CatGetFreqMode(unsigned long freq) //for remove warning messages
void CatGetFreqMode(unsigned long freq, byte fromType)
{
int i;
byte tmpValue;
@@ -131,40 +129,23 @@ void CatGetFreqMode(unsigned long freq) //for remove warning messages
}
//Mode Check
if (cwMode == 0)
{
if (isUSB)
CAT_BUFF[4] = CAT_MODE_USB;
else
CAT_BUFF[4] = CAT_MODE_LSB;
}
else if (cwMode == 1)
{
CAT_BUFF[4] = CAT_MODE_CW;
}
if (isUSB)
CAT_BUFF[4] = CAT_MODE_USB;
else
{
CAT_BUFF[4] = CAT_MODE_CW;
}
CAT_BUFF[4] = CAT_MODE_LSB;
SendCatData(5);
}
//void CatSetSplit(boolean isSplit, byte fromType)
void CatSetSplit(boolean isSplit) //for remove warning messages
void CatSetSplit(boolean isSplit, byte fromType)
{
if (isSplit)
splitOn = 1;
else
splitOn = 0;
Serial.write(ACK);
}
void CatSetPTT(boolean isPTTOn, byte fromType)
{
//
if ((!inTx) && (fromType == 2 || fromType == 3)) {
if (fromType == 2 || fromType == 3) {
Serial.write(ACK);
return;
}
@@ -200,7 +181,7 @@ void CatSetPTT(boolean isPTTOn, byte fromType)
void CatVFOToggle(boolean isSendACK, byte fromType)
{
if (fromType != 2 && fromType != 3) {
menuVfoToggle(1);
menuVfoToggle(1, 0);
}
if (isSendACK)
@@ -216,18 +197,12 @@ void CatSetMode(byte tmpMode, byte fromType)
if (!inTx)
{
if (tmpMode == CAT_MODE_CW)
if (tmpMode == CAT_MODE_USB)
{
cwMode = 1;
}
else if (tmpMode == CAT_MODE_USB)
{
cwMode = 0;
isUSB = true;
}
else
{
cwMode = 0;
isUSB = false;
}
@@ -239,8 +214,7 @@ void CatSetMode(byte tmpMode, byte fromType)
}
//Read EEProm by uBITX Manager Software
//void ReadEEPRom(byte fromType)
void ReadEEPRom() //for remove warnings.
void ReadEEPRom(byte fromType)
{
//5BYTES
//CAT_BUFF[0] [1] [2] [3] [4] //4 COMMAND
@@ -263,8 +237,7 @@ void ReadEEPRom() //for remove warnings.
}
//Write just proecess 1byes
//void WriteEEPRom(byte fromType)
void WriteEEPRom(void) //for remove warning
void WriteEEPRom(byte fromType)
{
//5BYTES
uint16_t eepromStartIndex = CAT_BUFF[0] + CAT_BUFF[1] * 256;
@@ -284,8 +257,7 @@ void WriteEEPRom(void) //for remove warning
}
}
//void ReadEEPRom_FT817(byte fromType)
void ReadEEPRom_FT817(void) //for remove warnings
void ReadEEPRom_FT817(byte fromType)
{
byte temp0 = CAT_BUFF[0];
byte temp1 = CAT_BUFF[1];
@@ -385,21 +357,10 @@ void ReadEEPRom_FT817(void) //for remove warnings
CAT_BUFF[1] = 0xB2;
break; case 0x69 : //FM Mic (#29) Contains 0-100 (decimal) as displayed
case 0x78 :
if (cwMode == 0)
{
if (isUSB)
CAT_BUFF[0] = CAT_MODE_USB;
else
CAT_BUFF[0] = CAT_MODE_LSB;
}
else if (cwMode == 1)
{
CAT_BUFF[0] = CAT_MODE_CW;
}
else if (cwMode == 2)
{
CAT_BUFF[0] = CAT_MODE_CW;
}
if (isUSB)
CAT_BUFF[0] = CAT_MODE_USB;
else
CAT_BUFF[0] = CAT_MODE_LSB;
if (CAT_BUFF[0] != 0) CAT_BUFF[0] = 1 << 5;
break;
@@ -422,7 +383,7 @@ void ReadEEPRom_FT817(void) //for remove warnings
//7A 6 ? ?
//7A 7 SPL On/Off 0 = Off, 1 = On
CAT_BUFF[0] = (splitOn ? 0xFF : 0x7F);
CAT_BUFF[0] = (isSplitOn ? 0xFF : 0x7F);
break;
case 0xB3 : //
CAT_BUFF[0] = 0x00;
@@ -510,7 +471,7 @@ void WriteEEPRom_FT817(byte fromType)
printLineF2(F("Sidetone set! CAT"));
EEPROM.put(CW_SIDETONE, sideTone);
delay(300); //If timeout errors occur in the calling software, remove them
clearLine2();
printLine2(""); //Ham radio deluxe is the only one that supports this feature yet. and ham radio deluxe has wait time as greater than 500ms
}
break;
@@ -522,8 +483,7 @@ void WriteEEPRom_FT817(byte fromType)
printLineF2(F("Sidetone set! CAT"));
EEPROM.put(CW_SIDETONE, sideTone);
delay(300); //If timeout errors occur in the calling software, remove them
clearLine2();
line2DisplayStatus = 0;
printLine2(""); //Ham radio deluxe is the only one that supports this feature yet. and ham radio deluxe has wait time as greater than 500ms
}
break;
@@ -543,7 +503,7 @@ void WriteEEPRom_FT817(byte fromType)
printLineF2(F("CW Speed set!"));
EEPROM.put(CW_DELAY, cwDelayTime);
delay(300);
clearLine2();
printLine2("");
break;
case 0x62 : //
//5-0 CW Speed (4-60 WPM) (#21) From 0 to 38 (HEX) with 0 = 4 WPM and 38 = 60 WPM (1 WPM steps)
@@ -552,7 +512,7 @@ void WriteEEPRom_FT817(byte fromType)
printLineF2(F("CW Speed set!"));
EEPROM.put(CW_SPEED, cwSpeed);
delay(300);
clearLine2();
printLine2("");
break;
/*
@@ -611,8 +571,7 @@ void WriteEEPRom_FT817(byte fromType)
Serial.write(ACK);
}
//void CatRxStatus(byte fromType)
void CatRxStatus(void) //for remove warning
void CatRxStatus(byte fromType)
{
byte sMeterValue = 1;
@@ -632,8 +591,7 @@ void CatRxStatus(void) //for remove warning
}
//void CatTxStatus(byte fromType)
void CatTxStatus(void) //for remove warning
void CatTxStatus(byte fromType)
{
boolean isHighSWR = false;
boolean isSplitOn = false;
@@ -734,11 +692,11 @@ void Check_Cat(byte fromType)
case 0x02 : //Split On
case 0x82: //Split Off
CatSetSplit(CAT_BUFF[4] == 0x02);
CatSetSplit(CAT_BUFF[4] == 0x02, fromType);
break;
case 0x03 : //Read Frequency and mode
CatGetFreqMode(frequency);
CatGetFreqMode(frequency, fromType);
break;
case 0x07 : //Set Operating Mode
@@ -755,24 +713,24 @@ void Check_Cat(byte fromType)
break;
case 0xDB: //Read uBITX EEPROM Data
ReadEEPRom(); //Call by uBITX Manager Program
ReadEEPRom(fromType); //Call by uBITX Manager Program
break;
case 0xBB: //Read FT-817 EEPROM Data (for comfirtable)
ReadEEPRom_FT817();
ReadEEPRom_FT817(fromType);
break;
case 0xDC: //Write uBITX EEPROM Data
WriteEEPRom(); //Call by uBITX Manager Program
WriteEEPRom(fromType); //Call by uBITX Manager Program
break;
case 0xBC: //Write FT-817 EEPROM Data (for comfirtable)
WriteEEPRom_FT817(fromType);
break;
case 0xE7 : //Read RX Status
CatRxStatus();
CatRxStatus(fromType);
break;
case 0xF7: //Read TX Status
CatTxStatus();
CatTxStatus(fromType);
break;
default:
/*

View File

@@ -1,6 +1,4 @@
/*************************************************************************
KD8CEC's Memory Keyer for HAM
This source code is written for All amateur radio operator,
I have not had amateur radio communication for a long time. CW has been
around for a long time, and I do not know what kind of keyer and keying
@@ -15,7 +13,6 @@
I wrote this code myself, so there is no license restriction.
So this code allows anyone to write with confidence.
But keep it as long as the original author of the code.
DE Ian KD8CEC
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -298,12 +295,8 @@ void controlAutoCW(){
}
printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ);
byte diplayAutoCWLine = 0;
if ((displayOption1 & 0x01) == 0x01)
diplayAutoCWLine = 1;
lcd.setCursor(0, diplayAutoCWLine);
lcd.setCursor(0,0);
lcd.write(byteToChar(selectedCWTextIndex));
lcd.write(':');
isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0;
@@ -365,11 +358,6 @@ void controlAutoCW(){
//check interval time, if you want adjust interval between chars, modify below
if (isAutoCWHold == 0 && (millis() - autoCWbeforeTime > cwSpeed * 3))
{
if (!inTx){ //if not TX Status, change RX -> TX
keyDown = 0;
startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time
}
sendCWChar(EEPROM.read(CW_AUTO_DATA + autoCWSendCharIndex++));
if (autoCWSendCharIndex > autoCWSendCharEndIndex) { //finish auto cw send

View File

@@ -1,10 +1,4 @@
/**
Since KD8CEC Version 0.29, most of the original code is no longer available.
Most features(TX, Frequency Range, Ham Band, TX Control, CW delay, start Delay... more) have been added by KD8CEC.
However, the license rules are subject to the original source rules.
DE Ian KD8CEC
Original source comment -------------------------------------------------------------
* This source file is under General Public License version 3.
*
* This verision uses a built-in Si5351 library
@@ -84,7 +78,6 @@
#define PTT (A3)
#define ANALOG_KEYER (A6)
#define ANALOG_SPARE (A7)
#define ANALOG_SMETER (A7) //by KD8CEC
/**
* The Raduino board is the size of a standard 16x2 LCD panel. It has three connectors:
@@ -151,38 +144,15 @@ int count = 0; //to generally count ticks, loops, etc
#define CW_SPEED 28
//AT328 has 1KBytes EEPROM
#define CW_CAL 252
#define VFO_A_MODE 256
#define VFO_B_MODE 257
#define CW_DELAY 258
#define CW_START 259
#define HAM_BAND_COUNT 260 //
#define TX_TUNE_TYPE 261 //
#define HAM_BAND_RANGE 262 //FROM (2BYTE) TO (2BYTE) * 10 = 40byte
#define HAM_BAND_FREQS 302 //40, 1 BAND = 4Byte most bit is mode
#define TUNING_STEP 342 //TUNING STEP * 6 (index 1 + STEPS 5) //1STEP :
//for reduce cw key error, eeprom address
#define CW_ADC_MOST_BIT1 348 //most 2bits of DOT_TO , DOT_FROM, ST_TO, ST_FROM
#define CW_ADC_ST_FROM 349 //CW ADC Range STRAIGHT KEY from (Lower 8 bit)
#define CW_ADC_ST_TO 350 //CW ADC Range STRAIGHT KEY to (Lower 8 bit)
#define CW_ADC_DOT_FROM 351 //CW ADC Range DOT from (Lower 8 bit)
#define CW_ADC_DOT_TO 352 //CW ADC Range DOT to (Lower 8 bit)
#define CW_ADC_MOST_BIT2 353 //most 2bits of BOTH_TO, BOTH_FROM, DASH_TO, DASH_FROM
#define CW_ADC_DASH_FROM 354 //CW ADC Range DASH from (Lower 8 bit)
#define CW_ADC_DASH_TO 355 //CW ADC Range DASH to (Lower 8 bit)
#define CW_ADC_BOTH_FROM 356 //CW ADC Range BOTH from (Lower 8 bit)
#define CW_ADC_BOTH_TO 357 //CW ADC Range BOTH to (Lower 8 bit)
#define CW_KEY_TYPE 358
#define DISPLAY_OPTION1 361 //Display Option1
#define DISPLAY_OPTION2 362 //Display Option2
#define CHANNEL_FREQ 630 //Channel 1 ~ 20, 1 Channel = 4 bytes
#define CHANNEL_DESC 710 //Channel 1 ~ 20, 1 Channel = 4 bytes
#define RESERVE3 770 //Reserve3 between Channel and Firmware id check
#define HAM_BAND_COUNT 260 //
#define TX_TUNE_TYPE 261 //
#define HAM_BAND_RANGE 262 //FROM (2BYTE) TO (2BYTE) * 10 = 40byte
#define HAM_BAND_FREQS 302 //40, 1 BAND = 4Byte most bit is mode
#define TUNING_STEP 342 //TUNING STEP * 6 (index 1 + STEPS 5)
//Check Firmware type and version
#define FIRMWAR_ID_ADDR 776 //776 : 0x59, 777 :0x58, 778 : 0x68 : Id Number, if not found id, erase eeprom(32~1023) for prevent system error.
@@ -238,7 +208,7 @@ int count = 0; //to generally count ticks, loops, etc
char ritOn = 0;
char vfoActive = VFO_A;
int8_t meter_reading = 0; // a -1 on meter makes it invisible
unsigned long vfoA=7150000L, vfoB=14200000L, sideTone=800, usbCarrier, cwmCarrier;
unsigned long vfoA=7150000L, vfoB=14200000L, sideTone=800, usbCarrier;
unsigned long vfoA_eeprom, vfoB_eeprom; //for protect eeprom life
unsigned long frequency, ritRxFrequency, ritTxFrequency; //frequency is the current frequency on the dial
@@ -255,6 +225,7 @@ byte saveIntervalSec = 10; //second
unsigned long saveCheckTime = 0;
unsigned long saveCheckFreq = 0;
bool isSplitOn = false;
byte cwDelayTime = 60;
byte delayBeforeCWStartTime = 50;
@@ -265,26 +236,9 @@ byte sideToneSub = 0;
//DialLock
byte isDialLock = 0; //000000[0]vfoB [0]vfoA 0Bit : A, 1Bit : B
byte isTxType = 0; //000000[0 - isSplit] [0 - isTXStop]
long arTuneStep[5];
byte arTuneStep[5];
byte tuneStepIndex; //default Value 0, start Offset is 0 because of check new user
byte displayOption1 = 0;
byte displayOption2 = 0;
//CW ADC Range
int cwAdcSTFrom = 0;
int cwAdcSTTo = 0;
int cwAdcDotFrom = 0;
int cwAdcDotTo = 0;
int cwAdcDashFrom = 0;
int cwAdcDashTo = 0;
int cwAdcBothFrom = 0;
int cwAdcBothTo = 0;
byte cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
bool Iambic_Key = true;
#define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B
unsigned char keyerControl = IAMBICB;
//Variables for auto cw mode
byte isCWAutoMode = 0; //0 : none, 1 : CW_AutoMode_Menu_Selection, 2 : CW_AutoMode Sending
byte cwAutoTextCount = 0; //cwAutoText Count
@@ -303,13 +257,9 @@ byte userCallsignLength = 0; //7 : display callsign at system startup, 6~0 :
*/
boolean txCAT = false; //turned on if the transmitting due to a CAT command
char inTx = 0; //it is set to 1 if in transmit mode (whatever the reason : cw, ptt or cat)
char splitOn = 0; //working split, uses VFO B as the transmit frequency
char splitOn = 0; //working split, uses VFO B as the transmit frequency, (NOT IMPLEMENTED YET)
char keyDown = 0; //in cw mode, denotes the carrier is being transmitted
char isUSB = 0; //upper sideband was selected, this is reset to the default for the
char cwMode = 0; //compatible original source, and extend mode //if cwMode == 0, mode check : isUSB, cwMode > 0, mode Check : cwMode
//iscwMode = 0 : ssbmode, 1 :cwl, 2 : cwu, 3 : cwn (none tx)
//frequency when it crosses the frequency border of 10 MHz
byte menuOn = 0; //set to 1 when the menu is being displayed, if a menu item sets it to zero, the menu is exited
unsigned long cwTimeout = 0; //milliseconds to go before the cw transmit line is released and the radio goes back to rx mode
@@ -317,14 +267,6 @@ unsigned long dbgCount = 0; //not used now
unsigned char txFilter = 0; //which of the four transmit filters are in use
boolean modeCalibrate = false;//this mode of menus shows extended menus to calibrate the oscillators and choose the proper
//beat frequency
unsigned long beforeIdle_ProcessTime = 0; //for check Idle time
byte line2DisplayStatus = 0; //0:Clear, 1 : menu, 1: DisplayFrom Idle,
char lcdMeter[17];
byte isIFShift = 0; //1 = ifShift, 2 extend
long ifShiftValue = 0; //
/**
* Below are the basic functions that control the uBitx. Understanding the functions before
* you start hacking around
@@ -377,24 +319,22 @@ void setNextHamBandFreq(unsigned long f, char moveDirection)
EEPROM.get(HAM_BAND_FREQS + 4 * findedIndex, resultFreq);
//loadMode = (byte)(resultFreq >> 30);
//resultFreq = resultFreq & 0x3FFFFFFF;
loadMode = (byte)(resultFreq >> 29);
resultFreq = resultFreq & 0x1FFFFFFF;
loadMode = (byte)(resultFreq >> 30);
resultFreq = resultFreq & 0x3FFFFFFF;
if ((resultFreq / 1000) < hamBandRange[(unsigned char)findedIndex][0] || (resultFreq / 1000) > hamBandRange[(unsigned char)findedIndex][1])
resultFreq = (unsigned long)(hamBandRange[(unsigned char)findedIndex][0]) * 1000;
setFrequency(resultFreq);
byteToMode(loadMode, 1);
byteWithFreqToMode(loadMode);
}
void saveBandFreqByIndex(unsigned long f, unsigned long mode, char bandIndex) {
if (bandIndex >= 0)
//EEPROM.put(HAM_BAND_FREQS + 4 * bandIndex, (f & 0x3FFFFFFF) | (mode << 30) );
EEPROM.put(HAM_BAND_FREQS + 4 * bandIndex, (f & 0x1FFFFFFF) | (mode << 29) );
EEPROM.put(HAM_BAND_FREQS + 4 * bandIndex, (f & 0x3FFFFFFF) | (mode << 30) );
}
/*
KD8CEC
When using the basic delay of the Arduino, the program freezes.
@@ -488,27 +428,13 @@ void setFrequency(unsigned long f){
setTXFilters(f);
if (cwMode == 0)
{
if (isUSB){
si5351bx_setfreq(2, SECOND_OSC_USB - usbCarrier + f + (isIFShift ? ifShiftValue : 0));
si5351bx_setfreq(1, SECOND_OSC_USB);
}
else{
si5351bx_setfreq(2, SECOND_OSC_LSB + usbCarrier + f + (isIFShift ? ifShiftValue : 0));
si5351bx_setfreq(1, SECOND_OSC_LSB);
}
if (isUSB){
si5351bx_setfreq(2, SECOND_OSC_USB - usbCarrier + f);
si5351bx_setfreq(1, SECOND_OSC_USB);
}
else
{
if (cwMode == 1){ //CWL
si5351bx_setfreq(2, SECOND_OSC_LSB + cwmCarrier + f + (isIFShift ? ifShiftValue : 0));
si5351bx_setfreq(1, SECOND_OSC_LSB);
}
else{ //CWU
si5351bx_setfreq(2, SECOND_OSC_USB - cwmCarrier + f + (isIFShift ? ifShiftValue : 0));
si5351bx_setfreq(1, SECOND_OSC_USB);
}
else{
si5351bx_setfreq(2, SECOND_OSC_LSB + usbCarrier + f);
si5351bx_setfreq(1, SECOND_OSC_LSB);
}
frequency = f;
@@ -537,21 +463,6 @@ void startTx(byte txMode, byte isDisplayUpdate){
ritRxFrequency = frequency;
setFrequency(ritTxFrequency);
}
else if (splitOn == 1) {
if (vfoActive == VFO_B) {
vfoActive = VFO_A;
frequency = vfoA;
byteToMode(vfoA_mode, 0);
}
else if (vfoActive == VFO_A){
vfoActive = VFO_B;
frequency = vfoB;
byteToMode(vfoB_mode, 0);
}
setFrequency(frequency);
} //end of else
if (txMode == TX_CW){
//turn off the second local oscillator and the bfo
@@ -561,22 +472,10 @@ void startTx(byte txMode, byte isDisplayUpdate){
//shif the first oscillator to the tx frequency directly
//the key up and key down will toggle the carrier unbalancing
//the exact cw frequency is the tuned frequency + sidetone
if (cwMode == 0)
{
if (isUSB)
si5351bx_setfreq(2, frequency + sideTone);
else
si5351bx_setfreq(2, frequency - sideTone);
}
else if (cwMode == 1) //CWL
{
si5351bx_setfreq(2, frequency - sideTone);
}
else //CWU
{
si5351bx_setfreq(2, frequency + sideTone);
}
if (isUSB)
si5351bx_setfreq(2, frequency + sideTone);
else
si5351bx_setfreq(2, frequency - sideTone);
}
//reduce latency time when begin of CW mode
@@ -588,28 +487,10 @@ void stopTx(){
inTx = 0;
digitalWrite(TX_RX, 0); //turn off the tx
if (cwMode == 0)
si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off
else
si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off
si5351bx_setfreq(0, usbCarrier); //set back the carrier oscillator anyway, cw tx switches it off
if (ritOn)
setFrequency(ritRxFrequency);
else if (splitOn == 1) {
//vfo Change
if (vfoActive == VFO_B){
vfoActive = VFO_A;
frequency = vfoA;
byteToMode(vfoA_mode, 0);
}
else if (vfoActive == VFO_A){
vfoActive = VFO_B;
frequency = vfoB;
byteToMode(vfoB_mode, 0);
}
setFrequency(frequency);
} //end of else
else
setFrequency(frequency);
@@ -687,15 +568,11 @@ applied Threshold for reduct errors, dial Lock, dynamic Step
byte threshold = 2; //noe action for count
unsigned long lastEncInputtime = 0;
int encodedSumValue = 0;
unsigned long lastTunetime = 0; //if continous moving, skip threshold processing
byte lastMovedirection = 0; //0 : stop, 1 : cw, 2 : ccw
#define skipThresholdTime 100
#define encodeTimeOut 1000
void doTuningWithThresHold(){
void doTuning(){
int s = 0;
unsigned long prev_freq;
long incdecValue = 0;
if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) ||
(vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02)))
@@ -709,8 +586,6 @@ void doTuningWithThresHold(){
if (s == 0) {
if (encodedSumValue != 0 && (millis() - encodeTimeOut) > lastEncInputtime)
encodedSumValue = 0;
lastMovedirection = 0;
return;
}
lastEncInputtime = millis();
@@ -718,25 +593,23 @@ void doTuningWithThresHold(){
//for check moving direction
encodedSumValue += (s > 0 ? 1 : -1);
//check threshold and operator actions (hold dial speed = continous moving, skip threshold check)
if ((lastTunetime < millis() - skipThresholdTime) && ((encodedSumValue * encodedSumValue) <= (threshold * threshold)))
//check threshold
if ((encodedSumValue * encodedSumValue) <= (threshold * threshold))
return;
lastTunetime = millis();
//Valid Action without noise
encodedSumValue = 0;
prev_freq = frequency;
//incdecValue = tuningStep * s;
frequency += (arTuneStep[tuneStepIndex -1] * s * (s * s < 10 ? 1 : 3)); //appield weight (s is speed)
frequency += (arTuneStep[tuneStepIndex -1] * s);
if (prev_freq < 10000000l && frequency > 10000000l)
isUSB = true;
if (prev_freq > 10000000l && frequency < 10000000l)
isUSB = false;
setFrequency(frequency);
updateDisplay();
}
@@ -758,8 +631,9 @@ void doRIT(){
updateDisplay();
}
}
/*
save Frequency and mode to eeprom for Auto Save with protected eeprom cycle, by kd8cec
/**
save Frequency and mode to eeprom
*/
void storeFrequencyAndMode(byte saveType)
{
@@ -791,22 +665,6 @@ void storeFrequencyAndMode(byte saveType)
}
}
//calculate step size from 1 byte, compatible uBITX Manager, by KD8CEC
unsigned int byteToSteps(byte srcByte) {
byte powerVal = (byte)(srcByte >> 6);
unsigned int baseVal = srcByte & 0x3F;
if (powerVal == 1)
return baseVal * 10;
else if (powerVal == 2)
return baseVal * 100;
else if (powerVal == 3)
return baseVal * 1000;
else
return baseVal;
}
/**
* The settings are read from EEPROM. The first time around, the values may not be
* present or out of range, in this case, some intelligent defaults are copied into the
@@ -822,10 +680,7 @@ void initSettings(){
EEPROM.get(VFO_B, vfoB);
EEPROM.get(CW_SIDETONE, sideTone);
EEPROM.get(CW_SPEED, cwSpeed);
//End of original code
//----------------------------------------------------------------
//Add Lines by KD8CEC
//for custom source Section =============================
//ID & Version Check from EEProm
//if found different firmware, erase eeprom (32
@@ -849,7 +704,6 @@ void initSettings(){
if (EEPROM.read(VERSION_ADDRESS) != VERSION_NUM)
EEPROM.write(VERSION_ADDRESS, VERSION_NUM);
EEPROM.get(CW_CAL, cwmCarrier);
//for Save VFO_A_MODE to eeprom
//0: default, 1:not use, 2:LSB, 3:USB, 4:CW, 5:AM, 6:FM
@@ -861,24 +715,6 @@ void initSettings(){
//CW interval between TX and CW Start
EEPROM.get(CW_START, delayBeforeCWStartTime);
EEPROM.get(CW_KEY_TYPE, cwKeyType);
if (cwKeyType > 2)
cwKeyType = 0;
if (cwKeyType == 0)
Iambic_Key = false;
else
{
Iambic_Key = true;
if (cwKeyType == 1)
keyerControl &= ~IAMBICB;
else
keyerControl |= IAMBICB;
}
EEPROM.get(DISPLAY_OPTION1, displayOption1);
EEPROM.get(DISPLAY_OPTION2, displayOption2);
//User callsign information
if (EEPROM.read(USER_CALLSIGN_KEY) == 0x59)
@@ -907,13 +743,13 @@ void initSettings(){
if ((3 < tuneTXType && tuneTXType < 100) || 103 < tuneTXType || useHamBandCount < 1 || findedValidValueCount < 5)
{
tuneTXType = 2;
//if empty band Information, auto insert default region 2 frequency range
//if empty band Information, auto insert default region 1 frequency range
//This part is made temporary for people who have difficulty setting up, so can remove it when you run out of memory.
useHamBandCount = 10;
hamBandRange[0][0] = 1810; hamBandRange[0][1] = 2000;
hamBandRange[1][0] = 3500; hamBandRange[1][1] = 3800;
hamBandRange[2][0] = 5351; hamBandRange[2][1] = 5367;
hamBandRange[3][0] = 7000; hamBandRange[3][1] = 7300; //region 2
hamBandRange[3][0] = 7000; hamBandRange[3][1] = 7200;
hamBandRange[4][0] = 10100; hamBandRange[4][1] = 10150;
hamBandRange[5][0] = 14000; hamBandRange[5][1] = 14350;
hamBandRange[6][0] = 18068; hamBandRange[6][1] = 18168;
@@ -927,8 +763,8 @@ void initSettings(){
findedValidValueCount = 0;
EEPROM.get(TUNING_STEP, tuneStepIndex);
for (byte i = 0; i < 5; i++) {
arTuneStep[i] = byteToSteps(EEPROM.read(TUNING_STEP + i + 1));
if (arTuneStep[i] >= 1 && arTuneStep[i] <= 60000) //Maximum 650 for check valid Value
arTuneStep[i] = EEPROM.read(TUNING_STEP + i + 1);
if (arTuneStep[i] >= 1 && arTuneStep[i] < 251) //Maximum 250 for check valid Value
findedValidValueCount++;
}
@@ -945,47 +781,8 @@ void initSettings(){
if (tuneStepIndex == 0) //New User
tuneStepIndex = 3;
//CW Key ADC Range ======= adjust set value for reduce cw keying error
//by KD8CEC
unsigned int tmpMostBits = 0;
tmpMostBits = EEPROM.read(CW_ADC_MOST_BIT1);
cwAdcSTFrom = EEPROM.read(CW_ADC_ST_FROM) | ((tmpMostBits & 0x03) << 8);
cwAdcSTTo = EEPROM.read(CW_ADC_ST_TO) | ((tmpMostBits & 0x0C) << 6);
cwAdcDotFrom = EEPROM.read(CW_ADC_DOT_FROM) | ((tmpMostBits & 0x30) << 4);
cwAdcDotTo = EEPROM.read(CW_ADC_DOT_TO) | ((tmpMostBits & 0xC0) << 2);
tmpMostBits = EEPROM.read(CW_ADC_MOST_BIT2);
cwAdcDashFrom = EEPROM.read(CW_ADC_DASH_FROM) | ((tmpMostBits & 0x03) << 8);
cwAdcDashTo = EEPROM.read(CW_ADC_DASH_TO) | ((tmpMostBits & 0x0C) << 6);
cwAdcBothFrom = EEPROM.read(CW_ADC_BOTH_FROM) | ((tmpMostBits & 0x30) << 4);
cwAdcBothTo = EEPROM.read(CW_ADC_BOTH_TO) | ((tmpMostBits & 0xC0) << 2);
//default Value (for original hardware)
if (cwAdcSTFrom >= cwAdcSTTo)
{
cwAdcSTFrom = 0;
cwAdcSTTo = 50;
}
if (cwAdcBothFrom >= cwAdcBothTo)
{
cwAdcBothFrom = 51;
cwAdcBothTo = 300;
}
if (cwAdcDotFrom >= cwAdcDotTo)
{
cwAdcDotFrom = 301;
cwAdcDotTo = 600;
}
if (cwAdcDashFrom >= cwAdcDashTo)
{
cwAdcDashFrom = 601;
cwAdcDashTo = 800;
}
//end of CW Keying Variables
if (cwDelayTime < 1 || cwDelayTime > 250)
cwDelayTime = 60;
@@ -995,25 +792,20 @@ void initSettings(){
if (vfoB_mode < 2)
vfoB_mode = 3;
//original code with modified by kd8cec
if (usbCarrier > 12010000l || usbCarrier < 11990000l)
usbCarrier = 11995000l;
if (cwmCarrier > 12010000l || cwmCarrier < 11990000l)
cwmCarrier = 11995000l;
if (vfoA > 35000000l || 3500000l > vfoA) {
vfoA = 7150000l;
vfoA_mode = 2; //LSB
vfoA_mode = 2;
}
if (vfoB > 35000000l || 3500000l > vfoB) {
vfoB = 14150000l;
vfoB_mode = 3; //USB
vfoB_mode = 3;
}
//end of original code section
//for protect eeprom life by KD8CEC
//for protect eeprom life
vfoA_eeprom = vfoA;
vfoB_eeprom = vfoB;
vfoA_mode_eeprom = vfoA_mode;
@@ -1049,7 +841,6 @@ void initPorts(){
pinMode(PTT, INPUT_PULLUP);
pinMode(ANALOG_KEYER, INPUT_PULLUP);
pinMode(ANALOG_SMETER, INPUT); //by KD8CEC
pinMode(CW_TONE, OUTPUT);
digitalWrite(CW_TONE, 0);
@@ -1085,7 +876,7 @@ void setup()
//Serial.begin(9600);
lcd.begin(16, 2);
printLineF(1, F("CECBT v1.01"));
printLineF(1, F("CECBT v0.27"));
Init_Cat(38400, SERIAL_8N1);
initMeter(); //not used in this build
@@ -1099,16 +890,15 @@ void setup()
else {
printLineF(0, F("uBITX v0.20"));
delay(500);
clearLine2();
printLine2("");
}
initPorts();
byteToMode(vfoA_mode, 0);
initOscillators();
frequency = vfoA;
saveCheckFreq = frequency; //for auto save frequency
byteToMode(vfoA_mode);
setFrequency(vfoA);
updateDisplay();
@@ -1117,11 +907,13 @@ void setup()
}
/**
* The loop checks for keydown, ptt, function button and tuning.
*/
//for debug
int dbgCnt = 0;
byte flasher = 0;
//Auto save Frequency and Mode with Protected eeprom life by KD8CEC
void checkAutoSaveFreqMode()
{
//when tx or ritOn, disable auto save
@@ -1139,7 +931,6 @@ void checkAutoSaveFreqMode()
//check time for Frequency auto save
if (millis() - saveCheckTime > saveIntervalSec * 1000)
{
/*
if (vfoActive == VFO_A)
{
vfoA = frequency;
@@ -1152,8 +943,6 @@ void checkAutoSaveFreqMode()
vfoB_mode = modeToByte();
storeFrequencyAndMode(2);
}
*/
FrequencyToVFO(1);
}
}
}
@@ -1173,16 +962,9 @@ void loop(){
if (!inTx){
if (ritOn)
doRIT();
//else if (isIFShift)
// doIFShift();
else
doTuningWithThresHold();
if (isCWAutoMode == 0 && beforeIdle_ProcessTime < millis() - 250) {
idle_process();
beforeIdle_ProcessTime = millis();
}
} //end of check TX Status
doTuning();
}
//we check CAT after the encoder as it might put the radio into TX
Check_Cat(inTx? 1 : 0);

View File

@@ -14,7 +14,6 @@ void btnWaitForClick(){
void factory_alignment(){
factoryCalibration(1);
line2DisplayStatus = 1;
if (calibration == 0){
printLine2("Setup Aborted");
@@ -37,7 +36,6 @@ void factory_alignment(){
printLine2("#3:Test 3.5MHz");
cwMode = 0;
isUSB = false;
setFrequency(3500000l);
updateDisplay();
@@ -60,7 +58,6 @@ void factory_alignment(){
btnWaitForClick();
printLine2("#5:Test 14MHz");
cwMode = 0;
isUSB = true;
setFrequency(14000000l);
updateDisplay();
@@ -82,7 +79,6 @@ void factory_alignment(){
printLine2("Alignment done");
delay(1000);
cwMode = 0;
isUSB = false;
setFrequency(7150000l);
updateDisplay();

View File

@@ -1,259 +0,0 @@
/*************************************************************************
KD8CEC's uBITX Idle time Processing
Functions that run at times that do not affect TX, CW, and CAT
It is called in 1/10 time unit.
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
char line2Buffer[16];
//KD8CEC 200Hz ST
//L14.150 200Hz ST
//U14.150 +150khz
int freqScrollPosition = 0;
//Example Line2 Optinal Display
//immediate execution, not call by scheulder
void updateLine2Buffer(char isDirectCall)
{
unsigned long tmpFreq = 0;
if (isDirectCall == 0)
{
if (ritOn)
{
line2Buffer[0] = 'R';
line2Buffer[1] = 'i';
line2Buffer[2] = 't';
line2Buffer[3] = 'T';
line2Buffer[4] = 'X';
line2Buffer[5] = ':';
//display frequency
tmpFreq = ritTxFrequency;
for (int i = 15; i >= 6; i--) {
if (tmpFreq > 0) {
if (i == 12 || i == 8) line2Buffer[i] = '.';
else {
line2Buffer[i] = tmpFreq % 10 + 0x30;
tmpFreq /= 10;
}
}
else
line2Buffer[i] = ' ';
}
return;
} //end of ritOn display
//======================================================
//other VFO display
//======================================================
if (vfoActive == VFO_B)
{
tmpFreq = vfoA;
//line2Buffer[0] = 'A';
}
else
{
tmpFreq = vfoB;
//line2Buffer[0] = 'B';
}
// EXAMPLE 1 & 2
//U14.150.100
//display frequency
for (int i = 9; i >= 0; i--) {
if (tmpFreq > 0) {
if (i == 2 || i == 6) line2Buffer[i] = '.';
else {
line2Buffer[i] = tmpFreq % 10 + 0x30;
tmpFreq /= 10;
}
}
else
line2Buffer[i] = ' ';
}
//EXAMPLE #1
if ((displayOption1 & 0x04) == 0x00) //none scroll display
line2Buffer[6] = 'k';
else
{
//example #2
if (freqScrollPosition++ > 18) //none scroll display time
{
line2Buffer[6] = 'k';
if (freqScrollPosition > 25)
freqScrollPosition = -1;
}
else //scroll frequency
{
line2Buffer[10] = 'H';
line2Buffer[11] = 'z';
if (freqScrollPosition < 7)
{
for (int i = 11; i >= 0; i--)
if (i - (7 - freqScrollPosition) >= 0)
line2Buffer[i] = line2Buffer[i - (7 - freqScrollPosition)];
else
line2Buffer[i] = ' ';
}
else
{
for (int i = 0; i < 11; i++)
if (i + (freqScrollPosition - 7) <= 11)
line2Buffer[i] = line2Buffer[i + (freqScrollPosition - 7)];
else
line2Buffer[i] = ' ';
}
}
} //scroll
line2Buffer[7] = ' ';
} //check direct call by encoder
if (isIFShift)
{
if (isDirectCall == 1)
for (int i = 0; i < 16; i++)
line2Buffer[i] = ' ';
//IFShift Offset Value
line2Buffer[8] = 'I';
line2Buffer[9] = 'F';
if (ifShiftValue == 0)
{
line2Buffer[10] = 'S';
line2Buffer[11] = ':';
line2Buffer[12] = 'O';
line2Buffer[13] = 'F';
line2Buffer[14] = 'F';
}
else
{
line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0;
line2Buffer[11] = 0;
line2Buffer[12] = ' ';
//11, 12, 13, 14, 15
memset(b, 0, sizeof(b));
ltoa(ifShiftValue, b, DEC);
strncat(line2Buffer, b, 5);
}
if (isDirectCall == 1) //if call by encoder (not scheduler), immediate print value
printLine2(line2Buffer);
} // end of display IF
else // step display
{
if (isDirectCall != 0)
return;
memset(&line2Buffer[8], ' ', 8);
//Step
long tmpStep = arTuneStep[tuneStepIndex -1];
byte isStepKhz = 0;
if (tmpStep >= 1000)
{
isStepKhz = 2;
}
for (int i = 10; i >= 8 - isStepKhz; i--) {
if (tmpStep > 0) {
line2Buffer[i + isStepKhz] = tmpStep % 10 + 0x30;
tmpStep /= 10;
}
else
line2Buffer[i +isStepKhz] = ' ';
}
//if (isStepKhz == 1)
// line2Buffer[10] = 'k';
if (isStepKhz == 0)
{
line2Buffer[11] = 'H';
line2Buffer[12] = 'z';
}
line2Buffer[13] = ' ';
//if (
//Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
if (cwKeyType == 0)
{
line2Buffer[14] = 'S';
line2Buffer[15] = 'T';
}
else if (cwKeyType == 1)
{
line2Buffer[14] = 'I';
line2Buffer[15] = 'A';
}
else
{
line2Buffer[14] = 'I';
line2Buffer[15] = 'B';
}
}
}
//meterType : 0 = S.Meter, 1 : P.Meter
void DisplayMeter(byte meterType, byte meterValue, char drawPosition)
{
if (meterType == 0 || meterType == 1 || meterType == 2)
{
drawMeter(meterValue); //call original source code
int lineNumber = 0;
if ((displayOption1 & 0x01) == 0x01)
lineNumber = 1;
lcd.setCursor(drawPosition, lineNumber);
for (int i = 0; i < 6; i++) //meter 5 + +db 1 = 6
lcd.write(lcdMeter[i]);
}
}
byte testValue = 0;
char checkCount = 0;
void idle_process()
{
//space for user graphic display
if (menuOn == 0)
{
if ((displayOption1 & 0x10) == 0x10) //always empty topline
return;
//if line2DisplayStatus == 0 <-- this condition is clear Line, you can display any message
if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2)) {
if (checkCount++ > 1)
{
updateLine2Buffer(0); //call by scheduler
printLine2(line2Buffer);
line2DisplayStatus = 2;
checkCount = 0;
}
//EX for Meters
/*
DisplayMeter(0, testValue++, 7);
if (testValue > 30)
testValue = 0;
*/
}
}
}

View File

@@ -1,9 +1,8 @@
/**
CW Keyer
CW Key logic change with ron's code (ubitx_keyer.cpp)
Ron's logic has been modified to work with the original uBITX by KD8CEC
Original Comment ----------------------------------------------------------------------------
* CW Keyer
* CW Key logic change with ron's code (ubitx_keyer.cpp) <=== **********************************
* The file you are working on. The code only applies and is still in testing. <==== ***********
*
* The CW keyer handles either a straight key or an iambic / paddle key.
* They all use just one analog input line. This is how it works.
* The analog line has the internal pull-up resistor enabled.
@@ -83,165 +82,204 @@ void cwKeyUp(){
cwTimeout = millis() + cwDelayTime * 10;
}
//Variables for Ron's new logic
/*****************************************************************************
// New logic, by RON
// modified by KD8CEC
******************************************************************************/
#define DIT_L 0x01 // DIT latch
#define DAH_L 0x02 // DAH latch
#define DIT_PROC 0x04 // DIT is being processed
#define PDLSWAP 0x08 // 0 for normal, 1 for swap
#define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B
enum KSTYPE {IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT };
static unsigned long ktimer;
static long ktimer;
bool Iambic_Key = true;
unsigned char keyerControl = IAMBICB;
unsigned char keyerState = IDLE;
//Below is a test to reduce the keying error. do not delete lines
//Below is a test to reduce the keying error.
/*
char update_PaddleLatch(byte isUpdateKeyState) {
int paddle = analogRead(ANALOG_KEYER);
unsigned char tmpKeyerControl;
if (paddle > 800) // above 4v is up
tmpKeyerControl = 0;
//else if (paddle > 600) // 4-3v is DASH
else if (paddle > 693 && paddle < 700) // 4-3v is DASH
tmpKeyerControl |= DAH_L;
//else if (paddle > 300) //1-2v is DOT
else if (paddle > 323 && paddle < 328) //1-2v is DOT
tmpKeyerControl |= DIT_L;
//else if (paddle > 50)
else if (paddle > 280 && paddle < 290)
tmpKeyerControl |= (DAH_L | DIT_L) ; //both are between 1 and 2v
else
tmpKeyerControl = 0 ; //STRAIGHT KEY in original code
//keyerControl |= (DAH_L | DIT_L) ; //STRAIGHT KEY in original code
if (isUpdateKeyState == 1) {
keyerControl |= tmpKeyerControl;
}
byte buff[17];
sprintf(buff, "Key : %d", paddle);
if (tmpKeyerControl > 0)
printLine2(buff);
return tmpKeyerControl;
//if (analogRead(ANALOG_DOT) < 600 ) keyerControl |= DIT_L;
//if (analogRead(ANALOG_DASH) < 600 ) keyerControl |= DAH_L;
}
*/
//create by KD8CEC for compatible with new CW Logic
char update_PaddleLatch(byte isUpdateKeyState) {
unsigned char tmpKeyerControl = 0;
int paddle = analogRead(ANALOG_KEYER);
unsigned char tmpKeyerControl;
if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo)
if (paddle > 800) // above 4v is up
tmpKeyerControl = 0;
else if (paddle > 600) // 4-3v is DASH
tmpKeyerControl |= DAH_L;
else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo)
else if (paddle > 300) //1-2v is DOT
tmpKeyerControl |= DIT_L;
else if (paddle >= cwAdcBothFrom && paddle <= cwAdcBothTo)
tmpKeyerControl |= (DAH_L | DIT_L) ;
else
{
if (Iambic_Key)
tmpKeyerControl = 0 ;
else if (paddle >= cwAdcSTFrom && paddle <= cwAdcSTTo)
tmpKeyerControl = DIT_L ;
else
tmpKeyerControl = 0 ;
}
else if (paddle > 50)
tmpKeyerControl |= (DAH_L | DIT_L) ; //both are between 1 and 2v
else
tmpKeyerControl = 0 ; //STRAIGHT KEY in original code
//keyerControl |= (DAH_L | DIT_L) ; //STRAIGHT KEY in original code
if (isUpdateKeyState == 1)
if (isUpdateKeyState == 1) {
keyerControl |= tmpKeyerControl;
}
return tmpKeyerControl;
//if (analogRead(ANALOG_DOT) < 600 ) keyerControl |= DIT_L;
//if (analogRead(ANALOG_DASH) < 600 ) keyerControl |= DAH_L;
}
/*****************************************************************************
// New logic, by RON
// modified by KD8CEC
******************************************************************************/
void cwKeyer(void){
byte paddle;
lastPaddle = 0;
int dot,dash;
bool continue_loop = true;
unsigned tmpKeyControl = 0;
if( Iambic_Key ) {
while(continue_loop) {
switch (keyerState) {
case IDLE:
tmpKeyControl = update_PaddleLatch(0);
if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L ||
tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) {
update_PaddleLatch(1);
keyerState = CHK_DIT;
}else{
if (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
stopTx();
}
continue_loop = false;
}
break;
case CHK_DIT:
if (keyerControl & DIT_L) {
keyerControl |= DIT_PROC;
ktimer = cwSpeed;
keyerState = KEYED_PREP;
}else{
keyerState = CHK_DAH;
}
break;
case CHK_DAH:
if (keyerControl & DAH_L) {
ktimer = cwSpeed*3;
keyerState = KEYED_PREP;
}else{
keyerState = IDLE;
}
break;
case KEYED_PREP:
ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state
if (!inTx){
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 1);
}
cwKeydown();
break;
case KEYED:
if (millis() > ktimer) { // are we at end of key down ?
cwKeyUp();
ktimer = millis() + cwSpeed; // inter-element time
keyerState = INTER_ELEMENT; // next state
}else if (keyerControl & IAMBICB) {
update_PaddleLatch(1); // early paddle latch in Iambic B mode
}
break;
case INTER_ELEMENT:
// Insert time between dits/dahs
update_PaddleLatch(1); // latch paddle state
if (millis() > ktimer) { // are we at end of inter-space ?
if (keyerControl & DIT_PROC) { // was it a dit or dah ?
keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits
keyerState = CHK_DAH; // dit done, check for dah
}else{
keyerControl &= ~(DAH_L); // clear dah latch
keyerState = IDLE; // go idle
}
}
break;
}
Check_Cat(2);
} //end of while
}
else{
while(1){
if (update_PaddleLatch(0) == DIT_L) {
// if we are here, it is only because the key is pressed
if (!inTx){
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 1);
}
cwKeydown();
while ( update_PaddleLatch(0) == DIT_L )
delay_background(1, 3);
cwKeyUp();
}
else{
if( Iambic_Key ){
while(continue_loop){
switch (keyerState) {
case IDLE:
tmpKeyControl = update_PaddleLatch(0);
if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L ||
tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) {
//DIT or DASH or current state DIT & DASH
//(analogRead(ANALOG_DOT) < 600) || //DIT
//(analogRead(ANALOG_DASH) < 600) || //DIT
// (keyerControl & 0x03)) {
update_PaddleLatch(1);
keyerState = CHK_DIT;
}else{
if (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
keyDown = 0;
stopTx();
}
if (!cwTimeout)
return;
// got back to the beginning of the loop, if no further activity happens on straight key
// we will time out, and return out of this routine
//delay(5);
delay_background(5, 3);
continue;
continue_loop = false;
}
break;
Check_Cat(2);
} //end of while
} //end of elese
case CHK_DIT:
if (keyerControl & DIT_L) {
keyerControl |= DIT_PROC;
ktimer = cwSpeed;
keyerState = KEYED_PREP;
}else{
keyerState = CHK_DAH;
}
break;
case CHK_DAH:
if (keyerControl & DAH_L) {
ktimer = cwSpeed*3;
keyerState = KEYED_PREP;
}else{
keyerState = IDLE;
}
break;
case KEYED_PREP:
ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state
if (!inTx){
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 0);
}
cwKeydown();
break;
case KEYED:
if (millis() > ktimer) { // are we at end of key down ?
cwKeyUp();
ktimer = millis() + cwSpeed; // inter-element time
keyerState = INTER_ELEMENT; // next state
}else if (keyerControl & IAMBICB) {
update_PaddleLatch(1); // early paddle latch in Iambic B mode
}
break;
case INTER_ELEMENT:
// Insert time between dits/dahs
update_PaddleLatch(1); // latch paddle state
if (millis() > ktimer) { // are we at end of inter-space ?
if (keyerControl & DIT_PROC) { // was it a dit or dah ?
keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits
keyerState = CHK_DAH; // dit done, check for dah
}else{
keyerControl &= ~(DAH_L); // clear dah latch
keyerState = IDLE; // go idle
}
}
break;
}
} //end of while
}else{
while(1){
//if (analogRead(ANALOG_DOT) < 600){
if (update_PaddleLatch(0) == DIT_L) {
// if we are here, it is only because the key is pressed
if (!inTx){
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 0);
}
// start the transmission)
cwKeydown();
//while ( analogRead(ANALOG_DOT) < 600 ) delay(1);
while ( update_PaddleLatch(0) == DIT_L ) delay(1);
cwKeyUp();
}else{
if (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
keyDown = 0;
stopTx();
}
if (!cwTimeout)
return;
// got back to the beginning of the loop, if no further activity happens on straight key
// we will time out, and return out of this routine
delay(5);
continue;
}
} //end of else
}
}
//=======================================================================================

File diff suppressed because it is too large Load Diff

View File

@@ -109,11 +109,7 @@ void initOscillators(){
//initialize the SI5351
si5351bx_init();
si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor
if (cwMode == 0)
si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0));
else
si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0));
si5351bx_setfreq(0, usbCarrier);
}

View File

@@ -25,8 +25,8 @@ int btnDown(){
* The current reading of the meter is assembled in the string called meter
*/
//char meter[17];
/*
const PROGMEM uint8_t s_meter_bitmap[] = {
B00000,B00000,B00000,B00000,B00000,B00100,B00100,B11011,
B10000,B10000,B10000,B10000,B10100,B10100,B10100,B11011,
@@ -35,18 +35,7 @@ const PROGMEM uint8_t s_meter_bitmap[] = {
B00010,B00010,B00010,B00010,B00110,B00110,B00110,B11011,
B00001,B00001,B00001,B00001,B00101,B00101,B00101,B11011
};
*/
const PROGMEM uint8_t meters_bitmap[] = {
B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1
B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2
B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100 , //custom 3
B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110 , //custom 4
B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5
B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6
};
PGM_P p_metes_bitmap = reinterpret_cast<PGM_P>(meters_bitmap);
PGM_P ps_meter_bitmap = reinterpret_cast<PGM_P>(s_meter_bitmap);
const PROGMEM uint8_t lock_bitmap[8] = {
0b01110,
@@ -71,54 +60,38 @@ void initMeter(){
lcd.createChar(0, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i);
tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i);
lcd.createChar(1, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8);
tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 8);
lcd.createChar(2, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16);
tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 16);
lcd.createChar(3, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24);
tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 24);
lcd.createChar(4, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32);
tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 28);
lcd.createChar(5, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40);
tmpbytes[i] = pgm_read_byte(ps_meter_bitmap + i + 32);
lcd.createChar(6, tmpbytes);
}
//by KD8CEC
//0 ~ 25 : 30 over : + 10
void drawMeter(int needle) {
//5Char + O over
int i;
/**
* The meter is drawn with special characters.
* character 1 is used to simple draw the blocks of the scale of the meter
* characters 2 to 6 are used to draw the needle in positions 1 to within the block
* This displays a meter from 0 to 100, -1 displays nothing
*/
for (i = 0; i < 5; i++) {
if (needle >= 5)
lcdMeter[i] = 5; //full
else if (needle > 0)
lcdMeter[i] = needle; //full
else //0
lcdMeter[i] = 0x20;
needle -= 5;
}
if (needle > 0)
lcdMeter[5] = 6;
else
lcdMeter[5] = 0x20;
}
/*
/*
void drawMeter(int8_t needle){
int16_t best, i, s;
@@ -128,23 +101,21 @@ void drawMeter(int8_t needle){
s = (needle * 4)/10;
for (i = 0; i < 8; i++){
if (s >= 5)
lcdMeter[i] = 1;
meter[i] = 1;
else if (s >= 0)
lcdMeter[i] = 2 + s;
meter[i] = 2 + s;
else
lcdMeter[i] = 1;
meter[i] = 1;
s = s - 5;
}
if (needle >= 40)
lcdMeter[i-1] = 6;
lcdMeter[i] = 0;
meter[i-1] = 6;
meter[i] = 0;
}
*/
// The generic routine to display one line on the LCD
void printLine(unsigned char linenmbr, const char *c) {
if ((displayOption1 & 0x01) == 0x01)
linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle
if (strcmp(c, printBuff[linenmbr])) { // only refresh the display when there was a change
lcd.setCursor(0, linenmbr); // place the cursor at the beginning of the selected line
lcd.print(c);
@@ -174,9 +145,6 @@ void printLineF(char linenmbr, const __FlashStringHelper *c)
#define LCD_MAX_COLUMN 16
void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex) {
if ((displayOption1 & 0x01) == 0x01)
linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle
lcd.setCursor(lcdColumn, linenmbr);
for (byte i = eepromStartIndex; i <= eepromEndIndex; i++)
@@ -200,12 +168,6 @@ void printLine2(const char *c){
printLine(0,c);
}
void clearLine2()
{
printLine2("");
line2DisplayStatus = 0;
}
// short cut to print to the first line
void printLine1Clear(){
printLine(1,"");
@@ -217,7 +179,6 @@ void printLine2Clear(){
void printLine2ClearAndUpdate(){
printLine(0, "");
line2DisplayStatus = 0;
updateDisplay();
}
@@ -233,6 +194,7 @@ char byteToChar(byte srcByte){
void updateDisplay() {
// tks Jack Purdum W8TEE
// replaced fsprint commmands by str commands for code size reduction
// replace code for Frequency numbering error (alignment, point...) by KD8CEC
int i;
unsigned long tmpFreq = frequency; //
@@ -259,21 +221,10 @@ void updateDisplay() {
if (ritOn)
strcpy(c, "RIT ");
else {
if (cwMode == 0)
{
if (isUSB)
strcpy(c, "USB ");
else
strcpy(c, "LSB ");
}
else if (cwMode == 1)
{
strcpy(c, "CWL ");
}
if (isUSB)
strcpy(c, "USB ");
else
{
strcpy(c, "CWU ");
}
strcpy(c, "LSB ");
}
if (vfoActive == VFO_A) // VFO A is active
strcat(c, "A:");
@@ -300,22 +251,18 @@ void updateDisplay() {
// strcat(c, " TX");
printLine(1, c);
byte diplayVFOLine = 1;
if ((displayOption1 & 0x01) == 0x01)
diplayVFOLine = 0;
if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) ||
(vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02))) {
lcd.setCursor(5,diplayVFOLine);
lcd.setCursor(5,1);
lcd.write((uint8_t)0);
}
else if (isCWAutoMode == 2){
lcd.setCursor(5,diplayVFOLine);
lcd.setCursor(5,1);
lcd.write(0x7E);
}
else
{
lcd.setCursor(5,diplayVFOLine);
lcd.setCursor(5,1);
lcd.write(":");
}