From 87e4480a590503b9b7feaf9c6d45089058c1eb95 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 17 Feb 2015 05:10:56 +0100 Subject: hhd70: getting/setting frequency --- software/avr.lib/cc1101.c | 30 ++++++++++++++++++++++----- software/avr.lib/cc1101.h | 3 +++ software/hhd70dongle/hhd70dongle.c | 42 +++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/software/avr.lib/cc1101.c b/software/avr.lib/cc1101.c index 2023c01..9053417 100644 --- a/software/avr.lib/cc1101.c +++ b/software/avr.lib/cc1101.c @@ -32,7 +32,7 @@ static cc1101_driver_conf_t drv = { .spi_write_byte = NULL, .spi_read_byte = NULL, .spi_transfer_byte = NULL, - .freq_corr = 0.0 + .freq_corr = 1.0 }; /* @@ -103,10 +103,7 @@ void cc1101_init(cc1101_driver_conf_t conf) void cc1101_reg_init(void) { - // Set freq to 437.525 MHz - cc1101_spi_write_register(CC1101_REG_RW_FREQ2,0x10); //Frequency Control Word, High Byte - cc1101_spi_write_register(CC1101_REG_RW_FREQ1,0xD3); //Frequency Control Word, Middle Byte - cc1101_spi_write_register(CC1101_REG_RW_FREQ0,0xF0); //Frequency Control Word, Low Byte + // TODO: init register depending on mode beacon vs. data } void cc1101_soft_reset(void) @@ -119,6 +116,29 @@ void cc1101_powerdown(void) cc1101_spi_strobe_command(CC1101_CMD_SPWD); } +void cc1101_set_freq_hz(uint32_t hz) +{ + uint32_t freq = (uint32_t)((float)hz / drv.freq_corr); + if(freq <= 0x3FFFFF) + + // TODO: this is only allowed in idle mode + cc1101_spi_write_register(CC1101_REG_RW_FREQ0, freq & 0xFF); + cc1101_spi_write_register(CC1101_REG_RW_FREQ1, (freq >> 8) & 0xFF); + cc1101_spi_write_register(CC1101_REG_RW_FREQ2, (freq >> 16) & 0x3F); +} + +uint32_t cc1101_get_freq_hz(void) +{ + uint32_t freq = 0; + freq = cc1101_spi_read_register(CC1101_REG_RW_FREQ2) & 0x3F; + freq = freq << 8; + freq |= cc1101_spi_read_register(CC1101_REG_RW_FREQ1); + freq = freq << 8; + freq |= cc1101_spi_read_register(CC1101_REG_RW_FREQ0); + + return (uint32_t)((float)freq * drv.freq_corr); +} + static char* cc1101_config_reg_to_string(uint8_t addr) { switch(addr) { diff --git a/software/avr.lib/cc1101.h b/software/avr.lib/cc1101.h index c5690e0..2ac92bb 100644 --- a/software/avr.lib/cc1101.h +++ b/software/avr.lib/cc1101.h @@ -40,6 +40,9 @@ void cc1101_reg_init(void); void cc1101_soft_reset(void); void cc1101_powerdown(void); +void cc1101_set_freq_hz(uint32_t hz); +uint32_t cc1101_get_freq_hz(void); + void cc1101_dump_register(void); #endif diff --git a/software/hhd70dongle/hhd70dongle.c b/software/hhd70dongle/hhd70dongle.c index 3db3c5c..2c239b4 100644 --- a/software/hhd70dongle/hhd70dongle.c +++ b/software/hhd70dongle/hhd70dongle.c @@ -44,7 +44,8 @@ #include "cc1101.h" #include "cc1101_defines.h" -#define DEFAULT_FREQ 437525 +#define DEFAULT_FREQ 437525000 +int32_t current_freq_hz = DEFAULT_FREQ; static void reset_hhd70(void) { @@ -58,6 +59,32 @@ static void reinit_hhd70(void) cc1101_reg_init(); } +static uint32_t print_actual_freq(void) +{ + uint32_t f = cc1101_get_freq_hz(); + uint16_t hz = f % 1000; + uint16_t mhz = f / 1000000; + uint16_t khz = (f % 1000000)/1000; + printf("actual frequency: %d.%03d%03d MHz\r\n", mhz, khz, hz); + return f; +} + +static void update_current_freq(void) +{ + uint16_t hz = current_freq_hz % 1000; + uint16_t mhz = current_freq_hz / 1000000; + uint16_t khz = (current_freq_hz % 1000000)/1000; + printf("setting frequency to %d.%03d%03d MHz\r\n", mhz, khz, hz); + + // TODO: goto idle mode + + cc1101_set_freq_hz(current_freq_hz); + + // TODO: if old mode wasn't idle go back to this mode + + print_actual_freq(); +} + static void print_status(void) { printf("HHD70 status:\r\n"); @@ -71,9 +98,22 @@ static void handle_cmd(uint8_t cmd) case '1': led_on(); printf("led ON\r\n"); break; case 't': led_toggle(); printf("led TOGGLE\r\n"); break; case '!': cc1101_soft_reset(); reset2bootloader(); break; + case 'r': reset_hhd70(); break; case 'i': reinit_hhd70(); break; + case 'F': current_freq_hz = DEFAULT_FREQ; update_current_freq(); break; + + case '#': current_freq_hz+=100000; update_current_freq(); break; + case '+': current_freq_hz+=10000; update_current_freq(); break; + case ':': current_freq_hz+=1000; update_current_freq(); break; + case '.': current_freq_hz-=1000; update_current_freq(); break; + case '-': current_freq_hz-=10000; update_current_freq(); break; + case '_': current_freq_hz-=100000; update_current_freq(); break; + case 'P': cc1101_powerdown(); print_status(); break; + + case 'f': print_actual_freq(); break; + case 's': print_status(); break; case 'D': cc1101_dump_register(); break; default: printf("unknown command\r\n"); return; -- cgit v1.2.3