Compare commits

...

128 Commits

Author SHA1 Message Date
phdlee
337320b433 Merge pull request #37 from phdlee/version1.080
add comment
2018-05-23 16:00:25 +09:00
phdlee
7c8088f753 add comment 2018-05-23 15:58:50 +09:00
phdlee
b172527d00 Merge pull request #36 from phdlee/version1.080
Version1.080
2018-05-23 15:46:01 +09:00
phdlee
67cdd14945 modified comments 2018-05-23 15:28:00 +09:00
phdlee
b375b7e9e4 modified some comments 2018-05-23 15:20:10 +09:00
phdlee
27092d23e0 Merge pull request #35 from phdlee/version1.080
Version1.080
2018-05-23 15:09:43 +09:00
phdlee
8a6e01e289 improve external switch check routine 2018-05-23 15:07:37 +09:00
phdlee
83dc1de18e fixed mode change 2018-05-22 11:37:10 +09:00
phdlee
2de1c873a1 Merge pull request #34 from phdlee/version1.075
Version1.075
2018-05-09 16:55:47 +09:00
phdlee
4d97ac2283 Merge pull request #33 from phdlee/version1.074
Version1.074
2018-05-09 16:54:51 +09:00
phdlee
65d21aba77 Fixed Band Select Bug 2018-05-09 16:53:49 +09:00
phdlee
6a2369bc27 Fixed Band Select Bug 2018-05-09 16:53:40 +09:00
phdlee
76d5c362d0 complete test for Factory Recovery 2018-05-07 14:08:22 +09:00
phdlee
70fc6aeba8 Add Factory Recovery function 2018-05-07 13:56:46 +09:00
phdlee
75d952718b Merge pull request #32 from phdlee/version1.073
reduce compiller warning
2018-05-06 22:34:15 +09:00
phdlee
1d28f3e7e9 update versioninfo.txt 2018-05-03 21:23:10 +09:00
phdlee
51f690ef85 change frequency display in WSPR Menu 2018-05-03 17:57:06 +09:00
phdlee
12984486a6 Modfied SMeter and CAT 2018-05-03 16:20:09 +09:00
phdlee
e961cd8ac9 reduce compiller warning 2018-04-24 18:00:41 +09:00
phdlee
5c40718bec Merge pull request #31 from phdlee/version1.073
Version1.073
2018-04-24 17:33:58 +09:00
phdlee
6add092391 Extended key (select key type) 2018-04-24 17:26:34 +09:00
phdlee
3b4bdafacc Merge pull request #30 from phdlee/version1.072
Version1.072
2018-04-23 21:43:56 +09:00
phdlee
82d9682ee9 Merge branch 'master' into version1.072 2018-04-23 21:43:50 +09:00
phdlee
6be127d811 test lcd 2018-04-23 21:40:45 +09:00
phdlee
5b13ede65b test of extended key and dual lcd 2018-04-23 08:29:19 +09:00
phdlee
0aafe32e27 Added Dual LCD 2018-04-21 16:09:21 +09:00
phdlee
289ae1bd77 Merge pull request #29 from phdlee/version1.071
Improve receive perforamnce for USB, CWU, custom uBITX
2018-04-18 20:25:32 +09:00
phdlee
5611e1c0ff lcdtest and extended ubutton tested 2018-04-18 20:22:52 +09:00
phdlee
86797181cf Merge pull request #28 from RichNeese/master
Tuning step change
2018-04-18 08:32:53 +09:00
phdlee
f600c18541 add extended Keys (mode, band, tunestep) and i2clcd working 2018-04-17 21:26:29 +09:00
Richard Neese
11b6fbc1f4 Tuning step change
changed tuning steps to 10/50/100/500/1000
2018-04-16 21:56:20 -04:00
phdlee
0e245fc488 Add 20x04LCD and S.Meter 2018-04-16 23:56:32 +09:00
phdlee
d721816039 LCD Work step1 2018-04-12 22:08:43 +09:00
phdlee
34be2d0845 Improve receive perforamnce for USB, CWU, custom uBITX 2018-04-09 23:35:13 +09:00
phdlee
0996870154 Merge pull request #27 from phdlee/version1.07
Version1.07
2018-04-07 21:33:30 +09:00
phdlee
689cfda09e Add Support SDR Receiver and improve ATT 2018-04-07 21:32:01 +09:00
phdlee
23f1b7cd5c Added IF Tune, ATT, SDR Functions 2018-04-06 21:43:36 +09:00
phdlee
d4ed0589e5 Applied 1602 Tiny LCD Library for reduce program Memory 2018-04-05 22:57:07 +09:00
phdlee
5f906a4497 To Support various LCD Type 2018-04-05 22:16:54 +09:00
phdlee
1210f56cd1 move display routine ui to idle 2018-04-05 21:30:35 +09:00
phdlee
e8d6792073 complete setup menu ui for reduce program memory 2018-04-05 17:36:16 +09:00
phdlee
9c4b694ce2 Update README.md 2018-04-05 10:19:38 +09:00
phdlee
02f22d66e5 Change Menu codes 2018-04-05 09:50:29 +09:00
phdlee
11e47fdccc Added Version Info at top of ubitx_20.ino 2018-04-04 22:20:04 +09:00
phdlee
7aafed9e95 rename ubitx_wspr.cpp to ubitx_wspr.ino 2018-04-04 20:29:27 +09:00
phdlee
5afcdf2583 Update README.md 2018-04-04 20:22:42 +09:00
phdlee
075f585a1e Update README.md 2018-03-29 22:31:36 +09:00
phdlee
d0c04df9d8 Merge pull request #26 from phdlee/version1.06
Version1.06
2018-03-25 03:22:29 +09:00
phdlee
dd6d4555a8 Update ubitx_20.ino 2018-03-25 03:21:31 +09:00
phdlee
8f8850f4da Update ubitx_wspr.cpp 2018-03-25 03:17:04 +09:00
phdlee
4e9437a735 Merge pull request #25 from phdlee/version1.06
Change Version Name
2018-03-24 21:34:17 +09:00
phdlee
bad62ef728 Change Version Name 2018-03-24 21:33:01 +09:00
phdlee
384c3c41b2 Merge pull request #24 from phdlee/version1.05
Version1.05
2018-03-21 14:21:28 +09:00
phdlee
93727e6b22 fixed Cat in IFSifht setup routine 2018-03-21 14:20:09 +09:00
phdlee
31a7f79569 ifshift store, cw mode shift change 2018-03-20 21:41:24 +09:00
phdlee
d7858e35c3 if shift bfo modified 2018-03-20 17:06:28 +09:00
phdlee
ecd104b686 Fixed IF Shift Bug (USB and TX Mode) 2018-03-19 21:35:41 +09:00
phdlee
bd52de59d2 bug fixed (found gereld) Autokey on Rit bug 2018-03-19 10:13:30 +09:00
phdlee
f0409d641d Auto key Bug fixed, LZ1LDO found bug 2018-03-17 11:11:27 +09:00
phdlee
8326b1ade3 bug fixed : cw start delay option 2018-03-15 21:00:42 +09:00
phdlee
94a3e5ca1b Test and some mod about WSPR Calibration 2018-03-13 01:17:06 +09:00
phdlee
a26978f573 Added WSPR and Reduce Program size 2018-03-09 22:02:10 +09:00
phdlee
a21dbe2fa5 Update README.md 2018-03-05 13:03:05 +09:00
phdlee
9faa8bb44c Merge pull request #23 from phdlee/version1.04
Optimized from Version1.03
2018-03-05 12:56:55 +09:00
phdlee
d926b15e3d Merge pull request #22 from phdlee/version1.03
Version1.03
2018-03-05 12:55:41 +09:00
phdlee
fb2c9d2cc3 Optimized from Version1.03 2018-03-05 12:51:14 +09:00
phdlee
bf68dd6c26 Change Version Number 2018-02-22 13:27:51 +09:00
phdlee
4a6909f361 Change BFO Cal Step(50 to 5), Change CW Frequency Method 2018-02-22 12:26:18 +09:00
phdlee
c911d26163 Merge pull request #21 from phdlee/version1.02
Version1.02
2018-02-14 12:11:38 +09:00
phdlee
98e3b41f5a Merge pull request #20 from phdlee/version1.0
Version1.0
2018-02-14 12:10:38 +09:00
phdlee
e0f9148972 Change RIT tune step (freq tune step) 2018-02-13 19:54:19 +09:00
phdlee
277666f82f Konstantinos (SV1ONW) shared the usage of uBITX Manager on Linux.
Konstantinos (SV1ONW) shared the usage of uBITX Manager on Linux.
2018-02-10 18:34:21 +09:00
phdlee
e532dccce7 Update README.md 2018-02-10 15:10:55 +09:00
phdlee
81333e7af4 modified CW Key Logic for AutoKey and reduce cpu use rate, reduce program memory 2018-02-10 15:07:56 +09:00
phdlee
04949cdb93 Update README.md 2018-02-10 13:41:12 +09:00
phdlee
bbdd0947d3 Update README.md 2018-02-10 13:31:51 +09:00
phdlee
ed767f2e34 CW Start Delay applied New CW Logic 2018-02-10 13:29:30 +09:00
phdlee
a374297d49 Update README.md 2018-02-09 13:42:36 +09:00
phdlee
1e9576ddc2 fixed cat with cw key (IA, IB) 2018-02-09 01:11:48 +09:00
phdlee
a7684284d2 write eeprom cycle test and reconvery 2018-02-08 12:45:54 +09:00
phdlee
c1d81d9d5b Update README.md 2018-02-08 01:15:39 +09:00
phdlee
3b4aaa664c version0.35 2018-02-06 16:13:05 +09:00
phdlee
d69588d999 Merge pull request #19 from phdlee/version0.35
Version0.35
2018-02-05 16:48:56 +09:00
phdlee
14888bb7d7 change channel name display code 2018-02-05 16:46:37 +09:00
phdlee
57cd385b8a add vfo to channel, channel to vfo 2018-02-05 15:07:25 +09:00
phdlee
e915c21412 Merge pull request #18 from phdlee/version0.34
Version0.34
2018-02-03 17:17:43 +09:00
phdlee
60777178a8 TX Check in auto keysend 2018-02-03 17:07:11 +09:00
phdlee
dd68b38454 Optimize codes 2018-02-03 16:35:27 +09:00
phdlee
d229a10092 change tune step size and fixed bug 2018-02-02 20:49:00 +09:00
phdlee
3d019cdd44 change IF Shift Step 1 -> 50Hz 2018-01-31 17:53:20 +09:00
phdlee
55cfeeb924 Update README.md 2018-01-31 12:13:44 +09:00
phdlee
c8879e0e59 Update README.md 2018-01-31 12:12:58 +09:00
phdlee
4f5ac283b7 Merge pull request #17 from phdlee/version0.33
Version0.33
2018-01-31 10:47:20 +09:00
phdlee
3058d52551 Merge pull request #16 from phdlee/version0.32
Version0.32
2018-01-30 12:20:18 +09:00
phdlee
04699ba074 Merge pull request #15 from phdlee/version0.31
Fixed Bug CW Key Range
Append Feature : Display Line Toggle, (Between line1 and line2)
 Append function : for other users / using s.meter, p.meter ... (when idle time execute function)
