aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Markgraf <steve@steve-m.de>2012-03-31 21:01:25 +0200
committerSteve Markgraf <steve@steve-m.de>2012-03-31 21:01:25 +0200
commitff7910482453d39a776fbbe2ad79c59e87fa5132 (patch)
treec16965b22589a3d7fc7f950ef0ccfc7454500362
parentc09fbb7c579d95a6b8d1ae319489cb5bc77a2a23 (diff)
add support for autoprobing the tuners
Signed-off-by: Steve Markgraf <steve@steve-m.de>
-rw-r--r--include/tuner_e4000.h111
-rw-r--r--include/tuner_fc0013.h4
-rw-r--r--src/rtl-sdr.c98
-rw-r--r--src/tuner_e4000.c2
-rw-r--r--src/tuner_fc0013.c1
5 files changed, 99 insertions, 117 deletions
diff --git a/include/tuner_e4000.h b/include/tuner_e4000.h
index 4c78f3e..5aa71f5 100644
--- a/include/tuner_e4000.h
+++ b/include/tuner_e4000.h
@@ -1,120 +1,15 @@
#ifndef __TUNER_E4000_H
#define __TUNER_E4000_H
-/**
-
-@file
-
-@brief E4000 tuner module declaration
-
-One can manipulate E4000 tuner through E4000 module.
-E4000 module is derived from tuner module.
-
-
-
-@par Example:
-@code
-
-// The example is the same as the tuner example in tuner_base.h except the listed lines.
-
-
-
-#include "tuner_e4000.h"
-
-
-...
-
-
-
-int main(void)
-{
- TUNER_MODULE *pTuner;
- E4000_EXTRA_MODULE *pTunerExtra;
-
- TUNER_MODULE TunerModuleMemory;
- BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
-// I2C_BRIDGE_MODULE I2cBridgeModuleMemory;
-
- unsigned long BandwidthMode;
-
-
- ...
-
-
-
- // Build E4000 tuner module.
- BuildE4000Module(
- &pTuner,
- &TunerModuleMemory,
- &BaseInterfaceModuleMemory,
- &I2cBridgeModuleMemory,
- 0xac, // I2C device address is 0xac in 8-bit format.
- CRYSTAL_FREQ_16384000HZ, // Crystal frequency is 16.384 MHz.
- E4000_AGC_INTERNAL // The E4000 AGC mode is internal AGC mode.
- );
-
-
-
-
-
- // Get E4000 tuner extra module.
- pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra);
-
-
-
-
-
- // ==== Initialize tuner and set its parameters =====
-
- ...
-
- // Set E4000 bandwidth.
- pTunerExtra->SetBandwidthMode(pTuner, E4000_BANDWIDTH_6MHZ);
-
-
-
-
-
- // ==== Get tuner information =====
-
- ...
-
- // Get E4000 bandwidth.
- pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode);
-
-
-
- // See the example for other tuner functions in tuner_base.h
-
-
- return 0;
-}
-
-
-@endcode
-
-*/
-
-
-
-
-
-//#include "tuner_base.h"
-
-
-
-
-
-// The following context is implemented for E4000 source code.
-
-
// Definition (implemeted for E4000)
#define E4000_1_SUCCESS 1
#define E4000_1_FAIL 0
#define E4000_I2C_SUCCESS 1
#define E4000_I2C_FAIL 0
-
+#define E4K_I2C_ADDR 0xc8
+#define E4K_CHECK_ADDR 0x02
+#define E4K_CHECK_VAL 0x40
// Function (implemeted for E4000)
int
diff --git a/include/tuner_fc0013.h b/include/tuner_fc0013.h
index b405808..ed89465 100644
--- a/include/tuner_fc0013.h
+++ b/include/tuner_fc0013.h
@@ -15,6 +15,10 @@ FC0013 module is derived from tuner module.
**/
+#define FC0013_I2C_ADDR 0xc6
+#define FC0013_CHECK_ADDR 0x00
+#define FC0013_CHECK_VAL 0xa3
+
// Definitions
enum FC0013_TRUE_FALSE_STATUS
{
diff --git a/src/rtl-sdr.c b/src/rtl-sdr.c
index d5a0e8d..b88ac60 100644
--- a/src/rtl-sdr.c
+++ b/src/rtl-sdr.c
@@ -5,7 +5,7 @@
* 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 2 of the License, or
- *(at your option) any later version.
+ * (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
@@ -44,7 +44,7 @@ int fc0013_init(void *dev) { return FC0013_Open(dev); }
int fc0013_exit(void *dev) { return 0; }
int fc0013_tune(void *dev, int freq) {
/* read bandwidth mode to reapply it */
- int bw = 0;
+ unsigned int bw = 6;
//fc0013_GetBandwidthMode(dev, &bw); // FIXME: missing
return FC0013_SetFrequency(dev, freq/1000, bw & 0xff);
}
@@ -57,10 +57,9 @@ int fc0013_set_bw(void *dev, int bw) {
}
enum rtlsdr_tuners {
- RTLSDR_TUNER_UNDEF,
RTLSDR_TUNER_E4000,
RTLSDR_TUNER_FC0012,
- RTLSDR_TUNER_FC0013
+ RTLSDR_TUNER_FC0013,
};
typedef struct rtlsdr_tuner {
@@ -161,6 +160,23 @@ int rtlsdr_write_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t
return r;
}
+int rtlsdr_i2c_write_reg(rtlsdr_dev_t *dev, uint8_t i2c_addr, uint8_t data)
+{
+ uint16_t addr = i2c_addr;
+ return rtlsdr_write_array(dev, IICB, addr, &data, 1);
+}
+
+uint8_t rtlsdr_i2c_read_reg(rtlsdr_dev_t *dev, uint8_t i2c_addr, uint8_t reg)
+{
+ uint16_t addr = i2c_addr;
+ uint8_t data;
+
+ rtlsdr_write_array(dev, IICB, addr, &reg, 1);
+ rtlsdr_read_array(dev, IICB, addr, &data, 1);
+
+ return data;
+}
+
int rtlsdr_i2c_write(rtlsdr_dev_t *dev, uint8_t i2c_addr, uint8_t *buffer, int len)
{
uint16_t addr = i2c_addr;
@@ -251,6 +267,27 @@ void rtlsdr_demod_write_reg(rtlsdr_dev_t *dev, uint8_t page, uint16_t addr, uint
rtlsdr_demod_read_reg(dev, 0x0a, 0x01, 1);
}
+void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val)
+{
+ uint8_t r;
+
+ 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);
+}
+
+void rtlsdr_set_gpio_output(rtlsdr_dev_t *dev, uint8_t gpio)
+{
+ int r;
+ gpio = 1 << gpio;
+
+ r = rtlsdr_read_reg(dev, SYSB, GPD, 1);
+ rtlsdr_write_reg(dev, SYSB, GPO, r & ~gpio, 1);
+ r = rtlsdr_read_reg(dev, SYSB, GPOE, 1);
+ rtlsdr_write_reg(dev, SYSB, GPOE, r | gpio, 1);
+}
+
void rtlsdr_set_i2c_repeater(rtlsdr_dev_t *dev, int on)
{
rtlsdr_demod_write_reg(dev, 1, 0x01, on ? 0x18 : 0x10, 1);
@@ -464,6 +501,15 @@ const char *rtlsdr_get_device_name(uint32_t index)
return "";
}
+/* TODO: put those defines in the tuner header once the drivers are added */
+#define FC0012_I2C_ADDR 0xc6
+#define FC0012_CHECK_ADDR 0x00
+#define FC0012_CHECK_VAL 0xa1
+
+#define FC2580_I2C_ADDR 0xac
+#define FC2580_CHECK_ADDR 0x01
+#define FC2580_CHECK_VAL 0x56
+
rtlsdr_dev_t *rtlsdr_open(int index)
{
int r;
@@ -473,6 +519,7 @@ rtlsdr_dev_t *rtlsdr_open(int index)
libusb_device *device = NULL;
uint32_t device_count = 0;
struct libusb_device_descriptor dd;
+ uint8_t reg;
dev = malloc(sizeof(rtlsdr_dev_t));
memset(dev, 0, sizeof(rtlsdr_dev_t));
@@ -514,10 +561,49 @@ rtlsdr_dev_t *rtlsdr_open(int index)
rtlsdr_init_baseband(dev);
- // TODO: probe the tuner and set dev->tuner member to appropriate tuner object
- // dev->tuner = &tuners[...];
+ /* Probe tuners */
+ rtlsdr_set_i2c_repeater(dev, 1);
+
+ reg = rtlsdr_i2c_read_reg(dev, E4K_I2C_ADDR, E4K_CHECK_ADDR);
+ if (reg == E4K_CHECK_VAL) {
+ printf("Found Elonics E4000 tuner\n");
+ dev->tuner = &tuners[RTLSDR_TUNER_E4000];
+ goto found;
+ }
+
+ reg = rtlsdr_i2c_read_reg(dev, FC0013_I2C_ADDR, FC0013_CHECK_ADDR);
+ if (reg == FC0013_CHECK_VAL) {
+ printf("Found Fitipower FC0013 tuner\n");
+ dev->tuner = &tuners[RTLSDR_TUNER_FC0013];
+ goto found;
+ }
+ reg = rtlsdr_i2c_read_reg(dev, FC2580_I2C_ADDR, FC2580_CHECK_ADDR);
+ if ((reg & 0x7f) == FC2580_CHECK_VAL) {
+ printf("Found FCI 2580 tuner\n");
+ //dev->tuner = &tuners[RTLSDR_TUNER_FC2580];
+ // TODO: set GPIO5 low
+ goto found;
+ }
+
+ /* initialise GPIOs (only needed for the FC0012 so far */
+ rtlsdr_set_gpio_output(dev, 5);
+
+ /* reset FC0012 before probing */
+ rtlsdr_set_gpio_bit(dev, 5, 1);
+ rtlsdr_set_gpio_bit(dev, 5, 0);
+
+ reg = rtlsdr_i2c_read_reg(dev, FC0012_I2C_ADDR, FC0012_CHECK_ADDR);
+ if (reg == FC0012_CHECK_VAL) {
+ printf("Found Fitipower FC0012 tuner\n");
+ dev->tuner = &tuners[RTLSDR_TUNER_FC0012];
+ goto found;
+ }
+
+found:
+ rtlsdr_set_i2c_repeater(dev, 0);
return dev;
+
err:
return NULL;
}
diff --git a/src/tuner_e4000.c b/src/tuner_e4000.c
index 7cf7159..18aa967 100644
--- a/src/tuner_e4000.c
+++ b/src/tuner_e4000.c
@@ -18,9 +18,7 @@
#define I2C_BUFFER_LEN 128
#define YES 1
#define NO 0
-
#define CRYSTAL_FREQ 28800000
-#define E4K_I2C_ADDR 0xc8
/* glue functions to rtl-sdr code */
int
diff --git a/src/tuner_fc0013.c b/src/tuner_fc0013.c
index 8da5d06..a228e03 100644
--- a/src/tuner_fc0013.c
+++ b/src/tuner_fc0013.c
@@ -11,7 +11,6 @@
#include "tuner_fc0013.h"
#define CRYSTAL_FREQ 28800000
-#define FC0013_I2C_ADDR 0xc6
/* glue functions to rtl-sdr code */
int FC0013_Write(void *pTuner, unsigned char RegAddr, unsigned char Byte)