Add gpio command to rigctl(d) usable with pttport setting CM108

e.g. to set gpio2 on use 'gpio GPIO2 1" and off "gpio GPIO2 0"
Should work with GPIO1-4
New API funcions rig_cm108_get_bit rig_cm108_set_bit
https://github.com/Hamlib/Hamlib/issues/1121
pull/1347/head
Mike Black W9MDB 2023-07-22 10:32:25 -05:00
rodzic d28ce6b798
commit 9ad070c33f
7 zmienionych plików z 243 dodań i 24 usunięć

1
NEWS
Wyświetl plik

@ -13,6 +13,7 @@ Version 5.x -- future
* Change FT1000MP Mark V model names to align with FT1000MP
Version 4.6
* Added rig_cm108_get/set_bit to API and get/set_gpio to rigctl(d) for GPIO1,2,3,4 access on CM108
* Added BG2FX FX4/C/CR/L
* Fixed IC7610 to use new 0x25 0x26 command added in latest firmware
* Fix W command in rigctld to work propery -- can take terminating char or # of bytes to expect

Wyświetl plik

@ -1398,6 +1398,31 @@ Examples:
.BR client_version " \(aq" \fIString\fP "\(aq
.EX
Client can send its version to rigctld and get feedback on compatibility, deprecation, and alternatives
.TP
.BR hamlib_version
.EX
Returns hamlib version with ISO8601 date/time
.
.TP
.BR test
.EX
Performs test routines. Under development.
.
.TP
.BR set_gpio " \(aq" \fIGPIO#\fP "\(aq
.EX
Sets GPIO1, GPIO2, GPIO3, GPIO4 on the GPIO ptt port
Can also use 1,2,3,4
.
.TP
.BR XXXX
.EX
Stuff
.
.TP
.BR XXXX
.EX
Stuff
.
.SH READLINE
.

Wyświetl plik