2018-01-29 18:44:05 +09:00
phdlee
aa61281c38 Merge pull request #14 from phdlee/version0.296
rename version to 0.30
2018-01-27 18:39:22 +09:00
phdlee
261215b1ad Merge pull request #13 from phdlee/version0.296
Version0.296 => Version 0.30
2018-01-27 18:36:07 +09:00
phdlee
1a2f5b4fde Update README.md 2018-01-27 18:33:51 +09:00
phdlee
8203427808 Merge pull request #12 from phdlee/version0.296
Add Comment
2018-01-26 18:25:48 +09:00
phdlee
4e15f2150c Update README.md 2018-01-25 23:39:33 +09:00
phdlee
82a5fd7df9 Merge pull request #11 from phdlee/version0.296
Version0.296
2018-01-25 23:33:04 +09:00
phdlee
386a0b2d46 Update README.md 2018-01-25 22:33:20 +09:00
phdlee
c6401af7d1 Merge pull request #10 from phdlee/version0.29
Version0.29
2018-01-25 22:26:19 +09:00
phdlee
b153a305d6 Merge branch 'master' into version0.29 2018-01-25 22:25:35 +09:00
phdlee
e61e45d3dd Update README.md 2018-01-22 18:26:22 +09:00
phdlee
a1f941f965 Update README.md 2018-01-22 18:25:41 +09:00
phdlee
d1e72b3bd5 Update README.md 2018-01-22 18:24:29 +09:00
phdlee
032e7f919f Update README.md 2018-01-22 18:21:55 +09:00
phdlee
b6bc264332 Update README.md 2018-01-22 18:11:15 +09:00
phdlee
b1cc5eb98a Update README.md 2018-01-22 02:11:35 +09:00
phdlee
2fe1662d67 Merge pull request #8 from qiwenmin/master
Fixed most compilation warnings and a delay issue
2018-01-20 21:24:15 +09:00
phdlee
ebbc5aae5e Merge pull request #9 from phdlee/version0.28
change delaytimes via cat
2018-01-18 11:47:21 +09:00
Qi Wenmin
209cd3a49c Fixed most compilation warnings and a delay issue
* Fixed most compilation warnings (Compiler warning level: All)
* Fixed a delay issue in enc_read function.
2018-01-17 14:42:15 +08:00
phdlee
95e5c1dfe5 Update README.md 2018-01-14 14:53:28 +09:00
phdlee
45a8479061 Update README.md 2018-01-14 14:52:58 +09:00
phdlee
a6ad381c24 Update README.md 2018-01-14 14:52:22 +09:00
phdlee
bcf80f851d Update README.md 2018-01-14 14:51:46 +09:00
phdlee
16304efacd Update README.md 2018-01-14 14:51:23 +09:00
phdlee
968024ab73 Merge pull request #7 from phdlee/beta0.26
Beta0.26
2018-01-14 14:19:53 +09:00
phdlee
3e60728727 Update README.md 2018-01-13 22:27:23 +09:00
phdlee
9781ef086b Update README.md 2018-01-13 10:58:47 +09:00
phdlee
f27f504ea4 Merge pull request #6 from phdlee/beta0.26
Beta0.26
2018-01-12 20:19:09 +09:00
phdlee
2b08a76fbf Update README.md 2018-01-12 10:16:59 +09:00
phdlee
90655e03b8 Update README.md
add status of project
2018-01-12 09:51:58 +09:00
phdlee
8551ff1b68 Update README.md 2018-01-11 17:40:00 +09:00
phdlee
5ce94e8e49 Merge pull request #5 from qiwenmin/master
Fix the delay condition bug when overflow
2018-01-10 13:51:59 +09:00
Qi Wenmin
7ef9c29fa8 Fix the delay condition bug when overflow
The original expression will cause bug when overflow.
2018-01-10 12:00:53 +08:00
phdlee
fda398046e Merge pull request #4 from phdlee/beta0.25
beta 0.25 commit
2018-01-10 11:39:15 +09:00
18 changed files with 4812 additions and 1654 deletions

119
README.md
View File

