Support Nextion LCD

This commit is contained in:
phdlee 2018-06-09 17:13:26 +09:00
parent 7c8088f753
commit e81413fa02
7 changed files with 1516 additions and 18 deletions

View File

@ -297,17 +297,18 @@ void controlAutoCW(){
displayScrolStep = 0; displayScrolStep = 0;
} }
#ifdef USE_SW_SERIAL
//Not need Scroll
//Display_AutoKeyTextIndex(selectedCWTextIndex);
SendCommand1Num('w', selectedCWTextIndex); //Index
SendEEPromData('a', cwStartIndex + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0) ; //Data
SendCommand1Num('y', 1); //Send YN
isNeedScroll = 0;
#else
printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0); printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0);
//byte diplayAutoCWLine = 0;
//if ((displayOption1 & 0x01) == 0x01)
// diplayAutoCWLine = 1;
Display_AutoKeyTextIndex(selectedCWTextIndex);
//lcd.setCursor(0, diplayAutoCWLine);
//lcd.write(byteToChar(selectedCWTextIndex));
//lcd.write(':');
isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0; isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0;
Display_AutoKeyTextIndex(selectedCWTextIndex);
#endif
scrollDispayTime = millis() + scrollSpeed; scrollDispayTime = millis() + scrollSpeed;
beforeCWTextIndex = selectedCWTextIndex; beforeCWTextIndex = selectedCWTextIndex;
} }

View File

