Compare commits

..

1 Commits

Author SHA1 Message Date
phdlee
fda398046e Merge pull request #4 from phdlee/beta0.25
beta 0.25 commit
2018-01-10 11:39:15 +09:00
12 changed files with 571 additions and 2505 deletions

View File

@@ -1,67 +1,11 @@
#IMPORTANT INFORMATION
----------------------------------------------------------------------------
- Beta 0.26 and Beta 0.261, Beta 0.262, Beta 0.27 is complete test
- You can download and use it.
#NOTICE
----------------------------------------------------------------------------
I received uBITX a month ago and found that many features are required, and began coding with the idea of implementing minimal functionality as a general hf transceiver rather than an experimental device.
- fixed bugs...
- Diallock for uBITX's sensitive encoders
- built in softare Memory keyer and cw options control for CW communication
- Implementation of CAT communication protocol for Digital Communication (as FT8, JT65, etc)
- Delay Options for external Linear.
- and more...
Most of the basic functions of the HF transceiver I thought were implemented.
The minimum basic specification for uBITX to operate as a radio, I think it is finished.
So I will release the 0.27 version and if I do not see the bug anymore, I will try to change the version name to 1.0.
Now uBITX is an HF radio and will be able to join you in your happy hams life.
Based on this source, you can use it by adding functions.
I am going to do a new project based on this source, linking with WSPR, WSJT-X and so on.
Of course, this repository is still running. If you have any bugs or ideas, please feel free to email me.
http://www.hamskey.com
DE KD8CEC
kd8cec@gmail.com
#uBITX
uBITX firmware, written for the Raduino/Arduino control of uBITX transceivers
This project is based on https://github.com/afarhan/ubitx and all copyright is inherited.
The copyright information of the original is below.
KD8CEC
----------------------------------------------------------------------------
Prepared or finished tasks for the next version
- Most of them are implemented and included in version 0.27.
- User Interface on LCD -> Option by user (not need)
- Include WSPR Beacone function - (implement other new repository)
complete experiment
need solve : Big code size (over 100%, then remove some functions for experment)
need replace Si5351 Library (increase risk and need more beta tester)
W3PM sent me his wonderful source - using BITX, GPS
----------------------------------------------------------------------------
## REVISION RECORD
0.27
(First alpha test version, This will be renamed to the major version 1.0)
- Dual VFO Dial Lock (vfoA Dial lock)
- Support Ham band on uBITX
default Hamband is regeion1 but customize by uBITX Manager Software
- Advanced ham band options (Tx control) for use in all countries. You can adjust it yourself.
- Convenience of band movement
0.26
- only Beta tester released & source code share
- find a bug on none initial eeprom uBITX - Fixed (Check -> initialized & compatible original source code)
- change the version number 0.26 -> 0.27
- Prevent overflow bugs
- bug with linux based Hamlib (raspberry pi), It was perfect for the 0.224 version, but there was a problem for the 0.25 version.
On Windows, ham deluxe, wsjt-x, jt65-hf, and fldigi were successfully run. Problem with Raspberry pi.
0.25
- Beta Version Released
http://www.hamskey.com/2018/01/release-beta-version-of-cat-support.html

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;
}
@@ -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;
@@ -437,7 +398,7 @@ void ReadEEPRom_FT817(void) //for remove warnings
void WriteEEPRom_FT817(byte fromType)
{
//byte temp0 = CAT_BUFF[0];
byte temp0 = CAT_BUFF[0];
byte temp1 = CAT_BUFF[1];
CAT_BUFF[0] = 0;
@@ -509,8 +470,8 @@ void WriteEEPRom_FT817(byte fromType)
sideTone = (sideTonePitch * 50 + 300) + sideToneSub;
printLineF2(F("Sidetone set! CAT"));
EEPROM.put(CW_SIDETONE, sideTone);
delay(300); //If timeout errors occur in the calling software, remove them
clearLine2();
delay(500);
printLine2("");
}
break;
@@ -521,9 +482,8 @@ void WriteEEPRom_FT817(byte fromType)
sideTone = (sideTonePitch * 50 + 300) + sideToneSub;
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;
delay(500);
printLine2("");
}
break;
@@ -542,8 +502,8 @@ void WriteEEPRom_FT817(byte fromType)
cwDelayTime = CAT_BUFF[2];
printLineF2(F("CW Speed set!"));
EEPROM.put(CW_DELAY, cwDelayTime);
delay(300);
clearLine2();
delay(500);
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)
@@ -551,8 +511,8 @@ void WriteEEPRom_FT817(byte fromType)
cwSpeed = 1200 / ((CAT_BUFF[2] & 0x3F) + 4);
printLineF2(F("CW Speed set!"));
EEPROM.put(CW_SPEED, cwSpeed);
delay(300);
clearLine2();
delay(500);
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;
@@ -690,6 +648,7 @@ void Check_Cat(byte fromType)
rxBufferCheckCount = Serial.available();
rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; //Set time for timeout
}
return;
}
@@ -734,11 +693,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 +714,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
@@ -36,7 +33,7 @@
//27 + 10 + 18 + 1(SPACE) = //56
const PROGMEM uint8_t cwAZTable[27] = {0b00100100 , 0b01001000 , 0b01001010 , 0b00111000 , 0b00010000, 0b01000010, 0b00111100, 0b01000000 , //A ~ H
0b00100000, 0b01000111 ,0b00111010, 0b01000100, 0b00101100, 0b00101000 , 0b00111110, 0b01000110, 0b01001101, 0b00110100, //I ~ R
0b00110000, 0b00011000, 0b00110010, 0b01000001, 0b00110110, 0b01001001, 0b01001011, 0b01001100}; //S ~ Z
0b00110000, 0b00011000, 0b00110010, 0b01000001, 0b00110110, 0b01001001, 0b01001011, 0b00111000}; //S ~ Z
PGM_P pCwAZTable = reinterpret_cast<PGM_P>(cwAZTable);
const PROGMEM uint8_t cw09Table[27] = {0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001, 0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110};
@@ -211,14 +208,10 @@ void sendCWChar(char cwKeyChar)
charLength = ((tmpChar >> 6) & 0x03) + 3;
for (j = 0; j < charLength; j++)
sendBuff[j] = (tmpChar << (j + 2)) & 0x80;
sendBuff[j] = (tmpChar << j + 2) & 0x80;
break;
}
else
{
charLength = 0;
}
}
}
@@ -264,7 +257,7 @@ unsigned long scrollDispayTime = 0;
#define scrollSpeed 500
byte displayScrolStep = 0;
void controlAutoCW(){
int controlAutoCW(){
int knob = 0;
byte i;
@@ -297,13 +290,9 @@ void controlAutoCW(){
displayScrolStep = 0;
}
printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0);
byte diplayAutoCWLine = 0;
if ((displayOption1 & 0x01) == 0x01)
diplayAutoCWLine = 1;
printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ);
lcd.setCursor(0, diplayAutoCWLine);
lcd.setCursor(0,0);
lcd.write(byteToChar(selectedCWTextIndex));
lcd.write(':');
isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0;
@@ -365,11 +354,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,80 +0,0 @@
/*************************************************************************
header file for C++ by 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
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/>.
**************************************************************************/
#define WSPR_COUNT 443 //WSPR_MESSAGE_COUNT
#define WSPR_MESSAGE1 444 //
#define WSPR_MESSAGE2 490 //
#define WSPR_MESSAGE3 536 //
#define WSPR_MESSAGE4 582 //
#define WSPR_BAND_COUNT 3
#define TX_SSB 0
#define TX_CW 1
extern void printLine1(const char *c);
extern void printLine2(const char *c);
extern void printLineF(char linenmbr, const __FlashStringHelper *c);
extern void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetType);
extern byte delay_background(unsigned delayTime, byte fromType);
extern int btnDown(void);
extern char c[30];
extern char b[30];
extern unsigned long frequency;
#define printLineF1(x) (printLineF(1, x))
#define printLineF2(x) (printLineF(0, x))
/**
* The second set of 16 pins on the Raduino's bottom connector are have the three clock outputs and the digital lines to control the rig.
* This assignment is as follows :
* Pin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
* GND +5V CLK0 GND GND CLK1 GND GND CLK2 GND D2 D3 D4 D5 D6 D7
* These too are flexible with what you may do with them, for the Raduino, we use them to :
* - TX_RX line : Switches between Transmit and Receive after sensing the PTT or the morse keyer
* - CW_KEY line : turns on the carrier for CW
*/
#define TX_RX (7)
#define CW_TONE (6)
#define TX_LPF_A (5)
#define TX_LPF_B (4)
#define TX_LPF_C (3)
#define CW_KEY (2)
//we directly generate the CW by programmin the Si5351 to the cw tx frequency, hence, both are different modes
//these are the parameter passed to startTx
#define TX_SSB 0
#define TX_CW 1
extern void si5351bx_init(void);
extern void si5351bx_setfreq(uint8_t clknum, uint32_t fout);
extern void si5351_set_calibration(int32_t cal);
extern void initOscillators(void);
extern void Set_WSPR_Param(void);
extern void TXSubFreq(unsigned long P2);
extern void startTx(byte txMode, byte isDisplayUpdate);
extern void stopTx(void);
extern void setTXFilters(unsigned long freq);
extern void SendWSPRManage(void);
extern byte WsprMSGCount;