@ -1202,6 +1202,52 @@ CW Skimmer is started and "set_lock_mode 0" when CW Skimmer is stopped.
.BR get_lock_mode
Returns current lock mode status 1=On, 2=Off (only useful with rigctld)
.
.TP
.BR send_raw " \(aq" \fITerminator\fP "\(aq \(aq" \fIString\fP \(aq
.EX
Can send ASCII string or 0xnn values -- there can be no spaces in the command string.
Possible terminator values are CR, LF, ;, ICOM, 0-100 (bytes to read), or -1 meaning unknown (will timeout on read)
Examples:
send_raw ; FA;MD;
send_raw icom 0xFE;0xFE;0x94;0x03;0xFD
send_raw -1 0xFE;0xFE;0x94;0x03;0xFD
send_raw 14 0xFE;0xFE;0x94;0x03;0xFD
.
.TP
.BR client_version " \(aq" \fIString\fP "\(aq
.EX
Client can send its version to rigctld and get feedback on compatibility, deprecation, and alternatives
.TP
.BR hamlib_version
.EX
Returns hamlib version with ISO8601 date/time
.
+.TP
+.BR hamlib_version
+.EX
+Returns hamlib version with ISO8601 date/time
+.
+.TP
+.BR test
+.EX
+Performs test routines. Under development.
+.
+.TP
+.BR set_gpio " \(aq" \fIGPIO#\fP "\(aq
+.EX
+Sets GPIO1, GPIO2, GPIO3, GPIO4 on the GPIO ptt port
+Can also use 1,2,3,4
+.
+.TP
+.BR XXXX
+.EX
+Stuff
+.
+.TP
+.BR XXXX
+.EX
+Stuff
.
.SH PROTOCOL
.

Wyświetl plik

@ -3694,6 +3694,10 @@ extern HAMLIB_EXPORT(int) rig_is_model(RIG *rig, rig_model_t model);
extern HAMLIB_EXPORT(char*) rig_date_strget(char *buf, int buflen, int localtime);
enum GPIO { GPIO1, GPIO2, GPIO3, GPIO4 };
extern HAMLIB_EXPORT(int) rig_cm108_get_bit(hamlib_port_t *p, enum GPIO gpio, int *bit);
extern HAMLIB_EXPORT(int) rig_cm108_set_bit(hamlib_port_t *p, enum GPIO gpio, int bit);
//! @endcond

Wyświetl plik

@ -195,7 +195,7 @@ int cm108_ptt_set(hamlib_port_t *p, ptt_t pttx)
case RIG_PTT_CM108:
{
ssize_t nw;
ssize_t bytes;
char out_rep[] =
{
0x00, // report number
@ -227,9 +227,9 @@ int cm108_ptt_set(hamlib_port_t *p, ptt_t pttx)
}
// Send the HID packet
nw = write(p->fd, out_rep, sizeof(out_rep));
bytes = write(p->fd, out_rep, sizeof(out_rep));
if (nw < 0)
if (bytes < 0)
{
return -RIG_EIO;
}
@ -295,30 +295,122 @@ int cm108_ptt_get(hamlib_port_t *p, ptt_t *pttx)
*/
int cm108_dcd_get(hamlib_port_t *p, dcd_t *dcdx)
{
int bytes;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
// On the CM108 and compatible chips the squelch line on the radio is
// wired to Volume Down input pin. The state of this pin is reported
// in HID messages from the CM108 device, but I am not sure how
// to query this state on demand.
switch (p->type.dcd)
{
case RIG_DCD_CM108:
{
return -RIG_ENIMPL;
}
default:
rig_debug(RIG_DEBUG_ERR,
"%s: unsupported DCD type %d\n",
__func__,
p->type.dcd);
return -RIG_ENAVAIL;
}
return RIG_OK;
}
#endif
int cm108_set_bit(hamlib_port_t *p, enum GPIO gpio, int bit)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
ssize_t bytes;
char out_rep[] =
{
0x00, // report number
// HID output report
0x00,
bit ? (1 << (gpio - 1)) : 0, // set GPIO
1 << (gpio - 1), // Data direction register (1=output)
0x00
};
rig_debug(RIG_DEBUG_VERBOSE, "%s: out_rep = 0x%02x 0x%02x\n", __func__,
out_rep[2], out_rep[3]);
// Build a packet for CM108 HID to turn GPIO bit on or off.
// Packet is 4 bytes, preceded by a 'report number' byte
// 0x00 report number
// Write data packet (from CM108 documentation)
// byte 0: 00xx xxxx Write GPIO
// byte 1: xxxx dcba GPIO3-0 output values (1=high)
// byte 2: xxxx dcba GPIO3-0 data-direction register (1=output)
// byte 3: xxxx xxxx SPDIF
// Send the HID packet
bytes = write(p->fd, out_rep, sizeof(out_rep));
if (bytes < 0)
{
return -RIG_EIO;
}
return RIG_OK;
}
int cm108_get_bit(hamlib_port_t *p, enum GPIO gpio, int *bit)
{
ssize_t bytes;
char reply[4];
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
char in_rep[] =
{
0x00, // report number
0x01, // HID input report
0x00,
0x00
};
// Send the HID packet
bytes = write(p->fd, in_rep, sizeof(in_rep));
if (bytes < 0)
{
return -RIG_EIO;
}
bytes = read(p->fd, reply, sizeof(reply));
if (bytes <= 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: read error: %s\n", __func__, strerror(errno));
return -RIG_EPROTO;
}
int mask = 1 << (gpio - 1);
*bit = (reply[1] & mask) != 0;
rig_debug(RIG_DEBUG_VERBOSE,
"%s: mask=0x%02x, reply=0x%02x 0x%02x 0x%02x 0x%02x, bit=%d\n", __func__, mask,
reply[0], reply[1], reply[2], reply[3], *bit);
return RIG_OK;
}
int rig_cm108_get_bit(hamlib_port_t *p, enum GPIO gpio, int *bit)
{
if (gpio < 1 || gpio > 4)
{
rig_debug(RIG_DEBUG_ERR, "%s: gpio must be 1,2,3,4 for cm108\n", __func__);
return -RIG_EINVAL;
}
cm108_get_bit(p, gpio, bit);
rig_debug(RIG_DEBUG_TRACE, "%s: gpio=%d bit=%d\n", __func__, gpio, *bit);
return RIG_OK;
}
int rig_cm108_set_bit(hamlib_port_t *p, enum GPIO gpio, int bit)
{
if (gpio < 1 || gpio > 4)
{
rig_debug(RIG_DEBUG_ERR, "%s: gpio must be 1,2,3,4 for cm108\n", __func__);
return -RIG_EINVAL;
}
int retval = cm108_set_bit(p, gpio, bit);
if (retval != RIG_OK)
{
rig_debug(RIG_DEBUG_ERR, "%s: cm108_set_bit: %s\n", __func__, strerror(retval));
return retval;
}
rig_debug(RIG_DEBUG_TRACE, "%s: simulated gpio=%d bit=%d\n", __func__, gpio,
bit);
return RIG_OK;
}
/** @} */

Wyświetl plik

@ -189,4 +189,3 @@ int gpio_dcd_get(hamlib_port_t *port, dcd_t *dcdx)
return RIG_OK;
}