@ -0,0 +1,354 @@
/*
KD8CEC, Ian Lee
-----------------------------------------------------------------------
It is a library rewritten in C format based on SoftwareSerial.c.
I tried to use as much as possible without modifying the SoftwareSerial.
But eventually I had to modify the code.
I rewrote it in C for the following reasons.
- Problems occurred when increasing Program Size and Program Memory
- We had to reduce the program size.
Of course, Software Serial is limited to one.
- reduce the steps for transmitting and receiving
useage
extern void SWSerial_Begin(long speedBaud);
extern void SWSerial_Write(uint8_t b);
extern int SWSerial_Available(void);
extern int SWSerial_Read(void);
extern void SWSerial_Print(uint8_t *b);
If you use Softwreserial library instead of this library, you can modify the code as shown below.
I kept the function name of SoftwareSerial so you only need to modify a few lines of code.
define top of source code
#include <SoftwareSerial.h>
SoftwareSerial sSerial(10, 11); // RX, TX
replace source code
SWSerial_Begin to sSerial.begin
SWSerial_Write to sSerial.write
SWSerial_Available to sSerial.available
SWSerial_Read to sSerial.read
-----------------------------------------------------------------------
License
All licenses for the source code are subject to the license of the original source SoftwareSerial Library.
However, if you use or modify this code, please keep the all comments in this source code.
KD8CEC
-----------------------------------------------------------------------
License from SoftwareSerial
-----------------------------------------------------------------------
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
Multi-instance software serial library for Arduino/Wiring
-- Interrupt-driven receive and other improvements by ladyada
(http://ladyada.net)
-- Tuning, circular buffer, derivation from class Print/Stream,
multi-instance support, porting to 8MHz processors,
various optimizations, PROGMEM delay tables, inverse logic and
direct port writing by Mikal Hart (http://www.arduiniana.org)
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
The latest version of this library can always be found at
http://arduiniana.org.
*/
#include <arduino.h>
//================================================================
//Public Variable
//================================================================
#define TX_PIN 9
#define RX_PIN 8
#define _SS_MAX_RX_BUFF 20 // RX buffer size
#define PRINT_MAX_LENGTH 30
//================================================================
//Internal Variable from SoftwareSerial.c and SoftwareSerial.h
//================================================================
//variable from softwareserial.c and softwareserial.h
static uint8_t swr_receive_buffer[_SS_MAX_RX_BUFF];
volatile uint8_t *_transmitPortRegister; //Write Port Register
uint8_t transmit_RegMask; //use Mask bit 1
uint8_t transmit_InvMask; //use mask bit 0
volatile uint8_t *_receivePortRegister; //Read Port Register
uint8_t _receiveBitMask;
//delay value for Bit
uint16_t _tx_delay;
//delay value for Receive
uint16_t _rx_delay_stopbit;
uint16_t _rx_delay_centering;
uint16_t _rx_delay_intrabit;
//Customize for uBITX Protocol
int8_t receiveIndex = 0;
int8_t receivedCommandLength = 0;
int8_t ffCount = 0;
//Values for Receive Buffer
//uint16_t _buffer_overflow;
//static volatile uint8_t _receive_buffer_head;
//static volatile uint8_t _receive_buffer_tail;
//Values for Interrupt (check Start Bit)
volatile uint8_t *_pcint_maskreg;
uint8_t _pcint_maskvalue;
//================================================================
//Internal Function from SoftwareSerial.c
//================================================================
uint16_t subtract_cap(uint16_t num, uint16_t sub)
{
if (num > sub)
return num - sub;
else
return 1;
}
inline void tunedDelay(uint16_t delay)
{
_delay_loop_2(delay);
}
void setRxIntMsk(bool enable)
{
if (enable)
*_pcint_maskreg |= _pcint_maskvalue;
else
*_pcint_maskreg &= ~_pcint_maskvalue;
}
uint8_t rx_pin_read()
{
return *_receivePortRegister & _receiveBitMask;
}
//
// The receive routine called by the interrupt handler
//
void softSerail_Recv()
{
#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Preserve the registers that the compiler misses
// (courtesy of Arduino forum user *etracer*)
asm volatile(
"push r18 \n\t"
"push r19 \n\t"
"push r20 \n\t"
"push r21 \n\t"
"push r22 \n\t"
"push r23 \n\t"
"push r26 \n\t"
"push r27 \n\t"
::);
#endif
uint8_t d = 0;
// If RX line is high, then we don't see any start bit
// so interrupt is probably not for us
if (!rx_pin_read()) //Start Bit
{
// Disable further interrupts during reception, this prevents
// triggering another interrupt directly after we return, which can
// cause problems at higher baudrates.
setRxIntMsk(false);
// Wait approximately 1/2 of a bit width to "center" the sample
tunedDelay(_rx_delay_centering);
// Read each of the 8 bits
for (uint8_t i=8; i > 0; --i)
{
tunedDelay(_rx_delay_intrabit);
d >>= 1;
if (rx_pin_read())
d |= 0x80;
}
if (receivedCommandLength == 0) //check Already Command
{
//Set Received Data
swr_receive_buffer[receiveIndex++] = d;
//Finded Command
if (d == 0x73 && ffCount > 1 && receiveIndex > 6)
{
receivedCommandLength = receiveIndex;
receiveIndex = 0;
ffCount = 0;
}
else if (receiveIndex > _SS_MAX_RX_BUFF)
{
//Buffer Overflow
receiveIndex = 0;
ffCount = 0;
}
else if (d == 0xFF)
{
ffCount++;
}
else
{
ffCount = 0;
}
}
// skip the stop bit
tunedDelay(_rx_delay_stopbit);
// Re-enable interrupts when we're sure to be inside the stop bit
setRxIntMsk(true);
}
#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Restore the registers that the compiler misses
asm volatile(
"pop r27 \n\t"
"pop r26 \n\t"
"pop r23 \n\t"
"pop r22 \n\t"
"pop r21 \n\t"
"pop r20 \n\t"
"pop r19 \n\t"
"pop r18 \n\t"
::);
#endif
}
ISR(PCINT0_vect)
{
softSerail_Recv();
}
//================================================================
//Public Function from SoftwareSerial.c and modified and create
//================================================================
// Read data from buffer
void SWSerial_Read(uint8_t * receive_cmdBuffer)
{
for (int i = 0; i < receivedCommandLength; i++)
receive_cmdBuffer[i] = swr_receive_buffer[i];
}
/*
int SWSerial_Read(void)
{
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail)
return -1;
// Read from "head"
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
return d;
}
int SWSerial_Available(void)
{
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
*/
void SWSerial_Write(uint8_t b)
{
volatile uint8_t *reg = _transmitPortRegister;
uint8_t oldSREG = SREG;
uint16_t delay = _tx_delay;
cli(); // turn off interrupts for a clean txmit
// Write the start bit
*reg &= transmit_InvMask;
tunedDelay(delay);
// Write each of the 8 bits
for (uint8_t i = 8; i > 0; --i)
{
if (b & 1) // choose bit
*reg |= transmit_RegMask; // send 1
else
*reg &= transmit_InvMask; // send 0
tunedDelay(delay);
b >>= 1;
}
// restore pin to natural state
*reg |= transmit_RegMask;
SREG = oldSREG; // turn interrupts back on
tunedDelay(_tx_delay);
}
void SWSerial_Print(uint8_t *b)
{
for (int i = 0; i < PRINT_MAX_LENGTH; i++)
{
if (b[i] == 0x00)
break;
else
SWSerial_Write(b[i]);
}
}
void SWSerial_Begin(long speedBaud)
{
//INT TX_PIN
digitalWrite(TX_PIN, HIGH);
pinMode(TX_PIN, OUTPUT);
transmit_RegMask = digitalPinToBitMask(TX_PIN); //use Bit 1
transmit_InvMask = ~digitalPinToBitMask(TX_PIN); //use Bit 0
_transmitPortRegister = portOutputRegister(digitalPinToPort(TX_PIN));
//INIT RX_PIN
pinMode(RX_PIN, INPUT);
digitalWrite(RX_PIN, HIGH); // pullup for normal logic!
_receiveBitMask = digitalPinToBitMask(RX_PIN);
_receivePortRegister = portInputRegister(digitalPinToPort(RX_PIN));
//Set Values
uint16_t bit_delay = (F_CPU / speedBaud) / 4;
_tx_delay = subtract_cap(bit_delay, 15 / 4);
if (digitalPinToPCICR(RX_PIN))
{
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
_rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
*digitalPinToPCICR(RX_PIN) |= _BV(digitalPinToPCICRbit(RX_PIN));
_pcint_maskreg = digitalPinToPCMSK(RX_PIN);
_pcint_maskvalue = _BV(digitalPinToPCMSKbit(RX_PIN));
tunedDelay(_tx_delay); // if we were low this establishes the end
}
//Start Listen
//_buffer_overflow = false;
//_receive_buffer_head = _receive_buffer_tail = 0;
setRxIntMsk(true);
}

