Minor improvement to my old program adding menus for speed change and fixed messages.
The following is the source code.
/* file name = ic7410.c */
/* % gcc ic7410.c -o ic7410 -lncurses */
#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#define ENTER 10
#define ESCAPE 27
#define NROWMIN 30
#define NCOLMIN 80
#define BUFSIZE 1024
#define BAUDRATE B19200
#define MYRIG "/dev/ttyUSB0"
static int speed[]={15,20,25,30,35,40,45,50};
static int nspeed =sizeof(speed) / sizeof(speed[0]);
static char *text_array[]={
"cq cq cq de jh1ood jh1ood jh1ood k ",
"de jh1ood jh1ood jh1ood k ",
"qrz? de jh1ood k ",
"ur 5nn ^bk ",
"73 tu e e "};
static int ntext =sizeof(text_array) / sizeof(text_array[0]);
int fd=-1;
void init_curses()
{
initscr ();
start_color();
noecho ();
raw ();
keypad (stdscr, TRUE);
scrollok (stdscr, TRUE);
curs_set (0);
init_pair (1,COLOR_WHITE,COLOR_BLUE);
init_pair (2,COLOR_BLUE,COLOR_WHITE);
init_pair (3,COLOR_RED,COLOR_WHITE);
init_pair (4,COLOR_BLACK,COLOR_GREEN);
}
void draw_menubar(WINDOW *menubar)
{
wbkgd(menubar,COLOR_PAIR(2));
waddstr(menubar," WPM ");
wattron(menubar,COLOR_PAIR(3));
waddstr(menubar,"(F1)");
wattroff(menubar,COLOR_PAIR(3));
wmove(menubar,0,20);
waddstr(menubar," Messages ");
wattron(menubar,COLOR_PAIR(3));
waddstr(menubar,"(F2)");
wattroff(menubar,COLOR_PAIR(3));
}
WINDOW **draw_menu1(int start_col)
{
int i;
WINDOW **items;
items=(WINDOW **)malloc((nspeed+1)*sizeof(WINDOW *));
items[0]=newwin(nspeed+2,9,1,start_col);
wbkgd(items[0],COLOR_PAIR(2));
box(items[0],ACS_VLINE,ACS_HLINE);
for (i=1;i<=nspeed;i++) {
items[i]=subwin(items[0],1,7,i+1,start_col+1);
wprintw(items[i],"%2d WPM",speed[i-1]);
}
wbkgd(items[1],COLOR_PAIR(1));
wrefresh(items[0]);
return items;
}
WINDOW **draw_menu2(int start_col)
{
int i;
WINDOW **items;
items=(WINDOW **)malloc((ntext+1)*sizeof(WINDOW *));
items[0]=newwin(ntext+2,49,1,start_col);
wbkgd(items[0],COLOR_PAIR(2));
box(items[0],ACS_VLINE,ACS_HLINE);
for (i=1;i<=ntext;i++) {
items[i]=subwin(items[0],1,47,i+1,start_col+1);
wprintw(items[i],"%s",text_array[i-1]);
}
wbkgd(items[1],COLOR_PAIR(1));
wrefresh(items[0]);
return items;
}
void delete_menu(WINDOW **items,int count)
{
int i;
for (i=0;i<count;i++)
delwin(items[i]);
free(items);
}
int scroll_menu(WINDOW **items,int count)
{
int key;
int selected=0;
while (1) {
key=getch();
if (key==KEY_DOWN || key==KEY_UP) {
wbkgd(items[selected+1],COLOR_PAIR(2));
wnoutrefresh(items[selected+1]);
if (key==KEY_DOWN) {
selected=(selected+1) % count;
} else {
selected=(selected+count-1) % count;
}
wbkgd(items[selected+1],COLOR_PAIR(1));
wnoutrefresh(items[selected+1]);
doupdate();
} else if (key==ESCAPE) {
return -1;
} else if (key==ENTER) {
return selected;
}
}
}
void send_cw(char* text);
/* IC-7410 key speed set */
/* the parameter 0-255 relates to 6wpm-48wpm */
void send_keyspeed(int wpm) {
static char output_ks [9] =
{0xfe, 0xfe, 0x80, 0x00, 0x14, 0x0c,
0x01, 0x28, /* from 0x00,0x00 to 0x02,0x55 */
0xfd};
int param, p0, p1, p2;
if(wpm < 6) wpm = 6;
if(wpm > 48) wpm = 48;
param = 255.0 * ((double)wpm - 6.0) / (48.0 - 6.0) + 0.0;
p0 = param % 10;
p1 = (param/ 10) % 10;
p2 = (param/100) % 10;
output_ks[6] = p2;
output_ks[7] = 16*p1+p0;
/* because param=123 goes as 0x01, 0x23 (BCD) */
write(fd, output_ks, 9);
}
void send_cw(char* text) { /* IC-7410 send CW */
static char output [BUFSIZE] = {0xfe, 0xfe, 0x80, 0x00, 0x17};
char *p;
int count;
count=0; p=output+5;
while((*p++ = *text++)) {
count++;
if(count == 30) { /* IC-7410 max CW text length */
*p = 0xfd; /* IC-7410 postamble */
write(fd, output, 5+count+1);
count=0; p=output+5;
}
}
if(count) {
*(--p) = 0xfd; /* replace zero with postamble */
write(fd, output, 5+count+1);
}
}
void send_stored_text(int id) { /* use Function Keys */
send_cw(text_array[id-1]); /* id=1, 2, ... */
attron(COLOR_PAIR(2)); printw (text_array[id-1]); attroff(COLOR_PAIR(2));
}
void serial_init(void) {
struct termios tio;
memset(&tio, 0, sizeof(tio));
tio.c_cflag = CS8 | CLOCAL | CREAD;
tio.c_cc[VTIME] = 0;
tio.c_cc[VEOL ] = 0xfd; /* IC-7410 postamble */
tio.c_lflag = ICANON;
tio.c_iflag = IGNPAR | ICRNL;
cfsetispeed(&tio, BAUDRATE);
cfsetospeed(&tio, BAUDRATE);
tcsetattr (fd, TCSANOW, &tio);
}
int main(void) {
int c, count=0, nrow, ncol, row=0, col=0;
char word[BUFSIZE];
struct termios oldtio;
int selected_item;
WINDOW *menubar,*messagebar, **menu_items;
/* IC-7410 USB I/F initialize */
fd = open(MYRIG, O_RDWR | O_NOCTTY);
if (fd < 0) {
fprintf(stderr,"Error: can not open %s \n", MYRIG);
return (-1);
}
tcgetattr (fd, &oldtio);
serial_init();
/* ncurses initialize */
init_curses();
getmaxyx (stdscr,nrow,ncol);
if(nrow<NROWMIN || ncol < NCOLMIN) {
row=1; col=0; move(row, col);
printw("Current Window size is %d rows, %d columns. \n\n"
,nrow, ncol);
printw("Please make the Window size greater than %d rows, %d columns. \n"
,NROWMIN, NCOLMIN);
printw("Hit anykey.. \n");
getch();
endwin();
return EXIT_FAILURE;
}
bkgd(COLOR_PAIR(4));
menubar =subwin(stdscr,1,40,0, 0);
messagebar=subwin(stdscr,1,10,0,ncol-10); /* 10chars */
wattron(messagebar, COLOR_PAIR(2));
draw_menubar(menubar);
row=5; col=0; move(row, col);
refresh();
while ( (c=getch()) != 0x04) { /* ^d, EOT */
switch (c) {
case KEY_F(1):
menu_items=draw_menu1(0);
selected_item=scroll_menu(menu_items,nspeed);
delete_menu(menu_items,nspeed);
if (selected_item<0)
;
else {
wclear(messagebar);
wprintw(messagebar,
"Now %2d WPM",speed[selected_item]); /* 10chars */
send_keyspeed(speed[selected_item]);
}
touchwin(stdscr);
refresh();
break;
case KEY_F(2):
menu_items=draw_menu2(20);
selected_item=scroll_menu(menu_items,ntext);
delete_menu(menu_items,ntext);
if (selected_item<0)
;
else
send_stored_text(selected_item+1);
touchwin(stdscr);
refresh();
break;
case KEY_BACKSPACE:
if(count) { /* only within a word */
getyx (stdscr, row, col);
count--; col--; /* only within the same line */
mvaddch(row, col, ' ');
move (row, col); /* cursor goes back */
}
break;
default:
if(isprint(c)) {
addch(c);
word[count++] = c;
}
break;
}
getyx(stdscr, row, col);
if(c == 0x0a || (c==' ' && (col >= ncol-10 || col == ncol)))
printw("\n");
refresh();
if(c == 0x0a || c == ' ' || c == '.' || c == ',') {
word[count] = 0; count=0;
send_cw(word);
}
}
tcsetattr(fd, TCSANOW, &oldtio); /* reset serial terminal */
endwin (); /* reset ncurses */
return EXIT_SUCCESS;
}
Note: The menu part of the code is from
http://www.linuxfocus.org/English/March2002/article233.shtml