From 9a026faf4e1863c2a44b2e1aa1c352fc0748d0b8 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 1 Aug 2021 18:16:31 -0500 Subject: [PATCH] Not sure where I was at... --- ubitx_20/cw_autokey.ino | 4 +- ubitx_20/ubitx.h | 6 +- ubitx_20/ubitx_20.ino | 37 +- ubitx_20/ubitx_keyer.ino | 369 --------------- ubitx_20/ubitx_lcd_1602.ino | 790 -------------------------------- ubitx_20/ubitx_lcd_1602Dual.ino | 727 ----------------------------- ubitx_20/ubitx_lcd_2004.ino | 743 ------------------------------ ubitx_20/ubitx_lcd_nextion.ino | 4 +- ubitx_20/ubitx_menu.ino | 4 +- ubitx_20/ubitx_si5351.ino | 4 +- 10 files changed, 33 insertions(+), 2655 deletions(-) delete mode 100644 ubitx_20/ubitx_keyer.ino delete mode 100644 ubitx_20/ubitx_lcd_1602.ino delete mode 100644 ubitx_20/ubitx_lcd_1602Dual.ino delete mode 100644 ubitx_20/ubitx_lcd_2004.ino diff --git a/ubitx_20/cw_autokey.ino b/ubitx_20/cw_autokey.ino index 9bf838e..73eb3d9 100644 --- a/ubitx_20/cw_autokey.ino +++ b/ubitx_20/cw_autokey.ino @@ -312,7 +312,7 @@ void controlAutoCW(){ autoCWSendReservCount = 0; //Init Reserve Count isAutoCWHold = 0; if (!inTx){ //if not TX Status, change RX -> TX - keyDown = 0; + keyDown = false; startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time updateDisplay(); @@ -344,7 +344,7 @@ void controlAutoCW(){ if (isAutoCWHold == 0 && (millis() - autoCWbeforeTime > cwSpeed * 3)) { if (!inTx){ //if not TX Status, change RX -> TX - keyDown = 0; + keyDown = false; startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time } diff --git a/ubitx_20/ubitx.h b/ubitx_20/ubitx.h index 7c17b11..6465aa4 100644 --- a/ubitx_20/ubitx.h +++ b/ubitx_20/ubitx.h @@ -20,10 +20,10 @@ #include //for Linux, On Linux it is case sensitive. //============================================================================== -// Compile Option +// Compile-Time Options //============================================================================== -//Ubitx Board Version -#define UBITX_BOARD_VERSION 2 //v1 ~ v4 : 4, v5: 5 +// uBITX Board Version - KC4UPR: updated to v5 +#define UBITX_BOARD_VERSION 5 //v1 ~ v4 : 4, v5: 5 //Depending on the type of LCD mounted on the uBITX, uncomment one of the options below. //You must select only one. diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index 2066939..99bfec1 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -1,4 +1,4 @@ - //Firmware Version +//Firmware Version //+ : This symbol identifies the firmware. // It was originally called 'CEC V1.072' but it is too long to waste the LCD window. // I do not want to make this Firmware users's uBITX messy with my callsign. @@ -53,6 +53,8 @@ #include "ubitx.h" #include "ubitx_eemap.h" +extern void Connect_Interrupts(void); + /** * The uBITX is an upconnversion transceiver. The first IF is at 45 MHz. * The first IF frequency is not exactly at 45 Mhz but about 5 khz lower, @@ -124,7 +126,7 @@ unsigned long vfoA=7150000L, vfoB=14200000L, sideTone=800, usbCarrier, cwmCarrie unsigned long vfoA_eeprom, vfoB_eeprom; //for protect eeprom life unsigned long frequency, ritRxFrequency, ritTxFrequency; //frequency is the current frequency on the dial -unsigned int cwSpeed = 100; //this is actuall the dot period in milliseconds +int cwSpeed = 100; //this is actuall the dot period in milliseconds extern int32_t calibration; //for store the mode in eeprom @@ -166,7 +168,11 @@ int cwAdcBothTo = 0; byte cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb bool Iambic_Key = true; #define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B -unsigned char keyerControl = IAMBICB; + +volatile unsigned char keyerControl = 0; // IAMBICB; +volatile unsigned char keyerState = 0; +volatile unsigned char IAMBIC = 0x10; // 0 for Iambic A, 1 for Iambic B +volatile unsigned char PDLSWAP = 0x00; // 0x00 for normal, 0x08 for swap byte isShiftDisplayCWFreq = 1; //Display Frequency int shiftDisplayAdjustVal = 0; // @@ -187,10 +193,10 @@ byte userCallsignLength = 0; //7 : display callsign at system startup, 6~0 : /** * Raduino needs to keep track of current state of the transceiver. These are a few variables that do it */ -boolean txCAT = false; //turned on if the transmitting due to a CAT command -char inTx = 0; //it is set to 1 if in transmit mode (whatever the reason : cw, ptt or cat) +bool txCAT = false; // 'True' if transmitting due to CAT command. +volatile bool inTx = false; // 'True' if transmitting (regardless of source: CW, PTT, or CAT) char splitOn = 0; //working split, uses VFO B as the transmit frequency -char keyDown = 0; //in cw mode, denotes the carrier is being transmitted +//char keyDown = 0; //in cw mode, denotes the carrier is being transmitted char isUSB = 0; //upper sideband was selected, this is reset to the default for the char cwMode = 0; //compatible original source, and extend mode //if cwMode == 0, mode check : isUSB, cwMode > 0, mode Check : cwMode @@ -444,7 +450,7 @@ void setFrequency(unsigned long f){ f = (f / arTuneStep[tuneStepIndex -1]) * arTuneStep[tuneStepIndex -1]; setTXFilters(f); - unsigned long appliedCarrier = ((cwMode == 0 ? usbCarrier : cwmCarrier) + (isIFShift && (inTx == 0) ? ifShiftValue : 0)); + unsigned long appliedCarrier = ((cwMode == 0 ? usbCarrier : cwmCarrier) + (isIFShift && !inTx) ? ifShiftValue : 0)); int appliedTuneValue = 0; //applied if tune @@ -454,7 +460,7 @@ void setFrequency(unsigned long f){ appliedTuneValue = if1TuneValue; //In the LSB state, the optimum reception value was found. To apply to USB, 3Khz decrease is required. - if (sdrModeOn && (inTx == 0)) + if (sdrModeOn && !inTx) appliedTuneValue -= 15; //decrease 1.55Khz //if (isUSB) @@ -464,13 +470,13 @@ void setFrequency(unsigned long f){ //if1Tune RX, TX Enabled, ATT : only RX Mode //The IF Tune shall be measured at the LSB. Then, move the 3Khz down for USB. - long if1AdjustValue = ((inTx == 0) ? (attLevel * 100) : 0) + (appliedTuneValue * 100); //if1Tune RX, TX Enabled, ATT : only RX Mode //5600 + long if1AdjustValue = (!inTx ? (attLevel * 100) : 0) + (appliedTuneValue * 100); //if1Tune RX, TX Enabled, ATT : only RX Mode //5600 //for DIY uBITX (custom filter) if ((advancedFreqOption1 & 0x80) != 0x00) //Reverse IF Tune (- Value for DIY uBITX) if1AdjustValue *= -1; - if (sdrModeOn && (inTx == 0)) //IF SDR MODE + if (sdrModeOn && !inTx) //IF SDR MODE { //Fixed Frequency SDR (Default Frequency : 32Mhz, available change sdr Frequency by uBITX Manager) //Dynamic Frequency is for SWL without cat @@ -555,7 +561,7 @@ void startTx(byte txMode, byte isDisplayUpdate){ if ((isTxType & 0x01) != 0x01) digitalWrite(TX_RX, 1); - inTx = 1; + inTx = true; if (ritOn){ //save the current as the rx frequency @@ -618,7 +624,7 @@ void startTx(byte txMode, byte isDisplayUpdate){ } void stopTx(void){ - inTx = 0; + inTx = false; digitalWrite(TX_RX, 0); //turn off the tx SetCarrierFreq(); @@ -682,12 +688,12 @@ void checkPTT(){ if (cwTimeout > 0) return; - if (digitalRead(PTT) == 0 && inTx == 0){ + if (digitalRead(PTT) == 0 && !inTx){ startTx(TX_SSB, 1); delay(50); //debounce the PTT } - if (digitalRead(PTT) == 1 && inTx == 1) + if (digitalRead(PTT) == 1 && inTx) stopTx(); } #ifdef EXTEND_KEY_GROUP1 @@ -1432,6 +1438,7 @@ void setup() factory_alignment(); #endif + Connect_Interrupts(); } //Auto save Frequency and Mode with Protected eeprom life by KD8CEC @@ -1487,7 +1494,7 @@ void loop(){ } //end of check TX Status //we check CAT after the encoder as it might put the radio into TX - Check_Cat(inTx? 1 : 0); + Check_Cat(inTx ? 1 : 0); //for SEND SW Serial #ifdef USE_SW_SERIAL diff --git a/ubitx_20/ubitx_keyer.ino b/ubitx_20/ubitx_keyer.ino deleted file mode 100644 index 1ac1c2f..0000000 --- a/ubitx_20/ubitx_keyer.ino +++ /dev/null @@ -1,369 +0,0 @@ -/** - 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 ---------------------------------------------------------------------------- - * 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. - * When a straight key is connected, it shorts the pull-up resistor, analog input is 0 volts - * When a paddle is connected, the dot and the dash are connected to the analog pin through - * a 10K and a 2.2K resistors. These produce a 4v and a 2v input to the analog pins. - * So, the readings are as follows : - * 0v - straight key - * 1-2.5 v - paddle dot - * 2.5 to 4.5 v - paddle dash - * 2.0 to 0.5 v - dot and dash pressed - * - * The keyer is written to transparently handle all these cases - * - * Generating CW - * The CW is cleanly generated by unbalancing the front-end mixer - * and putting the local oscillator directly at the CW transmit frequency. - * The sidetone, generated by the Arduino is injected into the volume control - */ - - -// in milliseconds, this is the parameter that determines how long the tx will hold between cw key downs -//#define CW_TIMEOUT (600l) //Change to CW Delaytime for value save to eeprom -#define PADDLE_DOT 1 -#define PADDLE_DASH 2 -#define PADDLE_BOTH 3 -#define PADDLE_STRAIGHT 4 - -//we store the last padde's character -//to alternatively send dots and dashes -//when both are simultaneously pressed -char lastPaddle = 0; - -//reads the analog keyer pin and reports the paddle -byte getPaddle(){ - int paddle = analogRead(ANALOG_KEYER); - - if (paddle > 800) // above 4v is up - return 0; - - if (paddle > 600) // 4-3v is dot - return PADDLE_DASH; - else if (paddle > 300) //1-2v is dash - return PADDLE_DOT; - else if (paddle > 50) - return PADDLE_BOTH; //both are between 1 and 2v - else - return PADDLE_STRAIGHT; //less than 1v is the straight key -} - -/** - * Starts transmitting the carrier with the sidetone - * It assumes that we have called cwTxStart and not called cwTxStop - * each time it is called, the cwTimeOut is pushed further into the future - */ -void cwKeydown(){ - keyDown = 1; //tracks the CW_KEY - tone(CW_TONE, (int)sideTone); - digitalWrite(CW_KEY, 1); - - //Modified by KD8CEC, for CW Delay Time save to eeprom - //cwTimeout = millis() + CW_TIMEOUT; - cwTimeout = millis() + cwDelayTime * 10; -} - -/** - * Stops the cw carrier transmission along with the sidetone - * Pushes the cwTimeout further into the future - */ -void cwKeyUp(){ - keyDown = 0; //tracks the CW_KEY - noTone(CW_TONE); - digitalWrite(CW_KEY, 0); - - //Modified by KD8CEC, for CW Delay Time save to eeprom - //cwTimeout = millis() + CW_TIMEOUT; - 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; - - while(1){ - paddle = getPaddle(); - - // do nothing if the paddle has not been touched, unless - // we are in the cw mode and we have timed out - if (!paddle){ - //modifed by KD8CEC for auto CW Send - if (isCWAutoMode > 1) //if while auto cw sending, dont stop tx by paddle position - return; - - if (0 < cwTimeout && cwTimeout < millis()){ - cwTimeout = 0; - keyDown = 0; - stopTx(); - } - - if (!cwTimeout) - return; - - Check_Cat(2); //for uBITX on Raspberry pi, when straight keying, disconnect / test complete - continue; - } - - //if while auto cw send, stop auto cw - //but isAutoCWHold for Manual Keying with cwAutoSend - if (isCWAutoMode > 1 && isAutoCWHold == 0) - isCWAutoMode = 1; //read status - - //Remoark Debug code / Serial Use by CAT Protocol - //Serial.print("paddle:");Serial.println(paddle); - // if we are here, it is only because the key or the paddle is pressed - if (!inTx){ - keyDown = 0; - //Modified by KD8CEC, for CW Delay Time save to eeprom - //cwTimeout = millis() + CW_TIMEOUT; - cwTimeout = millis() + cwDelayTime * 10; - - startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time - updateDisplay(); - - //DelayTime Option - delay_background(delayBeforeCWStartTime * 2, 2); - } - - // star the transmission) - // we store the transmitted character in the lastPaddle - cwKeydown(); - if (paddle == PADDLE_DOT){ - //delay(cwSpeed); - delay_background(cwSpeed, 3); - lastPaddle = PADDLE_DOT; - } - else if (paddle == PADDLE_DASH){ - //delay(cwSpeed * 3); - delay_background(cwSpeed * 3, 3); - lastPaddle = PADDLE_DASH; - } - else if (paddle == PADDLE_BOTH){ //both paddles down - //depending upon what was sent last, send the other - if (lastPaddle == PADDLE_DOT) { - //delay(cwSpeed * 3); - delay_background(cwSpeed * 3, 3); - lastPaddle = PADDLE_DASH; - }else{ - //delay(cwSpeed); - delay_background(cwSpeed, 3); - lastPaddle = PADDLE_DOT; - } - } - else if (paddle == PADDLE_STRAIGHT){ - while (getPaddle() == PADDLE_STRAIGHT) { - delay(1); - Check_Cat(2); - } - lastPaddle = PADDLE_STRAIGHT; - } - cwKeyUp(); - //introduce a dot long gap between characters if the keyer was used - if (lastPaddle != PADDLE_STRAIGHT) - delay(cwSpeed); - } -} -*/ - - diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino deleted file mode 100644 index 76f2e5b..0000000 --- a/ubitx_20/ubitx_lcd_1602.ino +++ /dev/null @@ -1,790 +0,0 @@ -/************************************************************************* - KD8CEC's uBITX Display Routine for LCD1602 Parrel - 1.This is the display code for the default LCD mounted in uBITX. - 2.Some functions moved from uBITX_Ui. ------------------------------------------------------------------------------ - 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 . - -**************************************************************************/ -#include "ubitx.h" -#include "ubitx_lcd.h" - -//======================================================================== -//Begin of TinyLCD Library by KD8CEC -//======================================================================== - -#ifdef UBITX_DISPLAY_LCD1602P -/************************************************************************* - LCD1602_TINY Library for 16 x 2 LCD - Referecnce Source : LiquidCrystal.cpp - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal Library - - 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 -**************************************************************************/ - -#define LCD_Command(x) (LCD_Send(x, LOW)) -#define LCD_Write(x) (LCD_Send(x, HIGH)) - -#define UBITX_DISPLAY_LCD1602_BASE - -//Define connected PIN -#define LCD_PIN_RS 8 -#define LCD_PIN_EN 9 -uint8_t LCD_PIN_DAT[4] = {10, 11, 12, 13}; - -void write4bits(uint8_t value) -{ - for (int i = 0; i < 4; i++) - digitalWrite(LCD_PIN_DAT[i], (value >> i) & 0x01); - - digitalWrite(LCD_PIN_EN, LOW); - delayMicroseconds(1); - digitalWrite(LCD_PIN_EN, HIGH); - delayMicroseconds(1); // enable pulse must be >450ns - digitalWrite(LCD_PIN_EN, LOW); - delayMicroseconds(100); // commands need > 37us to settle -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - digitalWrite(LCD_PIN_RS, mode); - write4bits(value>>4); - write4bits(value); -} - -void LCD1602_Init() -{ - pinMode(LCD_PIN_RS, OUTPUT); - pinMode(LCD_PIN_EN, OUTPUT); - for (int i = 0; i < 4; i++) - pinMode(LCD_PIN_DAT[i], OUTPUT); - - delayMicroseconds(50); - - // Now we pull both RS and R/W low to begin commands - digitalWrite(LCD_PIN_RS, LOW); - digitalWrite(LCD_PIN_EN, LOW); - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); -} - -#endif -//======================================================================== -//End of TinyLCD Library by KD8CEC -//======================================================================== - - -//======================================================================== -//Begin of I2CTinyLCD Library by KD8CEC -//======================================================================== -#ifdef UBITX_DISPLAY_LCD1602I -#include -/************************************************************************* - I2C Tiny LCD Library - Referecnce Source : LiquidCrystal_I2C.cpp // Based on the work by DFRobot - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal_I2C Library - - 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. - Ian KD8CEC -**************************************************************************/ -#define UBITX_DISPLAY_LCD1602_BASE - -#define En B00000100 // Enable bit -#define Rw B00000010 // Read/Write bit -#define Rs B00000001 // Register select bit - -#define LCD_Command(x) (LCD_Send(x, 0)) -#define LCD_Write(x) (LCD_Send(x, Rs)) - -uint8_t _Addr; -uint8_t _displayfunction; -uint8_t _displaycontrol; -uint8_t _displaymode; -uint8_t _numlines; -uint8_t _cols; -uint8_t _rows; -uint8_t _backlightval; - -#define printIIC(args) Wire.write(args) - -void expanderWrite(uint8_t _data) -{ - Wire.beginTransmission(_Addr); - printIIC((int)(_data) | _backlightval); - Wire.endTransmission(); -} - -void pulseEnable(uint8_t _data){ - expanderWrite(_data | En); // En high - delayMicroseconds(1); // enable pulse must be >450ns - - expanderWrite(_data & ~En); // En low - delayMicroseconds(50); // commands need > 37us to settle -} - -void write4bits(uint8_t value) -{ - expanderWrite(value); - pulseEnable(value); -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - uint8_t highnib=value&0xf0; - uint8_t lownib=(value<<4)&0xf0; - write4bits((highnib)|mode); - write4bits((lownib)|mode); -} - - -// Turn the (optional) backlight off/on -void noBacklight(void) { - _backlightval=LCD_NOBACKLIGHT; - expanderWrite(0); -} - -void backlight(void) { - _backlightval=LCD_BACKLIGHT; - expanderWrite(0); -} - -void LCD1602_Init() -{ - //I2C Init - _Addr = I2C_LCD_MASTER_ADDRESS; - _cols = 16; - _rows = 2; - _backlightval = LCD_NOBACKLIGHT; - Wire.begin(); - - delay(50); - - // Now we pull both RS and R/W low to begin commands - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - delay(1000); - //put the LCD into 4 bit mode - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); -} - -/* -void LCD_Print(const char *c) -{ - for (uint8_t i = 0; i < strlen(c); i++) - { - if (*(c + i) == 0x00) return; - LCD_Write(*(c + i)); - } -} - -void LCD_SetCursor(uint8_t col, uint8_t row) -{ - LCD_Command(LCD_SETDDRAMADDR | (col + row * 0x40)); //0 : 0x00, 1 : 0x40, only for 16 x 2 lcd -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ - location &= 0x7; // we only have 8 locations 0-7 - LCD_Command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) - LCD_Write(charmap[i]); -} -*/ -#endif -//======================================================================== -//End of I2CTinyLCD Library by KD8CEC -//======================================================================== - - -//======================================================================== -// 16 X 02 LCD Routines -//Begin of Display Base Routines (Init, printLine..) -//======================================================================== -#ifdef UBITX_DISPLAY_LCD1602_BASE - -//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA -#define OPTION_SKINNYBARS - -char c[30], b[30]; -char printBuff[2][17]; //mirrors what is showing on the two lines of the display - - -void LCD_Print(const char *c) -{ - for (uint8_t i = 0; i < strlen(c); i++) - { - if (*(c + i) == 0x00) return; - LCD_Write(*(c + i)); - } -} - -void LCD_SetCursor(uint8_t col, uint8_t row) -{ - LCD_Command(LCD_SETDDRAMADDR | (col + row * 0x40)); //0 : 0x00, 1 : 0x40, only for 16 x 2 lcd -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ - location &= 0x7; // we only have 8 locations 0-7 - LCD_Command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) - LCD_Write(charmap[i]); -} - -void LCD_Init(void) -{ - LCD1602_Init(); - initMeter(); //for Meter Display -} - -// The generic routine to display one line on the LCD -void printLine(unsigned char linenmbr, const char *c) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - if (strcmp(c, printBuff[linenmbr])) { // only refresh the display when there was a change - LCD_SetCursor(0, linenmbr); // place the cursor at the beginning of the selected line - LCD_Print(c); - strcpy(printBuff[linenmbr], c); - - for (byte i = strlen(c); i < 16; i++) { // add white spaces until the end of the 16 characters line is reached - LCD_Write(' '); - } - } -} - -void printLineF(char linenmbr, const __FlashStringHelper *c) -{ - int i; - char tmpBuff[17]; - PGM_P p = reinterpret_cast(c); - - for (i = 0; i < 17; i++){ - unsigned char fChar = pgm_read_byte(p++); - tmpBuff[i] = fChar; - if (fChar == 0) - break; - } - - printLine(linenmbr, tmpBuff); -} - -#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 - - 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)); - else - break; - } - - for (byte i = lcdColumn; i < 16; i++) //Right Padding by Space - LCD_Write(' '); -} - -// short cut to print to the first line -void printLine1(const char *c) -{ - printLine(1,c); -} -// short cut to print to the first line -void printLine2(const char *c) -{ - printLine(0,c); -} - -void clearLine2() -{ - printLine2(""); - line2DisplayStatus = 0; -} - -// short cut to print to the first line -void printLine1Clear(){ - printLine(1,""); -} -// short cut to print to the first line -void printLine2Clear(){ - printLine(0, ""); -} - -void printLine2ClearAndUpdate(){ - printLine(0, ""); - line2DisplayStatus = 0; - updateDisplay(); -} - -//================================================================================== -//End of Display Base Routines -//================================================================================== - - -//================================================================================== -//Begin of User Interface Routines -//================================================================================== - -//Main Display -// this builds up the top line of the display with frequency and mode -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; // - - memset(c, 0, sizeof(c)); - - if (inTx){ - if (isCWAutoMode == 2) { - for (i = 0; i < 4; i++) - c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); - - //display Sending Index - c[4] = byteToChar(sendingCWTextIndex); - c[5] = '='; - } - else { - if (cwTimeout > 0) - strcpy(c, " CW:"); - else - strcpy(c, " TX:"); - } - } - else { - 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 "); - } - else - { - strcpy(c, "CWU "); - } - } - if (vfoActive == VFO_A) // VFO A is active - strcat(c, "A:"); - else - 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) { - if (i == 12 || i == 8) c[i] = '.'; - else { - c[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - c[i] = ' '; - } - - //remarked by KD8CEC - //already RX/TX status display, and over index (16 x 2 LCD) - //if (inTx) - // strcat(c, " TX"); - printLine(1, c); - - byte diplayVFOLine = 1; - if ((displayOption1 & 0x01) == 0x01) - diplayVFOLine = 0; - - if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) || - (vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02))) { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write((uint8_t)0); - } - else if (isCWAutoMode == 2){ - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(0x7E); - } - else - { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(':'); - } -} - - - -char line2Buffer[17]; -//KD8CEC 200Hz ST -//L14.150 200Hz ST -//U14.150 +150khz -int freqScrollPosition = 0; - -//Example Line2 Optinal Display -//immediate execution, not call by scheulder -//warning : unused parameter 'displayType' <-- ignore, this is reserve -void updateLine2Buffer(char displayType) -{ - unsigned long tmpFreq = 0; - if (ritOn) - { - strcpy(line2Buffer, "RitTX:"); - - //display frequency - tmpFreq = ritTxFrequency; - - //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; - } - - 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] = 'M'; - else - { - //example #2 - if (freqScrollPosition++ > 18) //none scroll display time - { - line2Buffer[6] = 'M'; - 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] = ' '; - - if (isIFShift) - { -// if (isDirectCall == 1) -// for (int i = 0; i < 16; i++) -// line2Buffer[i] = ' '; - - //IFShift Offset Value - line2Buffer[8] = 'I'; - line2Buffer[9] = 'F'; - - 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 & Key Type 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 == 0) - { - line2Buffer[11] = 'H'; - line2Buffer[12] = 'z'; - } - - line2Buffer[13] = ' '; - - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (sdrModeOn == 1) - { - line2Buffer[13] = 'S'; - line2Buffer[14] = 'D'; - line2Buffer[15] = 'R'; - } - else 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); - int lineNumber = 0; - if ((displayOption1 & 0x01) == 0x01) - lineNumber = 1; - - LCD_SetCursor(drawPosition, lineNumber); - - LCD_Write(lcdMeter[0]); - LCD_Write(lcdMeter[1]); - LCD_Write(lcdMeter[2]); - } -} - -char checkCount = 0; -char checkCountSMeter = 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; - } - } - - //S-Meter Display - if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) - { - int newSMeter; - -#ifdef USE_I2CSMETER - scaledSMeter = GetI2CSmeterValue(I2CMETER_CALCS); -#else - //VK2ETA S-Meter from MAX9814 TC pin / divide 4 by KD8CEC for reduce EEPromSize - newSMeter = analogRead(ANALOG_SMETER) / 4; - - //Faster attack, Slower release - //currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10) / 4; - currentSMeter = newSMeter; - - scaledSMeter = 0; - for (byte s = 8; s >= 1; s--) { - if (currentSMeter > sMeterLevels[s]) { - scaledSMeter = s; - break; - } - } -#endif - - DisplayMeter(0, scaledSMeter, 13); - checkCountSMeter = 0; //Reset Latency time - } //end of S-Meter - - } -} - -//AutoKey LCD Display Routine -void Display_AutoKeyTextIndex(byte textIndex) -{ - byte diplayAutoCWLine = 0; - - if ((displayOption1 & 0x01) == 0x01) - diplayAutoCWLine = 1; - LCD_SetCursor(0, diplayAutoCWLine); - LCD_Write(byteToChar(textIndex)); - LCD_Write(':'); -} - -void DisplayCallsign(byte callSignLength) -{ - printLineFromEEPRom(0, 0, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT) - //delay(500); -} - -void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo) -{ - printLineF(1, fwVersionInfo); -} - -#endif diff --git a/ubitx_20/ubitx_lcd_1602Dual.ino b/ubitx_20/ubitx_lcd_1602Dual.ino deleted file mode 100644 index 48598cb..0000000 --- a/ubitx_20/ubitx_lcd_1602Dual.ino +++ /dev/null @@ -1,727 +0,0 @@ -/************************************************************************* - KD8CEC's uBITX Display Routine for LCD1602 Dual LCD - 1.This is the display code for the 16x02 Dual LCD - 2.Some functions moved from uBITX_Ui. ------------------------------------------------------------------------------ - 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 . - -**************************************************************************/ -#include "ubitx.h" -#include "ubitx_lcd.h" - -//======================================================================== -//Begin of I2CTinyLCD Library for Dual LCD by KD8CEC -//======================================================================== -#ifdef UBITX_DISPLAY_LCD1602I_DUAL - -#include -/************************************************************************* - I2C Tiny LCD Library - Referecnce Source : LiquidCrystal_I2C.cpp // Based on the work by DFRobot - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal_I2C Library - - 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. - Ian KD8CEC -**************************************************************************/ -#define UBITX_DISPLAY_LCD1602_BASE - -#define En B00000100 // Enable bit -#define Rw B00000010 // Read/Write bit -#define Rs B00000001 // Register select bit - -#define LCD_Command(x) (LCD_Send(x, 0)) -#define LCD_Write(x) (LCD_Send(x, Rs)) - -uint8_t _Addr; -uint8_t _displayfunction; -uint8_t _displaycontrol; -uint8_t _displaymode; -uint8_t _numlines; -uint8_t _cols; -uint8_t _rows; -uint8_t _backlightval; - -#define printIIC(args) Wire.write(args) - -void expanderWrite(uint8_t _data) -{ - Wire.beginTransmission(_Addr); - printIIC((int)(_data) | _backlightval); - Wire.endTransmission(); -} - -void pulseEnable(uint8_t _data){ - expanderWrite(_data | En); // En high - delayMicroseconds(1); // enable pulse must be >450ns - - expanderWrite(_data & ~En); // En low - delayMicroseconds(50); // commands need > 37us to settle -} - -void write4bits(uint8_t value) -{ - expanderWrite(value); - pulseEnable(value); -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - uint8_t highnib=value&0xf0; - uint8_t lownib=(value<<4)&0xf0; - write4bits((highnib)|mode); - write4bits((lownib)|mode); -} - - -// Turn the (optional) backlight off/on -void noBacklight(void) { - _backlightval=LCD_NOBACKLIGHT; - expanderWrite(0); -} - -void backlight(void) { - _backlightval=LCD_BACKLIGHT; - expanderWrite(0); -} - -void LCD1602_Dual_Init() -{ - //I2C Init - _cols = 16; - _rows = 2; - _backlightval = LCD_NOBACKLIGHT; - Wire.begin(); - - delay(50); - - // Now we pull both RS and R/W low to begin commands - _Addr = I2C_LCD_MASTER_ADDRESS; - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - _Addr = I2C_LCD_SECOND_ADDRESS; - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - delay(1000); - //put the LCD into 4 bit mode - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - _Addr = I2C_LCD_MASTER_ADDRESS; - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); - - - _Addr = I2C_LCD_SECOND_ADDRESS; - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); - - //Change to Default LCD (Master) - _Addr = I2C_LCD_MASTER_ADDRESS; -} - - -//======================================================================== -// 16 X 02 LCD Routines -//Begin of Display Base Routines (Init, printLine..) -//======================================================================== - -void LCD_Print(const char *c) -{ - for (uint8_t i = 0; i < strlen(c); i++) - { - if (*(c + i) == 0x00) return; - LCD_Write(*(c + i)); - } -} - -const int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; -void LCD_SetCursor(uint8_t col, uint8_t row) -{ - LCD_Command(LCD_SETDDRAMADDR | (col + row_offsets[row])); //0 : 0x00, 1 : 0x40, only for 20 x 4 lcd -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ - location &= 0x7; // we only have 8 locations 0-7 - LCD_Command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) - LCD_Write(charmap[i]); -} - -//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA -//#define OPTION_SKINNYBARS - -char c[30], b[30]; -char printBuff[4][20]; //mirrors what is showing on the two lines of the display - -void LCD_Init(void) -{ - LCD1602_Dual_Init(); - - _Addr = I2C_LCD_SECOND_ADDRESS; - initMeter(); //for Meter Display //when dual LCD, S.Meter on second LCD - _Addr = I2C_LCD_MASTER_ADDRESS; -} - - -// The generic routine to display one line on the LCD -void printLine(unsigned char linenmbr, const char *c) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - if (strcmp(c, printBuff[linenmbr])) { // only refresh the display when there was a change - LCD_SetCursor(0, linenmbr); // place the cursor at the beginning of the selected line - LCD_Print(c); - strcpy(printBuff[linenmbr], c); - - for (byte i = strlen(c); i < 20; i++) { // add white spaces until the end of the 20 characters line is reached - LCD_Write(' '); - } - } -} - -void printLineF(char linenmbr, const __FlashStringHelper *c) -{ - int i; - char tmpBuff[21]; - PGM_P p = reinterpret_cast(c); - - for (i = 0; i < 21; i++){ - unsigned char fChar = pgm_read_byte(p++); - tmpBuff[i] = fChar; - if (fChar == 0) - break; - } - - printLine(linenmbr, tmpBuff); -} - -#define LCD_MAX_COLUMN 20 -void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetTtype) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - - 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)); - else - break; - } - - for (byte i = lcdColumn; i < 20; i++) //Right Padding by Space - LCD_Write(' '); -} - -// short cut to print to the first line -void printLine1(const char *c) -{ - printLine(1,c); -} -// short cut to print to the first line -void printLine2(const char *c) -{ - printLine(0,c); -} - -void clearLine2() -{ - printLine2(""); - line2DisplayStatus = 0; -} - -// short cut to print to the first line -void printLine1Clear(){ - printLine(1,""); -} -// short cut to print to the first line -void printLine2Clear(){ - printLine(0, ""); -} - -void printLine2ClearAndUpdate(){ - printLine(0, ""); - line2DisplayStatus = 0; - updateDisplay(); -} - -//================================================================================== -//End of Display Base Routines -//================================================================================== - - -//================================================================================== -//Begin of User Interface Routines -//================================================================================== - -//Main Display -// this builds up the top line of the display with frequency and mode -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 - // i also Very TNX Purdum for good source code - int i; - unsigned long tmpFreq = frequency; // - - memset(c, 0, sizeof(c)); - - if (inTx){ - if (isCWAutoMode == 2) { - for (i = 0; i < 4; i++) - c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); - - //display Sending Index - c[4] = byteToChar(sendingCWTextIndex); - c[5] = '='; - } - else { - if (cwTimeout > 0) - strcpy(c, " CW:"); - else - strcpy(c, " TX:"); - } - } - else { - 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 "); - } - else - { - strcpy(c, "CWU "); - } - } - - if (vfoActive == VFO_A) // VFO A is active - strcat(c, "A:"); - else - 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) { - if (i == 12 || i == 8) c[i] = '.'; - else { - c[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - c[i] = ' '; - } - - //remarked by KD8CEC - //already RX/TX status display, and over index (16 x 2 LCD) - printLine(1, c); - - byte diplayVFOLine = 1; - if ((displayOption1 & 0x01) == 0x01) - diplayVFOLine = 0; - - if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) || - (vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02))) { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write((uint8_t)0); - } - else if (isCWAutoMode == 2){ - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(0x7E); - } - else - { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(':'); - } -} - - - -char line2Buffer[20]; -//KD8CEC 200Hz ST -//L14.150 200Hz ST -//U14.150 +150khz -int freqScrollPosition = 0; - -//Example Line2 Optinal Display -//immediate execution, not call by scheulder -//warning : unused parameter 'displayType' <-- ignore, this is reserve -void updateLine2Buffer(char displayType) -{ - unsigned long tmpFreq = 0; - if (ritOn) - { - strcpy(line2Buffer, "RitTX:"); - - //display frequency - tmpFreq = ritTxFrequency; - - //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; - } - - 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] = ' '; - } - - memset(&line2Buffer[10], ' ', 10); - - if (isIFShift) - { - line2Buffer[6] = 'M'; - line2Buffer[7] = ' '; - //IFShift Offset Value - line2Buffer[8] = 'I'; - line2Buffer[9] = 'F'; - - 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); - - for (int i = 12; i < 17; i++) - { - if (line2Buffer[i] == 0) - line2Buffer[i] = ' '; - } - } // end of display IF - else // step & Key Type display - { - //Step - long tmpStep = arTuneStep[tuneStepIndex -1]; - - byte isStepKhz = 0; - if (tmpStep >= 1000) - { - isStepKhz = 2; - } - - for (int i = 13; i >= 11 - isStepKhz; i--) { - if (tmpStep > 0) { - line2Buffer[i + isStepKhz] = tmpStep % 10 + 0x30; - tmpStep /= 10; - } - else - line2Buffer[i +isStepKhz] = ' '; - } - - if (isStepKhz == 0) - { - line2Buffer[14] = 'H'; - line2Buffer[15] = 'z'; - } - } - - //line2Buffer[17] = ' '; - /* ianlee - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - line2Buffer[18] = 'S'; - line2Buffer[19] = 'T'; - } - else if (cwKeyType == 1) - { - line2Buffer[18] = 'I'; - line2Buffer[19] = 'A'; - } - else - { - line2Buffer[18] = 'I'; - line2Buffer[19] = '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); - - LCD_SetCursor(drawPosition, 0); - LCD_Write('S'); - - LCD_Write(':'); - for (int i = 0; i < 7; i++) - LCD_Write(lcdMeter[i]); - } -} - - -char checkCount = 0; -char checkCountSMeter = 0; - -char beforeKeyType = -1; -char displaySDRON = 0; - -//execute interval : 0.25sec -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; - - //check change CW Key Type - if (beforeKeyType != cwKeyType) - { - _Addr = I2C_LCD_SECOND_ADDRESS; - LCD_SetCursor(10, 0); - LCD_Write('K'); - LCD_Write('E'); - LCD_Write('Y'); - LCD_Write(':'); - - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - LCD_Write('S'); - LCD_Write('T'); - } - else if (cwKeyType == 1) - { - LCD_Write('I'); - LCD_Write('A'); - } - else - { - LCD_Write('I'); - LCD_Write('B'); - } - - beforeKeyType = cwKeyType; - _Addr = I2C_LCD_MASTER_ADDRESS; - } //Display Second Screen - - } - } - - //EX for Meters - - //S-Meter Display - _Addr = I2C_LCD_SECOND_ADDRESS; - if (sdrModeOn == 1) - { - if (displaySDRON == 0) //once display - { - displaySDRON = 1; - LCD_SetCursor(0, 0); - LCD_Write('S'); - LCD_Write('D'); - LCD_Write('R'); - LCD_Write(' '); - LCD_Write('M'); - LCD_Write('O'); - LCD_Write('D'); - LCD_Write('E'); - } - } - else if (((displayOption1 & 0x08) == 0x08) && (++checkCountSMeter > 3)) - { - int newSMeter; - displaySDRON = 0; - -#ifdef USE_I2CSMETER - scaledSMeter = GetI2CSmeterValue(I2CMETER_CALCS); -#else - //VK2ETA S-Meter from MAX9814 TC pin / divide 4 by KD8CEC for reduce EEPromSize - newSMeter = analogRead(ANALOG_SMETER) / 4; - - //Faster attack, Slower release - //currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10); - //currentSMeter = (currentSMeter * 3 + newSMeter * 7) / 10; //remarked becaused of have already Latency time - currentSMeter = newSMeter; - - scaledSMeter = 0; - for (byte s = 8; s >= 1; s--) { - if (currentSMeter > sMeterLevels[s]) { - scaledSMeter = s; - break; - } - } -#endif - - DisplayMeter(0, scaledSMeter, 0); - checkCountSMeter = 0; - } //end of S-Meter - _Addr = I2C_LCD_MASTER_ADDRESS; - - - } -} - -//AutoKey LCD Display Routine -void Display_AutoKeyTextIndex(byte textIndex) -{ - byte diplayAutoCWLine = 0; - - if ((displayOption1 & 0x01) == 0x01) - diplayAutoCWLine = 1; - LCD_SetCursor(0, diplayAutoCWLine); - LCD_Write(byteToChar(textIndex)); - LCD_Write(':'); -} - -void DisplayCallsign(byte callSignLength) -{ - _Addr = I2C_LCD_SECOND_ADDRESS; - printLineFromEEPRom(1, 16 - userCallsignLength, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT) - _Addr = I2C_LCD_MASTER_ADDRESS; -} - -void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo) -{ - _Addr = I2C_LCD_SECOND_ADDRESS; - printLineF(1, fwVersionInfo); - _Addr = I2C_LCD_MASTER_ADDRESS; -} - -#endif diff --git a/ubitx_20/ubitx_lcd_2004.ino b/ubitx_20/ubitx_lcd_2004.ino deleted file mode 100644 index 06d44fa..0000000 --- a/ubitx_20/ubitx_lcd_2004.ino +++ /dev/null @@ -1,743 +0,0 @@ -/************************************************************************* - KD8CEC's uBITX Display Routine for LCD2004 Parrel & I2C - 1.This is the display code for the 20x04 LCD - 2.Some functions moved from uBITX_Ui. ------------------------------------------------------------------------------ - 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 . - -**************************************************************************/ -#include "ubitx.h" -#include "ubitx_lcd.h" - -//======================================================================== -//Begin of TinyLCD Library by KD8CEC -//======================================================================== - -#ifdef UBITX_DISPLAY_LCD2004P -/************************************************************************* - LCD2004TINY Library for 20 x 4 LCD - Referecnce Source : LiquidCrystal.cpp - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal Library - - 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 -**************************************************************************/ -#define LCD_Command(x) (LCD_Send(x, LOW)) -#define LCD_Write(x) (LCD_Send(x, HIGH)) - -#define UBITX_DISPLAY_LCD2004_BASE - -//Define connected PIN -#define LCD_PIN_RS 8 -#define LCD_PIN_EN 9 -uint8_t LCD_PIN_DAT[4] = {10, 11, 12, 13}; - -void write4bits(uint8_t value) -{ - for (int i = 0; i < 4; i++) - digitalWrite(LCD_PIN_DAT[i], (value >> i) & 0x01); - - digitalWrite(LCD_PIN_EN, LOW); - delayMicroseconds(1); - digitalWrite(LCD_PIN_EN, HIGH); - delayMicroseconds(1); // enable pulse must be >450ns - digitalWrite(LCD_PIN_EN, LOW); - delayMicroseconds(100); // commands need > 37us to settle -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - digitalWrite(LCD_PIN_RS, mode); - write4bits(value>>4); - write4bits(value); -} - -void LCD2004_Init() -{ - pinMode(LCD_PIN_RS, OUTPUT); - pinMode(LCD_PIN_EN, OUTPUT); - for (int i = 0; i < 4; i++) - pinMode(LCD_PIN_DAT[i], OUTPUT); - - delayMicroseconds(50); - - // Now we pull both RS and R/W low to begin commands - digitalWrite(LCD_PIN_RS, LOW); - digitalWrite(LCD_PIN_EN, LOW); - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); -} -#endif -//======================================================================== -//End of TinyLCD Library by KD8CEC -//======================================================================== - - - -//======================================================================== -//Begin of I2CTinyLCD Library by KD8CEC -//======================================================================== -#ifdef UBITX_DISPLAY_LCD2004I - -#include -/************************************************************************* - I2C Tiny LCD Library - Referecnce Source : LiquidCrystal_I2C.cpp // Based on the work by DFRobot - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal_I2C Library - - 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. - Ian KD8CEC -**************************************************************************/ -#define UBITX_DISPLAY_LCD2004_BASE - -#define En B00000100 // Enable bit -#define Rw B00000010 // Read/Write bit -#define Rs B00000001 // Register select bit - -#define LCD_Command(x) (LCD_Send(x, 0)) -#define LCD_Write(x) (LCD_Send(x, Rs)) - -uint8_t _Addr; -uint8_t _displayfunction; -uint8_t _displaycontrol; -uint8_t _displaymode; -uint8_t _numlines; -uint8_t _cols; -uint8_t _rows; -uint8_t _backlightval; - -#define printIIC(args) Wire.write(args) - -void expanderWrite(uint8_t _data) -{ - Wire.beginTransmission(_Addr); - printIIC((int)(_data) | _backlightval); - Wire.endTransmission(); -} - -void pulseEnable(uint8_t _data){ - expanderWrite(_data | En); // En high - delayMicroseconds(1); // enable pulse must be >450ns - - expanderWrite(_data & ~En); // En low - delayMicroseconds(50); // commands need > 37us to settle -} - -void write4bits(uint8_t value) -{ - expanderWrite(value); - pulseEnable(value); -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - uint8_t highnib=value&0xf0; - uint8_t lownib=(value<<4)&0xf0; - write4bits((highnib)|mode); - write4bits((lownib)|mode); -} - - -// Turn the (optional) backlight off/on -void noBacklight(void) { - _backlightval=LCD_NOBACKLIGHT; - expanderWrite(0); -} - -void backlight(void) { - _backlightval=LCD_BACKLIGHT; - expanderWrite(0); -} - -void LCD2004_Init() -{ - //I2C Init - _Addr = I2C_LCD_MASTER_ADDRESS; - _cols = 20; - _rows = 4; - _backlightval = LCD_NOBACKLIGHT; - Wire.begin(); - - delay(50); - - // Now we pull both RS and R/W low to begin commands - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - delay(1000); - //put the LCD into 4 bit mode - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); -} -#endif -//======================================================================== -//End of I2CTinyLCD Library by KD8CEC -//======================================================================== - - -//======================================================================== -// 20 X 04 LCD Routines -//Begin of Display Base Routines (Init, printLine..) -//======================================================================== -#ifdef UBITX_DISPLAY_LCD2004_BASE - -void LCD_Print(const char *c) -{ - for (uint8_t i = 0; i < strlen(c); i++) - { - if (*(c + i) == 0x00) return; - LCD_Write(*(c + i)); - } -} - -const int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; -void LCD_SetCursor(uint8_t col, uint8_t row) -{ - LCD_Command(LCD_SETDDRAMADDR | (col + row_offsets[row])); //0 : 0x00, 1 : 0x40, only for 20 x 4 lcd -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ - location &= 0x7; // we only have 8 locations 0-7 - LCD_Command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) - LCD_Write(charmap[i]); -} - -//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA -//#define OPTION_SKINNYBARS - -char c[30], b[30]; -char printBuff[4][21]; //mirrors what is showing on the two lines of the display - -void LCD_Init(void) -{ - LCD2004_Init(); - initMeter(); //for Meter Display -} - - -// The generic routine to display one line on the LCD -void printLine(unsigned char linenmbr, const char *c) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - if (strcmp(c, printBuff[linenmbr])) { // only refresh the display when there was a change - LCD_SetCursor(0, linenmbr); // place the cursor at the beginning of the selected line - LCD_Print(c); - strcpy(printBuff[linenmbr], c); - - for (byte i = strlen(c); i < 20; i++) { // add white spaces until the end of the 20 characters line is reached - LCD_Write(' '); - } - } -} - -void printLineF(char linenmbr, const __FlashStringHelper *c) -{ - int i; - char tmpBuff[21]; - PGM_P p = reinterpret_cast(c); - - for (i = 0; i < 21; i++){ - unsigned char fChar = pgm_read_byte(p++); - tmpBuff[i] = fChar; - if (fChar == 0) - break; - } - - printLine(linenmbr, tmpBuff); -} - -#define LCD_MAX_COLUMN 20 -void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetTtype) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - - 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)); - else - break; - } - - for (byte i = lcdColumn; i < 20; i++) //Right Padding by Space - LCD_Write(' '); -} - -// short cut to print to the first line -void printLine1(const char *c) -{ - printLine(1,c); -} -// short cut to print to the first line -void printLine2(const char *c) -{ - printLine(0,c); -} - -void clearLine2() -{ - printLine2(""); - line2DisplayStatus = 0; -} - -// short cut to print to the first line -void printLine1Clear(){ - printLine(1,""); -} -// short cut to print to the first line -void printLine2Clear(){ - printLine(0, ""); -} - -void printLine2ClearAndUpdate(){ - printLine(0, ""); - line2DisplayStatus = 0; - updateDisplay(); -} - -//================================================================================== -//End of Display Base Routines -//================================================================================== - - -//================================================================================== -//Begin of User Interface Routines -//================================================================================== - -//Main Display -// this builds up the top line of the display with frequency and mode -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 - // i also Very TNX Purdum for good source code - int i; - unsigned long tmpFreq = frequency; // - - memset(c, 0, sizeof(c)); - - if (inTx){ - if (isCWAutoMode == 2) { - for (i = 0; i < 4; i++) - c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); - - //display Sending Index - c[4] = byteToChar(sendingCWTextIndex); - c[5] = '='; - } - else { - if (cwTimeout > 0) - strcpy(c, " CW:"); - else - strcpy(c, " TX:"); - } - } - else { - 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 "); - } - else - { - strcpy(c, "CWU "); - } - } - - if (vfoActive == VFO_A) // VFO A is active - strcat(c, "A:"); - else - 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) { - if (i == 12 || i == 8) c[i] = '.'; - else { - c[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - c[i] = ' '; - } - - if (sdrModeOn) - strcat(c, " SDR"); - else - strcat(c, " SPK"); - - //remarked by KD8CEC - //already RX/TX status display, and over index (20 x 4 LCD) - //if (inTx) - // strcat(c, " TX"); - printLine(1, c); - - byte diplayVFOLine = 1; - if ((displayOption1 & 0x01) == 0x01) - diplayVFOLine = 0; - - if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) || - (vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02))) { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write((uint8_t)0); - } - else if (isCWAutoMode == 2){ - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(0x7E); - } - else - { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(':'); - } -} - - - -char line2Buffer[20]; -//KD8CEC 200Hz ST -//L14.150 200Hz ST -//U14.150 +150khz -int freqScrollPosition = 0; - -//Example Line2 Optinal Display -//immediate execution, not call by scheulder -//warning : unused parameter 'displayType' <-- ignore, this is reserve -void updateLine2Buffer(char displayType) -{ - unsigned long tmpFreq = 0; - if (ritOn) - { - strcpy(line2Buffer, "RitTX:"); - - //display frequency - tmpFreq = ritTxFrequency; - - //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; - } - - 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] = ' '; - } - - memset(&line2Buffer[10], ' ', 10); - - if (isIFShift) - { - line2Buffer[6] = 'M'; - line2Buffer[7] = ' '; - //IFShift Offset Value - line2Buffer[8] = 'I'; - line2Buffer[9] = 'F'; - - 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); - - for (int i = 12; i < 17; i++) - { - if (line2Buffer[i] == 0) - line2Buffer[i] = ' '; - } - } // end of display IF - else // step & Key Type display - { - //Step - long tmpStep = arTuneStep[tuneStepIndex -1]; - - byte isStepKhz = 0; - if (tmpStep >= 1000) - { - isStepKhz = 2; - } - - for (int i = 14; i >= 12 - isStepKhz; i--) { - if (tmpStep > 0) { - line2Buffer[i + isStepKhz] = tmpStep % 10 + 0x30; - tmpStep /= 10; - } - else - line2Buffer[i +isStepKhz] = ' '; - } - - if (isStepKhz == 0) - { - line2Buffer[15] = 'H'; - line2Buffer[16] = 'z'; - } - } - - line2Buffer[17] = ' '; - - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - line2Buffer[18] = 'S'; - line2Buffer[19] = 'T'; - } - else if (cwKeyType == 1) - { - line2Buffer[18] = 'I'; - line2Buffer[19] = 'A'; - } - else - { - line2Buffer[18] = 'I'; - line2Buffer[19] = '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); - - LCD_SetCursor(drawPosition, 2); - LCD_Write('S'); - LCD_Write(':'); - for (int i = 0; i < 7; i++) //meter 5 + +db 1 = 6 - LCD_Write(lcdMeter[i]); - } -} - -char checkCount = 0; -char checkCountSMeter = 0; - -//execute interval : 0.25sec -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++, 0); - if (testValue > 30) - testValue = 0; - */ - - //Sample - //DisplayMeter(0, analogRead(ANALOG_SMETER) / 30, 0); - //DisplayMeter(0, analogRead(ANALOG_SMETER) / 10, 0); - //delay_background(10, 0); - //DisplayMeter(0, analogRead(ANALOG_SMETER), 0); - //if (testValue > 30) - // testValue = 0; - - //S-Meter Display - if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) - { - int newSMeter; - -#ifdef USE_I2CSMETER - scaledSMeter = GetI2CSmeterValue(I2CMETER_CALCS); -#else - //VK2ETA S-Meter from MAX9814 TC pin - newSMeter = analogRead(ANALOG_SMETER) / 4; - - //Faster attack, Slower release - //currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10); - //currentSMeter = ((currentSMeter * 7 + newSMeter * 3) + 5) / 10; - currentSMeter = newSMeter; - - scaledSMeter = 0; - for (byte s = 8; s >= 1; s--) { - if (currentSMeter > sMeterLevels[s]) { - scaledSMeter = s; - break; - } - } -#endif - - DisplayMeter(0, scaledSMeter, 0); - checkCountSMeter = 0; //Reset Latency time - } //end of S-Meter - - } -} - -//AutoKey LCD Display Routine -void Display_AutoKeyTextIndex(byte textIndex) -{ - byte diplayAutoCWLine = 0; - - if ((displayOption1 & 0x01) == 0x01) - diplayAutoCWLine = 1; - LCD_SetCursor(0, diplayAutoCWLine); - LCD_Write(byteToChar(textIndex)); - LCD_Write(':'); -} - -void DisplayCallsign(byte callSignLength) -{ - printLineFromEEPRom(3, 20 - userCallsignLength, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT) -} - -void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo) -{ - printLineF(3, fwVersionInfo); -} - -#endif diff --git a/ubitx_20/ubitx_lcd_nextion.ino b/ubitx_20/ubitx_lcd_nextion.ino index 62667af..573091e 100644 --- a/ubitx_20/ubitx_lcd_nextion.ino +++ b/ubitx_20/ubitx_lcd_nextion.ino @@ -93,7 +93,7 @@ char L_ritOn; unsigned long L_ritTxFrequency; //ritTxFrequency #define CMD_IS_TX 't' //ct -char L_inTx; +bool L_inTx; #define CMD_IS_DIALLOCK 'l' //cl byte L_isDialLock; //byte isDialLock @@ -535,7 +535,7 @@ void sendUIData(int sendType) if (L_inTx != inTx) { L_inTx = inTx; - SendCommand1Num(CMD_IS_TX, L_inTx); + SendCommand1Num(CMD_IS_TX, L_inTx ? 1 : 0); } //#define CMD_IS_DIALLOCK 'l' //cl diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index 502bd94..31622f1 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -1528,7 +1528,7 @@ void factoryCalibration(int btn){ { if (digitalRead(PTT) == LOW && !keyDown) - cwKeydown(); + cwKeyDown(); if (digitalRead(PTT) == HIGH && keyDown) cwKeyUp(); @@ -1550,7 +1550,7 @@ void factoryCalibration(int btn){ } cwTimeout = 0; - keyDown = 0; + keyDown = false; stopTx(); printLineF2(F("Calibration set!")); diff --git a/ubitx_20/ubitx_si5351.ino b/ubitx_20/ubitx_si5351.ino index e230bfd..fe3063c 100644 --- a/ubitx_20/ubitx_si5351.ino +++ b/ubitx_20/ubitx_si5351.ino @@ -145,9 +145,9 @@ void si5351_set_calibration(int32_t cal){ void SetCarrierFreq() { - unsigned long appliedCarrier = ((cwMode == 0 ? usbCarrier : cwmCarrier) + (isIFShift && (inTx == 0) ? ifShiftValue : 0)); + unsigned long appliedCarrier = ((cwMode == 0 ? usbCarrier : cwmCarrier) + (isIFShift && !inTx ? ifShiftValue : 0)); //si5351bx_setfreq(0, (sdrModeOn ? 0 : appliedCarrier)); - si5351bx_setfreq(0, ((sdrModeOn && (inTx == 0)) ? 0 : appliedCarrier)); //found bug by KG4GEK + si5351bx_setfreq(0, ((sdrModeOn && !inTx) ? 0 : appliedCarrier)); //found bug by KG4GEK /*