View File

@ -24,14 +24,17 @@
//============================================================================== //==============================================================================
//Depending on the type of LCD mounted on the uBITX, uncomment one of the options below. //Depending on the type of LCD mounted on the uBITX, uncomment one of the options below.
//You must select only one. //You must select only one.
#define UBITX_DISPLAY_LCD1602P //LCD mounted on unmodified uBITX (Parallel) //#define UBITX_DISPLAY_LCD1602P //LCD mounted on unmodified uBITX (Parallel)
//#define UBITX_DISPLAY_LCD1602I //I2C type 16 x 02 LCD //#define UBITX_DISPLAY_LCD1602I //I2C type 16 x 02 LCD
//#define UBITX_DISPLAY_LCD1602I_DUAL //I2C type 16 x02 LCD Dual //#define UBITX_DISPLAY_LCD1602I_DUAL //I2C type 16 x02 LCD Dual
//#define UBITX_DISPLAY_LCD2004P //24 x 04 LCD (Parallel) //#define UBITX_DISPLAY_LCD2004P //24 x 04 LCD (Parallel)
//#define UBITX_DISPLAY_LCD2004I //I2C type 24 x 04 LCD //#define UBITX_DISPLAY_LCD2004I //I2C type 24 x 04 LCD
#define UBITX_DISPLAY_NEXTION //NEXTION LCD
//#define UBITX_CONTROL_MCU //CONTROL MCU
#define I2C_LCD_MASTER_ADDRESS_DEFAULT 0x3F //0x27 //DEFAULT, if Set I2C Address by uBITX Manager, read from EEProm
#define I2C_LCD_SECOND_ADDRESS_DEFAULT 0x27 //0x27 //only using Dual LCD Mode #define I2C_LCD_MASTER_ADDRESS_DEFAULT 0x27 //0x27 //DEFAULT, if Set I2C Address by uBITX Manager, read from EEProm
#define I2C_LCD_SECOND_ADDRESS_DEFAULT 0x3F //0x27 //only using Dual LCD Mode
#define EXTEND_KEY_GROUP1 //MODE, BAND(-), BAND(+), STEP #define EXTEND_KEY_GROUP1 //MODE, BAND(-), BAND(+), STEP
//#define EXTEND_KEY_GROUP2 //Numeric (0~9), Point(.), Enter //Not supported in Version 1.0x //#define EXTEND_KEY_GROUP2 //Numeric (0~9), Point(.), Enter //Not supported in Version 1.0x
@ -53,6 +56,12 @@ extern byte I2C_LCD_SECOND_ADDRESS; //only using Dual LCD Mode
#define USE_I2C_LCD #define USE_I2C_LCD
#endif #endif
#ifdef UBITX_DISPLAY_NEXTION
#define USE_SW_SERIAL
#elif defined(UBITX_CONTROL_MCU)
#define USE_SW_SERIAL
#endif
//============================================================================== //==============================================================================
// Hardware, Define PIN Usage // Hardware, Define PIN Usage
//============================================================================== //==============================================================================

View File