@@ -1,28 +1,18 @@
#IMPORTANT INFORMATION #IMPORTANT INFORMATION
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
- Beta 0.26 and Beta 0.261, Beta 0.262, Beta 0.27 is complete test - Now Release Version 1.061 on my blog (http://www.hamskey.com)
- You can download and use it. - You can download and compiled hex file and uBITX Manager application on my blog (http://www.hamskey.com)
#NOTICE #NOTICE
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
I received uBITX a month ago and found that many features are required, and began coding with the idea of implementing minimal functionality as a general hf transceiver rather than an experimental device. I received uBITX a month ago and found that many features are required, and began coding with the idea of implementing minimal functionality as a general hf transceiver rather than an experimental device.
- fixed bugs...
- Diallock for uBITX's sensitive encoders
- built in softare Memory keyer and cw options control for CW communication
- Implementation of CAT communication protocol for Digital Communication (as FT8, JT65, etc)
- Delay Options for external Linear.
- and more...
Most of the basic functions of the HF transceiver I thought were implemented. Most of the basic functions of the HF transceiver I thought were implemented.
The minimum basic specification for uBITX to operate as a radio, I think it is finished. The minimum basic specification for uBITX to operate as a radio, I think it is finished.
So I will release the 0.27 version and if I do not see the bug anymore, I will try to change the version name to 1.0. So I will release the 0.27 version and if I do not see the bug anymore, I will try to change the version name to 1.0.
Now uBITX is an HF radio and will be able to join you in your happy hams life. Now uBITX is an HF radio and will be able to join you in your happy hams life.
Based on this source, you can use it by adding functions. Based on this source, you can use it by adding functions.
I am going to do a new project based on this source, linking with WSPR, WSJT-X and so on.
Of course, this repository is still running. If you have any bugs or ideas, please feel free to email me.
http://www.hamskey.com http://www.hamskey.com
DE KD8CEC DE KD8CEC
@@ -36,16 +26,105 @@ The copyright information of the original is below.
KD8CEC KD8CEC
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Prepared or finished tasks for the next version Prepared or finished tasks for the next version
- Most of them are implemented and included in version 0.27. - Reduce Program size
- User Interface on LCD -> Option by user (not need) - uBITX with RTL-SDR
- Include WSPR Beacone function - (implement other new repository) - Direct control for Student
complete experiment
need solve : Big code size (over 100%, then remove some functions for experment)
need replace Si5351 Library (increase risk and need more beta tester)
W3PM sent me his wonderful source - using BITX, GPS
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
## REVISION RECORD ## REVISION RECORD
1.07 (Working...)
- Please do not download it yet. The code will continue to change for the time being.
- BetaVersion for Reduce program size
1.061
- Added WSPR
You only need uBITX to use WSPR. No external devices are required.
Added Si5351 module for WSPR
- Update uBITX Manager to Version 1.0
- Reduce program size
for WSPR
for other Module
- Fixed IF Shift Bug
Disable IF Shift on TX
IF shift available in USB mode
Fixed cat routine in IF Shift setup
- Bugs fixed
cw start delay option
Auto key Bug
(found bug : LZ1LDO)
Message selection when Auto Key is used in RIT mode
(found bug : gerald)
- Improve CW Keying (start TX)
1.05
- include 1.05W, 1.051, 1.051W
- for WSPR Beta Test Version
1.04
- Optimized from Version1.03
- Reduce program size (97% -> 95%)
1.03
- Change eBFO Calibration Step (50 to 5)
- Change CW Frequency Display type
1.02
- Applied CW Start Delay to New CW Key logic (This is my mistake when applying the new CW Key Logic.Since uBITX operations are not significantly affected, this does not create a separate Release, It will be reflected in the next release.) - complete
- Modified CW Key Logic for Auto Key, (available AutoKey function by any cw keytype) - complete
- reduce cpu use usage (working)
- reduce (working)
1.01
- Fixed Cat problem with (IAMBIC A or B Selected)
1.0
- rename 0.30 to 1.0
0.35
- vfo to channel bug fixed (not saved mode -> fixed, channel has frequency and mode)
- add Channel tag (ch.1 ~ 10) by uBITX Manager
- add VFO to Channel, Channel To VFO
0.34
- TX Status check in auto Keysend logic
- optimize codes
- change default tune step size, and fixed bug
- change IF shift step (1Hz -> 50Hz)
0.33
- Added CWL, CWU Mode, (dont complete test yet)
- fixed VFO changed bug.
- Added Additional BFO for CWL, CWL
- Added IF Shift
- Change confirmation key PTT -> function key (not critical menus)
- Change CW Key Select type, (toggle -> select by dial)
0.32
- Added function Scroll Frequencty on upper line
- Added Example code for Draw meter and remarked (you can see and use this code in source codes)
- Added Split function, just toggle VFOs when TX/RX
0.31
- Fixed CW ADC Range error
- Display Message on Upper Line (anothor VFO Frequency, Tune Step, Selected Key Type)
0.30
- implemented the function to monitor the value of all analog inputs. This allows you to monitor the status of the CW keys connected to your uBITX.
- possible to set the ADC range for CW Keying. If no setting is made, it will have the same range as the original code. If you set the CW Keying ADC Values using uBITX Manager 0.3, you can reduce the key error.
- Added the function to select Straight Key, IAMBICA, IAMBICB key from the menu.
- default Band select is Ham Band mode, if you want common type, long press function key at band select menu, uBITX Manager can be used to modify frequencies to suit your country.
0.29
- Remove the use of initialization values in BFO settings - using crruent value, if factory reset
- Select Tune Step, default 0, 20, 50, 100, 200, Use the uBITX Manager to set the steps value you want. You can select Step by pressing and holding the Function Key (1sec ~ 2sec).
- Modify Dial Lock Function, Press the Function key for more than 3 seconds to toggle dial lock.
- created a new frequency tune method. remove original source codes, Threshold has been applied to reduce malfunction. checked the continuity of the user operating to make natural tune possible.
- stabilize and remove many warning messages - by Pullrequest and merge
- Changed cw keying method. removed the original code and applied Ron's code and Improved compatibility with original hardware and CAT commnication. It can be used without modification of hardware.
0.28
- Fixed CAT problem with hamlib on Linux
- restore Protocol autorecovery logic
0.27 0.27
(First alpha test version, This will be renamed to the major version 1.0) (First alpha test version, This will be renamed to the major version 1.0)
- Dual VFO Dial Lock (vfoA Dial lock) - Dual VFO Dial Lock (vfoA Dial lock)

30
VersionInfo.txt Normal file
View File

@@ -0,0 +1,30 @@
This file will guide you to change the source code file.
For Windows-based Arduino IDE users, the directory name and the Main source file name must be the same.
You do not need to learn github to download .hex files or source code that I release.
However, if you want to see what I'm doing right now, you should use the github homepage.
You do not need to learn git to suggest source code. If you give me an e-mail, I will correct it at any time.
If you have not joined the BITX Group, join group. There will be discussions on various topics every day.
I am getting a lot of hints from the group.
Ian KD8CEC
kd8cec@gmail.com
==================================================================
Files modified in Version1.08 Beta
1.Delted Files.
2.Added Files
3.Modified Files
- ubitx_20.ino
- ubitx_ui.ino
- cat_libs.ino
- ubitx.h
- ubitx_eemap.h
- ubitx_lcd_1602.ino
- ubitx_lcd_1602Dual.ino
- ubitx_lcd_2004.ino
- ubitx_wspr.ino

View File

@@ -31,8 +31,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/ **************************************************************************/
#define printLineF1(x) (printLineF(1, x))
#define printLineF2(x) (printLineF(0, x)) #include "ubitx.h"
//for broken protocol //for broken protocol
#define CAT_RECEIVE_TIMEOUT 500 #define CAT_RECEIVE_TIMEOUT 500
@@ -109,7 +109,8 @@ void CatSetFreq(byte fromType)
//#define BCD_LEN 9 //#define BCD_LEN 9
//PROTOCOL : 0x03 //PROTOCOL : 0x03
//Computer <-(frequency)-> TRCV CAT_BUFF //Computer <-(frequency)-> TRCV CAT_BUFF
void CatGetFreqMode(unsigned long freq, byte fromType) //void CatGetFreqMode(unsigned long freq, byte fromType)
void CatGetFreqMode(unsigned long freq) //for remove warning messages
{ {
int i; int i;
byte tmpValue; byte tmpValue;
@@ -149,15 +150,21 @@ void CatGetFreqMode(unsigned long freq, byte fromType)
SendCatData(5); SendCatData(5);
} }
void CatSetSplit(boolean isSplit, byte fromType) //void CatSetSplit(boolean isSplit, byte fromType)
void CatSetSplit(boolean isSplit) //for remove warning messages
{ {
if (isSplit)
splitOn = 1;
else
splitOn = 0;
Serial.write(ACK); Serial.write(ACK);
} }
void CatSetPTT(boolean isPTTOn, byte fromType) void CatSetPTT(boolean isPTTOn, byte fromType)
{ {
if (fromType == 2 || fromType == 3) { //
if ((!inTx) && (fromType == 2 || fromType == 3)) {
Serial.write(ACK); Serial.write(ACK);
return; return;
} }
@@ -193,7 +200,7 @@ void CatSetPTT(boolean isPTTOn, byte fromType)
void CatVFOToggle(boolean isSendACK, byte fromType) void CatVFOToggle(boolean isSendACK, byte fromType)
{ {
if (fromType != 2 && fromType != 3) { if (fromType != 2 && fromType != 3) {
menuVfoToggle(1, 0); menuVfoToggle(1);
} }
if (isSendACK) if (isSendACK)
@@ -232,7 +239,8 @@ void CatSetMode(byte tmpMode, byte fromType)
} }
//Read EEProm by uBITX Manager Software //Read EEProm by uBITX Manager Software
void ReadEEPRom(byte fromType) //void ReadEEPRom(byte fromType)
void ReadEEPRom() //for remove warnings.
{ {
//5BYTES //5BYTES
//CAT_BUFF[0] [1] [2] [3] [4] //4 COMMAND //CAT_BUFF[0] [1] [2] [3] [4] //4 COMMAND
@@ -255,7 +263,8 @@ void ReadEEPRom(byte fromType)
} }
//Write just proecess 1byes //Write just proecess 1byes
void WriteEEPRom(byte fromType) //void WriteEEPRom(byte fromType)
void WriteEEPRom(void) //for remove warning
{ {
//5BYTES //5BYTES
uint16_t eepromStartIndex = CAT_BUFF[0] + CAT_BUFF[1] * 256; uint16_t eepromStartIndex = CAT_BUFF[0] + CAT_BUFF[1] * 256;
@@ -269,13 +278,26 @@ void WriteEEPRom(byte fromType)
} }
else else
{ {
EEPROM.write(eepromStartIndex, write1Byte); //Special Command
if (eepromStartIndex == 13131) //Magic Key
{
if (write1Byte == 0x51) //Restart
{
asm volatile (" jmp 0");
}
}
else
{
EEPROM.write(eepromStartIndex, write1Byte);
}
Serial.write(0x77); //OK Serial.write(0x77); //OK
Serial.write(ACK); Serial.write(ACK);
} }
} }
void ReadEEPRom_FT817(byte fromType) //void ReadEEPRom_FT817(byte fromType)
void ReadEEPRom_FT817(void) //for remove warnings
{ {
byte temp0 = CAT_BUFF[0]; byte temp0 = CAT_BUFF[0];
byte temp1 = CAT_BUFF[1]; byte temp1 = CAT_BUFF[1];
@@ -601,9 +623,38 @@ void WriteEEPRom_FT817(byte fromType)
Serial.write(ACK); Serial.write(ACK);
} }
void CatRxStatus(byte fromType) const byte anlogPinIndex[6] = {A0, A1, A2, A3, A6, A7};
//Read ADC Value by uBITX Manager Software
void ReadADCValue(void)
{ {
byte sMeterValue = 1; //ADC MAP for uBITX
int readedADCValue;
//5BYTES
//CAT_BUFF[0] [1] [2] [3] [4] //4 COMMAND
//0 READ ADDRESS
readedADCValue = analogRead(anlogPinIndex[CAT_BUFF[0]]);
CAT_BUFF[0] = readedADCValue >> 8;
CAT_BUFF[1] = readedADCValue;
SendCatData(2);
Serial.write(ACK);
}
void SetIFSValue(void)
{
//Set IFShift Value
isIFShift = CAT_BUFF[0];
ifShiftValue = CAT_BUFF[1] + CAT_BUFF[2] * 256;
setFrequency(frequency);
SetCarrierFreq();
updateLine2Buffer(1); //option, perhap not need
Serial.write(ACK);
}
//void CatRxStatus(byte fromType)
void CatRxStatus(void) //for remove warning
{
byte sMeterValue = 0;
/* /*
http://www.ka7oei.com/ft817_meow.html http://www.ka7oei.com/ft817_meow.html
@@ -616,12 +667,40 @@ void CatRxStatus(byte fromType)
Bit 7 is 0 if there is a signal present, or 1 if the receiver is squelched. Bit 7 is 0 if there is a signal present, or 1 if the receiver is squelched.
*/ */
// The lower 4 bits (0-3) of this byte indicate the current S-meter reading. 00 refers to an S-Zero reading, 04 = S4, 09 = S9, 0A = "10 over," 0B = "20 over" and so on up to 0F. // The lower 4 bits (0-3) of this byte indicate the current S-meter reading. 00 refers to an S-Zero reading, 04 = S4, 09 = S9, 0A = "10 over," 0B = "20 over" and so on up to 0F.
//0~8
switch (scaledSMeter)
{
case 8 : sMeterValue = 0x0B;
break;
case 7 : sMeterValue = 0x0A;
break;
case 6 : sMeterValue = 0x09;
break;
case 5 : sMeterValue = 0x07;
break;
case 4 : sMeterValue = 0x05;
break;
case 3 : sMeterValue = 0x04;
break;
case 2 : sMeterValue = 0x02;
break;
case 1 : sMeterValue = 0x01;
break;
}
/*
sMeterValue = (scaledSMeter * 2) -1;
if (sMeterValue > 0)
sMeterValue--;
*/
CAT_BUFF[0] = sMeterValue & 0b00001111; CAT_BUFF[0] = sMeterValue & 0b00001111;
SendCatData(1); SendCatData(1);
} }
void CatTxStatus(byte fromType) //void CatTxStatus(byte fromType)
void CatTxStatus(void) //for remove warning
{ {
boolean isHighSWR = false; boolean isHighSWR = false;
boolean isSplitOn = false; boolean isSplitOn = false;
@@ -722,11 +801,11 @@ void Check_Cat(byte fromType)
case 0x02 : //Split On case 0x02 : //Split On
case 0x82: //Split Off case 0x82: //Split Off
CatSetSplit(CAT_BUFF[4] == 0x02, fromType); CatSetSplit(CAT_BUFF[4] == 0x02);
break; break;
case 0x03 : //Read Frequency and mode case 0x03 : //Read Frequency and mode
CatGetFreqMode(frequency, fromType); CatGetFreqMode(frequency);
break; break;
case 0x07 : //Set Operating Mode case 0x07 : //Set Operating Mode
@@ -743,24 +822,32 @@ void Check_Cat(byte fromType)
break; break;
case 0xDB: //Read uBITX EEPROM Data case 0xDB: //Read uBITX EEPROM Data
ReadEEPRom(fromType); //Call by uBITX Manager Program ReadEEPRom(); //Call by uBITX Manager Program
break; break;
case 0xBB: //Read FT-817 EEPROM Data (for comfirtable) case 0xBB: //Read FT-817 EEPROM Data (for comfirtable)
ReadEEPRom_FT817(fromType); ReadEEPRom_FT817();
break; break;
case 0xDC: //Write uBITX EEPROM Data case 0xDC: //Write uBITX EEPROM Data
WriteEEPRom(fromType); //Call by uBITX Manager Program WriteEEPRom(); //Call by uBITX Manager Program
break; break;
case 0xBC: //Write FT-817 EEPROM Data (for comfirtable) case 0xBC: //Write FT-817 EEPROM Data (for comfirtable)
WriteEEPRom_FT817(fromType); WriteEEPRom_FT817(fromType);
break; break;
case 0xDD: //Read uBITX ADC Data
ReadADCValue(); //Call by uBITX Manager Program
break;
case 0xDE: //IF-Shift Control by CAT
SetIFSValue(); //
break;
case 0xE7 : //Read RX Status case 0xE7 : //Read RX Status
CatRxStatus(fromType); CatRxStatus();
break; break;
case 0xF7: //Read TX Status case 0xF7: //Read TX Status
CatTxStatus(fromType); CatTxStatus();
break; break;
default: default:
/* /*

View File

@@ -36,7 +36,7 @@
//27 + 10 + 18 + 1(SPACE) = //56 //27 + 10 + 18 + 1(SPACE) = //56
const PROGMEM uint8_t cwAZTable[27] = {0b00100100 , 0b01001000 , 0b01001010 , 0b00111000 , 0b00010000, 0b01000010, 0b00111100, 0b01000000 , //A ~ H const PROGMEM uint8_t cwAZTable[27] = {0b00100100 , 0b01001000 , 0b01001010 , 0b00111000 , 0b00010000, 0b01000010, 0b00111100, 0b01000000 , //A ~ H
0b00100000, 0b01000111 ,0b00111010, 0b01000100, 0b00101100, 0b00101000 , 0b00111110, 0b01000110, 0b01001101, 0b00110100, //I ~ R 0b00100000, 0b01000111 ,0b00111010, 0b01000100, 0b00101100, 0b00101000 , 0b00111110, 0b01000110, 0b01001101, 0b00110100, //I ~ R
0b00110000, 0b00011000, 0b00110010, 0b01000001, 0b00110110, 0b01001001, 0b01001011, 0b00111000}; //S ~ Z 0b00110000, 0b00011000, 0b00110010, 0b01000001, 0b00110110, 0b01001001, 0b01001011, 0b01001100}; //S ~ Z
PGM_P pCwAZTable = reinterpret_cast<PGM_P>(cwAZTable); PGM_P pCwAZTable = reinterpret_cast<PGM_P>(cwAZTable);
const PROGMEM uint8_t cw09Table[27] = {0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001, 0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110}; const PROGMEM uint8_t cw09Table[27] = {0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001, 0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110};
@@ -297,15 +297,16 @@ void controlAutoCW(){
displayScrolStep = 0; displayScrolStep = 0;
} }
printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ); printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0);
byte diplayAutoCWLine = 0; //byte diplayAutoCWLine = 0;
if ((displayOption1 & 0x01) == 0x01) //if ((displayOption1 & 0x01) == 0x01)
diplayAutoCWLine = 1; // diplayAutoCWLine = 1;
lcd.setCursor(0, diplayAutoCWLine); Display_AutoKeyTextIndex(selectedCWTextIndex);
lcd.write(byteToChar(selectedCWTextIndex)); //lcd.setCursor(0, diplayAutoCWLine);
lcd.write(':'); //lcd.write(byteToChar(selectedCWTextIndex));
//lcd.write(':');
isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0; isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0;
scrollDispayTime = millis() + scrollSpeed; scrollDispayTime = millis() + scrollSpeed;
beforeCWTextIndex = selectedCWTextIndex; beforeCWTextIndex = selectedCWTextIndex;
@@ -365,6 +366,11 @@ void controlAutoCW(){
//check interval time, if you want adjust interval between chars, modify below //check interval time, if you want adjust interval between chars, modify below
if (isAutoCWHold == 0 && (millis() - autoCWbeforeTime > cwSpeed * 3)) if (isAutoCWHold == 0 && (millis() - autoCWbeforeTime > cwSpeed * 3))
{ {
if (!inTx){ //if not TX Status, change RX -> TX
keyDown = 0;
startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time
}
sendCWChar(EEPROM.read(CW_AUTO_DATA + autoCWSendCharIndex++)); sendCWChar(EEPROM.read(CW_AUTO_DATA + autoCWSendCharIndex++));
if (autoCWSendCharIndex > autoCWSendCharEndIndex) { //finish auto cw send if (autoCWSendCharIndex > autoCWSendCharEndIndex) { //finish auto cw send

184
ubitx_20/ubitx.h Normal file
View File

@@ -0,0 +1,184 @@
/*************************************************************************
header file for C++ by KD8CEC
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
#ifndef _UBITX_HEADER__
#define _UBITX_HEADER__
#include <Arduino.h> //for Linux, On Linux it is case sensitive.
//==============================================================================
// Compile Option
//==============================================================================
//Depending on the type of LCD mounted on the uBITX, uncomment one of the options below.
//You must select only one.
#define UBITX_DISPLAY_LCD1602P //LCD mounted on unmodified uBITX (Parallel)
//#define UBITX_DISPLAY_LCD1602I //I2C type 16 x 02 LCD
//#define UBITX_DISPLAY_LCD1602I_DUAL //I2C type 16 x02 LCD Dual
//#define UBITX_DISPLAY_LCD2004P //24 x 04 LCD (Parallel)
//#define UBITX_DISPLAY_LCD2004I //I2C type 24 x 04 LCD
#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 EXTEND_KEY_GROUP1 //MODE, BAND(-), BAND(+), STEP
//#define EXTEND_KEY_GROUP2 //Numeric (0~9), Point(.), Enter //Not supported in Version 1.0x
//#define ENABLE_FACTORYALIGN
#define FACTORY_RECOVERY_BOOTUP //Whether to enter Factory Recovery mode by pressing FKey and turning on power
#define ENABLE_ADCMONITOR //Starting with Version 1.07, you can read ADC values directly from uBITX Manager. So this function is not necessary.
extern byte I2C_LCD_MASTER_ADDRESS; //0x27 //if Set I2C Address by uBITX Manager, read from EEProm
extern byte I2C_LCD_SECOND_ADDRESS; //only using Dual LCD Mode
#define SMeterLatency 3 //1 is 0.25 sec
#ifdef UBITX_DISPLAY_LCD1602I
#define USE_I2C_LCD
#elif defined(UBITX_DISPLAY_LCD1602I_DUAL)
#define USE_I2C_LCD
#elif defined(UBITX_DISPLAY_LCD2004I)
#define USE_I2C_LCD
#endif
//==============================================================================
// Hardware, Define PIN Usage
//==============================================================================
/**
* We need to carefully pick assignment of pin for various purposes.
* There are two sets of completely programmable pins on the Raduino.
* First, on the top of the board, in line with the LCD connector is an 8-pin connector
* that is largely meant for analog inputs and front-panel control. It has a regulated 5v output,
* ground and six pins. Each of these six pins can be individually programmed
* either as an analog input, a digital input or a digital output.
* The pins are assigned as follows (left to right, display facing you):
* Pin 1 (Violet), A7, SPARE
* Pin 2 (Blue), A6, KEYER (DATA)
* Pin 3 (Green), +5v
* Pin 4 (Yellow), Gnd
* Pin 5 (Orange), A3, PTT
* Pin 6 (Red), A2, F BUTTON
* Pin 7 (Brown), A1, ENC B
* Pin 8 (Black), A0, ENC A
*Note: A5, A4 are wired to the Si5351 as I2C interface
* *
* Though, this can be assigned anyway, for this application of the Arduino, we will make the following
* assignment
* A2 will connect to the PTT line, which is the usually a part of the mic connector
* A3 is connected to a push button that can momentarily ground this line. This will be used for RIT/Bandswitching, etc.
* A6 is to implement a keyer, it is reserved and not yet implemented
* A7 is connected to a center pin of good quality 100K or 10K linear potentiometer with the two other ends connected to
* ground and +5v lines available on the connector. This implments the tuning mechanism
*/
#define ENC_A (A0)
#define ENC_B (A1)
#define FBUTTON (A2)
#define PTT (A3)
#define ANALOG_KEYER (A6)
#define ANALOG_SPARE (A7)
#define ANALOG_SMETER (A7) //by KD8CEC
/**
* The second set of 16 pins on the Raduino's bottom connector are have the three clock outputs and the digital lines to control the rig.
* This assignment is as follows :
* Pin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
* GND +5V CLK0 GND GND CLK1 GND GND CLK2 GND D2 D3 D4 D5 D6 D7
* These too are flexible with what you may do with them, for the Raduino, we use them to :
* - TX_RX line : Switches between Transmit and Receive after sensing the PTT or the morse keyer
* - CW_KEY line : turns on the carrier for CW
*/
#define TX_RX (7) //Relay
#define CW_TONE (6)
#define TX_LPF_A (5) //Relay
#define TX_LPF_B (4) //Relay
#define TX_LPF_C (3) //Relay
#define CW_KEY (2)
//==============================================================================
// for public, Variable, functions
//==============================================================================
#define WSPR_BAND_COUNT 3
#define TX_SSB 0
#define TX_CW 1
#define printLineF1(x) (printLineF(1, x))
#define printLineF2(x) (printLineF(0, x))
//0x00 : None, 0x01 : MODE, 0x02:BAND+, 0x03:BAND-, 0x04:TUNE_STEP, 0x05:VFO Toggle, 0x06:SplitOn/Off, 0x07:TX/ON-OFF, 0x08:SDR Mode On / Off, 0x09:Rit Toggle
#define FUNCTION_KEY_ADC 80 //MODE, BAND(-), BAND(+), STEP
#define FKEY_PRESS 0x78
#define FKEY_MODE 0x01
#define FKEY_BANDUP 0x02
#define FKEY_BANDDOWN 0x03
#define FKEY_STEP 0x04
#define FKEY_VFOCHANGE 0x05
#define FKEY_SPLIT 0x06
#define FKEY_TXOFF 0x07
#define FKEY_SDRMODE 0x08
#define FKEY_RIT 0x09
#define FKEY_ENTER 0x0A
#define FKEY_POINT 0x0B
#define FKEY_DELETE 0x0C
#define FKEY_CANCEL 0x0D
#define FKEY_NUM0 0x10
#define FKEY_NUM1 0x11
#define FKEY_NUM2 0x12
#define FKEY_NUM3 0x13
#define FKEY_NUM4 0x14
#define FKEY_NUM5 0x15
#define FKEY_NUM6 0x16
#define FKEY_NUM7 0x17
#define FKEY_NUM8 0x18
#define FKEY_NUM9 0x19
#define FKEY_TYPE_MAX 0x1F
extern unsigned long frequency;
extern byte WsprMSGCount;
extern byte sMeterLevels[9];
extern int currentSMeter; //ADC Value for S.Meter
extern byte scaledSMeter; //Calculated S.Meter Level
extern byte KeyValues[16][3]; //Set : Start Value, End Value, Key Type, 16 Set (3 * 16 = 48)
extern void printLine1(const char *c);
extern void printLine2(const char *c);
extern void printLineF(char linenmbr, const __FlashStringHelper *c);
extern void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetType);
extern byte delay_background(unsigned delayTime, byte fromType);
extern int btnDown(void);
extern char c[30];
extern char b[30];
extern int enc_read(void);
extern void si5351bx_init(void);
extern void si5351bx_setfreq(uint8_t clknum, uint32_t fout);
extern void si5351_set_calibration(int32_t cal);
extern void initOscillators(void);
extern void Set_WSPR_Param(void);
extern void TXSubFreq(unsigned long P2);
extern void startTx(byte txMode, byte isDisplayUpdate);
extern void stopTx(void);
extern void setTXFilters(unsigned long freq);
extern void SendWSPRManage(void);
extern char byteToChar(byte srcByte);
extern void DisplayCallsign(byte callSignLength);
extern void DisplayVersionInfo(const char* fwVersionInfo);
#endif //end of if header define

File diff suppressed because it is too large Load Diff

134
ubitx_20/ubitx_eemap.h Normal file
View File

@@ -0,0 +1,134 @@
/*************************************************************************
header file for EEProm Address Map by KD8CEC
It must be protected to protect the factory calibrated calibration.
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
#ifndef _UBITX_EEPOM_HEADER__
#define _UBITX_EEPOM_HEADER__
//==============================================================================
// Factory-shipped EEProm address
// (factory Firmware)
// Address : 0 ~ 31
//==============================================================================
#define MASTER_CAL 0
#define LSB_CAL 4
#define USB_CAL 8
#define SIDE_TONE 12
//these are ids of the vfos as well as their offset into the eeprom storage, don't change these 'magic' values
#define VFO_A 16
#define VFO_B 20
#define CW_SIDETONE 24
#define CW_SPEED 28
//==============================================================================
// The spare space available in the original firmware #1
// Address : 32 ~ 63
//==============================================================================
#define RESERVE_FOR_FACTORY1 32
//==============================================================================
// The spare space available in the original firmware #2
// (Enabled if the EEProm address is insufficient)
// Address : 64 ~ 100
//==============================================================================
#define RESERVE_FOR_FACTORY2 64 //use Factory backup from Version 1.075
#define FACTORY_BACKUP_YN 64 //Check Backup //Magic : 0x13
#define FACTORY_VALUES 65 //65 ~ 65 + 32
//==============================================================================
// KD8CEC EEPROM MAP
// Address : 101 ~ 1023
// 256 is the base address
// 256 ~ 1023 (EEProm Section #1)
// 255 ~ 101 (EEProm Section #2)
//==============================================================================
//0x00 : None, 0x01 : MODE, 0x02:BAND+, 0x03:BAND-, 0x04:TUNE_STEP, 0x05:VFO Toggle, 0x06:SplitOn/Off, 0x07:TX/ON-OFF, 0x08:SDR Mode On / Off, 0x09:Rit Toggle
#define EXTENDED_KEY_RANGE 140 //Extended Key => Set : Start Value, End Value, Key Type, 16 Set (3 * 16 = 48)
#define I2C_LCD_MASTER 190
#define I2C_LCD_SECOND 191
#define S_METER_LEVELS 230 //LEVEL0 ~ LEVEL7
#define ADVANCED_FREQ_OPTION1 240 //Bit0: use IFTune_Value, Bit1 : use Stored enabled SDR Mode, Bit2 : dynamic sdr frequency
#define IF1_CAL 241
#define ENABLE_SDR 242
#define SDR_FREQUNCY 243
#define CW_CAL 252
#define VFO_A_MODE 256
#define VFO_B_MODE 257
#define CW_DELAY 258
#define CW_START 259
#define HAM_BAND_COUNT 260 //
#define TX_TUNE_TYPE 261 //
#define HAM_BAND_RANGE 262 //FROM (2BYTE) TO (2BYTE) * 10 = 40byte
#define HAM_BAND_FREQS 302 //40, 1 BAND = 4Byte most bit is mode
#define TUNING_STEP 342 //TUNING STEP * 6 (index 1 + STEPS 5) //1STEP :
//for reduce cw key error, eeprom address
#define CW_ADC_MOST_BIT1 348 //most 2bits of DOT_TO , DOT_FROM, ST_TO, ST_FROM
#define CW_ADC_ST_FROM 349 //CW ADC Range STRAIGHT KEY from (Lower 8 bit)
#define CW_ADC_ST_TO 350 //CW ADC Range STRAIGHT KEY to (Lower 8 bit)
#define CW_ADC_DOT_FROM 351 //CW ADC Range DOT from (Lower 8 bit)
#define CW_ADC_DOT_TO 352 //CW ADC Range DOT to (Lower 8 bit)
#define CW_ADC_MOST_BIT2 353 //most 2bits of BOTH_TO, BOTH_FROM, DASH_TO, DASH_FROM
#define CW_ADC_DASH_FROM 354 //CW ADC Range DASH from (Lower 8 bit)
#define CW_ADC_DASH_TO 355 //CW ADC Range DASH to (Lower 8 bit)
#define CW_ADC_BOTH_FROM 356 //CW ADC Range BOTH from (Lower 8 bit)
#define CW_ADC_BOTH_TO 357 //CW ADC Range BOTH to (Lower 8 bit)
#define CW_KEY_TYPE 358
#define CW_DISPLAY_SHIFT 359 //Transmits on CWL, CWU Mode, LCD Frequency shifts Sidetone Frequency.
//(7:Enable / Disable //0: enable, 1:disable, (default is applied shift)
//6 : 0 : Adjust Pulus, 1 : Adjust Minus
//0~5: Adjust Value : * 10 = Adjust Value (0~300)
#define COMMON_OPTION0 360 //0: Confirm : CW Frequency Shift
//1 : IF Shift Save
#define IF_SHIFTVALUE 363
#define DISPLAY_OPTION1 361 //Display Option1
#define DISPLAY_OPTION2 362 //Display Option2
#define WSPR_COUNT 443 //WSPR_MESSAGE_COUNT
#define WSPR_MESSAGE1 444 //
#define WSPR_MESSAGE2 490 //
#define WSPR_MESSAGE3 536 //
#define WSPR_MESSAGE4 582 //
#define CHANNEL_FREQ 630 //Channel 1 ~ 20, 1 Channel = 4 bytes
#define CHANNEL_DESC 710 //Channel 1 ~ 20, 1 Channel = 4 bytes
#define RESERVE3 770 //Reserve3 between Channel and Firmware id check
//Check Firmware type and version
#define FIRMWAR_ID_ADDR 776 //776 : 0x59, 777 :0x58, 778 : 0x68 : Id Number, if not found id, erase eeprom(32~1023) for prevent system error.
#define VERSION_ADDRESS 779 //check Firmware version
//USER INFORMATION
#define USER_CALLSIGN_KEY 780 //0x59
#define USER_CALLSIGN_LEN 781 //1BYTE (OPTION + LENGTH) + CALLSIGN (MAXIMUM 18)
#define USER_CALLSIGN_DAT 782 //CALL SIGN DATA //direct EEPROM to LCD basic offset
//AUTO KEY STRUCTURE
//AUTO KEY USE 800 ~ 1023
#define CW_AUTO_MAGIC_KEY 800 //0x73
#define CW_AUTO_COUNT 801 //0 ~ 255
#define CW_AUTO_DATA 803 //[INDEX, INDEX, INDEX,DATA,DATA, DATA (Positon offset is CW_AUTO_DATA
#define CW_DATA_OFSTADJ CW_AUTO_DATA - USER_CALLSIGN_DAT //offset adjust for ditect eeprom to lcd (basic offset is USER_CALLSIGN_DAT
#define CW_STATION_LEN 1023 //value range : 4 ~ 30
#endif //end of if header define

View File

@@ -1,237 +0,0 @@
/*************************************************************************
KD8CEC's uBITX Idle time Processing
Functions that run at times that do not affect TX, CW, and CAT
It is called in 1/10 time unit.
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
byte line2Buffer[16];
//KD8CEC 200Hz ST
//L14.150 200Hz ST
//U14.150 +150khz
int freqScrollPosition = 0;
//Example Line2 Optinal Display
//immediate execution, not call by scheulder
void updateLine2Buffer(char isDirectCall)
{
unsigned long tmpFreq = 0;
if (isDirectCall == 0)
{
if (ritOn)
{
line2Buffer[0] = 'R';
line2Buffer[1] = 'i';
line2Buffer[2] = 't';
line2Buffer[3] = 'T';
line2Buffer[4] = 'X';
line2Buffer[5] = ':';
//display frequency
tmpFreq = ritTxFrequency;
for (int i = 15; i >= 6; i--) {
if (tmpFreq > 0) {
if (i == 12 || i == 8) line2Buffer[i] = '.';
else {
line2Buffer[i] = tmpFreq % 10 + 0x30;
tmpFreq /= 10;
}
}
else
line2Buffer[i] = ' ';
}
return;
}
if (vfoActive == VFO_B)
{
tmpFreq = vfoA;
//line2Buffer[0] = 'A';
}
else
{
tmpFreq = vfoB;
//line2Buffer[0] = 'B';
}
// 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)
line2Buffer[6] = 'k';
else
{
//example #2
if (freqScrollPosition++ > 18)
{
line2Buffer[6] = 'k';
if (freqScrollPosition > 25)
freqScrollPosition = -1;
}
else
{
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] = ' ';
}
}
}
line2Buffer[7] = ' ';
} //check direct call by encoder
if (isIFShift)
{
if (isDirectCall == 1)
for (int i = 0; i < 16; i++)
line2Buffer[i] = ' ';
//IFShift Offset Value
line2Buffer[8] = 'I';
line2Buffer[9] = 'F';
if (ifShiftValue == 0)
{
line2Buffer[10] = 'S';
line2Buffer[11] = ':';
line2Buffer[12] = 'O';
line2Buffer[13] = 'F';
line2Buffer[14] = 'F';
}
else
{
line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0;
line2Buffer[11] = 0;
line2Buffer[12] = ' ';
//11, 12, 13, 14, 15
memset(b, 0, sizeof(b));
ltoa(ifShiftValue, b, DEC);
strncat(line2Buffer, b, 5);
}
if (isDirectCall == 1) //if call by encoder (not scheduler), immediate print value
printLine2(line2Buffer);
}
else
{
if (isDirectCall != 0)
return;
//Step
byte tmpStep = arTuneStep[tuneStepIndex -1];
for (int i = 10; i >= 8; i--) {
if (tmpStep > 0) {
line2Buffer[i] = tmpStep % 10 + 0x30;
tmpStep /= 10;
}
else
line2Buffer[i] = ' ';
}
line2Buffer[11] = 'H';
line2Buffer[12] = 'z';
line2Buffer[13] = ' ';
//if (
//Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
if (cwKeyType == 0)
{
line2Buffer[14] = 'S';
line2Buffer[15] = 'T';
}
else if (cwKeyType == 1)
{
line2Buffer[14] = 'I';
line2Buffer[15] = 'A';
}
else
{
line2Buffer[14] = 'I';
line2Buffer[15] = 'B';
}
}
}
//meterType : 0 = S.Meter, 1 : P.Meter
void DisplayMeter(byte meterType, byte meterValue, char drawPosition)
{
drawMeter(meterValue); //call original source code
int lineNumber = 0;
if ((displayOption1 & 0x01) == 0x01)
lineNumber = 1;
lcd.setCursor(drawPosition, lineNumber);
for (int i = 0; i < 6; i++) //meter 5 + +db 1 = 6
lcd.write(lcdMeter[i]);
}
byte testValue = 0;
char checkCount = 0;
void idle_process()
{
//space for user graphic display
if (menuOn == 0)
{
//if line2DisplayStatus == 0 <-- this condition is clear Line, you can display any message
if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2)) {
if (checkCount++ > 1)
{
updateLine2Buffer(0); //call by scheduler
printLine2(line2Buffer);
line2DisplayStatus = 2;
checkCount = 0;
}
//EX for Meters
/*
DisplayMeter(0, testValue++, 7);
if (testValue > 30)
testValue = 0;
*/
}
}
}

