Compare commits
8 Commits
master
...
meter-to-t
Author | SHA1 | Date | |
---|---|---|---|
|
da58606409 | ||
|
091f414409 | ||
|
87b6e3fbde | ||
|
48cb6cf304 | ||
|
c59d53fb9e | ||
|
16b350cb0f | ||
|
bb31ccfbe4 | ||
|
c1c4dd3f19 |
149
TeensyDSP/DSP.cpp
Normal file
149
TeensyDSP/DSP.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
//======================================================================
|
||||
// DSP.cpp
|
||||
//======================================================================
|
||||
|
||||
#include "DSP.h"
|
||||
|
||||
#include <Audio.h>
|
||||
#include <i2c_t3.h>
|
||||
//#include <Wire.h>
|
||||
//#include <SPI.h>
|
||||
//#include <SD.h>
|
||||
//#include <SerialFlash.h>
|
||||
|
||||
#define RX_AUDIO_CH 0
|
||||
|
||||
#define TX_MIC_IN_CH 0
|
||||
#define TX_LINE_IN_CH 0
|
||||
#define TX_USB_IN_CH1 1
|
||||
#define TX_USB_IN_CH2 2
|
||||
|
||||
UBitxDSP DSP;
|
||||
|
||||
//static struct {
|
||||
|
||||
// GUItool: begin automatically generated code
|
||||
AudioInputI2S lineIn; //xy=137,220
|
||||
AudioInputUSB usbIn; //xy=142,326
|
||||
AudioMixer4 rxAudio; //xy=394,134
|
||||
AudioMixer4 txAudio; //xy=398,322
|
||||
AudioOutputAnalog spkrOut; //xy=774,104
|
||||
AudioOutputUSB usbOut; //xy=774,138
|
||||
AudioOutputI2S lineOut; //xy=776,236
|
||||
AudioConnection patchCord1(lineIn, 0, rxAudio, 0);
|
||||
AudioConnection patchCord2(lineIn, 1, txAudio, 0);
|
||||
AudioConnection patchCord3(usbIn, 0, txAudio, 1);
|
||||
AudioConnection patchCord4(usbIn, 1, txAudio, 2);
|
||||
AudioConnection patchCord5(rxAudio, spkrOut);
|
||||
AudioConnection patchCord6(rxAudio, 0, lineOut, 0);
|
||||
AudioConnection patchCord7(rxAudio, 0, usbOut, 0);
|
||||
AudioConnection patchCord8(rxAudio, 0, usbOut, 1);
|
||||
AudioConnection patchCord9(txAudio, 0, lineOut, 1);
|
||||
AudioControlSGTL5000 audioCtrl; //xy=403,463
|
||||
// GUItool: end automatically generated code
|
||||
|
||||
//} audio;
|
||||
|
||||
void UBitxDSP::begin() {
|
||||
AudioMemory(20);
|
||||
audioCtrl.enable();
|
||||
audioCtrl.volume(0.0); // headphone volume...
|
||||
audioCtrl.muteHeadphone(); // ...not used by UBitxDSP
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i == RX_AUDIO_CH)
|
||||
rxAudio.gain(i, 1.0);
|
||||
else
|
||||
rxAudio.gain(i, 0.0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
txAudio.gain(i, 0.0);
|
||||
}
|
||||
|
||||
// SETUP THE AUDIO INPUTS
|
||||
|
||||
// Rig (Line) Input (RX)
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
audioCtrl.unmuteLineout();
|
||||
audioCtrl.lineInLevel(5, 5); // RX, TX
|
||||
audioCtrl.lineOutLevel(29, 29); //RX, TX
|
||||
|
||||
// Mic Input (TX)
|
||||
audioCtrl.micGain(0); // TODO: set value
|
||||
|
||||
// Line Input (TX)
|
||||
|
||||
// USB Input (TX)
|
||||
|
||||
// SETUP THE AUDIO OUTPUTS
|
||||
|
||||
// Speaker Output (RX)
|
||||
spkrOut.analogReference(INTERNAL);
|
||||
|
||||
// Line Output (RX)
|
||||
|
||||
// USB Output (RX)
|
||||
|
||||
// Rig (Line) Output (TX)
|
||||
|
||||
// Default to RX.
|
||||
rx();
|
||||
}
|
||||
|
||||
void UBitxDSP::end() {
|
||||
}
|
||||
|
||||
void UBitxDSP::rx() {
|
||||
// mute all tx audio
|
||||
for (int i = 0; i < 4; i++) {
|
||||
txAudio.gain(i, 0.0);
|
||||
}
|
||||
// select line in for rx
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
// restore rx audio
|
||||
rxAudio.gain(RX_AUDIO_CH, 1.0); // restore the RX audio
|
||||
}
|
||||
|
||||
void UBitxDSP::txMicIn() {
|
||||
// mute the rx audio
|
||||
rxAudio.gain(RX_AUDIO_CH, 0.0);
|
||||
// restore the tx mic audio
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_MIC);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i == TX_MIC_IN_CH)
|
||||
txAudio.gain(i, 1.0);
|
||||
else
|
||||
txAudio.gain(i, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::txLineIn() {
|
||||
// mute the rx audio
|
||||
rxAudio.gain(RX_AUDIO_CH, 0.0);
|
||||
// restore the tx line in audio
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i == TX_LINE_IN_CH)
|
||||
txAudio.gain(i, 1.0);
|
||||
else
|
||||
txAudio.gain(i, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::txUSBIn() {
|
||||
// mute the rx audio
|
||||
rxAudio.gain(RX_AUDIO_CH, 0.0);
|
||||
// restore the tx usb in audio
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i == TX_USB_IN_CH1 || i == TX_USB_IN_CH2)
|
||||
txAudio.gain(i, 1.0);
|
||||
else
|
||||
txAudio.gain(i, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
42
TeensyDSP/DSP.h
Normal file
42
TeensyDSP/DSP.h
Normal file
@ -0,0 +1,42 @@
|
||||
//======================================================================
|
||||
// DSP.h
|
||||
//======================================================================
|
||||
|
||||
#ifndef __DSP_h__
|
||||
#define __DSP_h__
|
||||
|
||||
#include "Debug.h"
|
||||
|
||||
enum TRState {
|
||||
TRANSMIT,
|
||||
RECEIVE
|
||||
};
|
||||
|
||||
enum RxAudioIn {
|
||||
RIG_AUDIO
|
||||
};
|
||||
|
||||
enum TxAudioIn {
|
||||
MIC_IN,
|
||||
LINE_IN,
|
||||
USB_IN
|
||||
};
|
||||
|
||||
class UBitxDSP {
|
||||
public:
|
||||
UBitxDSP() {};
|
||||
void begin();
|
||||
void end();
|
||||
void rx();
|
||||
void txMicIn();
|
||||
void txLineIn();
|
||||
void txUSBIn();
|
||||
};
|
||||
|
||||
extern UBitxDSP DSP;
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
18
TeensyDSP/Debug.h
Normal file
18
TeensyDSP/Debug.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef __Debug_h__
|
||||
#define __Debug_h__
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBGPRINT(MSG) do { Serial.print("DBG: "); Serial.print(MSG); } while (0)
|
||||
#define DBGPRINTLN(MSG) do { Serial.print("DBG: "); Serial.println(MSG); } while (0)
|
||||
#define DBGNEWLINE() do { Serial.println(); } while (0)
|
||||
#define DBGCMD(CMD) do { Serial.println("DBG: "); Serial.println(#CMD); CMD; } while (0)
|
||||
#else
|
||||
#define DBGPRINT(MSG) do {} while (0)
|
||||
#define DBGPRINTLN(MSG) do {} while (0)
|
||||
#define DBGNEWLINE() do {} while (0)
|
||||
#define DBGCMD(CMD) do { CMD; } while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
186
TeensyDSP/HamFuncs.h
Normal file
186
TeensyDSP/HamFuncs.h
Normal file
@ -0,0 +1,186 @@
|
||||
#ifndef __HamFuncs_h__
|
||||
#define __HamFuncs_h__
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#ifndef HF_PWR_DEFAULT_LOAD
|
||||
#define HF_PWR_DEFAULT_LOAD 50.0
|
||||
#endif
|
||||
|
||||
#ifndef HF_VSWR_MAX_REPORTED
|
||||
#define HF_VSWR_MAX_REPORTED 9.9
|
||||
#endif
|
||||
|
||||
#ifndef HF_BRIDGE_FWD_VRECT
|
||||
#define HF_BRIDGE_FWD_VRECT 0.25
|
||||
#endif
|
||||
|
||||
#ifndef HF_BRIDGE_FWD_TURNS
|
||||
#define HF_BRIDGE_FWD_TURNS 10.0
|
||||
#endif
|
||||
|
||||
#ifndef HF_BRIDGE_REV_VRECT
|
||||
#define HF_BRIDGE_REV_VRECT 0.25
|
||||
#endif
|
||||
|
||||
#ifndef HF_BRIDGE_REV_TURNS
|
||||
#define HF_BRIDGE_REV_TURNS 10.0
|
||||
#endif
|
||||
|
||||
#ifndef HF_ADC_DEFAULT_BITS
|
||||
#define HF_ADC_DEFAULT_BITS 10
|
||||
#endif
|
||||
|
||||
#ifndef HF_ADC_DEFAULT_VREF
|
||||
#define HF_ADC_DEFAULT_VREF 3.3
|
||||
#endif
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
namespace HF {
|
||||
|
||||
const float pwrDefaultLoad = HF_PWR_DEFAULT_LOAD;
|
||||
const float vswrMaxReported = HF_VSWR_MAX_REPORTED;
|
||||
const float bridgeFwdVrect = HF_BRIDGE_FWD_VRECT;
|
||||
const float bridgeFwdTurns = HF_BRIDGE_FWD_TURNS;
|
||||
const float bridgeRevVrect = HF_BRIDGE_REV_VRECT;
|
||||
const float bridgeRevTurns = HF_BRIDGE_REV_TURNS;
|
||||
const unsigned adcDefaultBits = HF_ADC_DEFAULT_BITS;
|
||||
const float adcDefaultVref = HF_ADC_DEFAULT_VREF;
|
||||
|
||||
const float rms = sqrt(2.0) / 2.0;
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Calculate the output voltage of a resistive divider
|
||||
* network, given the input voltage and the values of the
|
||||
* resistors. The input voltage is applied to R1, the output
|
||||
* voltage is taken from the junction of R1 and R2, and R2 is
|
||||
* connected to ground.
|
||||
* @param Vin
|
||||
* Input voltage.
|
||||
* @param R1
|
||||
* Input resistor (ohms). Input voltage is measured between
|
||||
* the top of this resistor and ground.
|
||||
* @param R2
|
||||
* Output resistor (ohms). Output voltage is measured
|
||||
* between the top of this resistor and ground.
|
||||
* @return Output voltage.
|
||||
*/
|
||||
inline float divOut(float Vin, float R1, float R2) {
|
||||
return Vin * R2 / (R1 + R2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate the input voltage of a resistive divider
|
||||
* network, given the output voltage and the values of the
|
||||
* resistors. The input voltage is applied to R1, the output
|
||||
* voltage is taken from the junction of R1 and R2, and R2 is
|
||||
* connected to ground.
|
||||
* @param Vout
|
||||
* Output voltage.
|
||||
* @param R1
|
||||
* Input resistor (ohms). Input voltage is measured between
|
||||
* the top of this resistor and ground.
|
||||
* @param R2
|
||||
* Output resistor (ohms). Output voltage is measured between
|
||||
* the top of this resistor and ground.
|
||||
* @return Input voltage.
|
||||
*/
|
||||
inline float divIn(float Vout, float R1, float R2) {
|
||||
return Vout * (R1 + R2) / R2;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate and return the power in watts, given a
|
||||
* resistance and the voltage across the resistance.
|
||||
* @param V
|
||||
* Voltage across the load.
|
||||
* @param R
|
||||
* (optional) Resistance of the load (ohms). If not provided,
|
||||
* a default is used (HF_PWR_DEFAULT_LOAD).
|
||||
* @return Power dissipated (watts). This is calculated as
|
||||
* P = V^2/R.
|
||||
*/
|
||||
inline float P(float V, float R = pwrDefaultLoad) {
|
||||
return (V * V) / R;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate and return the Voltage Standing Wave Ratio
|
||||
* (VSWR) based on the given forward and reverse voltages.
|
||||
* @param Vfwd
|
||||
* Measured forward voltage.
|
||||
* @param Vrev
|
||||
* Measured reverse voltage.
|
||||
* @param VSWRmax
|
||||
* (optional) Maximum reported VSWR. The output will be
|
||||
* clamped to this value if necessary (HF_VSWR_MAX_REPORTED).
|
||||
* @return Voltage Standing Wave Ratio (VSWR). This is calculated
|
||||
* as VSWR = (Vfwd + Vrev) / (Vfwd - Vrev).
|
||||
*/
|
||||
inline float VSWR(float Vfwd, float Vrev, float VSWRmax = vswrMaxReported) {
|
||||
if (Vfwd - Vrev == 0.0) {
|
||||
return VSWRmax;
|
||||
} else {
|
||||
float swr = (Vfwd + Vrev) / (Vfwd - Vrev);
|
||||
return (swr > VSWRmax ? VSWRmax : swr);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate and return the forward RMS input voltage across
|
||||
* a Stockton bridge.
|
||||
* @param Vout
|
||||
* Rectified output voltage (e.g. read via an ADC).
|
||||
* @param Vrect
|
||||
* (optional) Voltage drop across the rectifier diode. If
|
||||
* not provided, a default is used (HF_BRIDGE_FWD_VRECT).
|
||||
* @param turns
|
||||
* (optional) Coupling transformer turns ratio. If not
|
||||
* provided, a default is used (HF_BRIDGE_FWD_TURNS).
|
||||
* @return Input voltage (i.e. the actual forward voltage).
|
||||
*/
|
||||
inline float bridgeFwd(float Vout, float Vrect = bridgeFwdVrect, float turns = bridgeFwdTurns) {
|
||||
return (Vout + Vrect) * turns * rms;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate and return the reverse RMS input voltage across
|
||||
* a Stockton bridge.
|
||||
* @param Vout
|
||||
* Rectified output voltage (e.g. read via an ADC).
|
||||
* @param Vrect
|
||||
* (optional) Voltage drop across the rectifier diode. If
|
||||
* not provided, a default is used (HF_BRIDGE_REV_VRECT).
|
||||
* @param turns
|
||||
* (optional) Coupling transformer turns ratio. If not
|
||||
* provided, a default is used (HF_BRIDGE_REV_TURNS).
|
||||
* @return Input voltage (i.e. the actual reverse voltage).
|
||||
*/
|
||||
inline float bridgeRev(float Vout, float Vrect = bridgeRevVrect, float turns = bridgeRevTurns) {
|
||||
return (Vout + Vrect) * turns * rms;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate and return the input voltage to an Analog-to-
|
||||
* Digital Converter (ADC) given the resolution (number of
|
||||
* bits) and the voltage reference of the ADC.
|
||||
* @param counts
|
||||
* Value of the ADC measurement (in unitless counts).
|
||||
* @param res
|
||||
* (optional) Resolution (in bits) of the ADC. If not
|
||||
* provided, the default is used (HF_ADC_DEFAULT_BITS).
|
||||
* @param Vref
|
||||
* (optional) Voltage reference of the ADC. If not
|
||||
* provided, the default is used (HF_ADC_DEFAULT_VREF).
|
||||
* @return Input voltage to the ADC.
|
||||
*/
|
||||
inline float adcIn(unsigned counts, unsigned res = adcDefaultBits, float Vref = adcDefaultVref) {
|
||||
return float(counts) * Vref / float(1 << res);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
141
TeensyDSP/Nextion.cpp
Normal file
141
TeensyDSP/Nextion.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include "Nextion.h"
|
||||
|
||||
char L_nowdisp = -1; //Sended nowdisp
|
||||
char L_vfoActive; //vfoActive
|
||||
unsigned long L_vfoCurr; //vfoA
|
||||
byte L_vfoCurr_mode; //vfoA_mode
|
||||
unsigned long L_vfoA; //vfoA
|
||||
byte L_vfoA_mode; //vfoA_mode
|
||||
unsigned long L_vfoB; //vfoB
|
||||
byte L_vfoB_mode; //vfoB_mode
|
||||
char L_ritOn;
|
||||
unsigned long L_ritTxFrequency; //ritTxFrequency
|
||||
char L_inTx;
|
||||
byte L_isDialLock; //byte isDialLock
|
||||
byte L_Split; //isTxType
|
||||
byte L_TXStop; //isTxType
|
||||
byte L_tuneStepIndex; //byte tuneStepIndex
|
||||
byte L_scaledSMeter; //scaledSMeter
|
||||
unsigned long L_sideTone; //sideTone
|
||||
byte L_cwKeyType; //L_cwKeyType 0: straight, 1 : iambica, 2: iambicb
|
||||
unsigned int L_cwSpeed; //cwSpeed
|
||||
byte L_cwDelayTime; //cwDelayTime
|
||||
byte L_delayBeforeCWStartTime; //byte delayBeforeCWStartTime
|
||||
byte L_attLevel;
|
||||
byte L_isIFShift; //1 = ifShift, 2 extend
|
||||
int L_ifShiftValue;
|
||||
byte L_sdrModeOn;
|
||||
byte scaledSMeter = 0;
|
||||
float calcVSWR = 0.0;
|
||||
float L_calcVSWR = 0.0;
|
||||
byte scaledVSWR = 0;
|
||||
byte L_scaledVSWR = 0;
|
||||
int fwdPower = 0;
|
||||
int L_fwdPower = 0;
|
||||
int revPower = 0;
|
||||
int L_revPower = 0;
|
||||
|
||||
|
||||
//Control must have prefix 'v' or 's'
|
||||
char softSTRHeader[11] = {'p', 'm', '.', 's', '0', '.', 't', 'x', 't', '=', '\"'};
|
||||
char softINTHeader[10] = {'p', 'm', '.', 'v', '0', '.', 'v', 'a', 'l', '='};
|
||||
|
||||
char softTemp[20];
|
||||
|
||||
/*!
|
||||
@brief Send a string or numeric variable to the Nextion LCD.
|
||||
@param varType
|
||||
The type of the variable being sent to the Nextion LCD.
|
||||
@param varIndex
|
||||
The index (ID) of the variable being sent to the Nextion LCD.
|
||||
*/
|
||||
void sendHeader(char varType, char varIndex)
|
||||
{
|
||||
if (varType == SWS_HEADER_STR_TYPE)
|
||||
{
|
||||
softSTRHeader[4] = varIndex;
|
||||
for (unsigned i = 0; i < sizeof(softSTRHeader)/sizeof(softSTRHeader[0]); i++)
|
||||
Serial1.write(softSTRHeader[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
softINTHeader[4] = varIndex;
|
||||
for (unsigned i = 0; i < sizeof(softINTHeader)/sizeof(softINTHeader[0]); i++)
|
||||
Serial1.write(softINTHeader[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Send an unsigned long variable to the Nextion LCD.
|
||||
@param varIndex
|
||||
The index (ID) of the variable being sent to the Nextion LCD.
|
||||
@param sendValue
|
||||
The value of the variable being sent to the Nextion LCD.
|
||||
*/
|
||||
void sendCommandUL(char varIndex, unsigned long sendValue)
|
||||
{
|
||||
sendHeader(SWS_HEADER_INT_TYPE, varIndex);
|
||||
|
||||
memset(softTemp, 0, 20);
|
||||
ultoa(sendValue, softTemp, DEC);
|
||||
Serial1.print(softTemp);
|
||||
Serial1.write(0xff);
|
||||
Serial1.write(0xff);
|
||||
Serial1.write(0xff);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Send a (signed) long variable to the Nextion LCD.
|
||||
@param varIndex
|
||||
The index (ID) of the variable being sent to the Nextion LCD.
|
||||
@param sendValue
|
||||
The value of the variable being sent to the Nextion LCD.
|
||||
*/
|
||||
void sendCommandL(char varIndex, long sendValue)
|
||||
{
|
||||
sendHeader(SWS_HEADER_INT_TYPE, varIndex);
|
||||
|
||||
memset(softTemp, 0, 20);
|
||||
ltoa(sendValue, softTemp, DEC);
|
||||
Serial1.print(softTemp);
|
||||
Serial1.write(0xff);
|
||||
Serial1.write(0xff);
|
||||
Serial1.write(0xff);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Send a string variable to the Nextion LCD.
|
||||
@param varIndex
|
||||
The index (ID) of the variable being sent to the Nextion LCD.
|
||||
@param sendValue
|
||||
The value of the variable being sent to the Nextion LCD.
|
||||
*/
|
||||
void sendCommandStr(char varIndex, const char* sendValue)
|
||||
{
|
||||
sendHeader(SWS_HEADER_STR_TYPE, varIndex);
|
||||
|
||||
Serial1.print(sendValue);
|
||||
Serial1.write('\"');
|
||||
Serial1.write(0xFF);
|
||||
Serial1.write(0xFF);
|
||||
Serial1.write(0xFF);
|
||||
}
|
||||
|
||||
unsigned char softBuff1Num[14] = {'p', 'm', '.', 'c', '0', '.', 'v', 'a', 'l', '=', 0, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
/*!
|
||||
@brief Send a single digit variable to the Nextion LCD.
|
||||
@param varIndex
|
||||
The index (ID) of the variable being sent to the Nextion LCD.
|
||||
Values 0~9 are: Mode, nowDisp, ActiveVFO, IsDialLock, IsTxtType, IsSplitType.
|
||||
@param sendValue
|
||||
The value of the variable being sent to the Nextion LCD.
|
||||
*/
|
||||
void sendCommand1Num(char varIndex, char sendValue)
|
||||
{
|
||||
softBuff1Num[4] = varIndex;
|
||||
softBuff1Num[10] = sendValue + 0x30; // convert to character digit
|
||||
|
||||
for (unsigned i = 0; i < sizeof(softBuff1Num)/sizeof(softBuff1Num[0]); i++)
|
||||
Serial1.write(softBuff1Num[i]);
|
||||
}
|
126
TeensyDSP/Nextion.h
Normal file
126
TeensyDSP/Nextion.h
Normal file
@ -0,0 +1,126 @@
|
||||
#ifndef __Nextion_h__
|
||||
#define __Nextion_h__
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Debug.h"
|
||||
|
||||
#define SWS_HEADER_CHAR_TYPE 'c' //1Byte Protocol Prefix
|
||||
#define SWS_HEADER_INT_TYPE 'v' //Numeric Protocol Prefex
|
||||
#define SWS_HEADER_STR_TYPE 's' //for TEXT Line compatiable Character LCD Control
|
||||
|
||||
//===================================================================
|
||||
//Begin of Nextion LCD Protocol
|
||||
//
|
||||
// v0~v9, va~vz : Numeric (Transceiver -> Nextion LCD)
|
||||
// s0~s9 : String (Text) (Transceiver -> Nextion LCD)
|
||||
// vlSendxxx, vloxxx: Reserve for Nextion (Nextion LCD -> Transceiver)
|
||||
//
|
||||
//===================================================================
|
||||
|
||||
#define CMD_NOW_DISP '0' //c0
|
||||
extern char L_nowdisp; //Sended nowdisp
|
||||
|
||||
#define CMD_VFO_TYPE 'v' //cv
|
||||
extern char L_vfoActive; //vfoActive
|
||||
|
||||
#define CMD_CURR_FREQ 'c' //vc
|
||||
extern unsigned long L_vfoCurr; //vfoA
|
||||
#define CMD_CURR_MODE 'c' //cc
|
||||
extern byte L_vfoCurr_mode; //vfoA_mode
|
||||
|
||||
#define CMD_VFOA_FREQ 'a' //va
|
||||
extern unsigned long L_vfoA; //vfoA
|
||||
#define CMD_VFOA_MODE 'a' //ca
|
||||
extern byte L_vfoA_mode; //vfoA_mode
|
||||
|
||||
#define CMD_VFOB_FREQ 'b' //vb
|
||||
extern unsigned long L_vfoB; //vfoB
|
||||
#define CMD_VFOB_MODE 'b' //cb
|
||||
extern byte L_vfoB_mode; //vfoB_mode
|
||||
|
||||
#define CMD_IS_RIT 'r' //cr
|
||||
extern char L_ritOn;
|
||||
#define CMD_RIT_FREQ 'r' //vr
|
||||
extern unsigned long L_ritTxFrequency; //ritTxFrequency
|
||||
|
||||
#define CMD_IS_TX 't' //ct
|
||||
extern char L_inTx;
|
||||
|
||||
#define CMD_IS_DIALLOCK 'l' //cl
|
||||
extern byte L_isDialLock; //byte isDialLock
|
||||
|
||||
#define CMD_IS_SPLIT 's' //cs
|
||||
extern byte L_Split; //isTxType
|
||||
#define CMD_IS_TXSTOP 'x' //cx
|
||||
extern byte L_TXStop; //isTxType
|
||||
|
||||
#define CMD_TUNEINDEX 'n' //cn
|
||||
extern byte L_tuneStepIndex; //byte tuneStepIndex
|
||||
|
||||
#define CMD_SMETER 'p' //cs
|
||||
extern byte L_scaledSMeter; //scaledSMeter
|
||||
|
||||
#define CMD_SIDE_TONE 't' //vt
|
||||
extern unsigned long L_sideTone; //sideTone
|
||||
#define CMD_KEY_TYPE 'k' //ck
|
||||
extern byte L_cwKeyType; //L_cwKeyType 0: straight, 1 : iambica, 2: iambicb
|
||||
|
||||
#define CMD_CW_SPEED 's' //vs
|
||||
extern unsigned int L_cwSpeed; //cwSpeed
|
||||
|
||||
#define CMD_CW_DELAY 'y' //vy
|
||||
extern byte L_cwDelayTime; //cwDelayTime
|
||||
|
||||
#define CMD_CW_STARTDELAY 'e' //ve
|
||||
extern byte L_delayBeforeCWStartTime; //byte delayBeforeCWStartTime
|
||||
|
||||
#define CMD_ATT_LEVEL 'f' //vf
|
||||
extern byte L_attLevel;
|
||||
|
||||
extern byte L_isIFShift; //1 = ifShift, 2 extend
|
||||
#define CMD_IS_IFSHIFT 'i' //ci
|
||||
|
||||
extern int L_ifShiftValue;
|
||||
#define CMD_IFSHIFT_VALUE 'i' //vi
|
||||
|
||||
extern byte L_sdrModeOn;
|
||||
#define CMD_SDR_MODE 'j' //cj
|
||||
|
||||
#define CMD_UBITX_INFO 'm' //cm Complete Send uBITX Information
|
||||
|
||||
//Once Send Data, When boot
|
||||
//arTuneStep, When boot, once send
|
||||
//long arTuneStep[5];
|
||||
|
||||
#define CMD_AR_TUNE1 '1' //v1
|
||||
#define CMD_AR_TUNE2 '2' //v2
|
||||
#define CMD_AR_TUNE3 '3' //v3
|
||||
#define CMD_AR_TUNE4 '4' //v4
|
||||
#define CMD_AR_TUNE5 '5' //v5
|
||||
|
||||
//int idleStep = 0;
|
||||
extern byte scaledSMeter;
|
||||
|
||||
extern float calcVSWR;
|
||||
extern float L_calcVSWR;
|
||||
|
||||
extern byte scaledVSWR;
|
||||
extern byte L_scaledVSWR;
|
||||
|
||||
extern int fwdPower;
|
||||
extern int L_fwdPower;
|
||||
|
||||
extern int revPower;
|
||||
extern int L_revPower;
|
||||
|
||||
void sendHeader(char varType, char varIndex);
|
||||
void sendCommandUL(char varIndex, unsigned long sendValue);
|
||||
void sendCommandL(char varIndex, long sendValue);
|
||||
void sendCommandStr(char varIndex, const char* sendValue);
|
||||
void sendCommand1Num(char varIndex, char sendValue);
|
||||
|
||||
//=======================================================
|
||||
//END OF Nextion Protocol
|
||||
//=======================================================
|
||||
|
||||
#endif
|
5
TeensyDSP/Sensors.cpp
Normal file
5
TeensyDSP/Sensors.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "Sensors.h"
|
||||
|
||||
UBitxSensors Sensors;
|
||||
|
||||
ADC adc;
|
342
TeensyDSP/Sensors.h
Normal file
342
TeensyDSP/Sensors.h
Normal file
@ -0,0 +1,342 @@
|
||||
#ifndef __Sensor_h__
|
||||
#define __Sensor_h__
|
||||
|
||||
#include <ADC.h>
|
||||
#include "Debug.h"
|
||||
#include "HamFuncs.h"
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_PIN
|
||||
#define UBITX_SENSORS_S_METER_PIN 27
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_FWD_PWR_PIN
|
||||
#define UBITX_SENSORS_FWD_PWR_PIN 20
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_REV_PWR_PIN
|
||||
#define UBITX_SENSORS_REV_PWR_PIN 28
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_SUPPLY_PIN
|
||||
#define UBITX_SENSORS_SUPPLY_PIN 21
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_AVG_SAMPLES
|
||||
#define UBITX_SENSORS_AVG_SAMPLES 16
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_R1
|
||||
#define UBITX_SENSORS_S_METER_R1 22000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_R2
|
||||
#define UBITX_SENSORS_S_METER_R2 33000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_FWD_PWR_R1
|
||||
#define UBITX_SENSORS_FWD_PWR_R1 22000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_FWD_PWR_R2
|
||||
#define UBITX_SENSORS_FWD_PWR_R2 33000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_REV_PWR_R1
|
||||
#define UBITX_SENSORS_REV_PWR_R1 22000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_REV_PWR_R2
|
||||
#define UBITX_SENSORS_REV_PWR_R2 33000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_SUPPLY_R1
|
||||
#define UBITX_SENSORS_SUPPLY_R1 56000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_SUPPLY_R2
|
||||
#define UBITX_SENSORS_SUPPLY_R2 10000.0
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL0
|
||||
#define UBITX_SENSORS_S_METER_LVL0 2
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL1
|
||||
#define UBITX_SENSORS_S_METER_LVL1 4
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL2
|
||||
#define UBITX_SENSORS_S_METER_LVL2 8
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL3
|
||||
#define UBITX_SENSORS_S_METER_LVL3 16
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL4
|
||||
#define UBITX_SENSORS_S_METER_LVL4 32
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL5
|
||||
#define UBITX_SENSORS_S_METER_LVL5 64
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL6
|
||||
#define UBITX_SENSORS_S_METER_LVL6 128
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL7
|
||||
#define UBITX_SENSORS_S_METER_LVL7 256
|
||||
#endif
|
||||
|
||||
#ifndef UBITX_SENSORS_S_METER_LVL8
|
||||
#define UBITX_SENSORS_S_METER_LVL8 512
|
||||
#endif
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
const int uBitxSensorsSMeterPin = UBITX_SENSORS_S_METER_PIN;
|
||||
const int uBitxSensorsFwdPwrPin = UBITX_SENSORS_FWD_PWR_PIN;
|
||||
const int uBitxSensorsRevPwrPin = UBITX_SENSORS_REV_PWR_PIN;
|
||||
const int uBitxSensorsSupplyPin = UBITX_SENSORS_SUPPLY_PIN;
|
||||
const int uBitxSensorsAvgSamples = UBITX_SENSORS_AVG_SAMPLES;
|
||||
const float uBitxSensorsSMeterR1 = UBITX_SENSORS_S_METER_R1;
|
||||
const float uBitxSensorsSMeterR2 = UBITX_SENSORS_S_METER_R2;
|
||||
const float uBitxSensorsFwdPwrR1 = UBITX_SENSORS_FWD_PWR_R1;
|
||||
const float uBitxSensorsFwdPwrR2 = UBITX_SENSORS_FWD_PWR_R2;
|
||||
const float uBitxSensorsRevPwrR1 = UBITX_SENSORS_REV_PWR_R1;
|
||||
const float uBitxSensorsRevPwrR2 = UBITX_SENSORS_REV_PWR_R2;
|
||||
const float uBitxSensorsSupplyR1 = UBITX_SENSORS_SUPPLY_R1;
|
||||
const float uBitxSensorsSupplyR2 = UBITX_SENSORS_SUPPLY_R2;
|
||||
|
||||
const int uBitxSensorsSMeterValues[] = {
|
||||
UBITX_SENSORS_S_METER_LVL0,
|
||||
UBITX_SENSORS_S_METER_LVL1,
|
||||
UBITX_SENSORS_S_METER_LVL2,
|
||||
UBITX_SENSORS_S_METER_LVL3,
|
||||
UBITX_SENSORS_S_METER_LVL4,
|
||||
UBITX_SENSORS_S_METER_LVL5,
|
||||
UBITX_SENSORS_S_METER_LVL6,
|
||||
UBITX_SENSORS_S_METER_LVL7,
|
||||
UBITX_SENSORS_S_METER_LVL8
|
||||
};
|
||||
|
||||
const int uBitxSensorsSMeterLevels = sizeof(uBitxSensorsSMeterValues) /
|
||||
sizeof(uBitxSensorsSMeterValues[0]);
|
||||
|
||||
extern ADC adc;
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Class that maintains a "trailing average" of the last X
|
||||
* samples provided. It is a template that can be instantiated
|
||||
* with both the (numeric) data type that is being stored and
|
||||
* averaged, as well as the number of samples to maintain the
|
||||
* trailing average across.
|
||||
*/
|
||||
template <typename T, int N>
|
||||
class TrailingAverage {
|
||||
public:
|
||||
/*!
|
||||
* @brief Create a new TrailingAverage object. Data type averaged,
|
||||
* and number of elements to average, are determined when the
|
||||
* template is instantiated.
|
||||
*/
|
||||
TrailingAverage():
|
||||
average(T(0)),
|
||||
current(0),
|
||||
divisor(T(N))
|
||||
{
|
||||
for (int i = 0; i < N; i++) {
|
||||
data[i] = T(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Add a new element to the average. The current last (Nth)
|
||||
* element is removed, and the new element is added.
|
||||
* @param val
|
||||
* The new element/value to incorporate into the average.
|
||||
*/
|
||||
inline void add(T val) {
|
||||
int last = (current - 1) % N;
|
||||
average -= data[last];
|
||||
current = (current + 1) % N;
|
||||
average += data[current] / divisor;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read the current value of the average.
|
||||
* @return The current average.
|
||||
*/
|
||||
inline T read() {
|
||||
return average;
|
||||
}
|
||||
|
||||
private:
|
||||
T data[N];
|
||||
T average;
|
||||
int current;
|
||||
T divisor;
|
||||
};
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Class that handles the various sensors in the uBitx:
|
||||
* S-Meter, forward/reverse power and SWR, and supply voltage.
|
||||
*/
|
||||
class UBitxSensors {
|
||||
public:
|
||||
/*!
|
||||
* @brief Create a new UBitxSensors object. It uses the default
|
||||
* S-Meter, Forward Power, Reverse Power, and Supply Voltage
|
||||
* ADC pins.
|
||||
*/
|
||||
UBitxSensors():
|
||||
sMeterPin(uBitxSensorsSMeterPin),
|
||||
fwdPwrPin(uBitxSensorsFwdPwrPin),
|
||||
revPwrPin(uBitxSensorsRevPwrPin),
|
||||
supplyPin(uBitxSensorsSupplyPin)
|
||||
{
|
||||
pinMode(sMeterPin, INPUT); // analog
|
||||
pinMode(fwdPwrPin, INPUT); // analog
|
||||
pinMode(revPwrPin, INPUT); // analog
|
||||
pinMode(supplyPin, INPUT); // analog
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Update the value of the S-Meter by reading the associated
|
||||
* ADC pin.
|
||||
*/
|
||||
inline void updateSMeter() {
|
||||
int value = adc.analogRead(sMeterPin);
|
||||
sMeter.add(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Update the value of the Forward and Reverse Power
|
||||
* measurements by reading the associated ADC pin.
|
||||
*/
|
||||
void updatePower() {
|
||||
ADC::Sync_result value = adc.analogSyncRead(fwdPwrPin, revPwrPin);
|
||||
|
||||
float fwdV = HF::adcIn(value.result_adc0);
|
||||
float revV = HF::adcIn(value.result_adc1);
|
||||
|
||||
fwdV = HF::divIn(fwdV, uBitxSensorsFwdPwrR1, uBitxSensorsFwdPwrR2);
|
||||
fwdV = HF::bridgeFwd(fwdV);
|
||||
|
||||
revV = HF::divIn(revV, uBitxSensorsRevPwrR1, uBitxSensorsRevPwrR2);
|
||||
revV = HF::bridgeFwd(revV);
|
||||
|
||||
fwdPwr.add(HF::P(fwdV));
|
||||
revPwr.add(HF::P(revV));
|
||||
vswr.add(HF::VSWR(fwdV, revV));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Update the value of the Supply Voltage measurement by
|
||||
* reading the associated ADC pin.
|
||||
*/
|
||||
inline void updateSupply() {
|
||||
float value = HF::adcIn(adc.analogRead(supplyPin));
|
||||
value = HF::divIn(value, uBitxSensorsSupplyR1, uBitxSensorsSupplyR2);
|
||||
supply.add(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the unscaled value of the S-Meter reading.
|
||||
* @return Unscaled S-Meter reading.
|
||||
*/
|
||||
inline int sMeterUnscaled() {
|
||||
return sMeter.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the scaled value of the S-Meter reading. This
|
||||
* is the value that is used to directly control the S-Meter
|
||||
* display on the Nextion LCD.
|
||||
* @return Scaled S-Meter reading.
|
||||
*/
|
||||
int sMeterScaled() {
|
||||
float sig = sMeter.read();
|
||||
// small number of elements; just doing a linear search
|
||||
for (int i = uBitxSensorsSMeterLevels; i > 0; i--) {
|
||||
if (sig > uBitxSensorsSMeterValues[i - 1]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the current Forward Power measurement.
|
||||
* @return Forward Power measurement.
|
||||
*/
|
||||
inline float Pfwd() {
|
||||
return fwdPwr.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the current Reverse Power measurement.
|
||||
* @return Reverse Power measurement.
|
||||
*/
|
||||
inline float Prev() {
|
||||
return revPwr.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the current Voltage Standing Wave Ration (VSWR).
|
||||
* @return Current VSWR calculation.
|
||||
*/
|
||||
inline float VSWR() {
|
||||
return vswr.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the current Voltage Standing Wave Ration (VSWR),
|
||||
* scaled for the Nextion display protocol.
|
||||
* @return Current VSWR calculation (scaled).
|
||||
*/
|
||||
float scaledVSWR() {
|
||||
int val = int(vswr.read());
|
||||
if (val < 0) {
|
||||
return 0;
|
||||
} else if (val > uBitxSensorsSMeterLevels) {
|
||||
return uBitxSensorsSMeterLevels;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Return the current Supply Voltage measurement.
|
||||
* @return Current Supply Voltage.
|
||||
*/
|
||||
inline float supplyVoltage() {
|
||||
return supply.read();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Pins
|
||||
int sMeterPin;
|
||||
int fwdPwrPin;
|
||||
int revPwrPin;
|
||||
int supplyPin;
|
||||
|
||||
// Buffers for averages
|
||||
TrailingAverage<int, uBitxSensorsAvgSamples> sMeter;
|
||||
TrailingAverage<float, uBitxSensorsAvgSamples> fwdPwr;
|
||||
TrailingAverage<float, uBitxSensorsAvgSamples> revPwr;
|
||||
TrailingAverage<float, uBitxSensorsAvgSamples> vswr;
|
||||
TrailingAverage<float, uBitxSensorsAvgSamples> supply;
|
||||
};
|
||||
|
||||
extern UBitxSensors Sensors;
|
||||
|
||||
#endif
|
45
TeensyDSP/TR.cpp
Normal file
45
TeensyDSP/TR.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
//======================================================================
|
||||
// TR.cpp
|
||||
//======================================================================
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "TR.h"
|
||||
|
||||
UBitxTR TR(DSP);
|
||||
|
||||
void UBitxTR::update(bool cw) {
|
||||
updatePTT();
|
||||
updateVOX();
|
||||
updateKey();
|
||||
|
||||
if (isTX) {
|
||||
// If we are currently transmitting, then ANY T/R release (key
|
||||
// release) will result in exitting transmit... except for VOX
|
||||
// and CAT which can only function as a release if it was enabled.
|
||||
if (pttReleased() || keyReleased() ||
|
||||
(voxEnabled && voxDeactivated()) ||
|
||||
(catEnabled && catDeactivated())) {
|
||||
// first, stop transmitting; then, setup RX audio
|
||||
DBGCMD( setRX() );
|
||||
DBGCMD( dsp.rx() );
|
||||
}
|
||||
} else {
|
||||
if ((pttEnabled && pttPressed()) || (voxEnabled && voxActivated())) {
|
||||
// first, setup TX audio; then, start transmitting (from Mic)
|
||||
DBGCMD( dsp.txMicIn() );
|
||||
DBGCMD( setTX() );
|
||||
} else if (keyEnabled && keyPressed()) {
|
||||
// first, setup TX audio; then, start transmitting (from Line In)
|
||||
DBGCMD( dsp.txLineIn() );
|
||||
DBGCMD( setTX() );
|
||||
} else if (catEnabled && catActivated()) {
|
||||
// first, setup TX audio; then, start transmitting (USB)
|
||||
DBGCMD( dsp.txUSBIn() );
|
||||
DBGCMD( setTX() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
169
TeensyDSP/TR.h
Normal file
169
TeensyDSP/TR.h
Normal file
@ -0,0 +1,169 @@
|
||||
//======================================================================
|
||||
// TR.h
|
||||
//======================================================================
|
||||
|
||||
#ifndef __TR_h__
|
||||
#define __TR_h__
|
||||
|
||||
#include <Bounce2.h>
|
||||
#include "Debug.h"
|
||||
#include "DSP.h"
|
||||
|
||||
#define UBITX_TR_OUT_PIN 2
|
||||
#define UBITX_TR_PTT_PIN 3
|
||||
#define UBITX_TR_VOX_PIN 4
|
||||
#define UBITX_TR_KEY_PIN 5
|
||||
|
||||
const int uBitxTROutPin = UBITX_TR_OUT_PIN;
|
||||
const int uBitxTRPttPin = UBITX_TR_PTT_PIN;
|
||||
const int uBitxTRVoxPin = UBITX_TR_VOX_PIN;
|
||||
const int uBitxTRKeyPin = UBITX_TR_KEY_PIN;
|
||||
|
||||
class UBitxTR {
|
||||
public:
|
||||
UBitxTR(UBitxDSP& d, int out = uBitxTROutPin, int p = uBitxTRPttPin, int v = uBitxTRVoxPin, int k = uBitxTRKeyPin):
|
||||
dsp(d), outPin(out), pttPin(p), voxPin(v), keyPin(k) {}
|
||||
|
||||
void begin() {
|
||||
pinMode(outPin, OUTPUT);
|
||||
pinMode(voxPin, INPUT_PULLUP);
|
||||
pinMode(keyPin, INPUT_PULLUP);
|
||||
ptt.attach(pttPin, INPUT_PULLUP);
|
||||
ptt.interval(5);
|
||||
|
||||
// default configuration: PTT, key, and CAT enabled; VOX disabled
|
||||
DBGCMD( enablePTT() );
|
||||
DBGCMD( disableVOX() );
|
||||
DBGCMD( enableKey() );
|
||||
DBGCMD( enableCAT() );
|
||||
}
|
||||
|
||||
inline void enablePTT() { pttEnabled = true; }
|
||||
inline void enableVOX() { voxEnabled = true; }
|
||||
inline void enableKey() { keyEnabled = true; }
|
||||
inline void enableCAT() { catEnabled = true; }
|
||||
inline void disablePTT() { pttEnabled = false; }
|
||||
inline void disableVOX() { voxEnabled = false; }
|
||||
inline void disableKey() { keyEnabled = false; }
|
||||
inline void disableCAT() { catEnabled = false; }
|
||||
|
||||
|
||||
inline void catTX() {
|
||||
L_catActive = catActive;
|
||||
catActive = true;
|
||||
}
|
||||
|
||||
inline void catRX() {
|
||||
L_catActive = catActive;
|
||||
catActive = false;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
inline bool transmitting() { return isTX; }
|
||||
inline bool receiving() { return !isTX; }
|
||||
|
||||
/*!
|
||||
* @brief Check if any of the PTT's have been pressed or released
|
||||
* since the last update. Only one thing is allowed to occur
|
||||
* based on an order of precedence. The highest priority is
|
||||
* to stop transmitting.
|
||||
*
|
||||
* @param cw
|
||||
* True if CW mode is currently active; false otherwise.
|
||||
* Different/faster logic is used in CW mode.
|
||||
*/
|
||||
void update(bool cw = false);
|
||||
|
||||
void end() {
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline void setTX() {
|
||||
digitalWrite(outPin, LOW);
|
||||
isTX = true;
|
||||
}
|
||||
|
||||
inline void setRX() {
|
||||
isTX = false;
|
||||
digitalWrite(outPin, HIGH);
|
||||
}
|
||||
|
||||
inline void updatePTT() {
|
||||
ptt.update();
|
||||
}
|
||||
|
||||
inline bool pttPressed() {
|
||||
return ptt.fell();
|
||||
}
|
||||
|
||||
inline bool pttReleased() {
|
||||
return ptt.rose();
|
||||
}
|
||||
|
||||
inline void updateVOX() {
|
||||
L_voxActive = voxActive;
|
||||
voxActive = (digitalRead(voxPin) == LOW);
|
||||
}
|
||||
|
||||
inline bool voxActivated() {
|
||||
return (L_voxActive != voxActive) && L_voxActive;
|
||||
}
|
||||
|
||||
inline bool voxDeactivated() {
|
||||
return (L_voxActive != voxActive) && voxActive;
|
||||
}
|
||||
|
||||
inline void updateKey() {
|
||||
L_keyDown = keyDown;
|
||||
keyDown = (digitalRead(keyPin) == LOW);
|
||||
}
|
||||
|
||||
inline bool keyPressed() {
|
||||
return (L_keyDown != keyDown) && L_keyDown;
|
||||
}
|
||||
|
||||
inline bool keyReleased() {
|
||||
return (L_keyDown != keyDown) && keyDown;
|
||||
}
|
||||
|
||||
inline bool catActivated() {
|
||||
return (L_catActive != catActive) && L_catActive;
|
||||
}
|
||||
|
||||
inline bool catDeactivated() {
|
||||
return (L_catActive != catActive) && catActive;
|
||||
}
|
||||
|
||||
UBitxDSP& dsp;
|
||||
|
||||
Bounce ptt;
|
||||
|
||||
int outPin;
|
||||
int pttPin;
|
||||
int voxPin;
|
||||
int keyPin;
|
||||
|
||||
bool isTX = false;
|
||||
|
||||
bool pttEnabled = false;
|
||||
bool voxEnabled = false;
|
||||
bool keyEnabled = false;
|
||||
bool catEnabled = false;
|
||||
|
||||
bool voxActive = false;
|
||||
bool L_voxActive = false;
|
||||
bool keyDown = false;
|
||||
bool L_keyDown = false;
|
||||
bool catActive = false;
|
||||
bool L_catActive = false;
|
||||
};
|
||||
|
||||
extern UBitxTR TR;
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
@ -7,30 +7,23 @@ KD8CEC, Ian Lee
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include <arduino.h>
|
||||
#include <Arduino.h>
|
||||
#include "Debug.h"
|
||||
#include "DSP.h"
|
||||
#include "Nextion.h"
|
||||
#include "Sensors.h"
|
||||
#include "TR.h"
|
||||
|
||||
//================================================================
|
||||
//COMMUNICATION SECTION
|
||||
//================================================================
|
||||
#define USE_SW_SERIAL
|
||||
|
||||
extern void SWSerial_Write(uint8_t b);
|
||||
extern void SWSerial_Print(uint8_t *b);
|
||||
|
||||
#ifdef USE_SW_SERIAL
|
||||
extern void SWSerial_Begin(long speedBaud);
|
||||
extern int SWSerial_Available(void);
|
||||
extern int SWSerial_Read(void);
|
||||
#else
|
||||
|
||||
#define PRINT_MAX_LENGTH 30
|
||||
#endif
|
||||
|
||||
//================================================================
|
||||
//FFT and Decode Morse
|
||||
// FFT and Decode Morse
|
||||
//================================================================
|
||||
|
||||
#define FFTSIZE 64
|
||||
#define SAMPLE_PREQUENCY 6000
|
||||
#define SAMPLE_FREQUENCY 6000
|
||||
#define SAMPLESIZE (FFTSIZE * 2)
|
||||
#define DECODE_MORSE_SAMPLESIZE 48
|
||||
|
||||
@ -38,8 +31,9 @@ extern uint8_t cwDecodeHz;
|
||||
extern int magnitudelimit_low;
|
||||
|
||||
//================================================================
|
||||
//EEPROM Section
|
||||
// EEPROM Section
|
||||
//================================================================
|
||||
|
||||
#define MAX_FORWARD_BUFF_LENGTH 128
|
||||
#define EEPROM_DSPTYPE 100
|
||||
#define EEPROM_SMETER_UART 111
|
||||
@ -52,8 +46,9 @@ extern int magnitudelimit_low;
|
||||
#define EEPROM_RTTYDECODEHZ 130
|
||||
|
||||
//================================================================
|
||||
//DEFINE for I2C Command
|
||||
// DEFINE for I2C Command
|
||||
//================================================================
|
||||
|
||||
//S-Meter Address
|
||||
#define I2CMETER_ADDR 0x58 //changed from 0x6A
|
||||
//VALUE TYPE============================================
|
||||
@ -68,9 +63,3 @@ extern int magnitudelimit_low;
|
||||
//SWR
|
||||
#define I2CMETER_CALCR 0x55 //Calculated SWR Meter
|
||||
#define I2CMETER_UNCALCR 0x54 //Uncalculated SWR Meter
|
||||
|
||||
#define SIGNAL_METER_ADC A7
|
||||
#define POWER_METER_ADC A3
|
||||
#define SWR_METER_ADC A2
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,362 +0,0 @@
|
||||
/*
|
||||
FFTFunctions for Nextion LCD and Control MCU
|
||||
This code is for FFT and CW Decode.
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
//The section on CW decode logic is specified at the bottom of this code.
|
||||
License : I follow the license of the previous code and I do not add any extra constraints.
|
||||
I hope that the Comment I made or the Comment of OZ1JHM will be maintained.
|
||||
**********************************************************************/
|
||||
#include <arduino.h>
|
||||
#include "TeensyDSP.h"
|
||||
|
||||
// Code Referency : http://paulbourke.net/miscellaneous/dft/
|
||||
// DFT, FFT Wiritten by Paul Bourke, June 1993
|
||||
void FFT(double *x,double *y, int n, long m)
|
||||
{
|
||||
long i,i1,j,k,i2,l,l1,l2;
|
||||
double c1,c2,tx,ty,t1,t2,u1,u2,z;
|
||||
short int dir = 0;
|
||||
|
||||
/* Do the bit reversal */
|
||||
i2 = n >> 1;
|
||||
j = 0;
|
||||
for (i=0;i<n-1;i++) {
|
||||
if (i < j) {
|
||||
tx = x[i];
|
||||
ty = y[i];
|
||||
x[i] = x[j];
|
||||
y[i] = y[j];
|
||||
x[j] = tx;
|
||||
y[j] = ty;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j -= k;
|
||||
k >>= 1;
|
||||
}
|
||||
j += k;
|
||||
}
|
||||
|
||||
/* Compute the FFT */
|
||||
c1 = -1.0;
|
||||
c2 = 0.0;
|
||||
l2 = 1;
|
||||
|
||||
for (l=0;l<m;l++)
|
||||
{
|
||||
l1 = l2;
|
||||
l2 <<= 1;
|
||||
u1 = 1.0;
|
||||
u2 = 0.0;
|
||||
for (j=0;j<l1;j++)
|
||||
{
|
||||
for (i=j;i<n;i+=l2)
|
||||
{
|
||||
i1 = i + l1;
|
||||
t1 = u1 * x[i1] - u2 * y[i1];
|
||||
t2 = u1 * y[i1] + u2 * x[i1];
|
||||
x[i1] = x[i] - t1;
|
||||
y[i1] = y[i] - t2;
|
||||
x[i] += t1;
|
||||
y[i] += t2;
|
||||
}
|
||||
z = u1 * c1 - u2 * c2;
|
||||
u2 = u1 * c2 + u2 * c1;
|
||||
u1 = z;
|
||||
}
|
||||
c2 = sqrt((1.0 - c1) / 2.0);
|
||||
if (dir == 1)
|
||||
c2 = -c2;
|
||||
c1 = sqrt((1.0 + c1) / 2.0);
|
||||
}
|
||||
|
||||
/* Scaling for forward transform */
|
||||
/*
|
||||
if (dir == 1) {
|
||||
for (i=0;i<n;i++) {
|
||||
x[i] /= n;
|
||||
y[i] /= n;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
*/
|
||||
|
||||
//return(TRUE);
|
||||
}
|
||||
|
||||
double coeff;
|
||||
|
||||
void CalculateCoeff(uint8_t freqIndex)
|
||||
{
|
||||
float omega;
|
||||
int targetFrequency = freqIndex * 50 + 300;
|
||||
int k = (int) (0.5 + ((DECODE_MORSE_SAMPLESIZE * targetFrequency) / SAMPLE_PREQUENCY));
|
||||
omega = (2.0 * PI * k) / DECODE_MORSE_SAMPLESIZE;
|
||||
coeff = 2.0 * cos(omega);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//The CW Decode code refers to the site code below.
|
||||
//https://k2jji.org/2014/09/18/arduino-base-cw-decoder/
|
||||
//Some code has been modified, but the original comments remain intact.
|
||||
// code below is optimal for use in Arduino.
|
||||
//Thanks to OZ1JHM
|
||||
//KD8CEC
|
||||
//=====================================================================
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CW Decoder made by Hjalmar Skovholm Hansen OZ1JHM VER 1.01 //
|
||||
// Feel free to change, copy or what ever you like but respect //
|
||||
// that license is http://www.gnu.org/copyleft/gpl.html //
|
||||
// Discuss and give great ideas on //
|
||||
// https://groups.yahoo.com/neo/groups/oz1jhm/conversations/messages //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Read more here http://en.wikipedia.org/wiki/Goertzel_algorithm //
|
||||
// if you want to know about FFT the http://www.dspguide.com/pdfbook.htm //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//int magnitudelimit = 50;
|
||||
//int magnitudelimit_low = 50;
|
||||
int magnitudelimit = 30;
|
||||
int magnitudelimit_low = 30;
|
||||
char realstate = LOW;
|
||||
char realstatebefore = LOW;
|
||||
char filteredstate = LOW;
|
||||
char filteredstatebefore = LOW;
|
||||
long laststarttime = 0;
|
||||
int nbtime = 6; /// ms noise blanker
|
||||
|
||||
long starttimehigh;
|
||||
long highduration;
|
||||
long lasthighduration;
|
||||
long hightimesavg;
|
||||
long lowtimesavg;
|
||||
long startttimelow;
|
||||
long lowduration;
|
||||
|
||||
char code[20];
|
||||
uint8_t stop = LOW;
|
||||
int wpm;
|
||||
uint8_t cwDecodeHz = 9;
|
||||
|
||||
extern void SendCommandStr(char varIndex, char* sendValue);
|
||||
|
||||
void printascii(int asciinumber)
|
||||
{
|
||||
char rstDecode[4] = {0, 0, 0, 0};
|
||||
|
||||
if (asciinumber == 3)
|
||||
{
|
||||
|
||||
}
|
||||
else if (asciinumber == 4)
|
||||
{
|
||||
|
||||
}
|
||||
else if (asciinumber == 6)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
rstDecode[0] = asciinumber;
|
||||
}
|
||||
SendCommandStr('b', rstDecode);
|
||||
|
||||
//Serial.write(asciinumber);
|
||||
//if (writeCount++ > 20)
|
||||
//{
|
||||
//writeCount = 0;
|
||||
//Serial.println("");
|
||||
//}
|
||||
}
|
||||
|
||||
uint8_t docode()
|
||||
{
|
||||
if (strcmp(code,".-") == 0) printascii(65);
|
||||
if (strcmp(code,"-...") == 0) printascii(66);
|
||||
if (strcmp(code,"-.-.") == 0) printascii(67);
|
||||
if (strcmp(code,"-..") == 0) printascii(68);
|
||||
if (strcmp(code,".") == 0) printascii(69);
|
||||
if (strcmp(code,"..-.") == 0) printascii(70);
|
||||
if (strcmp(code,"--.") == 0) printascii(71);
|
||||
if (strcmp(code,"....") == 0) printascii(72);
|
||||
if (strcmp(code,"..") == 0) printascii(73);
|
||||
if (strcmp(code,".---") == 0) printascii(74);
|
||||
if (strcmp(code,"-.-") == 0) printascii(75);
|
||||
if (strcmp(code,".-..") == 0) printascii(76);
|
||||
if (strcmp(code,"--") == 0) printascii(77);
|
||||
if (strcmp(code,"-.") == 0) printascii(78);
|
||||
if (strcmp(code,"---") == 0) printascii(79);
|
||||
if (strcmp(code,".--.") == 0) printascii(80);
|
||||
if (strcmp(code,"--.-") == 0) printascii(81);
|
||||
if (strcmp(code,".-.") == 0) printascii(82);
|
||||
if (strcmp(code,"...") == 0) printascii(83);
|
||||
if (strcmp(code,"-") == 0) printascii(84);
|
||||
if (strcmp(code,"..-") == 0) printascii(85);
|
||||
if (strcmp(code,"...-") == 0) printascii(86);
|
||||
if (strcmp(code,".--") == 0) printascii(87);
|
||||
if (strcmp(code,"-..-") == 0) printascii(88);
|
||||
if (strcmp(code,"-.--") == 0) printascii(89);
|
||||
if (strcmp(code,"--..") == 0) printascii(90);
|
||||
|
||||
if (strcmp(code,".----") == 0) printascii(49);
|
||||
if (strcmp(code,"..---") == 0) printascii(50);
|
||||
if (strcmp(code,"...--") == 0) printascii(51);
|
||||
if (strcmp(code,"....-") == 0) printascii(52);
|
||||
if (strcmp(code,".....") == 0) printascii(53);
|
||||
if (strcmp(code,"-....") == 0) printascii(54);
|
||||
if (strcmp(code,"--...") == 0) printascii(55);
|
||||
if (strcmp(code,"---..") == 0) printascii(56);
|
||||
if (strcmp(code,"----.") == 0) printascii(57);
|
||||
if (strcmp(code,"-----") == 0) printascii(48);
|
||||
|
||||
if (strcmp(code,"..--..") == 0) printascii(63);
|
||||
if (strcmp(code,".-.-.-") == 0) printascii(46);
|
||||
if (strcmp(code,"--..--") == 0) printascii(44);
|
||||
if (strcmp(code,"-.-.--") == 0) printascii(33);
|
||||
if (strcmp(code,".--.-.") == 0) printascii(64);
|
||||
if (strcmp(code,"---...") == 0) printascii(58);
|
||||
if (strcmp(code,"-....-") == 0) printascii(45);
|
||||
if (strcmp(code,"-..-.") == 0) printascii(47);
|
||||
|
||||
if (strcmp(code,"-.--.") == 0) printascii(40);
|
||||
if (strcmp(code,"-.--.-") == 0) printascii(41);
|
||||
if (strcmp(code,".-...") == 0) printascii(95);
|
||||
if (strcmp(code,"...-..-") == 0) printascii(36);
|
||||
if (strcmp(code,"...-.-") == 0) printascii(62);
|
||||
if (strcmp(code,".-.-.") == 0) printascii(60);
|
||||
if (strcmp(code,"...-.") == 0) printascii(126);
|
||||
//////////////////
|
||||
// The specials //
|
||||
//////////////////
|
||||
if (strcmp(code,".-.-") == 0) printascii(3);
|
||||
if (strcmp(code,"---.") == 0) printascii(4);
|
||||
if (strcmp(code,".--.-") == 0) printascii(6);
|
||||
|
||||
}
|
||||
|
||||
void Decode_Morse(float magnitude)
|
||||
{
|
||||
//magnitudelimit auto Increase
|
||||
if (magnitude > magnitudelimit_low)
|
||||
{
|
||||
magnitudelimit = (magnitudelimit +((magnitude - magnitudelimit)/6)); /// moving average filter
|
||||
}
|
||||
|
||||
if (magnitudelimit < magnitudelimit_low)
|
||||
magnitudelimit = magnitudelimit_low;
|
||||
|
||||
if(magnitude > magnitudelimit*0.6) // just to have some space up
|
||||
realstate = HIGH;
|
||||
else
|
||||
realstate = LOW;
|
||||
|
||||
if (realstate != realstatebefore)
|
||||
laststarttime = millis();
|
||||
|
||||
if ((millis()-laststarttime) > nbtime)
|
||||
{
|
||||
if (realstate != filteredstate)
|
||||
{
|
||||
filteredstate = realstate;
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredstate != filteredstatebefore)
|
||||
{
|
||||
if (filteredstate == HIGH)
|
||||
{
|
||||
starttimehigh = millis();
|
||||
lowduration = (millis() - startttimelow);
|
||||
}
|
||||
|
||||
if (filteredstate == LOW)
|
||||
{
|
||||
startttimelow = millis();
|
||||
highduration = (millis() - starttimehigh);
|
||||
|
||||
if (highduration < (2*hightimesavg) || hightimesavg == 0)
|
||||
{
|
||||
hightimesavg = (highduration+hightimesavg+hightimesavg)/3; // now we know avg dit time ( rolling 3 avg)
|
||||
}
|
||||
|
||||
if (highduration > (5*hightimesavg) )
|
||||
{
|
||||
hightimesavg = highduration+hightimesavg; // if speed decrease fast ..
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// now we will check which kind of baud we have - dit or dah //
|
||||
// and what kind of pause we do have 1 - 3 or 7 pause //
|
||||
// we think that hightimeavg = 1 bit //
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
if (filteredstate != filteredstatebefore)
|
||||
{
|
||||
stop = LOW;
|
||||
if (filteredstate == LOW)
|
||||
{
|
||||
if (highduration < (hightimesavg*2) && highduration > (hightimesavg*0.6)) /// 0.6 filter out false dits
|
||||
{
|
||||
strcat(code,".");
|
||||
}
|
||||
if (highduration > (hightimesavg*2) && highduration < (hightimesavg*6))
|
||||
{
|
||||
strcat(code,"-");
|
||||
wpm = (wpm + (1200/((highduration)/3)))/2; //// the most precise we can do ;o)
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredstate == HIGH)
|
||||
{
|
||||
float lacktime = 1;
|
||||
if(wpm > 25)lacktime=1.0; /// when high speeds we have to have a little more pause before new letter or new word
|
||||
if(wpm > 30)lacktime=1.2;
|
||||
if(wpm > 35)lacktime=1.5;
|
||||
|
||||
if (lowduration > (hightimesavg*(2*lacktime)) && lowduration < hightimesavg*(5*lacktime)) // letter space
|
||||
{
|
||||
docode();
|
||||
code[0] = '\0';
|
||||
}
|
||||
if (lowduration >= hightimesavg*(5*lacktime))
|
||||
{ // word space
|
||||
docode();
|
||||
code[0] = '\0';
|
||||
printascii(32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((millis() - startttimelow) > (highduration * 6) && stop == LOW)
|
||||
{
|
||||
docode();
|
||||
code[0] = '\0';
|
||||
stop = HIGH;
|
||||
}
|
||||
|
||||
/*
|
||||
if(filteredstate == HIGH)
|
||||
{
|
||||
digitalWrite(ledPin, HIGH);
|
||||
tone(audioOutPin,target_freq);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(ledPin, LOW);
|
||||
noTone(audioOutPin);
|
||||
}
|
||||
*/
|
||||
|
||||
realstatebefore = realstate;
|
||||
lasthighduration = highduration;
|
||||
filteredstatebefore = filteredstate;
|
||||
}
|
||||
|
@ -1,355 +0,0 @@
|
||||
/*
|
||||
Softserial for Nextion LCD and Control MCU
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
It is a library rewritten in C format based on SoftwareSerial.c.
|
||||
I tried to use as much as possible without modifying the SoftwareSerial.
|
||||
But eventually I had to modify the code.
|
||||
|
||||
I rewrote it in C for the following reasons.
|
||||
- Problems occurred when increasing Program Size and Program Memory
|
||||
- We had to reduce the program size.
|
||||
Of course, Software Serial is limited to one.
|
||||
- reduce the steps for transmitting and receiving
|
||||
|
||||
useage
|
||||
extern void SWSerial_Begin(long speedBaud);
|
||||
extern void SWSerial_Write(uint8_t b);
|
||||
extern int SWSerial_Available(void);
|
||||
extern int SWSerial_Read(void);
|
||||
extern void SWSerial_Print(uint8_t *b);
|
||||
|
||||
If you use Softwreserial library instead of this library, you can modify the code as shown below.
|
||||
I kept the function name of SoftwareSerial so you only need to modify a few lines of code.
|
||||
|
||||
define top of source code
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial sSerial(10, 11); // RX, TX
|
||||
|
||||
replace source code
|
||||
SWSerial_Begin to sSerial.begin
|
||||
SWSerial_Write to sSerial.write
|
||||
SWSerial_Available to sSerial.available
|
||||
SWSerial_Read to sSerial.read
|
||||
|
||||
KD8CEC, Ian Lee
|
||||
-----------------------------------------------------------------------
|
||||
License
|
||||
All licenses for the source code are subject to the license of the original source SoftwareSerial Library.
|
||||
However, if you use or modify this code, please keep the all comments in this source code.
|
||||
KD8CEC
|
||||
-----------------------------------------------------------------------
|
||||
License from SoftwareSerial
|
||||
-----------------------------------------------------------------------
|
||||
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
|
||||
Multi-instance software serial library for Arduino/Wiring
|
||||
-- Interrupt-driven receive and other improvements by ladyada
|
||||
(http://ladyada.net)
|
||||
-- Tuning, circular buffer, derivation from class Print/Stream,
|
||||
multi-instance support, porting to 8MHz processors,
|
||||
various optimizations, PROGMEM delay tables, inverse logic and
|
||||
direct port writing by Mikal Hart (http://www.arduiniana.org)
|
||||
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
|
||||
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
|
||||
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
The latest version of this library can always be found at
|
||||
http://arduiniana.org.
|
||||
*/
|
||||
#include "TeensyDSP.h"
|
||||
|
||||
#ifdef USE_SW_SERIAL
|
||||
//================================================================
|
||||
//Public Variable
|
||||
//================================================================
|
||||
#define TX_PIN 9
|
||||
#define RX_PIN 8
|
||||
#define _SS_MAX_RX_BUFF 35 // RX buffer size
|
||||
#define PRINT_MAX_LENGTH 30
|
||||
|
||||
//================================================================
|
||||
//Internal Variable from SoftwareSerial.c and SoftwareSerial.h
|
||||
//================================================================
|
||||
//variable from softwareserial.c and softwareserial.h
|
||||
static uint8_t swr_receive_buffer[_SS_MAX_RX_BUFF];
|
||||
|
||||
volatile uint8_t *_transmitPortRegister; //Write Port Register
|
||||
uint8_t transmit_RegMask; //use Mask bit 1
|
||||
uint8_t transmit_InvMask; //use mask bit 0
|
||||
|
||||
volatile uint8_t *_receivePortRegister; //Read Port Register
|
||||
uint8_t _receiveBitMask;
|
||||
|
||||
//delay value for Bit
|
||||
uint16_t _tx_delay;
|
||||
|
||||
//delay value for Receive
|
||||
uint16_t _rx_delay_stopbit;
|
||||
uint16_t _rx_delay_centering;
|
||||
uint16_t _rx_delay_intrabit;
|
||||
|
||||
//Customize for uBITX Protocol
|
||||
int8_t receiveIndex = 0;
|
||||
int8_t receivedCommandLength = 0;
|
||||
int8_t ffCount = 0;
|
||||
|
||||
//Values for Receive Buffer
|
||||
//uint16_t _buffer_overflow;
|
||||
//static volatile uint8_t _receive_buffer_head;
|
||||
//static volatile uint8_t _receive_buffer_tail;
|
||||
|
||||
//Values for Interrupt (check Start Bit)
|
||||
volatile uint8_t *_pcint_maskreg;
|
||||
uint8_t _pcint_maskvalue;
|
||||
|
||||
//================================================================
|
||||
//Internal Function from SoftwareSerial.c
|
||||
//================================================================
|
||||
uint16_t subtract_cap(uint16_t num, uint16_t sub)
|
||||
{
|
||||
if (num > sub)
|
||||
return num - sub;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline void tunedDelay(uint16_t delay)
|
||||
{
|
||||
_delay_loop_2(delay);
|
||||
}
|
||||
|
||||
void setRxIntMsk(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
*_pcint_maskreg |= _pcint_maskvalue;
|
||||
else
|
||||
*_pcint_maskreg &= ~_pcint_maskvalue;
|
||||
}
|
||||
|
||||
uint8_t rx_pin_read()
|
||||
{
|
||||
return *_receivePortRegister & _receiveBitMask;
|
||||
}
|
||||
|
||||
//
|
||||
// The receive routine called by the interrupt handler
|
||||
//
|
||||
void softSerail_Recv()
|
||||
{
|
||||
#if GCC_VERSION < 40302
|
||||
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||
// Preserve the registers that the compiler misses
|
||||
// (courtesy of Arduino forum user *etracer*)
|
||||
asm volatile(
|
||||
"push r18 \n\t"
|
||||
"push r19 \n\t"
|
||||
"push r20 \n\t"
|
||||
"push r21 \n\t"
|
||||
"push r22 \n\t"
|
||||
"push r23 \n\t"
|
||||
"push r26 \n\t"
|
||||
"push r27 \n\t"
|
||||
::);
|
||||
#endif
|
||||
|
||||
uint8_t d = 0;
|
||||
|
||||
// If RX line is high, then we don't see any start bit
|
||||
// so interrupt is probably not for us
|
||||
if (!rx_pin_read()) //Start Bit
|
||||
{
|
||||
// Disable further interrupts during reception, this prevents
|
||||
// triggering another interrupt directly after we return, which can
|
||||
// cause problems at higher baudrates.
|
||||
setRxIntMsk(false);
|
||||
|
||||
// Wait approximately 1/2 of a bit width to "center" the sample
|
||||
tunedDelay(_rx_delay_centering);
|
||||
|
||||
// Read each of the 8 bits
|
||||
for (uint8_t i=8; i > 0; --i)
|
||||
{
|
||||
tunedDelay(_rx_delay_intrabit);
|
||||
d >>= 1;
|
||||
|
||||
if (rx_pin_read())
|
||||
d |= 0x80;
|
||||
}
|
||||
|
||||
if (receivedCommandLength == 0) //check Already Command
|
||||
{
|
||||
//Set Received Data
|
||||
swr_receive_buffer[receiveIndex++] = d;
|
||||
|
||||
//Finded Command
|
||||
if (d == 0x73 && ffCount > 1 && receiveIndex > 6)
|
||||
{
|
||||
receivedCommandLength = receiveIndex;
|
||||
receiveIndex = 0;
|
||||
ffCount = 0;
|
||||
}
|
||||
else if (receiveIndex > _SS_MAX_RX_BUFF)
|
||||
{
|
||||
//Buffer Overflow
|
||||
receiveIndex = 0;
|
||||
ffCount = 0;
|
||||
}
|
||||
else if (d == 0xFF)
|
||||
{
|
||||
ffCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ffCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// skip the stop bit
|
||||
tunedDelay(_rx_delay_stopbit);
|
||||
|
||||
// Re-enable interrupts when we're sure to be inside the stop bit
|
||||
setRxIntMsk(true);
|
||||
}
|
||||
|
||||
#if GCC_VERSION < 40302
|
||||
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||
// Restore the registers that the compiler misses
|
||||
asm volatile(
|
||||
"pop r27 \n\t"
|
||||
"pop r26 \n\t"
|
||||
"pop r23 \n\t"
|
||||
"pop r22 \n\t"
|
||||
"pop r21 \n\t"
|
||||
"pop r20 \n\t"
|
||||
"pop r19 \n\t"
|
||||
"pop r18 \n\t"
|
||||
::);
|
||||
#endif
|
||||
}
|
||||
|
||||
ISR(PCINT0_vect)
|
||||
{
|
||||
softSerail_Recv();
|
||||
}
|
||||
|
||||
//================================================================
|
||||
//Public Function from SoftwareSerial.c and modified and create
|
||||
//================================================================
|
||||
// Read data from buffer
|
||||
void SWSerial_Read(uint8_t * receive_cmdBuffer)
|
||||
{
|
||||
for (int i = 0; i < receivedCommandLength; i++)
|
||||
receive_cmdBuffer[i] = swr_receive_buffer[i];
|
||||
}
|
||||
|
||||
void SWSerial_Write(uint8_t b)
|
||||
{
|
||||
volatile uint8_t *reg = _transmitPortRegister;
|
||||
uint8_t oldSREG = SREG;
|
||||
uint16_t delay = _tx_delay;
|
||||
|
||||
cli(); // turn off interrupts for a clean txmit
|
||||
|
||||
// Write the start bit
|
||||
*reg &= transmit_InvMask;
|
||||
|
||||
tunedDelay(delay);
|
||||
|
||||
// Write each of the 8 bits
|
||||
for (uint8_t i = 8; i > 0; --i)
|
||||
{
|
||||
if (b & 1) // choose bit
|
||||
*reg |= transmit_RegMask; // send 1
|
||||
else
|
||||
*reg &= transmit_InvMask; // send 0
|
||||
|
||||
tunedDelay(delay);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
// restore pin to natural state
|
||||
*reg |= transmit_RegMask;
|
||||
|
||||
SREG = oldSREG; // turn interrupts back on
|
||||
tunedDelay(_tx_delay);
|
||||
}
|
||||
|
||||
void SWSerial_Print(uint8_t *b)
|
||||
{
|
||||
for (int i = 0; i < PRINT_MAX_LENGTH; i++)
|
||||
{
|
||||
if (b[i] == 0x00)
|
||||
break;
|
||||
else
|
||||
SWSerial_Write(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SWSerial_Begin(long speedBaud)
|
||||
{
|
||||
//INT TX_PIN
|
||||
digitalWrite(TX_PIN, HIGH);
|
||||
pinMode(TX_PIN, OUTPUT);
|
||||
transmit_RegMask = digitalPinToBitMask(TX_PIN); //use Bit 1
|
||||
transmit_InvMask = ~digitalPinToBitMask(TX_PIN); //use Bit 0
|
||||
_transmitPortRegister = portOutputRegister(digitalPinToPort(TX_PIN));
|
||||
|
||||
//INIT RX_PIN
|
||||
pinMode(RX_PIN, INPUT);
|
||||
digitalWrite(RX_PIN, HIGH); // pullup for normal logic!
|
||||
_receiveBitMask = digitalPinToBitMask(RX_PIN);
|
||||
_receivePortRegister = portInputRegister(digitalPinToPort(RX_PIN));
|
||||
|
||||
//Set Values
|
||||
uint16_t bit_delay = (F_CPU / speedBaud) / 4;
|
||||
_tx_delay = subtract_cap(bit_delay, 15 / 4);
|
||||
|
||||
if (digitalPinToPCICR(RX_PIN))
|
||||
{
|
||||
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
|
||||
_rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
|
||||
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
|
||||
*digitalPinToPCICR(RX_PIN) |= _BV(digitalPinToPCICRbit(RX_PIN));
|
||||
_pcint_maskreg = digitalPinToPCMSK(RX_PIN);
|
||||
_pcint_maskvalue = _BV(digitalPinToPCMSKbit(RX_PIN));
|
||||
|
||||
tunedDelay(_tx_delay); // if we were low this establishes the end
|
||||
}
|
||||
|
||||
//Start Listen
|
||||
setRxIntMsk(true);
|
||||
}
|
||||
#else
|
||||
void SWSerial_Write(uint8_t b)
|
||||
{
|
||||
Serial.write(b);
|
||||
//Serial.flush();
|
||||
}
|
||||
|
||||
void SWSerial_Print(uint8_t *b)
|
||||
{
|
||||
for (int i = 0; i < PRINT_MAX_LENGTH; i++)
|
||||
{
|
||||
if (b[i] == 0x00)
|
||||
break;
|
||||
else
|
||||
SWSerial_Write(b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user