Wyświetl plik

@ -267,6 +267,8 @@ declare_proto_rig(send_raw);
declare_proto_rig(client_version);
declare_proto_rig(hamlib_version);
declare_proto_rig(test);
declare_proto_rig(cm108_get_bit);
declare_proto_rig(cm108_set_bit);
/*
@ -384,6 +386,8 @@ static struct test_table test_list[] =
{ 0xa6, "get_vfo_list", ACTION(get_vfo_list), ARG_NOVFO },
{ 0xa7, "test", ACTION(test), ARG_NOVFO | ARG_IN, "routine" },
{ 0xa8, "hamlib_version", ACTION(hamlib_version), ARG_NOVFO },
{ 0xa9, "get_gpio", ACTION(cm108_get_bit), ARG_NOVFO | ARG_IN1 | ARG_OUT1, "GPIO#", "0/1" },
{ 0xaa, "set_gpio", ACTION(cm108_set_bit), ARG_NOVFO | ARG_IN , "GPIO#", "0/1" },
{ 0x00, "", NULL },
};
@ -5609,3 +5613,51 @@ declare_proto_rig(send_raw)
return RIG_OK;
}
declare_proto_rig(cm108_get_bit)
{
rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__);
int gpio = -1;
int bit = -1;
// try GPIO format first
int n = sscanf(arg1,"GPIO%d", &gpio);
if (n == 0)
n = sscanf(arg1,"%d", &gpio);
if (n != 1) return -RIG_EINVAL;
int retval = rig_cm108_get_bit(&rig->state.pttport, gpio, &bit);
if (retval != RIG_OK)
{
rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, strerror(retval));
return retval;
}
rig_debug(RIG_DEBUG_TRACE, "%s: gpio=%d\n", __func__, gpio);
if ((interactive && prompt) || (interactive && !prompt && ext_resp))
{
fprintf(fout, "%s: ", cmd->arg2);
}
fprintf(fout, "%d (simulated)\n", 1);
return RIG_OK;
}
declare_proto_rig(cm108_set_bit)
{
rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__);
int gpio, bit=-1;
// try GPIO format first
int n = sscanf(arg1,"GPIO%d", &gpio);
if (n == 0)
n = sscanf(arg1,"%d", &gpio);
if (n != 1) return -RIG_EINVAL;
n = sscanf(arg2, "%d", &bit);
if (n != 1) return -RIG_EINVAL;
rig_debug(RIG_DEBUG_TRACE, "%s: set gpio=%d, bit=%d\n", __func__, gpio, bit);
int retval = rig_cm108_set_bit(&rig->state.pttport, gpio, bit);
if (retval != RIG_OK)
{
rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, strerror(retval));
}
return retval;
}