View File

@@ -90,13 +90,13 @@ void cwKeyUp(){
#define PDLSWAP 0x08 // 0 for normal, 1 for swap #define PDLSWAP 0x08 // 0 for normal, 1 for swap
#define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B #define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B
enum KSTYPE {IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT }; enum KSTYPE {IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT };
static long ktimer; static unsigned long ktimer;
unsigned char keyerState = IDLE; unsigned char keyerState = IDLE;
//Below is a test to reduce the keying error. do not delete lines //Below is a test to reduce the keying error. do not delete lines
//create by KD8CEC for compatible with new CW Logic //create by KD8CEC for compatible with new CW Logic
char update_PaddleLatch(byte isUpdateKeyState) { char update_PaddleLatch(byte isUpdateKeyState) {
unsigned char tmpKeyerControl; unsigned char tmpKeyerControl = 0;
int paddle = analogRead(ANALOG_KEYER); int paddle = analogRead(ANALOG_KEYER);
if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo) if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo)
@@ -126,9 +126,7 @@ char update_PaddleLatch(byte isUpdateKeyState) {
// modified by KD8CEC // modified by KD8CEC
******************************************************************************/ ******************************************************************************/
void cwKeyer(void){ void cwKeyer(void){
byte paddle;
lastPaddle = 0; lastPaddle = 0;
int dot,dash;
bool continue_loop = true; bool continue_loop = true;
unsigned tmpKeyControl = 0; unsigned tmpKeyControl = 0;
@@ -170,14 +168,32 @@ void cwKeyer(void){
break; break;
case KEYED_PREP: case KEYED_PREP:
//modified KD8CEC
/*
ktimer += millis(); // set ktimer to interval end time ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state keyerState = KEYED; // next state
if (!inTx){ if (!inTx){
//DelayTime Option
delay_background(delayBeforeCWStartTime * 2, 2);
keyDown = 0; keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 1); 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(); cwKeydown();
break; break;
@@ -206,7 +222,7 @@ void cwKeyer(void){
break; break;
} }
Check_Cat(3); Check_Cat(2);
} //end of while } //end of while
} }
else{ else{
@@ -214,6 +230,9 @@ void cwKeyer(void){
if (update_PaddleLatch(0) == DIT_L) { if (update_PaddleLatch(0) == DIT_L) {
// if we are here, it is only because the key is pressed // if we are here, it is only because the key is pressed
if (!inTx){ if (!inTx){
//DelayTime Option
delay_background(delayBeforeCWStartTime * 2, 2);
keyDown = 0; keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW, 1); startTx(TX_CW, 1);
@@ -231,13 +250,14 @@ void cwKeyer(void){
keyDown = 0; keyDown = 0;
stopTx(); stopTx();
} }
if (!cwTimeout) //if (!cwTimeout) //removed by KD8CEC
return; // return;
// got back to the beginning of the loop, if no further activity happens on straight key // 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 // we will time out, and return out of this routine
//delay(5); //delay(5);
delay_background(5, 3); //delay_background(5, 3); //removed by KD8CEC
continue; //continue; //removed by KD8CEC
return; //Tx stop control by Main Loop
} }
Check_Cat(2); Check_Cat(2);

64
ubitx_20/ubitx_lcd.h Normal file
View File

@@ -0,0 +1,64 @@
/*************************************************************************
header file for LCD by KD8CEC
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
#ifndef _UBITX_LCD_HEADER__
#define _UBITX_LCD_HEADER__
//Common Defines *********************************************************
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
// flags for backlight control
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#endif //end of if header define

786
ubitx_20/ubitx_lcd_1602.ino Normal file
View File

@@ -0,0 +1,786 @@
/*************************************************************************
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 <http://www.gnu.org/licenses/>.
**************************************************************************/
#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 <Wire.h>
/*************************************************************************
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<PGM_P>(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;
//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;
}
}
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

View File

@@ -0,0 +1,724 @@
/*************************************************************************
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 <http://www.gnu.org/licenses/>.
**************************************************************************/
#include "ubitx.h"
#include "ubitx_lcd.h"
//========================================================================
//Begin of I2CTinyLCD Library for Dual LCD by KD8CEC
//========================================================================
#ifdef UBITX_DISPLAY_LCD1602I_DUAL
#include <Wire.h>
/*************************************************************************
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<PGM_P>(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;
//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;
}
}
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

739
ubitx_20/ubitx_lcd_2004.ino Normal file
View File

@@ -0,0 +1,739 @@
/*************************************************************************
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 <http://www.gnu.org/licenses/>.
**************************************************************************/
#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 <Wire.h>
/*************************************************************************
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<PGM_P>(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;
//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;
}
}
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

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,20 @@
// ************* SI5315 routines - tks Jerry Gaffke, KE7ER *********************** /************************************************************************************
* KD8CEC
* kd8cec@gmail.com http://www.hamskey.com
*
* Merge two SI5351 Librarys
* KE7ER's fixed vco and variable Clocks Configure values
* G3ZIL's fixed Clock Configure Value and variable VCO
* * I have combined the two libraries above. All licenses follow the above library.
*
* PLL-A is generated by fixing 850Mhz clock. All output clocks use PLL-A to
* generate the frequency. This is the method used in QRP radios such as uBITX.
* When switching to WSPR transmission mode, PLL-B operates for the base frequency to transmit WSPR.
* The output clock channel that controls the frequency is connected to the PLL-B.
* The WSPR protocol is generated by changing the clock of the PLL-B.
************************************************************************************/
// ************* SI5315 routines - tks Jerry Gaffke, KE7ER ***********************
// An minimalist standalone set of Si5351 routines. // An minimalist standalone set of Si5351 routines.
// VCOA is fixed at 875mhz, VCOB not used. // VCOA is fixed at 875mhz, VCOB not used.
// The output msynth dividers are used to generate 3 independent clocks // The output msynth dividers are used to generate 3 independent clocks
@@ -60,6 +75,7 @@ void i2cWriten(uint8_t reg, uint8_t *vals, uint8_t vcnt) { // write array
Wire.endTransmission(); Wire.endTransmission();
} }
uint8_t si5351Val[8] = {0, 1, 0, 0, 0, 0, 0, 0}; //for reduce program memory size
void si5351bx_init() { // Call once at power-up, start PLLA void si5351bx_init() { // Call once at power-up, start PLLA
uint32_t msxp1; uint32_t msxp1;
@@ -68,11 +84,13 @@ void si5351bx_init() { // Call once at power-up, start PLLA
i2cWrite(3, si5351bx_clken); // Disable all CLK output drivers i2cWrite(3, si5351bx_clken); // Disable all CLK output drivers
i2cWrite(183, SI5351BX_XTALPF << 6); // Set 25mhz crystal load capacitance i2cWrite(183, SI5351BX_XTALPF << 6); // Set 25mhz crystal load capacitance
msxp1 = 128 * SI5351BX_MSA - 512; // and msxp2=0, msxp3=1, not fractional msxp1 = 128 * SI5351BX_MSA - 512; // and msxp2=0, msxp3=1, not fractional
uint8_t vals[8] = {0, 1, BB2(msxp1), BB1(msxp1), BB0(msxp1), 0, 0, 0}; //uint8_t vals[8] = {0, 1, BB2(msxp1), BB1(msxp1), BB0(msxp1), 0, 0, 0};
i2cWriten(26, vals, 8); // Write to 8 PLLA msynth regs si5351Val[2] = BB2(msxp1);
si5351Val[3] = BB1(msxp1);
si5351Val[4] = BB0(msxp1);
i2cWriten(26, si5351Val, 8); // Write to 8 PLLA msynth regs
i2cWrite(177, 0x20); // Reset PLLA (0x80 resets PLLB) i2cWrite(177, 0x20); // Reset PLLA (0x80 resets PLLB)
// for (reg=16; reg<=23; reg++) i2cWrite(reg, 0x80); // Powerdown CLK's
// i2cWrite(187, 0); // No fannout of clkin, xtal, ms0, ms4
} }
void si5351bx_setfreq(uint8_t clknum, uint32_t fout) { // Set a CLK to fout Hz void si5351bx_setfreq(uint8_t clknum, uint32_t fout) { // Set a CLK to fout Hz
@@ -105,15 +123,50 @@ void si5351_set_calibration(int32_t cal){
si5351bx_setfreq(0, usbCarrier); si5351bx_setfreq(0, usbCarrier);
} }
void SetCarrierFreq()
{
unsigned long appliedCarrier = ((cwMode == 0 ? usbCarrier : cwmCarrier) + (isIFShift && (inTx == 0) ? ifShiftValue : 0));
//si5351bx_setfreq(0, (sdrModeOn ? 0 : appliedCarrier));
si5351bx_setfreq(0, ((sdrModeOn && (inTx == 0)) ? 0 : appliedCarrier)); //found bug by KG4GEK
/*
if (cwMode == 0)
si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0));
else
si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0));
*/
}
void initOscillators(){ void initOscillators(){
//initialize the SI5351 //initialize the SI5351
si5351bx_init(); si5351bx_init();
si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor
SetCarrierFreq();
}
if (cwMode == 0) //============================================================
si5351bx_setfreq(0, usbCarrier + (isIFShift ? ifShiftValue : 0)); // ADD FUNCTIONS by KD8CEC
else //============================================================
si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); uint8_t Wspr_Reg1[8] = {0xFF,0xFE, 0x00, 0, 0, 0, 0, 0}; //3, 4, 5, 6, 7
uint8_t Wspr_Reg2[8] = {0, 1, 0, 0, 0, 0, 0, 0}; //2, 3, 4
void Set_WSPR_Param(void)
{
i2cWrite(18, 128);
i2cWriten(34, Wspr_Reg1, 8);
i2cWriten(58, Wspr_Reg2, 8);
i2cWrite(177, 128);
i2cWrite(18, 111);
si5351bx_clken &= ~(1 << 2);
i2cWrite(3, si5351bx_clken);
}
void TXSubFreq(unsigned long P2)
{
i2cWrite(40, (P2 & 65280) >> 8);
i2cWrite(41, P2 & 255);
} }

View File

@@ -5,38 +5,9 @@
* of the radio. Occasionally, it is used to provide a two-line information that is * of the radio. Occasionally, it is used to provide a two-line information that is
* quickly cleared up. * quickly cleared up.
*/ */
//#define printLineF1(x) (printLineF(1, x))
//#define printLineF2(x) (printLineF(0, x))
//returns true if the button is pressed
int btnDown(){
if (digitalRead(FBUTTON) == HIGH)
return 0;
else
return 1;
}
/**
* Meter (not used in this build for anything)
* the meter is drawn using special characters. Each character is composed of 5 x 8 matrix.
* The s_meter array holds the definition of the these characters.
* each line of the array is is one character such that 5 bits of every byte
* makes up one line of pixels of the that character (only 5 bits are used)
* The current reading of the meter is assembled in the string called meter
*/
/* /*
const PROGMEM uint8_t s_meter_bitmap[] = {
B00000,B00000,B00000,B00000,B00000,B00100,B00100,B11011,
B10000,B10000,B10000,B10000,B10100,B10100,B10100,B11011,
B01000,B01000,B01000,B01000,B01100,B01100,B01100,B11011,
B00100,B00100,B00100,B00100,B00100,B00100,B00100,B11011,
B00010,B00010,B00010,B00010,B00110,B00110,B00110,B11011,
B00001,B00001,B00001,B00001,B00101,B00101,B00101,B11011
};
*/
const PROGMEM uint8_t meters_bitmap[] = { const PROGMEM uint8_t meters_bitmap[] = {
B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1 B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000 , //custom 1
B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2 B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000 , //custom 2
@@ -45,7 +16,35 @@ const PROGMEM uint8_t meters_bitmap[] = {
B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5 B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 , //custom 5
B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6 B01000, B11100, B01000, B00000, B10111, B10101, B10101, B10111 //custom 6
}; };
*/
//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA
#ifdef OPTION_SKINNYBARS //We want skninny bars with more text
//VK2ETA modded "Skinny" bitmaps
const PROGMEM uint8_t meters_bitmap[] = {
// B01110, B10001, B10001, B11111, B11011, B11011, B11111, B00000, //Padlock Symbol, for merging. Not working, see below
B00000, B00000, B00000, B00000, B00000, B00000, B00000, B10000, //shortest bar
B00000, B00000, B00000, B00000, B00000, B00000, B00100, B10100,
B00000, B00000, B00000, B00000, B00000, B00001, B00101, B10101,
B00000, B00000, B00000, B00000, B10000, B10000, B10000, B10000,
B00000, B00000, B00000, B00100, B10100, B10100, B10100, B10100,
B00000, B00000, B00001, B00101, B10101, B10101, B10101, B10101, //tallest bar
B00000, B00010, B00111, B00010, B01000, B11100, B01000, B00000, // ++ sign
};
#else
//VK2ETA "Fat" bars, easy to read, with less text
const PROGMEM uint8_t meters_bitmap[] = {
// B01110, B10001, B10001, B11111, B11011, B11011, B11111, B00000, //Padlock Symbol, for merging. Not working, see below
B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111, //shortest bar
B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111,
B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111,
B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111,
B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111,
B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111, //tallest bar
B00000, B00010, B00111, B00010, B01000, B11100, B01000, B00000, // ++ sign
};
#endif //OPTION_SKINNYBARS
PGM_P p_metes_bitmap = reinterpret_cast<PGM_P>(meters_bitmap); PGM_P p_metes_bitmap = reinterpret_cast<PGM_P>(meters_bitmap);
const PROGMEM uint8_t lock_bitmap[8] = { const PROGMEM uint8_t lock_bitmap[8] = {
@@ -68,39 +67,43 @@ void initMeter(){
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(plock_bitmap + i); tmpbytes[i] = pgm_read_byte(plock_bitmap + i);
lcd.createChar(0, tmpbytes); LCD_CreateChar(0, tmpbytes);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i); tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i);
lcd.createChar(1, tmpbytes); LCD_CreateChar(1, tmpbytes);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8); tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 8);
lcd.createChar(2, tmpbytes); LCD_CreateChar(2, tmpbytes);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16); tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 16);
lcd.createChar(3, tmpbytes); LCD_CreateChar(3, tmpbytes);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24); tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 24);
lcd.createChar(4, tmpbytes); LCD_CreateChar(4, tmpbytes);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32); tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 32);
lcd.createChar(5, tmpbytes); LCD_CreateChar(5, tmpbytes);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40); tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 40);
lcd.createChar(6, tmpbytes); LCD_CreateChar(6, tmpbytes);
for (i = 0; i < 8; i++)
tmpbytes[i] = pgm_read_byte(p_metes_bitmap + i + 48);
LCD_CreateChar(7, tmpbytes);
} }
//by KD8CEC //by KD8CEC
//0 ~ 25 : 30 over : + 10 //0 ~ 25 : 30 over : + 10
/*
void drawMeter(int needle) { void drawMeter(int needle) {
//5Char + O over //5Char + O over
int drawCharLength = needle / 5;
int drawCharLengthLast = needle % 5;
int i; int i;
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
@@ -119,225 +122,91 @@ void drawMeter(int needle) {
else else
lcdMeter[5] = 0x20; lcdMeter[5] = 0x20;
} }
/*
void drawMeter(int8_t needle){
int16_t best, i, s;
if (needle < 0)
return;
s = (needle * 4)/10;
for (i = 0; i < 8; i++){
if (s >= 5)
lcdMeter[i] = 1;
else if (s >= 0)
lcdMeter[i] = 2 + s;
else
lcdMeter[i] = 1;
s = s - 5;
}
if (needle >= 40)
lcdMeter[i-1] = 6;
lcdMeter[i] = 0;
}
*/ */
// The generic routine to display one line on the LCD //VK2ETA meter for S.Meter, power and SWR
void printLine(unsigned char linenmbr, const char *c) { void drawMeter(int needle)
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.print(' ');
}
}
}
void printLineF(char linenmbr, const __FlashStringHelper *c)
{ {
int i; #ifdef OPTION_SKINNYBARS
char tmpBuff[17]; //Fill buffer with growing set of bars, up to needle value
PGM_P p = reinterpret_cast<PGM_P>(c); lcdMeter[0] = 0x20;
lcdMeter[1] = 0x20;
for (i = 0; i < 17; i++){ for (int i = 0; i < 6; i++) {
unsigned char fChar = pgm_read_byte(p++); if (needle > i)
tmpBuff[i] = fChar; lcdMeter[i / 3] = byte(i + 1); //Custom characters above
if (fChar == 0) //else if (i == 1 || i == 4) {
break; // lcdMeter[i / 3] = 0x20; //blank
//}
} }
printLine(linenmbr, tmpBuff); if (needle > 7) {
} lcdMeter[2] = byte(7); //Custom character "++"
} else if (needle > 6) {
#define LCD_MAX_COLUMN 16 lcdMeter[2] = '+'; //"+"
void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex) { } else lcdMeter[2] = 0x20;
if ((displayOption1 & 0x01) == 0x01)
linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle
lcd.setCursor(lcdColumn, linenmbr);
#else //Must be "fat" bars
for (byte i = eepromStartIndex; i <= eepromEndIndex; i++) //Fill buffer with growing set of bars, up to needle value
{ for (int i = 0; i < 6; i++) {
if (++lcdColumn <= LCD_MAX_COLUMN) if (needle > i)
lcd.write(EEPROM.read(USER_CALLSIGN_DAT + i)); lcdMeter[i] = byte(i + 1); //Custom characters above
else else
break; lcdMeter[i] = 0x20; //blank
} }
if (needle > 7) {
lcdMeter[6] = byte(7); //Custom character "++"
} else if (needle > 6) {
lcdMeter[6] = '+'; //"+"
} else lcdMeter[6] = 0x20;
for (byte i = lcdColumn; i < 16; i++) //Right Padding by Space #endif //OPTION_FATBARS
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 char byteToChar(byte srcByte){
void printLine1Clear(){
printLine(1,"");
}
// short cut to print to the first line
void printLine2Clear(){
printLine(0, "");
}
void printLine2ClearAndUpdate(){
printLine(0, "");
line2DisplayStatus = 0;
updateDisplay();
}
//012...89ABC...Z
char byteToChar(byte srcByte){
if (srcByte < 10) if (srcByte < 10)
return 0x30 + srcByte; return 0x30 + srcByte;
else else
return 'A' + srcByte - 10; return 'A' + srcByte - 10;
} }
// this builds up the top line of the display with frequency and mode //returns true if the button is pressed
void updateDisplay() { int btnDown(void){
// tks Jack Purdum W8TEE #ifdef EXTEND_KEY_GROUP1
// replaced fsprint commmands by str commands for code size reduction if (analogRead(FBUTTON) > FUNCTION_KEY_ADC)
return 0;
// replace code for Frequency numbering error (alignment, point...) by KD8CEC else
int i; return 1;
unsigned long tmpFreq = frequency; //
memset(c, 0, sizeof(c));
if (inTx){ #else
if (isCWAutoMode == 2) { if (digitalRead(FBUTTON) == HIGH)
for (i = 0; i < 4; i++) return 0;
c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); else
return 1;
#endif
}
//display Sending Index #ifdef EXTEND_KEY_GROUP1
c[4] = byteToChar(sendingCWTextIndex); int getBtnStatus(void){
c[5] = '='; int readButtonValue = analogRead(FBUTTON);
}
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:");
}
//display frequency if (analogRead(FBUTTON) < FUNCTION_KEY_ADC)
for (int i = 15; i >= 6; i--) { return FKEY_PRESS;
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 else
{ {
lcd.setCursor(5,diplayVFOLine); readButtonValue = readButtonValue / 4;
lcd.write(":"); //return FKEY_VFOCHANGE;
for (int i = 0; i < 16; i++)
if (KeyValues[i][2] != 0 && KeyValues[i][0] <= readButtonValue && KeyValues[i][1] >= readButtonValue)
return KeyValues[i][2];
//return i;
} }
/* return -1;
//now, the second line
memset(c, 0, sizeof(c));
memset(b, 0, sizeof(b));
if (inTx)
strcat(c, "TX ");
else if (ritOn)
strcpy(c, "RIT");
strcpy(c, " \xff");
drawMeter(meter_reading);
strcat(c, meter);
strcat(c, "\xff");
printLine2(c);*/
} }
#endif
int enc_prev_state = 3; int enc_prev_state = 3;

192
ubitx_20/ubitx_wspr.ino Normal file
View File

@@ -0,0 +1,192 @@
/**********************************************************************************
WSPR SENDER for uBITX by KD8CEC
Some of the code that sends WSPR referenced the code in G3ZIL.
Thanks to G3ZIL for sharing great code.
Due to the limited memory of uBITX, I have implemented at least only a few of the codes in uBITX.
Thanks for testing
Beta Tester :
-----------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**********************************************************************************/
#include <EEPROM.h>
#include "ubitx.h"
//begin of test
byte WsprToneCode[164];
unsigned long lastTime=0;
unsigned long TX_MSNB_P2; // Si5351 register MSNB_P2 PLLB for Tx
unsigned long TX_P2; // Variable values for MSNB_P2 which defines the frequencies for the data
extern int enc_read(void);
byte WsprMSGCount = 0;
#define WSPR_BAND1 401
extern uint8_t Wspr_Reg1[8]; //3, 4, 5, 6, 7
extern uint8_t Wspr_Reg2[8]; //2, 3, 4
void SendWSPRManage()
{
int knob = 0;
byte knobPosition = 0;
//char isNeedDisplayInfo = 0;
char nowSelectedIndex = 0;
char nowWsprStep = 0; //0 : select Message, 1 : select band, 2 : send
char selectedWsprMessageIndex = -1;
char selectedWsprBandIndex = -1;
unsigned long WsprTXFreq = 0;
unsigned int WsprMultiChan = 0;
//unsigned long prevFreq;
byte loopIndex;
delay_background(500, 0);
//Readed WsprMSGCount, WsprTone
while(1)
{
knob = enc_read();
if (knobPosition > 0 && knob < 0)
knobPosition--;
else if (knob > 0 && (knobPosition <= (nowWsprStep == 0 ? WsprMSGCount : WSPR_BAND_COUNT) * 10 -2))
knobPosition++;
nowSelectedIndex = knobPosition / 10;
if (nowWsprStep == 0) //select Message status
{
printLineF2(F("WSPR:"));
if (selectedWsprMessageIndex != nowSelectedIndex)
{
selectedWsprMessageIndex = nowSelectedIndex;
int wsprMessageBuffIndex = selectedWsprMessageIndex * 46;
//Display WSPR Name tag
printLineFromEEPRom(0, 6, wsprMessageBuffIndex, wsprMessageBuffIndex + 4, 1);
//Load WSPR Tonecode
//Read Tone Code
for (int i = 0; i < 41; i++)
{
byte readData = EEPROM.read(WSPR_MESSAGE1 + 5 + (wsprMessageBuffIndex) + i); //NAME TAG 5, MESSAGE 41 = 46
WsprToneCode[i * 4 + 0] = readData & 3;
WsprToneCode[i * 4 + 1] = (readData >> 2) & 3;
WsprToneCode[i * 4 + 2] = (readData >> 4) & 3;
WsprToneCode[i * 4 + 3] = (readData >> 6) & 3;
}
}
else if (btnDown())
{
nowWsprStep = 1; //Change Status to Select Band
knobPosition = 0;
nowSelectedIndex = 0;
delay_background(500, 0);
}
}
else if (nowWsprStep == 1)
{
//printLineF2(F("Select Band"));
if (selectedWsprBandIndex != nowSelectedIndex)
{
selectedWsprBandIndex = nowSelectedIndex;
int bandBuffIndex = WSPR_BAND1 + selectedWsprBandIndex * 14;
EEPROM.get(bandBuffIndex, WsprTXFreq);
EEPROM.get(bandBuffIndex + 4, WsprMultiChan);
for (loopIndex = 3; loopIndex < 8; loopIndex++)
Wspr_Reg1[loopIndex] = EEPROM.read(bandBuffIndex + loopIndex + 3);
//2, 3, 4
for (loopIndex = 2; loopIndex < 5; loopIndex++)
Wspr_Reg2[loopIndex] = EEPROM.read(bandBuffIndex + loopIndex + 9);
TX_MSNB_P2 = ((unsigned long)Wspr_Reg1[5] & 0x0F) << 16 | ((unsigned long)Wspr_Reg1[6]) << 8 | Wspr_Reg1[7];
}
if (digitalRead(PTT) == 0)
strcpy(c, "SEND: ");
else
strcpy(c, "PTT-> ");
//ltoa(WsprTXFreq, b, DEC);
//strcat(c, b);
//display frequency, Frequency to String for KD8CEC
unsigned long tmpFreq = WsprTXFreq;
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] = ' ';
}
printLine1(c);
if (digitalRead(PTT) == 0)
{
//SEND WSPR
//If you need to consider the Rit and Sprite modes, uncomment them below.
//remark = To reduce the size of the program
//prevFreq = frequency;
//frequency = WsprTXFreq;
startTx(TX_CW, 0);
setTXFilters(WsprTXFreq);
//Start WSPR
Set_WSPR_Param();
digitalWrite(CW_KEY, 1);
for (int i = 0; i < 162; i++)
{ // Now this is the message loop
lastTime = millis(); // Store away the time when the last message symbol was sent
TX_P2 = TX_MSNB_P2 + WsprMultiChan * WsprToneCode[i]; // This represents the 1.46 Hz shift and is correct only for the bands specified in the array
TXSubFreq(TX_P2); // TX at the appropriate channel frequency for....
//if (btnDown())
// break;
while (millis() < lastTime + 683){} // .... 0,683 seconds
}
digitalWrite(CW_KEY, 0);
stopTx(); //call setFrequency -> recovery TX Filter
//frequency = prevFreq;
selectedWsprBandIndex = -1;
} //end of PTT Check
else if (btnDown())
{
return;
}
} //end of status check
//delay_background(50, 1);
} //end of while
}

BIN
ubitxmanager ubuntu.odt Normal file

Binary file not shown.