mirror of
https://git.FreeBSD.org/ports.git
synced 2024-12-26 05:02:18 +00:00
a69be38555
EEPROM programmer for GE Phoenix SX Radios WWW: http://members.shaw.ca/swstuff/phoenix2212.html PR: ports/169090 Submitted by: Stephen Hurd <shurd at sasktel.net>
331 lines
10 KiB
C
331 lines
10 KiB
C
--- ./src/callbacks.c.orig 2010-09-16 00:10:17.000000000 +0000
|
|
+++ ./src/callbacks.c 2012-09-18 15:29:36.554081126 +0000
|
|
@@ -9,6 +9,11 @@
|
|
#include "interface.h"
|
|
#include "support.h"
|
|
|
|
+#ifdef USE_PPI_DEV
|
|
+#include <dev/ppbus/ppi.h>
|
|
+#include <dev/ppbus/ppbconf.h>
|
|
+#endif
|
|
+
|
|
|
|
#ifdef __GLIBC__
|
|
#include <sys/io.h>
|
|
@@ -20,6 +25,7 @@
|
|
#define DIRBIT 0x20
|
|
|
|
extern GtkWidget *app1;
|
|
+extern gboolean uhf;
|
|
|
|
// new port defines to get 0x378 working on lp0
|
|
#define LPTBASE 0x378
|
|
@@ -76,6 +82,36 @@
|
|
"ch09cct", "ch10cct", "ch11cct", "ch12cct",
|
|
"ch13cct", "ch14cct", "ch15cct", "ch16cct" };
|
|
|
|
+#ifdef USE_PPI_DEV
|
|
+static void ppi_outb(u_int8_t outb_val, int addr) {
|
|
+ int outb_action=-1;
|
|
+
|
|
+ if(addr==LPTBASE || addr==LPTDAT)
|
|
+ outb_action=PPISDATA;
|
|
+ else if(addr==LPTSTAT)
|
|
+ outb_action=PPISSTATUS;
|
|
+ else if(addr==LPTCTRL)
|
|
+ outb_action=PPISCTRL;
|
|
+ ioctl(fd0, outb_action, &outb_val);
|
|
+}
|
|
+
|
|
+static u_int8_t ppi_inb(int addr)
|
|
+{
|
|
+ u_int8_t ret=0;
|
|
+
|
|
+ if(addr==LPTBASE || addr==LPTDAT)
|
|
+ ioctl(fd0, PPIGDATA, &ret);
|
|
+ else if(addr==LPTSTAT)
|
|
+ ioctl(fd0, PPIGSTATUS, &ret);
|
|
+ else if(addr==LPTCTRL)
|
|
+ ioctl(fd0, PPIGCTRL, &ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#define outb(v,a) ppi_outb((v),(a))
|
|
+#define inb(a) ppi_inb(a)
|
|
+#endif
|
|
+
|
|
/* convert 2 ascii chars in hex to a decimal number */
|
|
static int hex2( unsigned char a, unsigned char b)
|
|
{
|
|
@@ -111,7 +147,9 @@
|
|
/* release parallel port */
|
|
if (fd0 > 0)
|
|
close(fd0);
|
|
+#ifndef USE_PPI_DEV
|
|
ioperm(LPTDAT, 3, 0);
|
|
+#endif
|
|
}
|
|
//=====================================================================
|
|
//
|
|
@@ -209,6 +247,7 @@
|
|
case 0x03: space = 6250.0; break;
|
|
default: fprintf(stderr,"Invalid channel spacing code %d\n",r);
|
|
}
|
|
+ if(uhf) space *= 3;
|
|
|
|
// g_print("ref = %fhz, spacing = %fhz \n",ref,space);
|
|
|
|
@@ -736,6 +775,35 @@
|
|
return 0;
|
|
}
|
|
|
|
+gboolean freq_good(double freq)
|
|
+{
|
|
+ if(uhf)
|
|
+ return ( freq >= 134.33*3 && freq <= 185.66*3 );
|
|
+ return ( freq >= 136.0 && freq <= 174.0 );
|
|
+}
|
|
+
|
|
+int calc_divisor(double freq, double space, gboolean is_rx)
|
|
+{
|
|
+ int divisor = (((freq + (is_rx?45.0:0))*1e6) + (space/2.0)) / space;
|
|
+ /* Out of range... */
|
|
+ if(divisor > 0xffff || divisor < 0)
|
|
+ divisor=0;
|
|
+ return divisor;
|
|
+}
|
|
+
|
|
+double calc_realfreq(int divisor, double space, gboolean is_rx)
|
|
+{
|
|
+ return ((divisor * space ) - (is_rx?45e6:0))/1e6; /* in mhz */
|
|
+}
|
|
+
|
|
+void fill_ch(unsigned char *chbuff, int divisor)
|
|
+{
|
|
+ chbuff[1] = ( divisor & 0x8000) >> 12;
|
|
+ chbuff[2] = (divisor & 0x780) >> 7;
|
|
+ chbuff[3] = (divisor & 0x7800) >> 11;
|
|
+ chbuff[4] = divisor & 0xf;
|
|
+ chbuff[5] = ((divisor & 0x30) >> 4) + ((divisor & 0x40) >> 3);
|
|
+}
|
|
|
|
//=====================================================================
|
|
//
|
|
@@ -743,15 +811,37 @@
|
|
//=====================================================================
|
|
void encoderom( void )
|
|
{
|
|
- int i;
|
|
+ int i,j;
|
|
int chan;
|
|
- double freq, realfreq;
|
|
+ double realfreq;
|
|
+ double rx_freq;
|
|
+ double tx_freq;
|
|
int divisor;
|
|
unsigned char *chbuff;
|
|
-
|
|
+ double spaces[3];
|
|
+ double errors[3];
|
|
+ int spacecode[3];
|
|
+ int sc_idx;
|
|
+
|
|
+ if(uhf) {
|
|
+ spaces[0]=12500.0;
|
|
+ spaces[1]=15000.0;
|
|
+ spaces[2]=18750.0;
|
|
+ spacecode[0]=1;
|
|
+ spacecode[1]=2;
|
|
+ spacecode[2]=3;
|
|
+ }
|
|
+ else {
|
|
+ spaces[0]=5000.0;
|
|
+ spaces[1]=12500.0/3.0;
|
|
+ spaces[2]=6250.0;
|
|
+ spacecode[0]=2;
|
|
+ spacecode[1]=1;
|
|
+ spacecode[2]=3;
|
|
+ }
|
|
GtkWidget *wid;
|
|
G_CONST_RETURN gchar *txt;
|
|
-
|
|
+
|
|
/* start with a clean image */
|
|
memset(x2212,0,sizeof(x2212));
|
|
|
|
@@ -778,55 +868,61 @@
|
|
/* single digit conversion */
|
|
x2212[0x40] = hex2bin(txt[0]) - 1;
|
|
|
|
- /* number of channels in radio... to do this we need to look */
|
|
- /* at all the rx channels and count any in the range of 136-174 */
|
|
- chan = 0;
|
|
- for ( i = 0; i<16; i++ )
|
|
- {
|
|
- wid = lookup_widget(app1,rxfreq[i]);
|
|
- txt = gtk_entry_get_text((GtkEntry *)wid);
|
|
- freq = atof(txt);
|
|
- if ( freq >= 136.0 && freq <= 174.0 ) chan++;
|
|
- }
|
|
- if ( chan < 1 )
|
|
- fprintf(stderr,"Warning, no valid channels found\n");
|
|
- x2212[0x80] = chan - 1;
|
|
-
|
|
+ chan=0;
|
|
/* now lets fill in all the channels */
|
|
for ( i = 0; i<16; i++ )
|
|
{
|
|
/* rx freq lookup off the screen */
|
|
wid = lookup_widget(app1,rxfreq[i]);
|
|
txt = gtk_entry_get_text((GtkEntry *)wid);
|
|
- freq = atof(txt);
|
|
+ rx_freq = atof(txt);
|
|
+
|
|
+ if ( !freq_good(rx_freq) ) {
|
|
+ if(rx_freq > 0)
|
|
+ g_printf("Warning, ignoring and removing invalid channel %d\n",i+1);
|
|
+ continue;
|
|
+ }
|
|
+ chan++;
|
|
+ if(chan != i+1)
|
|
+ g_printf("Warning, channel %d will be renumbered to %d\n",i+1,chan);
|
|
+
|
|
+ /* tx freq lookup off the screen */
|
|
+ wid = lookup_widget(app1,txfreq[i]);
|
|
+ txt = gtk_entry_get_text((GtkEntry *)wid);
|
|
+ tx_freq = atof(txt);
|
|
+
|
|
+ for(j=0; j<3; j++) {
|
|
+ divisor = calc_divisor(rx_freq, spaces[j], TRUE);
|
|
+ realfreq = calc_realfreq(divisor, spaces[j], TRUE); /* in mhz */
|
|
+ errors[j] = fabs(rx_freq-realfreq);
|
|
+ divisor = calc_divisor(tx_freq, spaces[j], FALSE);
|
|
+ realfreq = calc_realfreq(divisor, spaces[j], FALSE); /* in mhz */
|
|
+ errors[j] += fabs(tx_freq-realfreq)*2;
|
|
+ }
|
|
+ sc_idx=0;
|
|
+ for(j=1; j<3; j++) {
|
|
+ if(errors[j] < errors[sc_idx])
|
|
+ sc_idx=j;
|
|
+ }
|
|
+// if(sc_idx)
|
|
+// g_printf("Using non-standard spacing of %fHz for channel %d\n",spaces[sc_idx],i+1);
|
|
|
|
- /* 3 gross assumptions!!!, timebomb below */
|
|
ref = 13.2e6;
|
|
- space = 5000.0;
|
|
-#define REFCODE 2
|
|
|
|
/* point to the 8 bytes of rx channel data for specified channel */
|
|
- chbuff = &x2212[0] + (((i+1) % 16) * 16);
|
|
+ chbuff = &x2212[0] + ((chan % 16) * 16);
|
|
/* there are 20 packed bits of freq info... lets build the numbers */
|
|
|
|
/* fill in info for valid rx channels */
|
|
- if ( freq >= 136.0 && freq <= 174.0 )
|
|
+ if ( freq_good(rx_freq) )
|
|
{
|
|
- /* we have a choice of 3 ch spacings when building info */
|
|
- /* for a particular rx and tx channel pair */
|
|
- /* as a start, we assume 5khz will do.. should probably */
|
|
- /* try all 3 and use the one with the least error */
|
|
- divisor = (((freq + 45.0)*1e6) + (space/2.0)) / space;
|
|
- realfreq = ((divisor * space ) - 45e6)/1e6; /* in mhz */
|
|
- if ( fabs(freq-realfreq) > 0.001 )
|
|
+ divisor = calc_divisor(rx_freq, spaces[sc_idx], TRUE);
|
|
+ realfreq = calc_realfreq(divisor, spaces[sc_idx], TRUE); /* in mhz */
|
|
+ if ( fabs(rx_freq-realfreq) > 0.001 )
|
|
fprintf(stderr,"Warning ch %d freq error: %f <> %fmhz\n",
|
|
- i+1,realfreq,freq);
|
|
- chbuff[1] = REFCODE + (( divisor & 0x8000) >> 12);
|
|
- chbuff[2] = (divisor & 0x780) >> 7;
|
|
- chbuff[3] = (divisor & 0x7800) >> 11;
|
|
- chbuff[4] = divisor & 0xf;
|
|
- chbuff[5] = ((divisor & 0x30) >> 4) + ((divisor & 0x40) >> 3);
|
|
-
|
|
+ i+1,realfreq,rx_freq);
|
|
+ fill_ch(chbuff, divisor);
|
|
+ chbuff[1] |= spacecode[sc_idx];
|
|
}
|
|
/* fill in the rx cg code (1st 2 digits of entrybox) */
|
|
wid = lookup_widget(app1,rxcg[i]);
|
|
@@ -835,28 +931,19 @@
|
|
chbuff[7] = hex2bin(txt[1]);
|
|
|
|
/* now fill in the tx info */
|
|
- /* tx freq lookup off the screen */
|
|
- wid = lookup_widget(app1,txfreq[i]);
|
|
- txt = gtk_entry_get_text((GtkEntry *)wid);
|
|
- freq = atof(txt);
|
|
-
|
|
/* point to the 8 bytes of tx channel data for specified channel */
|
|
- chbuff = &x2212[0] + (((i+1) % 16) * 16) + 8;
|
|
+ chbuff = &x2212[0] + ((chan % 16) * 16) + 8;
|
|
/* there are 20 packed bits of freq info... lets build the numbers */
|
|
|
|
/* fill in info for valid tx channels */
|
|
- if ( freq >= 136.0 && freq <= 174.0 )
|
|
+ if ( freq_good(tx_freq) )
|
|
{
|
|
- divisor = ((freq*1e6) + (space/2.0)) / space;
|
|
- realfreq = divisor * space /1e6; /* in mhz */
|
|
- if ( fabs(freq-realfreq) > 0.001 )
|
|
+ divisor = calc_divisor(tx_freq, spaces[sc_idx], FALSE);
|
|
+ realfreq = calc_realfreq(divisor, spaces[sc_idx], FALSE); /* in mhz */
|
|
+ if ( fabs(tx_freq-realfreq) > 0.001 )
|
|
fprintf(stderr,"Warning ch %d freq error: %f <> %fmhz\n",
|
|
- i+1,realfreq,freq);
|
|
- chbuff[1] = ( divisor & 0x8000) >> 12;
|
|
- chbuff[2] = (divisor & 0x780) >> 7;
|
|
- chbuff[3] = (divisor & 0x7800) >> 11;
|
|
- chbuff[4] = divisor & 0xf;
|
|
- chbuff[5] = ((divisor & 0x30) >> 4) + ((divisor & 0x40) >> 3);
|
|
+ i+1,realfreq,tx_freq);
|
|
+ fill_ch(chbuff, divisor);
|
|
}
|
|
/* fill in the tx cg code (1st 2 digits of entrybox) */
|
|
wid = lookup_widget(app1,txcg[i]);
|
|
@@ -869,6 +956,11 @@
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)wid))
|
|
chbuff[1] = chbuff[1] + 0x04;
|
|
}
|
|
+ /* number of channels in radio... to do this we need to look */
|
|
+ /* at all the rx channels and count any in the range of 136-174 */
|
|
+ if ( chan < 1 )
|
|
+ fprintf(stderr,"Warning, no valid channels found\n");
|
|
+ x2212[0x80] = chan - 1;
|
|
}
|
|
|
|
|
|
@@ -1148,19 +1240,30 @@
|
|
}
|
|
|
|
/* to read and write to the parallel port, we need it open as root */
|
|
+#ifdef USE_PPI_DEV
|
|
+ fd0 = open("/dev/ppi0", O_RDWR | O_NONBLOCK);
|
|
+#else
|
|
fd0 = open("/dev/lp0", O_RDWR | O_NONBLOCK);
|
|
+#endif
|
|
if (fd0 >= 0)
|
|
{
|
|
+#ifndef USE_PPI_DEV
|
|
int stat = ioperm(LPTDAT, 3, 1);
|
|
if ( stat == -1 )
|
|
perror("ioperm failed ");
|
|
+#endif
|
|
}
|
|
else
|
|
{
|
|
+#ifdef USE_PPI_DEV
|
|
+ fprintf(stderr,"\n\n*** open on /dev/ppi0 failed...Do you have permission?\n");
|
|
+ perror("/dev/lp0");
|
|
+#else
|
|
fprintf(stderr,"\n\n*** open on /dev/lp0 failed...Do you have permission?\n");
|
|
fprintf(stderr,"*** you may need to 'sudo modprobe parport_pc'\n");
|
|
fprintf(stderr,"*** 'sudo ge-x2212-2'\n");
|
|
perror("/dev/lp0");
|
|
+#endif
|
|
done();
|
|
}
|
|
// g_print("Using port: 0x%x \n", LPTDAT);
|