mirror of
https://github.com/rtlsdrblog/rtl-sdr-blog.git
synced 2024-11-10 04:37:37 +01:00
add support for autoprobing the tuners
Signed-off-by: Steve Markgraf <steve@steve-m.de>
This commit is contained in:
parent
c09fbb7c57
commit
ff79104824
@ -1,120 +1,15 @@
|
|||||||
#ifndef __TUNER_E4000_H
|
#ifndef __TUNER_E4000_H
|
||||||
#define __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)
|
// Definition (implemeted for E4000)
|
||||||
#define E4000_1_SUCCESS 1
|
#define E4000_1_SUCCESS 1
|
||||||
#define E4000_1_FAIL 0
|
#define E4000_1_FAIL 0
|
||||||
#define E4000_I2C_SUCCESS 1
|
#define E4000_I2C_SUCCESS 1
|
||||||
#define E4000_I2C_FAIL 0
|
#define E4000_I2C_FAIL 0
|
||||||
|
|
||||||
|
#define E4K_I2C_ADDR 0xc8
|
||||||
|
#define E4K_CHECK_ADDR 0x02
|
||||||
|
#define E4K_CHECK_VAL 0x40
|
||||||
|
|
||||||
// Function (implemeted for E4000)
|
// Function (implemeted for E4000)
|
||||||
int
|
int
|
||||||
|
@ -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
|
// Definitions
|
||||||
enum FC0013_TRUE_FALSE_STATUS
|
enum FC0013_TRUE_FALSE_STATUS
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* 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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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_exit(void *dev) { return 0; }
|
||||||
int fc0013_tune(void *dev, int freq) {
|
int fc0013_tune(void *dev, int freq) {
|
||||||
/* read bandwidth mode to reapply it */
|
/* read bandwidth mode to reapply it */
|
||||||
int bw = 0;
|
unsigned int bw = 6;
|
||||||
//fc0013_GetBandwidthMode(dev, &bw); // FIXME: missing
|
//fc0013_GetBandwidthMode(dev, &bw); // FIXME: missing
|
||||||
return FC0013_SetFrequency(dev, freq/1000, bw & 0xff);
|
return FC0013_SetFrequency(dev, freq/1000, bw & 0xff);
|
||||||
}
|
}
|
||||||
@ -57,10 +57,9 @@ int fc0013_set_bw(void *dev, int bw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum rtlsdr_tuners {
|
enum rtlsdr_tuners {
|
||||||
RTLSDR_TUNER_UNDEF,
|
|
||||||
RTLSDR_TUNER_E4000,
|
RTLSDR_TUNER_E4000,
|
||||||
RTLSDR_TUNER_FC0012,
|
RTLSDR_TUNER_FC0012,
|
||||||
RTLSDR_TUNER_FC0013
|
RTLSDR_TUNER_FC0013,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct rtlsdr_tuner {
|
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;
|
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, ®, 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)
|
int rtlsdr_i2c_write(rtlsdr_dev_t *dev, uint8_t i2c_addr, uint8_t *buffer, int len)
|
||||||
{
|
{
|
||||||
uint16_t addr = i2c_addr;
|
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);
|
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)
|
void rtlsdr_set_i2c_repeater(rtlsdr_dev_t *dev, int on)
|
||||||
{
|
{
|
||||||
rtlsdr_demod_write_reg(dev, 1, 0x01, on ? 0x18 : 0x10, 1);
|
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 "";
|
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)
|
rtlsdr_dev_t *rtlsdr_open(int index)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@ -473,6 +519,7 @@ rtlsdr_dev_t *rtlsdr_open(int index)
|
|||||||
libusb_device *device = NULL;
|
libusb_device *device = NULL;
|
||||||
uint32_t device_count = 0;
|
uint32_t device_count = 0;
|
||||||
struct libusb_device_descriptor dd;
|
struct libusb_device_descriptor dd;
|
||||||
|
uint8_t reg;
|
||||||
|
|
||||||
dev = malloc(sizeof(rtlsdr_dev_t));
|
dev = malloc(sizeof(rtlsdr_dev_t));
|
||||||
memset(dev, 0, 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);
|
rtlsdr_init_baseband(dev);
|
||||||
|
|
||||||
// TODO: probe the tuner and set dev->tuner member to appropriate tuner object
|
/* Probe tuners */
|
||||||
// dev->tuner = &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;
|
return dev;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,7 @@
|
|||||||
#define I2C_BUFFER_LEN 128
|
#define I2C_BUFFER_LEN 128
|
||||||
#define YES 1
|
#define YES 1
|
||||||
#define NO 0
|
#define NO 0
|
||||||
|
|
||||||
#define CRYSTAL_FREQ 28800000
|
#define CRYSTAL_FREQ 28800000
|
||||||
#define E4K_I2C_ADDR 0xc8
|
|
||||||
|
|
||||||
/* glue functions to rtl-sdr code */
|
/* glue functions to rtl-sdr code */
|
||||||
int
|
int
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "tuner_fc0013.h"
|
#include "tuner_fc0013.h"
|
||||||
|
|
||||||
#define CRYSTAL_FREQ 28800000
|
#define CRYSTAL_FREQ 28800000
|
||||||
#define FC0013_I2C_ADDR 0xc6
|
|
||||||
|
|
||||||
/* glue functions to rtl-sdr code */
|
/* glue functions to rtl-sdr code */
|
||||||
int FC0013_Write(void *pTuner, unsigned char RegAddr, unsigned char Byte)
|
int FC0013_Write(void *pTuner, unsigned char RegAddr, unsigned char Byte)
|
||||||
|
Loading…
Reference in New Issue
Block a user