@ -6,7 +6,7 @@
// So I put + in the sense that it was improved one by one based on Original Firmware. // So I put + in the sense that it was improved one by one based on Original Firmware.
// This firmware has been gradually changed based on the original firmware created by Farhan, Jack, Jerry and others. // This firmware has been gradually changed based on the original firmware created by Farhan, Jack, Jerry and others.
#define FIRMWARE_VERSION_INFO F("+v1.080") #define FIRMWARE_VERSION_INFO F("+v1.091")
#define FIRMWARE_VERSION_NUM 0x03 //1st Complete Project : 1 (Version 1.061), 2st Project : 2 #define FIRMWARE_VERSION_NUM 0x03 //1st Complete Project : 1 (Version 1.061), 2st Project : 2
/** /**
@ -602,7 +602,18 @@ void checkButton(){
return; return;
if (keyStatus == FKEY_PRESS) //Menu Key if (keyStatus == FKEY_PRESS) //Menu Key
{
//for touch screen
#ifdef USE_SW_SERIAL
SetSWActivePage(1);
doMenu(); doMenu();
if (isCWAutoMode == 0)
SetSWActivePage(0);
#else
doMenu();
#endif
}
else if (keyStatus <= FKEY_TYPE_MAX) //EXTEND KEY GROUP #1 else if (keyStatus <= FKEY_TYPE_MAX) //EXTEND KEY GROUP #1
{ {
@ -1294,6 +1305,7 @@ void setup()
Init_Cat(38400, SERIAL_8N1); Init_Cat(38400, SERIAL_8N1);
initSettings(); initSettings();
initPorts();
if (userCallsignLength > 0 && ((userCallsignLength & 0x80) == 0x80)) { if (userCallsignLength > 0 && ((userCallsignLength & 0x80) == 0x80)) {
userCallsignLength = userCallsignLength & 0x7F; userCallsignLength = userCallsignLength & 0x7F;
@ -1307,7 +1319,6 @@ void setup()
clearLine2(); clearLine2();
} }
initPorts();
#ifdef FACTORY_RECOVERY_BOOTUP #ifdef FACTORY_RECOVERY_BOOTUP
if (btnDown()) if (btnDown())
@ -1320,6 +1331,11 @@ void setup()
frequency = vfoA; frequency = vfoA;
saveCheckFreq = frequency; //for auto save frequency saveCheckFreq = frequency; //for auto save frequency
setFrequency(vfoA); setFrequency(vfoA);
#ifdef USE_SW_SERIAL
SendUbitxData();
#endif
updateDisplay(); updateDisplay();
#ifdef ENABLE_FACTORYALIGN #ifdef ENABLE_FACTORYALIGN
@ -1383,4 +1399,9 @@ void loop(){
//we check CAT after the encoder as it might put the radio into TX //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
SWS_Process();
#endif
} }

File diff suppressed because it is too large Load Diff

View File

@ -498,9 +498,9 @@ void menuCWAutoKey(int btn){
printLineF1(F("PTT to Send")); printLineF1(F("PTT to Send"));
delay_background(500, 0); delay_background(500, 0);
updateDisplay();
beforeCWTextIndex = 255; //255 value is for start check beforeCWTextIndex = 255; //255 value is for start check
isCWAutoMode = 1; isCWAutoMode = 1;
updateDisplay();
menuOn = 0; menuOn = 0;
} }
@ -667,6 +667,10 @@ int getValueByKnob(int valueType, int targetValue, int minKnobValue, int maxKnob
else else
attLevel = targetValue; attLevel = targetValue;
#ifdef USE_SW_SERIAL
menuOn=2;
updateDisplay();
#endif
setFrequency(frequency); setFrequency(frequency);
SetCarrierFreq(); SetCarrierFreq();
} }

View File

@ -73,13 +73,14 @@ void SendWSPRManage()
if (nowWsprStep == 0) //select Message status if (nowWsprStep == 0) //select Message status
{ {
printLineF2(F("WSPR:")); //printLineF2(F("WSPR:"));
if (selectedWsprMessageIndex != nowSelectedIndex) if (selectedWsprMessageIndex != nowSelectedIndex)
{ {
selectedWsprMessageIndex = nowSelectedIndex; selectedWsprMessageIndex = nowSelectedIndex;
int wsprMessageBuffIndex = selectedWsprMessageIndex * 46; int wsprMessageBuffIndex = selectedWsprMessageIndex * 46;
printLineF2(F("WSPR:"));
//Display WSPR Name tag //Display WSPR Name tag
printLineFromEEPRom(0, 6, wsprMessageBuffIndex, wsprMessageBuffIndex + 4, 1); printLineFromEEPRom(0, 6, wsprMessageBuffIndex, wsprMessageBuffIndex + 4, 1);