mirror of
https://codeberg.org/mclemens/ubitxv6.git
synced 2024-06-13 08:20:45 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6dceffd993 | ||
|
36cd505e8e | ||
|
6d4fc996d9 | ||
|
6c9e759901 | ||
|
4918670eaa | ||
|
4eecda170d | ||
|
50381da6de | ||
|
b136f5e43c | ||
|
a4f5f4b3cb | ||
|
ab678f3e8b | ||
|
c62eaaba2e | ||
|
c11c8bfbe3 | ||
|
84f47b0a23 | ||
|
740e881d28 | ||
|
71e5f877da | ||
|
e6fa6f935b | ||
|
b3a7e34d1b | ||
|
d282062eef | ||
|
f76b50fcc3 | ||
|
488e462c6c | ||
|
c323cec0cb | ||
|
f541ff8928 | ||
|
e7748d2878 |
52
README.md
52
README.md
|
@ -7,10 +7,62 @@ It was forked from https://github.com/afarhan/ubitxv6/
|
|||
The purpose of this project is to clean up (modularize) the source code, and add features that were not present
|
||||
in Ashhar's original version of the project, without requiring any hardware modifications to a stock uBiTXv6.
|
||||
|
||||
New features include:
|
||||
|
||||
* Much faster screen refresh (vs Ashhar's 6.3.1 aka 6.0 release)
|
||||
* Morse code readback for sightless operation
|
||||
* Save/recall your favorite frequencies
|
||||
* When adjusting settings, the existing/current setting is shown as reference
|
||||
* Cancel touch recalibration
|
||||
|
||||
User Manual: https://docs.google.com/document/d/1jlllZbvFMCzO1MJLzlJDGb10HXSehlFNMDPsxGJZtvY/edit?usp=drivesdk
|
||||
|
||||
# Installing on Your Radio
|
||||
|
||||
There are plenty of tutorials on how to upload sketches to Arduino Nanos. Just search for them. Addtionally,
|
||||
Ashhar created a video explaining the process specifically for uBiTX v6: https://www.youtube.com/watch?v=3n_V3prSJ_E
|
||||
|
||||
I developed this code using the Arduino IDE 1.8.9 toolchain, with -Wall and -Wextra compiler options turned on.
|
||||
Arduino IDE 1.8.13 was reported to compile too big (see https://groups.io/g/BITX20/topic/75008576), but this
|
||||
should be resolved in this project's tag R1.5.1.
|
||||
|
||||
# Personalized Callsign
|
||||
|
||||
To edit the callsign displayed, open the file `callsign.cpp` and change the string. Then re-compile and upload.
|
||||
|
||||
# Future Features/Modifications
|
||||
|
||||
There are some features that would be good to add, but I just didn't get around to.
|
||||
|
||||
* Setting to choose the tuning step size
|
||||
* Setting to choose whether or not the knob tuning should accelerate (current behavior) or have a fixed interval
|
||||
* Provide an option in each menu screen to load the default option for each setting
|
||||
|
||||
While the current code (as of 2020-05-05) is ~100 bytes shy of the full 30720 available on the nano, there's still
|
||||
opportunity to add new features by "creating" room. Below is a list of places you might create room:
|
||||
|
||||
I added lots of bounds checking, especially on string writes, that, if removed, could free a good number of bytes.
|
||||
While keeping them is best practice, for a non-IoT, non-critical piece of hardware, it shouldn't be a huge issue.
|
||||
|
||||
I added the RACK to the CAT to better emulate the FT-817 (I hope, at least!). Removing the RACK's and just leaving
|
||||
the default ACK's will also free up bytes.
|
||||
|
||||
I added a bunch of strings to the menuing with the intention of helping people understand their functions, but
|
||||
technically they're not necessary, and could all be removed.
|
||||
|
||||
I switched to a smaller footprint font than Ashhar's original code, but there are MUCH smaller fonts out there.
|
||||
Changing to a lower resolution, scaled up font can save hundreds or thousands of bytes, but won't look as pretty.
|
||||
Also, the star, gear, and numpad icons will need to be either added to the new font, or replaced with characters.
|
||||
|
||||
The first change I made to this fork was to replace Ashhar's original (incredibly slow) screen drawing routines
|
||||
with PDQ. Since that change, Ashhar has updated his drawing routine to be MUCH faster than his original, but
|
||||
still slightly slower than PDQ. It may be that Ashhar's new routines are smaller that PDQ, but I don't actually
|
||||
know that for certain.
|
||||
|
||||
There are a good number of instances of back-to-back calls of strncpy_P and displayText. Creating a single
|
||||
function that performs these operations together, and then calling that new function instead of the
|
||||
back-to-back calls everywhere may save space.
|
||||
|
||||
# License
|
||||
|
||||
The majority of this code is released under GPL v3 license, per Ashhar's original code.
|
||||
|
|
17
bands.cpp
17
bands.cpp
|
@ -16,19 +16,19 @@ struct Band_t {
|
|||
const char UNKNOWN_BAND_NAME [] PROGMEM = "??";
|
||||
|
||||
constexpr Band_t bands [] PROGMEM {
|
||||
{ 0UL, 255UL, 255, "U8"},//Utility conversion option
|
||||
{ 0UL, 65535UL, 254, "UF"},//Utility conversion option
|
||||
{ 530000UL, 1700000UL, 253, "AM"},//Broadcast AM, actually centers at 268, but uint8 can't do that
|
||||
{ 1800000UL, 2000000UL, 160, "A0"},//0xA0 is 160
|
||||
{ 3500000UL, 4000000UL, 80, "80"},
|
||||
{ 5330500UL, 5403500UL, 60, "60"},
|
||||
{ 7000000UL, 7300000UL, 40, "40"},
|
||||
// { 0UL, 255UL, 255, "U8"},//Utility conversion option
|
||||
// { 0UL, 65535UL, 254, "UF"},//Utility conversion option
|
||||
// { 530000UL, 1700000UL, 253, "AM"},//Broadcast AM, actually centers at 268, but uint8 can't do that
|
||||
// { 1800000UL, 2000000UL, 160, "A0"},//0xA0 is 160
|
||||
{ 3500000UL, 3800000UL, 80, "80"},
|
||||
// { 5330500UL, 5403500UL, 60, "60"},
|
||||
{ 7000000UL, 7200000UL, 40, "40"},
|
||||
{10100000UL, 10150000UL, 30, "30"},
|
||||
{14000000UL, 14350000UL, 20, "20"},
|
||||
{18068000UL, 18168000UL, 17, "17"},
|
||||
{21000000UL, 21450000UL, 15, "15"},
|
||||
{24890000UL, 24990000UL, 12, "12"},
|
||||
{26965000UL, 27405000UL, 11, "CB"},//Citizen's Band
|
||||
// {26965000UL, 27405000UL, 11, "CB"},//Citizen's Band
|
||||
{28000000UL, 29700000UL, 10, "10"},
|
||||
};
|
||||
constexpr uint8_t NUM_BANDS = sizeof(bands)/sizeof(bands[0]);
|
||||
|
@ -127,4 +127,3 @@ bool isFreqInBand(const uint32_t frequency,
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "callsign.h"
|
||||
|
||||
const char CALLSIGN_STRING_PRIVATE [] PROGMEM = "CALLSIGN";
|
||||
const char* const CALLSIGN_STRING = CALLSIGN_STRING_PRIVATE;
|
||||
const char CALLSIGN_STRING_PRIVATE [] PROGMEM = "DL6MHC";
|
||||
const char* const CALLSIGN_STRING = CALLSIGN_STRING_PRIVATE;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "colors.h"
|
||||
|
||||
static const unsigned int COLOR_TEXT = DISPLAY_WHITE;
|
||||
static const unsigned int COLOR_BACKGROUND = DISPLAY_NAVY;
|
||||
static const unsigned int COLOR_BACKGROUND = DISPLAY_BLACK;
|
||||
|
||||
static const unsigned int COLOR_ACTIVE_VFO_TEXT = DISPLAY_WHITE;
|
||||
static const unsigned int COLOR_ACTIVE_VFO_BACKGROUND = DISPLAY_BLACK;
|
||||
|
@ -16,7 +16,7 @@ static const unsigned int COLOR_INACTIVE_BACKGROUND = DISPLAY_BLACK;
|
|||
static const unsigned int COLOR_INACTIVE_BORDER = DISPLAY_DARKGREY;
|
||||
|
||||
static const unsigned int COLOR_ACTIVE_TEXT = DISPLAY_BLACK;
|
||||
static const unsigned int COLOR_ACTIVE_BACKGROUND = DISPLAY_ORANGE;
|
||||
static const unsigned int COLOR_ACTIVE_BACKGROUND = DISPLAY_GREEN;
|
||||
static const unsigned int COLOR_ACTIVE_BORDER = DISPLAY_WHITE;
|
||||
|
||||
static const unsigned int COLOR_VERSION_TEXT = DISPLAY_LIGHTGREY;
|
||||
static const unsigned int COLOR_VERSION_TEXT = DISPLAY_GREEN;
|
||||
|
|
38
colors.h
38
colors.h
|
@ -1,20 +1,20 @@
|
|||
// Color definitions
|
||||
#define DISPLAY_BLACK 0x0000 ///< 0, 0, 0
|
||||
#define DISPLAY_NAVY 0x000F ///< 0, 0, 123
|
||||
#define DISPLAY_DARKGREEN 0x03E0 ///< 0, 125, 0
|
||||
#define DISPLAY_DARKCYAN 0x03EF ///< 0, 125, 123
|
||||
#define DISPLAY_MAROON 0x7800 ///< 123, 0, 0
|
||||
#define DISPLAY_PURPLE 0x780F ///< 123, 0, 123
|
||||
#define DISPLAY_OLIVE 0x7BE0 ///< 123, 125, 0
|
||||
#define DISPLAY_LIGHTGREY 0xC618 ///< 198, 195, 198
|
||||
#define DISPLAY_DARKGREY 0x7BEF ///< 123, 125, 123
|
||||
#define DISPLAY_BLUE 0x001F ///< 0, 0, 255
|
||||
#define DISPLAY_GREEN 0x07E0 ///< 0, 255, 0
|
||||
#define DISPLAY_CYAN 0x07FF ///< 0, 255, 255
|
||||
#define DISPLAY_RED 0xF800 ///< 255, 0, 0
|
||||
#define DISPLAY_MAGENTA 0xF81F ///< 255, 0, 255
|
||||
#define DISPLAY_YELLOW 0xFFE0 ///< 255, 255, 0
|
||||
#define DISPLAY_WHITE 0xFFFF ///< 255, 255, 255
|
||||
#define DISPLAY_ORANGE 0xFD20 ///< 255, 165, 0
|
||||
#define DISPLAY_GREENYELLOW 0xAFE5 ///< 173, 255, 41
|
||||
#define DISPLAY_PINK 0xFC18 ///< 255, 130, 198
|
||||
static const uint16_t DISPLAY_BLACK = 0x0000; ///< 0, 0, 0
|
||||
static const uint16_t DISPLAY_NAVY = 0x000F; ///< 0, 0, 123
|
||||
static const uint16_t DISPLAY_DARKGREEN = 0x03E0; ///< 0, 125, 0
|
||||
static const uint16_t DISPLAY_DARKCYAN = 0x03EF; ///< 0, 125, 123
|
||||
static const uint16_t DISPLAY_MAROON = 0x7800; ///< 123, 0, 0
|
||||
static const uint16_t DISPLAY_PURPLE = 0x780F; ///< 123, 0, 123
|
||||
static const uint16_t DISPLAY_OLIVE = 0x7BE0; ///< 123, 125, 0
|
||||
static const uint16_t DISPLAY_LIGHTGREY = 0xC618; ///< 198, 195, 198
|
||||
static const uint16_t DISPLAY_DARKGREY = 0x7BEF; ///< 123, 125, 123
|
||||
static const uint16_t DISPLAY_BLUE = 0x001F; ///< 0, 0, 255
|
||||
static const uint16_t DISPLAY_GREEN = 0x07E0; ///< 0, 255, 0
|
||||
static const uint16_t DISPLAY_CYAN = 0x07FF; ///< 0, 255, 255
|
||||
static const uint16_t DISPLAY_RED = 0xF800; ///< 255, 0, 0
|
||||
static const uint16_t DISPLAY_MAGENTA = 0xF81F; ///< 255, 0, 255
|
||||
static const uint16_t DISPLAY_YELLOW = 0xFFE0; ///< 255, 255, 0
|
||||
static const uint16_t DISPLAY_WHITE = 0xFFFF; ///< 255, 255, 255
|
||||
static const uint16_t DISPLAY_ORANGE = 0xFD20; ///< 255, 165, 0
|
||||
static const uint16_t DISPLAY_GREENYELLOW = 0xAFE5; ///< 173, 255, 41
|
||||
static const uint16_t DISPLAY_PINK = 0xFC18; ///< 255, 130, 198
|
||||
|
|
|
@ -16,7 +16,7 @@ static const uint8_t MOMENTUM_MULTIPLIER = 1;
|
|||
|
||||
uint8_t enc_state (void)
|
||||
{
|
||||
return (digitalRead(PIN_ENC_A)?1:0 + digitalRead(PIN_ENC_B)?2:0);
|
||||
return (digitalRead(PIN_ENC_B) << 1) + (digitalRead(PIN_ENC_A) << 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
72
keyer.cpp
72
keyer.cpp
|
@ -77,13 +77,8 @@ uint8_t keyerControl = 0;
|
|||
//create by KD8CEC for compatible with new CW Logic
|
||||
char update_PaddleLatch(bool isUpdateKeyState) {
|
||||
unsigned char tmpKeyerControl = 0;
|
||||
|
||||
unsigned int paddle = analogRead(PIN_ANALOG_KEYER);
|
||||
|
||||
//use the PTT as the key for tune up, quick QSOs
|
||||
if (digitalRead(PIN_PTT) == 0)
|
||||
tmpKeyerControl |= DIT_L;
|
||||
else if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo)
|
||||
if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo)
|
||||
tmpKeyerControl |= DAH_L;
|
||||
else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo)
|
||||
tmpKeyerControl |= DIT_L;
|
||||
|
@ -110,9 +105,41 @@ char update_PaddleLatch(bool isUpdateKeyState) {
|
|||
******************************************************************************/
|
||||
void cwKeyer(void){
|
||||
bool continue_loop = true;
|
||||
unsigned tmpKeyControl = 0;
|
||||
char tmpKeyControl = 0;
|
||||
|
||||
if(KeyerMode_e::KEYER_STRAIGHT != globalSettings.keyerMode){
|
||||
if((KeyerMode_e::KEYER_STRAIGHT == globalSettings.keyerMode)
|
||||
|| (digitalRead(PIN_PTT) == 0)){//use the PTT as the key for tune up, quick QSOs
|
||||
while(1){
|
||||
tmpKeyControl = update_PaddleLatch(0) | (digitalRead(PIN_PTT)?0:DIT_L);
|
||||
//Serial.println((int)tmpKeyControl);
|
||||
if ((tmpKeyControl & DIT_L) == DIT_L) {
|
||||
// if we are here, it is only because the key is pressed
|
||||
if (!globalSettings.txActive){
|
||||
startTx(TuningMode_e::TUNE_CW);
|
||||
globalSettings.cwExpirationTimeMs = millis() + globalSettings.cwActiveTimeoutMs;
|
||||
}
|
||||
cwKeydown();
|
||||
|
||||
while ( tmpKeyControl & DIT_L == DIT_L){
|
||||
tmpKeyControl = update_PaddleLatch(0) | (digitalRead(PIN_PTT)?0:DIT_L);
|
||||
//Serial.println((int)tmpKeyControl);
|
||||
}
|
||||
|
||||
cwKeyUp();
|
||||
}
|
||||
else{
|
||||
if (0 < globalSettings.cwExpirationTimeMs && globalSettings.cwExpirationTimeMs < millis()){
|
||||
globalSettings.cwExpirationTimeMs = 0;
|
||||
stopTx();
|
||||
}
|
||||
return;//Tx stop control by Main Loop
|
||||
}
|
||||
|
||||
checkCAT();
|
||||
} //end of while
|
||||
|
||||
}
|
||||
else{//KEYER_IAMBIC_*
|
||||
while(continue_loop){
|
||||
switch(keyerState){
|
||||
case IDLE:
|
||||
|
@ -193,34 +220,7 @@ void cwKeyer(void){
|
|||
|
||||
checkCAT();
|
||||
} //end of while
|
||||
}
|
||||
else{//KEYER_STRAIGHT
|
||||
while(1){
|
||||
char state = update_PaddleLatch(0);
|
||||
// Serial.println((int)state);
|
||||
if (state == DIT_L) {
|
||||
// if we are here, it is only because the key is pressed
|
||||
if (!globalSettings.txActive){
|
||||
startTx(TuningMode_e::TUNE_CW);
|
||||
globalSettings.cwExpirationTimeMs = millis() + globalSettings.cwActiveTimeoutMs;
|
||||
}
|
||||
cwKeydown();
|
||||
|
||||
while ( update_PaddleLatch(0) == DIT_L );
|
||||
|
||||
cwKeyUp();
|
||||
}
|
||||
else{
|
||||
if (0 < globalSettings.cwExpirationTimeMs && globalSettings.cwExpirationTimeMs < millis()){
|
||||
globalSettings.cwExpirationTimeMs = 0;
|
||||
stopTx();
|
||||
}
|
||||
return;//Tx stop control by Main Loop
|
||||
}
|
||||
|
||||
checkCAT();
|
||||
} //end of while
|
||||
}//end of else KEYER_STRAIGHT
|
||||
}//end of KEYER_IAMBIC_*
|
||||
}
|
||||
|
||||
|
||||
|
|
18
nano_gui.cpp
18
nano_gui.cpp
|
@ -2,6 +2,7 @@
|
|||
#include "nano_gui.h"
|
||||
#include "colors.h"
|
||||
#include "pin_definitions.h"
|
||||
#include "push_button.h"
|
||||
#include "scratch_space.h"
|
||||
#include "settings.h"
|
||||
#include "touch.h"
|
||||
|
@ -116,7 +117,7 @@ void setupTouch(){
|
|||
};
|
||||
|
||||
displayClear(DISPLAY_BLACK);
|
||||
strncpy_P(b,(const char*)F("Click on the cross"),sizeof(b));
|
||||
strncpy_P(b,(const char*)F("Click on the cross\nPush tune to cancel"),sizeof(b));
|
||||
displayText(b, 20,100, 200, 50, DISPLAY_WHITE, DISPLAY_BLACK, DISPLAY_BLACK);
|
||||
|
||||
Point cal_points[sizeof(CROSS_CORNER_POINTS)/sizeof(CROSS_CORNER_POINTS[0])];
|
||||
|
@ -124,6 +125,9 @@ void setupTouch(){
|
|||
for(uint8_t i = 0; i < sizeof(CROSS_CORNER_POINTS)/sizeof(CROSS_CORNER_POINTS[0]); ++i){
|
||||
drawCross(CROSS_CORNER_POINTS[i].x,CROSS_CORNER_POINTS[i].y,DISPLAY_WHITE);
|
||||
while(!readTouch(&cal_points[i])){
|
||||
if(ButtonPress_e::NotPressed != CheckTunerButton()){
|
||||
return;
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
while(readTouch(&cal_points[i])){
|
||||
|
@ -153,20 +157,20 @@ void setupTouch(){
|
|||
globalSettings.touchOffsetX = cal_points[0].x - ((CROSS_CORNER_OFFSET * globalSettings.touchSlopeX)/SCALE_SENSITIVITY_MULTIPLIER);
|
||||
globalSettings.touchOffsetY = cal_points[0].y - ((CROSS_CORNER_OFFSET * globalSettings.touchSlopeY)/SCALE_SENSITIVITY_MULTIPLIER);
|
||||
|
||||
|
||||
/*
|
||||
Serial.print(x1);Serial.print(':');Serial.println(y1);
|
||||
Serial.print(x2);Serial.print(':');Serial.println(y2);
|
||||
Serial.print(x3);Serial.print(':');Serial.println(y3);
|
||||
Serial.print(x4);Serial.print(':');Serial.println(y4);
|
||||
for(uint8_t i = 0; i < sizeof(cal_points)/sizeof(cal_points[0]); ++i){
|
||||
Serial.print(cal_points[i].x);Serial.print(':');Serial.println(cal_points[i].y);
|
||||
}
|
||||
|
||||
//for debugging
|
||||
Serial.print(globalSettings.touchSlopeX); Serial.print(' ');
|
||||
Serial.print(globalSettings.touchSlopeY); Serial.print(' ');
|
||||
Serial.print(globalSettings.touchOffsetX); Serial.print(' ');
|
||||
Serial.println(globalSettings.touchOffsetY); Serial.println(' ');
|
||||
*/
|
||||
*/
|
||||
|
||||
SaveSettingsToEeprom();
|
||||
displayClear(DISPLAY_BLACK);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ void displayChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t
|
|||
void displayText(const char *const text, int x1, int y1, int w, int h, int color, int background, int border, TextJustification_e justification = TextJustification_e::Center);
|
||||
|
||||
/* these functions are called universally to update the display */
|
||||
void updateDisplay(); //updates just the VFO frequency to show what is in 'frequency' variable
|
||||
void redrawVFOs(); //redraws only the changed digits of the vfo
|
||||
void drawTx();
|
||||
|
||||
#define TEXT_LINE_HEIGHT 18
|
||||
|
|
|
@ -26,8 +26,9 @@ static const uint16_t EEPROM_ADDR_CW_DELAYTIME = 48;//uint16_t
|
|||
static const uint16_t EEPROM_ADDR_VFO_A_MODE = 256;//uint8_t
|
||||
static const uint16_t EEPROM_ADDR_VFO_B_MODE = 257;//uint8_t
|
||||
static const uint16_t EEPROM_ADDR_CW_KEY_TYPE = 358;//uint8_t
|
||||
static const uint16_t EEPROM_ADDR_QUICKLIST_FREQ = 630;//uint32_t array
|
||||
static const uint16_t EEPROM_ADDR_QUICKLIST_MODE = 710;//uint8_t array
|
||||
static const uint16_t EEPROM_ADDR_QUICKLIST_FREQ = 630;//uint32_t array of size NUM_QUICKLIST_SETTINGS
|
||||
static const uint16_t EEPROM_ADDR_QUICKLIST_MODE = 710;//uint8_t array of size NUM_QUICKLIST_SETTINGS
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool LoadSane(T& dest,uint16_t addr, T min, T max)
|
||||
|
@ -189,5 +190,4 @@ void SetActiveVfoMode(VfoMode_e mode)
|
|||
else{
|
||||
globalSettings.vfoB.mode = mode;
|
||||
}
|
||||
redrawVFOs();
|
||||
}
|
||||
|
|
11
setup.cpp
11
setup.cpp
|
@ -539,16 +539,23 @@ MenuReturn_e runSetupMenu(const MenuItem_t* const menu_items,
|
|||
enterSubmenu(&setupMenu##menu_name);\
|
||||
}\
|
||||
|
||||
const char MT_CAL [] PROGMEM = "Calibrations";
|
||||
const char MI_TOUCH [] PROGMEM = "Touch Screen";
|
||||
void setupTouchSetting();
|
||||
|
||||
const char MT_CAL [] PROGMEM = "Calibrations";
|
||||
const MenuItem_t menuItemsCalibration [] PROGMEM {
|
||||
{MT_CAL,nullptr},//Title
|
||||
{SS_LOCAL_OSC_T,runLocalOscSetting},
|
||||
{SS_BFO_T,runBfoSetting},
|
||||
{MI_TOUCH,setupTouch},
|
||||
{MI_TOUCH,setupTouchSetting},
|
||||
};
|
||||
GENERATE_MENU_T(Calibration);
|
||||
|
||||
void setupTouchSetting(){
|
||||
setupTouch();
|
||||
initSetupMenuCalibration();
|
||||
}
|
||||
|
||||
const char MT_CW [] PROGMEM = "CW Setup";
|
||||
const MenuItem_t menuItemsCw [] PROGMEM {
|
||||
{MT_CW,nullptr},//Title
|
||||
|
|
77
touch.cpp
77
touch.cpp
|
@ -6,7 +6,28 @@
|
|||
#include "settings.h"
|
||||
|
||||
constexpr int16_t Z_THRESHOLD = 400;
|
||||
constexpr uint8_t MSEC_THRESHOLD = 3;
|
||||
constexpr uint8_t MSEC_THRESHOLD = 3;//Max sample rate is 125kHz, but we'll limit ourselves conservatively
|
||||
|
||||
constexpr uint8_t START_COMMAND = 1 << 7;
|
||||
constexpr uint8_t CHANNEL_Y = 1 << 4;
|
||||
constexpr uint8_t CHANNEL_Z1 = 3 << 4;
|
||||
constexpr uint8_t CHANNEL_Z2 = 4 << 4;
|
||||
constexpr uint8_t CHANNEL_X = 5 << 4;
|
||||
constexpr uint8_t CHANNEL_TEMPERATURE = 7 << 4;
|
||||
constexpr uint8_t USE_8_INSTEAD_OF_12_BIT = 1 << 3;
|
||||
constexpr uint8_t USE_SINGLE_ENDED_MEASUREMENT = 1 << 2;
|
||||
constexpr uint8_t POWER_OFF = 0 << 0;
|
||||
constexpr uint8_t POWER_ADC = 1 << 0;
|
||||
constexpr uint8_t POWER_REF = 2 << 0;
|
||||
constexpr uint8_t POWER_ADC_REF = 3 << 0;
|
||||
|
||||
constexpr uint16_t MEASURE_X = START_COMMAND | POWER_ADC | CHANNEL_Y;//X and Y channel labelling flip due to screen orientation
|
||||
constexpr uint16_t MEASURE_Y = START_COMMAND | POWER_ADC | CHANNEL_X;//X and Y channel labelling flip due to screen orientation
|
||||
constexpr uint16_t MEASURE_Z1 = START_COMMAND | POWER_ADC | CHANNEL_Z1;
|
||||
constexpr uint16_t MEASURE_Z2 = START_COMMAND | POWER_ADC | CHANNEL_Z2;
|
||||
|
||||
constexpr uint8_t RAW_READ_TO_12BIT_VALUE_SHIFT = 3;//16 bits read, zero-padded, but the MSB of the 16 is where the "BUSY" signal is asserted, so only need to shift by 3 instead of 4
|
||||
|
||||
|
||||
uint32_t msraw=0x80000000;
|
||||
int16_t xraw=0, yraw=0, zraw=0;
|
||||
|
@ -28,44 +49,51 @@ int16_t touch_besttwoavg( int16_t x , int16_t y , int16_t z ) {
|
|||
return (reta);
|
||||
}
|
||||
|
||||
void touch_update(){
|
||||
int16_t data[6];
|
||||
uint16_t touchReadChannel(uint8_t channel_command){
|
||||
//We assume that SPI.beginTransaction has already been called, and CS is LOW
|
||||
SPI.transfer(channel_command);//Throw away any bytes here
|
||||
const uint16_t tmpH = SPI.transfer(0) & 0x7F;//Leading 0 (during "busy" signal), followed by bits 11-5
|
||||
const uint16_t tmpL = SPI.transfer(0);//Bits 4-0, followed by 0s
|
||||
return tmpH << 5 | tmpL >> 3;
|
||||
}
|
||||
|
||||
void touch_update(){
|
||||
uint32_t now = millis();
|
||||
if (now - msraw < MSEC_THRESHOLD) return;
|
||||
if (now - msraw < MSEC_THRESHOLD){
|
||||
return;
|
||||
}
|
||||
|
||||
SPI.beginTransaction(spiSettingsTouch);
|
||||
digitalWrite(PIN_TOUCH_CS, LOW);
|
||||
SPI.transfer(0xB1 /* Z1 */);
|
||||
int16_t z1 = SPI.transfer16(0xC1 /* Z2 */) >> 3;
|
||||
int z = z1 + 4095;
|
||||
int16_t z2 = SPI.transfer16(0x91 /* X */) >> 3;
|
||||
z -= z2;
|
||||
if (z < 0) z = 0;
|
||||
if (z < Z_THRESHOLD) { // if ( !touched ) {
|
||||
// Serial.println();
|
||||
zraw = 0;
|
||||
|
||||
int16_t z1 = touchReadChannel(MEASURE_Z1);//~0 when not pressed, increases with pressure
|
||||
int32_t z = z1;
|
||||
int16_t z2 = touchReadChannel(MEASURE_Z2);//~4095 when not pressed, decreases with pressure
|
||||
z += (4095 - z2);
|
||||
//Serial.print(F("z1:"));Serial.print(z1);Serial.print(F(" z2:"));Serial.print(z2);Serial.print(F(" z:"));Serial.println(z);
|
||||
|
||||
zraw = z;
|
||||
if (zraw < Z_THRESHOLD) {//Don't bother reading x/y if we're not being touched
|
||||
digitalWrite(PIN_TOUCH_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
return;
|
||||
}
|
||||
zraw = z;
|
||||
|
||||
SPI.transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
|
||||
data[0] = SPI.transfer16(0xD1 /* Y */) >> 3;
|
||||
data[1] = SPI.transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
|
||||
data[2] = SPI.transfer16(0xD1 /* Y */) >> 3;
|
||||
data[3] = SPI.transfer16(0x91 /* X */) >> 3;
|
||||
data[4] = SPI.transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
|
||||
data[5] = SPI.transfer16(0) >> 3;
|
||||
// make 3 x-y measurements
|
||||
int16_t data[6];
|
||||
data[0] = touchReadChannel(MEASURE_X);
|
||||
data[1] = touchReadChannel(MEASURE_Y);
|
||||
data[2] = touchReadChannel(MEASURE_X);
|
||||
data[3] = touchReadChannel(MEASURE_Y);
|
||||
data[4] = touchReadChannel(MEASURE_X);
|
||||
data[5] = touchReadChannel(MEASURE_Y & ~POWER_ADC_REF);//Turn off sensor
|
||||
|
||||
digitalWrite(PIN_TOUCH_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
|
||||
int16_t x = touch_besttwoavg( data[0], data[2], data[4] );
|
||||
int16_t y = touch_besttwoavg( data[1], data[3], data[5] );
|
||||
|
||||
//Serial.printf(" %d,%d", x, y);
|
||||
//Serial.println();
|
||||
|
||||
msraw = now; // good read completed, set wait
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
|
@ -93,6 +121,7 @@ void initTouch(){
|
|||
|
||||
bool readTouch(Point *const touch_point_out){
|
||||
touch_update();
|
||||
//Serial.print(F("readTouch found zraw of "));Serial.println(zraw);
|
||||
if (zraw >= Z_THRESHOLD) {
|
||||
touch_point_out->x = xraw;
|
||||
touch_point_out->y = yraw;
|
||||
|
|
|
@ -19,7 +19,6 @@ void switchVFO(Vfo_e new_vfo){
|
|||
|
||||
globalSettings.activeVfo = new_vfo;
|
||||
setFrequency(GetActiveVfoFreq());
|
||||
redrawVFOs();
|
||||
saveVFOs();
|
||||
}
|
||||
|
||||
|
@ -194,7 +193,6 @@ void ritDisable(){
|
|||
if(globalSettings.ritOn){
|
||||
globalSettings.ritOn = false;
|
||||
setFrequency(globalSettings.ritFrequency);
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,6 @@ void processCatCommand(uint8_t* cmd) {
|
|||
{
|
||||
uint32_t f = readFreq(cmd);
|
||||
setFrequency(f);
|
||||
updateDisplay();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -320,7 +319,6 @@ void processCatCommand(uint8_t* cmd) {
|
|||
}
|
||||
|
||||
setFrequency(GetActiveVfoFreq());//Refresh frequency to get new mode to take effect
|
||||
updateDisplay();
|
||||
break;
|
||||
|
||||
case Ft817Command_e::PttOn:
|
||||
|
@ -331,7 +329,6 @@ void processCatCommand(uint8_t* cmd) {
|
|||
else {
|
||||
response[0] = RACK;
|
||||
}
|
||||
updateDisplay();
|
||||
break;
|
||||
|
||||
case Ft817Command_e::PttOff:
|
||||
|
@ -342,7 +339,6 @@ void processCatCommand(uint8_t* cmd) {
|
|||
response[0] = RACK;
|
||||
}
|
||||
globalSettings.txCatActive = false;
|
||||
updateDisplay();
|
||||
break;
|
||||
|
||||
case Ft817Command_e::VfoToggle:
|
||||
|
@ -352,7 +348,6 @@ void processCatCommand(uint8_t* cmd) {
|
|||
else{
|
||||
globalSettings.activeVfo = Vfo_e::VFO_A;
|
||||
}
|
||||
updateDisplay();
|
||||
break;
|
||||
|
||||
case Ft817Command_e::ReadEeprom:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "version.h"
|
||||
|
||||
const char VERSION_STRING_PRIVATE [] PROGMEM = "R1.4.0";
|
||||
const char VERSION_STRING_PRIVATE [] PROGMEM = "R1.5.1";
|
||||
const char* const VERSION_STRING = VERSION_STRING_PRIVATE;
|
Loading…
Reference in New Issue
Block a user