added gpio functions to API and extended rtl_biast

* functions were provided from Marko Cebokli
at http://lea.hamradio.si/~s57uuu/mischam/rtlsdr/ports.html
* changed functions to return error/status
* added rtlsdr_set_gpio_status() - for testing

Signed-off-by: hayati ayguen <h_ayguen@web.de>
development
hayati ayguen 2020-08-31 07:40:28 +02:00
parent 3864bf7889
commit 35b8c01015
3 changed files with 169 additions and 17 deletions

View File

@ -535,8 +535,10 @@ RTLSDR_API int rtlsdr_ir_query(rtlsdr_dev_t *dev, uint8_t *buf, size_t buf_len);
/*!
* Enable or disable (the bias tee on) GPIO PIN 0. (Works for rtl-sdr.com v3 dongles)
* See: http://www.rtl-sdr.com/rtl-sdr-blog-v-3-dongles-user-guide/
* Enable or disable (the bias tee on) GPIO PIN 0 - if not reconfigured.
* See rtlsdr_set_opt_string() option 'T'.
* This works for rtl-sdr.com v3 dongles, see
* http://www.rtl-sdr.com/rtl-sdr-blog-v-3-dongles-user-guide/
* Note: rtlsdr_close() does not clear GPIO lines,
* so it leaves the (bias tee) line enabled if a client program
* doesn't explictly disable it.
@ -554,12 +556,30 @@ RTLSDR_API int rtlsdr_set_bias_tee(rtlsdr_dev_t *dev, int on);
* doesn't explictly disable it.
*
* \param dev the device handle given by rtlsdr_open()
* \param gpio the gpio pin to configure as a Bias T control.
* \param gpio the gpio pin -- assuming this line is connected to Bias T.
* gpio needs to be in 0 .. 7. BUT pin 4 is connected to Tuner RESET.
* and for FC0012 is already connected/reserved pin 6 for switching V/U-HF.
* \param on 1 for Bias T on. 0 for Bias T off.
* \return -1 if device is not initialized. 0 otherwise.
*/
RTLSDR_API int rtlsdr_set_bias_tee_gpio(rtlsdr_dev_t *dev, int gpio, int on);
/* from http://lea.hamradio.si/~s57uuu/mischam/rtlsdr/ports.html
* added return of error/status */
RTLSDR_API int rtlsdr_set_gpio_output(rtlsdr_dev_t *dev, uint8_t gpio);
RTLSDR_API int rtlsdr_set_gpio_input(rtlsdr_dev_t *dev, uint8_t gpio);
RTLSDR_API int rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
RTLSDR_API int rtlsdr_get_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int *val);
RTLSDR_API int rtlsdr_set_gpio_byte(rtlsdr_dev_t *dev, int val);
RTLSDR_API int rtlsdr_get_gpio_byte(rtlsdr_dev_t *dev, int *val);
/* added for testing: */
RTLSDR_API int rtlsdr_set_gpio_status(rtlsdr_dev_t *dev, int *status );
/*!
* Sets multiple options from a string encoded like "bw=300:agc=0:gain=27.3:dagc=0:T=1".
* this is a helper function, that programs don't need to implement every single option

View File

@ -266,7 +266,6 @@ struct rtlsdr_dev {
int dev_num;
};
static void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
static int rtlsdr_demod_write_reg(rtlsdr_dev_t *dev, uint8_t page, uint16_t addr, uint16_t val, uint8_t len);
static int rtlsdr_set_if_freq(rtlsdr_dev_t *dev, uint32_t freq);
static int rtlsdr_update_ds(rtlsdr_dev_t *dev, uint32_t freq);
@ -929,27 +928,77 @@ int rtlsdr_demod_write_reg(rtlsdr_dev_t *dev, uint8_t page, uint16_t addr, uint1
return (r == len) ? 0 : -1;
}
void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val)
int rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val)
{
uint16_t r;
uint16_t r, retval;
gpio = 1 << gpio;
r = rtlsdr_read_reg(dev, SYSB, GPO, 1);
r = val ? (r | gpio) : (r & ~gpio);
rtlsdr_write_reg(dev, SYSB, GPO, r, 1);
retval = rtlsdr_write_reg(dev, SYSB, GPO, r, 1);
return retval;
}
void rtlsdr_set_gpio_output(rtlsdr_dev_t *dev, uint8_t gpio)
int rtlsdr_set_gpio_output(rtlsdr_dev_t *dev, uint8_t gpio)
{
int r;
int r, retval;
gpio = 1 << gpio;
r = rtlsdr_read_reg(dev, SYSB, GPD, 1);
rtlsdr_write_reg(dev, SYSB, GPD, r & ~gpio, 1);
retval = rtlsdr_write_reg(dev, SYSB, GPD, r & ~gpio, 1);
if (retval < 0)
return retval;
r = rtlsdr_read_reg(dev, SYSB, GPOE, 1);
rtlsdr_write_reg(dev, SYSB, GPOE, r | gpio, 1);
retval = rtlsdr_write_reg(dev, SYSB, GPOE, r | gpio, 1);
return retval;
}
int rtlsdr_get_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int *val)
{
uint16_t r;
gpio = 1 << gpio;
r = rtlsdr_read_reg(dev, SYSB, GPI, 1);
*val = (r & gpio) ? 1 : 0;
return 0; /* no way to determine error with rtlsdr_read_reg() for now! */
}
int rtlsdr_set_gpio_input(rtlsdr_dev_t *dev, uint8_t gpio)
{
int r, retval;
gpio = 1 << gpio;
r = rtlsdr_read_reg(dev, SYSB, GPD, 1);
retval = rtlsdr_write_reg(dev, SYSB, GPD, r | gpio, 1);
if (retval < 0)
return retval;
r = rtlsdr_read_reg(dev, SYSB, GPOE, 1);
retval = rtlsdr_write_reg(dev, SYSB, GPOE, r & ~gpio, 1);
return retval;
}
int rtlsdr_set_gpio_status(rtlsdr_dev_t *dev, int *status )
{
int r;
r = rtlsdr_read_reg(dev, SYSB, GPD, 1);
*status = r;
return 0; /* no way to determine error with rtlsdr_read_reg() for now! */
}
int rtlsdr_get_gpio_byte(rtlsdr_dev_t *dev, int *val)
{
*val = rtlsdr_read_reg(dev, SYSB, GPI, 1);
return 0; /* no way to determine error with rtlsdr_read_reg() for now! */
}
int rtlsdr_set_gpio_byte(rtlsdr_dev_t *dev, int val)
{
int retval = rtlsdr_write_reg(dev, SYSB, GPO, val, 1);
return retval;
}
void rtlsdr_set_i2c_repeater(rtlsdr_dev_t *dev, int on)
{
if (on)

View File

@ -50,32 +50,51 @@ void usage(void)
fprintf(stderr,
"Usage:\trtl_biast [-options]\n"
"\t[-d device_index (default: 0)]\n"
"\t[-b bias_on (default: 0)]\n"
"\t[-g GPIO select (default: 0)]\n");
"\t[-g GPIO select (default: 0)]\n"
"\t[-b set write bias_on (default: 0, in output mode)]\n"
"\t[-r read pin (in input mode)]\n"
"\t[-w write pin (in output mode)]\n"
"\t[-s read all GPIO pins status (0 = write, 1 = read ?? )]\n"
"\t[-R read all GPIO pins ?? ]\n");
exit(1);
}
int main(int argc, char **argv)
{
int i, r, opt;
int i, r, opt, val;
int dev_index = 0;
int dev_given = 0;
int write_pin_given = 0;
int read_pin_given = 0;
int read_all_given = 0;
int req_status = 0;
uint32_t bias_on = 0;
uint32_t gpio_pin = 0;
int gpio_pin = 0;
int device_count;
while ((opt = getopt(argc, argv, "d:b:g:h?")) != -1) {
while ((opt = getopt(argc, argv, "d:b:w:g:srRh?")) != -1) {
switch (opt) {
case 'd':
dev_index = verbose_device_search(optarg);
dev_given = 1;
break;
case 'b':
case 'w':
bias_on = atoi(optarg);
write_pin_given = 1;
break;
case 'g':
gpio_pin = atoi(optarg);
break;
case 'r':
read_pin_given = 1;
break;
case 'R':
read_all_given = 1;
break;
case 's':
req_status = 1;
break;
default:
usage();
break;
@ -91,7 +110,71 @@ int main(int argc, char **argv)
}
r = rtlsdr_open(&dev, dev_index);
rtlsdr_set_bias_tee_gpio(dev, gpio_pin, bias_on);
if (r < 0)
{
fprintf(stderr, "error opening device with index %d\n", dev_index);
return -r;
}
if (write_pin_given)
{
r = rtlsdr_set_bias_tee_gpio(dev, gpio_pin, bias_on);
if (r < 0)
fprintf(stderr, "error setting value %d on pin %d\n", bias_on, gpio_pin);
}
else if (read_pin_given)
{
r = rtlsdr_set_gpio_input(dev, gpio_pin);
if (r < 0)
fprintf(stderr, "error configuring pin %d to input\n", gpio_pin);
r = rtlsdr_get_gpio_bit(dev, gpio_pin, &val);
if (r < 0)
fprintf(stderr, "error reading value for pin %d\n", gpio_pin);
else
printf("value %d at pin %d\n", val, gpio_pin);
}
else if (read_all_given)
{
r = rtlsdr_get_gpio_byte(dev, &val);
if (r < 0)
fprintf(stderr, "error reading value for all pins\n");
else
{
printf("GPIO 0x%02x = bin ", val);
for (gpio_pin = 7; gpio_pin >= 4; --gpio_pin)
printf("%d", ((val >> gpio_pin) & 1));
printf(" ");
for (gpio_pin = 3; gpio_pin >= 0; --gpio_pin)
printf("%d", ((val >> gpio_pin) & 1));
printf("\n");
}
}
else if (req_status)
{
r = rtlsdr_set_gpio_status(dev, &val);
if (r < 0)
fprintf(stderr, "error reading status for all pins\n");
else
{
printf("STATUS 0x%02x = bin ", val);
for (gpio_pin = 7; gpio_pin >= 4; --gpio_pin)
printf("%d", ((val >> gpio_pin) & 1));
printf(" ");
for (gpio_pin = 3; gpio_pin >= 0; --gpio_pin)
printf("%d", ((val >> gpio_pin) & 1));
printf("\n");
}
}
else
{
usage();
r = -1;
}
exit:
/*