File diff suppressed because it is too large Load Diff

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,254 +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)
{
strcpy(line2Buffer, "RitTX:");
//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;
}
else
{
tmpFreq = vfoB;
}
// 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,6 @@
/**
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
*
* 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.
@@ -37,6 +34,7 @@
//when both are simultaneously pressed
char lastPaddle = 0;
//reads the analog keyer pin and reports the paddle
byte getPaddle(){
int paddle = analogRead(ANALOG_KEYER);
@@ -83,201 +81,13 @@ void cwKeyUp(){
cwTimeout = millis() + cwDelayTime * 10;
}
//Variables for Ron's new logic
#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;
unsigned char keyerState = IDLE;
//Below is a test to reduce the keying error. do not delete lines
//create by KD8CEC for compatible with new CW Logic
char update_PaddleLatch(byte isUpdateKeyState) {
unsigned char tmpKeyerControl = 0;
int paddle = analogRead(ANALOG_KEYER);
if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo)
tmpKeyerControl |= DAH_L;
else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo)
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 ;
}
if (isUpdateKeyState == 1)
keyerControl |= tmpKeyerControl;
return tmpKeyerControl;
}
/*****************************************************************************
// New logic, by RON
// modified by KD8CEC
******************************************************************************/
void cwKeyer(void){
lastPaddle = 0;
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:
//modified KD8CEC
/*
ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state
if (!inTx){
//DelayTime Option
delay_background(delayBeforeCWStartTime * 2, 2);
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 1);
}
*/
if (!inTx){
//DelayTime Option
delay_background(delayBeforeCWStartTime * 2, 2);
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 1);
}
ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state
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){
//DelayTime Option
delay_background(delayBeforeCWStartTime * 2, 2);
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 (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
keyDown = 0;
stopTx();
}
//if (!cwTimeout) //removed by KD8CEC
// 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); //removed by KD8CEC
//continue; //removed by KD8CEC
return; //Tx stop control by Main Loop
}
Check_Cat(2);
} //end of while
} //end of elese
}
//=======================================================================================
//Before logic
//by Farhan and modified by KD8CEC
//======================================================================================
/**
* The keyer handles the straight key as well as the iambic key
* This module keeps looping until the user stops sending cw
* if the cwTimeout is set to 0, then it means, we have to exit the keyer loop
* Each time the key is hit the cwTimeout is pushed to a time in the future by cwKeyDown()
*/
/*
void cwKeyer(){
byte paddle;
lastPaddle = 0;
@@ -301,7 +111,17 @@ void cwKeyer(){
if (!cwTimeout)
return;
Check_Cat(2); //for uBITX on Raspberry pi, when straight keying, disconnect / test complete
//if a paddle was used (not a straight key) we should extend the space to be a full dash
//by adding two more dots long space (one has already been added at the end of the dot or dash)
/*
if (cwTimeout > 0 && lastPaddle != PADDLE_STRAIGHT)
delay_background(cwSpeed * 2, 3);
//delay(cwSpeed * 2);
// got back to the begining of the loop, if no further activity happens on the paddle or the straight key
// we will time out, and return out of this routine
delay(5);
*/
continue;
}
@@ -364,6 +184,3 @@ void cwKeyer(){
delay(cwSpeed);
}
}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,3 @@
/************************************************************************************
* KD8CEC
* kd8cec@gmail.com http://www.hamskey.com
*
* Merge two SI5351 Librarys
* KE7ER's fixed vco and variable Clocks Configure values
* G3ZIL's fixed Clock Configure Value and variable VCO
* * I have combined the two libraries above. All licenses follow the above library.
*
* PLL-A is generated by fixing 850Mhz clock. All output clocks use PLL-A to
* generate the frequency. This is the method used in QRP radios such as uBITX.
* When switching to WSPR transmission mode, PLL-B operates for the base frequency to transmit WSPR.
* The output clock channel that controls the frequency is connected to the PLL-B.
* The WSPR protocol is generated by changing the clock of the PLL-B.
************************************************************************************/
// ************* SI5315 routines - tks Jerry Gaffke, KE7ER ***********************
// An minimalist standalone set of Si5351 routines.
@@ -76,22 +60,19 @@ void i2cWriten(uint8_t reg, uint8_t *vals, uint8_t vcnt) { // write array
Wire.endTransmission();
}
uint8_t si5351Val[8] = {0, 1, 0, 0, 0, 0, 0, 0}; //for reduce program memory size
void si5351bx_init() { // Call once at power-up, start PLLA
uint32_t msxp1;
uint8_t reg; uint32_t msxp1;
Wire.begin();
i2cWrite(149, 0); // SpreadSpectrum off
i2cWrite(3, si5351bx_clken); // Disable all CLK output drivers
i2cWrite(183, SI5351BX_XTALPF << 6); // Set 25mhz crystal load capacitance
msxp1 = 128 * SI5351BX_MSA - 512; // and msxp2=0, msxp3=1, not fractional
//uint8_t vals[8] = {0, 1, BB2(msxp1), BB1(msxp1), BB0(msxp1), 0, 0, 0};
si5351Val[2] = BB2(msxp1);
si5351Val[3] = BB1(msxp1);
si5351Val[4] = BB0(msxp1);
i2cWriten(26, si5351Val, 8); // Write to 8 PLLA msynth regs
uint8_t vals[8] = {0, 1, BB2(msxp1), BB1(msxp1), BB0(msxp1), 0, 0, 0};
i2cWriten(26, vals, 8); // Write to 8 PLLA msynth regs
i2cWrite(177, 0x20); // Reset PLLA (0x80 resets PLLB)
// for (reg=16; reg<=23; reg++) i2cWrite(reg, 0x80); // Powerdown CLK's
// i2cWrite(187, 0); // No fannout of clkin, xtal, ms0, ms4
}
void si5351bx_setfreq(uint8_t clknum, uint32_t fout) { // Set a CLK to fout Hz
@@ -124,48 +105,11 @@ void si5351_set_calibration(int32_t cal){
si5351bx_setfreq(0, usbCarrier);
}
void SetCarrierFreq()
{
unsigned long appliedCarrier = ((cwMode == 0 ? usbCarrier : cwmCarrier) + (isIFShift && (inTx == 0) ? ifShiftValue : 0));
si5351bx_setfreq(0, appliedCarrier);
/*
if (cwMode == 0)
si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0));
else
si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0));
*/
}
void initOscillators(){
//initialize the SI5351
si5351bx_init();
si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor
SetCarrierFreq();
}
//============================================================
// ADD FUNCTIONS by KD8CEC
//============================================================
uint8_t Wspr_Reg1[8] = {0xFF,0xFE, 0x00, 0, 0, 0, 0, 0}; //3, 4, 5, 6, 7
uint8_t Wspr_Reg2[8] = {0, 1, 0, 0, 0, 0, 0, 0}; //2, 3, 4
void Set_WSPR_Param(void)
{
i2cWrite(18, 128);
i2cWriten(34, Wspr_Reg1, 8);
i2cWriten(58, Wspr_Reg2, 8);
i2cWrite(177, 128);
i2cWrite(18, 111);
si5351bx_clken &= ~(1 << 2);
i2cWrite(3, si5351bx_clken);
}
void TXSubFreq(unsigned long P2)
{
i2cWrite(40, (P2 & 65280) >> 8);
i2cWrite(41, P2 & 255);
si5351bx_setfreq(0, usbCarrier);
}

View File

@@ -9,7 +9,7 @@
//#define printLineF2(x) (printLineF(0, x))
//returns true if the button is pressed
int btnDown(void){
int btnDown(){
if (digitalRead(FBUTTON) == HIGH)
return 0;
else
@@ -25,8 +25,8 @@ int btnDown(void){
* 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
void printLine(char linenmbr, char *c) {
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);
@@ -173,16 +144,13 @@ void printLineF(char linenmbr, const __FlashStringHelper *c)
}
#define LCD_MAX_COLUMN 16
void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetTtype) {
if ((displayOption1 & 0x01) == 0x01)
linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle
void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex) {
lcd.setCursor(lcdColumn, linenmbr);
for (byte i = eepromStartIndex; i <= eepromEndIndex; i++)
{
if (++lcdColumn <= LCD_MAX_COLUMN)
lcd.write(EEPROM.read((offsetTtype == 0 ? USER_CALLSIGN_DAT : WSPR_MESSAGE1) + i));
lcd.write(EEPROM.read(USER_CALLSIGN_DAT + i));
else
break;
}
@@ -192,20 +160,14 @@ void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, b
}
// short cut to print to the first line
void printLine1(const char *c){
void printLine1(char *c){
printLine(1,c);
}
// short cut to print to the first line
void printLine2(const char *c){
void printLine2(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:");
@@ -281,15 +232,6 @@ void updateDisplay() {
strcat(c, "B:");
}
//Fixed by Mitani Massaru (JE4SMQ)
if (isShiftDisplayCWFreq == 1)
{
if (cwMode == 1) //CWL
tmpFreq = tmpFreq - sideTone + shiftDisplayAdjustVal;
else if (cwMode == 2) //CWU
tmpFreq = tmpFreq + sideTone + shiftDisplayAdjustVal;
}
//display frequency
for (int i = 15; i >= 6; i--) {
if (tmpFreq > 0) {
@@ -309,24 +251,35 @@ 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);
if (isDialLock == 1) {
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(":");
}
/*
//now, the second line
memset(c, 0, sizeof(c));
memset(b, 0, sizeof(b));
if (inTx)
strcat(c, "TX ");
else if (ritOn)
strcpy(c, "RIT");
strcpy(c, " \xff");
drawMeter(meter_reading);
strcat(c, meter);
strcat(c, "\xff");
printLine2(c);*/
}
int enc_prev_state = 3;
@@ -358,9 +311,9 @@ int enc_read(void) {
byte newState;
int enc_speed = 0;
unsigned long start_at = millis();
long stop_by = millis() + 50;
while (millis() - start_at < 50) { // check if the previous state was stable
while (millis() < stop_by) { // check if the previous state was stable
newState = enc_state(); // Get current state
if (newState != enc_prev_state)

View File

@@ -1,193 +0,0 @@
/**********************************************************************************
WSPR SENDER for uBITX by KD8CEC
Some of the code that sends WSPR referenced the code in G3ZIL.
Thanks to G3ZIL for sharing great code.
Due to the limited memory of uBITX, I have implemented at least only a few of the codes in uBITX.
Thanks for testing
Beta Tester :
-----------------------------------------------------------------------------
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/>.
**********************************************************************************/
#include <arduino.h>
#include <EEPROM.h>
#include "ubitx.h"
//begin of test
byte WsprToneCode[164];
long lastTime=0;
unsigned long TX_MSNB_P2; // Si5351 register MSNB_P2 PLLB for Tx
unsigned long TX_P2; // Variable values for MSNB_P2 which defines the frequencies for the data
extern int enc_read(void);
byte WsprMSGCount = 0;
#define PTT (A3)
#define WSPR_BAND1 401
extern uint8_t Wspr_Reg1[8]; //3, 4, 5, 6, 7
extern uint8_t Wspr_Reg2[8]; //2, 3, 4
void SendWSPRManage()
{
int knob = 0;
byte knobPosition = 0;
char isNeedDisplayInfo = 0;
char nowSelectedIndex = 0;
char nowWsprStep = 0; //0 : select Message, 1 : select band, 2 : send
char selectedWsprMessageIndex = -1;
char selectedWsprBandIndex = -1;
unsigned long WsprTXFreq = 0;
unsigned int WsprMultiChan = 0;
unsigned long prevFreq;
char loopIndex;
delay_background(500, 0);
//Readed WsprMSGCount, WsprTone
while(1)
{
knob = enc_read();
if (knobPosition > 0 && knob < 0)
knobPosition--;
else if (knob > 0 && (knobPosition <= (nowWsprStep == 0 ? WsprMSGCount : WSPR_BAND_COUNT) * 10 -2))
knobPosition++;
nowSelectedIndex = knobPosition / 10;
if (nowWsprStep == 0) //select Message status
{
printLineF2(F("WSPR:"));
if (selectedWsprMessageIndex != nowSelectedIndex)
{
selectedWsprMessageIndex = nowSelectedIndex;
int wsprMessageBuffIndex = selectedWsprMessageIndex * 46;
//Display WSPR Name tag
printLineFromEEPRom(0, 6, wsprMessageBuffIndex, wsprMessageBuffIndex + 4, 1);
//Load WSPR Tonecode
//Read Tone Code
for (int i = 0; i < 41; i++)
{
byte readData = EEPROM.read(WSPR_MESSAGE1 + 5 + (wsprMessageBuffIndex) + i); //NAME TAG 5, MESSAGE 41 = 46
WsprToneCode[i * 4 + 0] = readData & 3;
WsprToneCode[i * 4 + 1] = (readData >> 2) & 3;
WsprToneCode[i * 4 + 2] = (readData >> 4) & 3;
WsprToneCode[i * 4 + 3] = (readData >> 6) & 3;
}
}
else if (btnDown())
{
nowWsprStep = 1; //Change Status to Select Band
knobPosition = 0;
nowSelectedIndex = 0;
delay_background(500, 0);
}
}
else if (nowWsprStep == 1)
{
//printLineF2(F("Select Band"));
if (selectedWsprBandIndex != nowSelectedIndex)
{
selectedWsprBandIndex = nowSelectedIndex;
int bandBuffIndex = WSPR_BAND1 + selectedWsprBandIndex * 14;
EEPROM.get(bandBuffIndex, WsprTXFreq);
EEPROM.get(bandBuffIndex + 4, WsprMultiChan);
/*
//3, 4, 5, 6, 7
Wspr_Reg1[3] = EEPROM.read(bandBuffIndex + 6);
Wspr_Reg1[4] = EEPROM.read(bandBuffIndex + 7);
Wspr_Reg1[5] = EEPROM.read(bandBuffIndex + 8);
Wspr_Reg1[6] = EEPROM.read(bandBuffIndex + 9);
Wspr_Reg1[7] = EEPROM.read(bandBuffIndex + 10);
*/
for (loopIndex = 3; loopIndex < 8; loopIndex++)
Wspr_Reg1[loopIndex] = EEPROM.read(bandBuffIndex + loopIndex + 3);
/*
Wspr_Reg2[2] = EEPROM.read(bandBuffIndex + 11);
Wspr_Reg2[3] = EEPROM.read(bandBuffIndex + 12);
Wspr_Reg2[4] = EEPROM.read(bandBuffIndex + 13);
*/
//2, 3, 4
for (loopIndex = 2; loopIndex < 5; loopIndex++)
Wspr_Reg2[loopIndex] = EEPROM.read(bandBuffIndex + loopIndex + 9);
TX_MSNB_P2 = ((unsigned long)Wspr_Reg1[5] & 0x0F) << 16 | ((unsigned long)Wspr_Reg1[6]) << 8 | Wspr_Reg1[7];
}
ltoa(WsprTXFreq, b, DEC);
if (digitalRead(PTT) == 0)
strcpy(c, "SEND:");
else
strcpy(c, "PTT->");
strcat(c, b);
printLine1(c);
if (digitalRead(PTT) == 0)
{
//printLineF1(F("Transmitting"));
//SEND WSPR
//If you need to consider the Rit and Sprite modes, uncomment them below.
//remark = To reduce the size of the program
//prevFreq = frequency;
//frequency = WsprTXFreq;
startTx(TX_CW, 0);
setTXFilters(WsprTXFreq);
//Start WSPR
Set_WSPR_Param();
digitalWrite(CW_KEY, 1);
for (int i = 0; i < 162; i++)
{ // Now this is the message loop
lastTime = millis(); // Store away the time when the last message symbol was sent
TX_P2 = TX_MSNB_P2 + WsprMultiChan * WsprToneCode[i]; // This represents the 1.46 Hz shift and is correct only for the bands specified in the array
TXSubFreq(TX_P2); // TX at the appropriate channel frequency for....
//if (btnDown())
// break;
while (millis() < lastTime + 683){} // .... 0,683 seconds
}
digitalWrite(CW_KEY, 0);
stopTx(); //call setFrequency -> recovery TX Filter
//frequency = prevFreq;
selectedWsprBandIndex = -1;
} //end of PTT Check
else if (btnDown())
{
return;
}
} //end of status check
//delay_background(50, 1);
} //end of while
}