Compare commits
1 Commits
version1.0
...
v0.25
Author | SHA1 | Date | |
---|---|---|---|
|
fda398046e |
56
README.md
56
README.md
@@ -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
|
||||
|
@@ -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:
|
||||
/*
|
||||
|
@@ -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
|
||||
|
@@ -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
@@ -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();
|
||||
|
@@ -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;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user