Interpret last four bytes of EEPROM as value in Hz using network byte
order and use it as default if it is between MIN_RTL_XTAL_FREQ and
MAX_RTL_XTAL_FREQ.
---
src/librtlsdr.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/librtlsdr.c b/src/librtlsdr.c
index 2f5d90a..c986018 100644
--- a/src/librtlsdr.c
+++ b/src/librtlsdr.c
@@ -25,6 +25,9 @@
#ifndef _WIN32
#include <unistd.h>
#define min(a, b) (((a) < (b)) ? (a) : (b))
+#include <arpa/inet.h>
+#else
+#include <WinSock2.h>
#endif
#include <libusb.h>
@@ -279,6 +282,7 @@ static rtlsdr_dongle_t known_devices[] = {
#define BULK_TIMEOUT 0
#define EEPROM_ADDR 0xa0
+#define EEPROM_SIZE 256
enum usb_reg {
USB_SYSCTL = 0x2000,
@@ -1365,14 +1369,27 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
goto err;
}
- dev->rtl_xtal = DEF_RTL_XTAL_FREQ;
-
/* perform a dummy write, if it fails, reset the device */
if (rtlsdr_write_reg(dev, USBB, USB_SYSCTL, 0x09, 1) < 0) {
fprintf(stderr, "Resetting device...\n");
libusb_reset_device(dev->devh);
}
+ dev->rtl_xtal = DEF_RTL_XTAL_FREQ;
+
+ /* Allow for the last four bytes of the EEPROM to contain a
+ calibration frequency. */
+ {
+ uint32_t rtl_freq;
+
+ if (0 < rtlsdr_read_eeprom(dev, (void *)&rtl_freq, EEPROM_SIZE-4, 4))
+ rtl_freq = ntohl(rtl_freq);
+ if (rtl_freq >= MIN_RTL_XTAL_FREQ && rtl_freq <= MAX_RTL_XTAL_FREQ) {
+ fprintf(stderr, "Found valid XTAL calibration in EEPROM: %u Hz\n",
+ dev->rtl_xtal = rtl_freq);
+ }
+ }
+
rtlsdr_init_baseband(dev);
dev->dev_lost = 0;
--
1.7.10.4
Show replies by date