From 9bff605af8e33da7df0b35e4790849ac2985ee9f Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 25 Mar 2013 00:51:09 +0000 Subject: major interface cleanup api now knows state of rda get freq works now git-svn-id: https://svn.spreadspace.org/mur.sat@708 7de4ea59-55d0-425e-a1af-a3118ea81d4c --- software/rda1846dongle/rda1846.c | 175 ++++++++++++++++++++----------- software/rda1846dongle/rda1846.h | 28 +++-- software/rda1846dongle/rda1846_defines.h | 10 ++ software/rda1846dongle/rda1846dongle.c | 61 +++++------ 4 files changed, 163 insertions(+), 111 deletions(-) (limited to 'software') diff --git a/software/rda1846dongle/rda1846.c b/software/rda1846dongle/rda1846.c index bd68710..c7f612c 100644 --- a/software/rda1846dongle/rda1846.c +++ b/software/rda1846dongle/rda1846.c @@ -117,7 +117,45 @@ static uint8_t rda1846_read_register(const uint8_t addr, uint16_t* data) return 1; } +static rf_band_t rf_band_; +static channel_bw_t channel_bw_; +static rda1846_state_t state_; +/* + * EXTERNAL INTERFACE + */ + +char* rda1846_rf_band_to_string(rf_band_t b) +{ + switch(b) + { + case b_2m: return "2m (134-174 MHz)"; + case b_70cm: return "70cm (400-520 MHz)"; + } + return ""; +} + +char* rda1846_channel_bw_to_string(channel_bw_t bw) +{ + switch(bw) + { + case bw_12k5: return "12,5 kHz"; + case bw_25k: return "25 kHz"; + } + return ""; +} + +char* rda1846_state_to_string(rda1846_state_t s) +{ + switch(s) + { + case powerdown: return "powerdown"; + case idle: return "idle"; + case receive: return "receiving"; + case transmit: return "transmitting"; + } + return ""; +} void rda1846_init(void) { @@ -129,13 +167,16 @@ void rda1846_reg_init(void) rda1846_write_register(RDA1846_REG_CTL, RDA1846_CTL_SOFT_RST); rda1846_write_register(RDA1846_REG_CTL, RDA1846_CTL_PDN); - // set crystal frequency (12.288 MHz) rda1846_write_register(RDA1846_REG_XTAL, RDA1846_XTAL_FREQ); rda1846_write_register(RDA1846_REG_ADCLK, RDA1846_ADCLK_FREQ); rda1846_write_register(RDA1846_REG_CLK_MODE, RDA1846_CLK_MODE); rda1846_write_register(RDA1846_REG_RF_BAND, RDA1846_RF_BAND_2M); + rf_band_ = b_2m; + rda1846_write_register(RDA1846_REG_CTL, RDA1846_CTL_CH_12K5 | RDA1846_CTL_RX_M_TX_M | RDA1846_CTL_PDN); + channel_bw_ = bw_12k5; + state_ = idle; rda1846_write_register(RDA1846_REG_TX_VOICE, RDA1846_TX_VOICE_NONE); // rda1846_write_register(RDA1846_REG_TX_VOICE, RDA1846_TX_VOICE_MIC); @@ -153,60 +194,87 @@ void rda1846_soft_reset(void) rda1846_write_register(RDA1846_REG_CTL, RDA1846_CTL_SOFT_RST); } -void rda1846_powerdown(void) + + +void rda1846_set_band(rf_band_t b) { - uint16_t data; - if(rda1846_read_register(RDA1846_REG_CTL, &data)) - return; + if(!rda1846_write_register(RDA1846_REG_RF_BAND, b == b_2m ? RDA1846_RF_BAND_2M : RDA1846_RF_BAND_70CM)) + rf_band_ = b; +} - data &= ~(RDA1846_CTL_PDN); - rda1846_write_register(RDA1846_REG_CTL, data); +rf_band_t rda1846_get_band(void) +{ + return rf_band_; } -void rda1846_wakeup(void) +void rda1846_set_bw(channel_bw_t bw) { uint16_t data; if(rda1846_read_register(RDA1846_REG_CTL, &data)) return; - data |= RDA1846_CTL_PDN; - rda1846_write_register(RDA1846_REG_CTL, data); + data &= RDA1846_CTL_CH_RESET; + data |= bw == bw_12k5 ? RDA1846_CTL_CH_12K5 : RDA1846_CTL_CH_25K; + if(!rda1846_write_register(RDA1846_REG_CTL, data)) + channel_bw_ = bw; } +channel_bw_t rda1846_get_bw(void) +{ + return channel_bw_; +} -void rda1846_set_band_2m(void) +uint8_t rda1846_set_freq_kHz(int32_t freq) { - rda1846_write_register(RDA1846_REG_RF_BAND, RDA1846_RF_BAND_2M); + if(freq < (rf_band_ == b_2m ? RDA1846_BAND_2M_LOW : RDA1846_BAND_70CM_LOW) || + freq > (rf_band_ == b_2m ? RDA1846_BAND_2M_HIGH : RDA1846_BAND_70CM_HIGH)) + return 1; + + freq = freq<<3; + uint8_t ret = rda1846_write_register(RDA1846_REG_FREQH, ((freq>>16) & 0x00003FFF)); + if(ret) + return 1; + + return rda1846_write_register(RDA1846_REG_FREQL, (freq & 0x0000FFFF)); } -void rda1846_set_band_70cm(void) +static int32_t corr_freq(int32_t f) { - rda1846_write_register(RDA1846_REG_RF_BAND, RDA1846_RF_BAND_70CM); + return (int32_t)(((float)f)/(rf_band_ == b_2m ? RDA1846_FREQ_CORR_2M : RDA1846_FREQ_CORR_70CM)); } -void rda1846_set_bw_12k5(void) +int32_t rda1846_get_freq_kHz(void) { + if(state_ == powerdown || state_ == idle) + return -1; + uint16_t data; - if(rda1846_read_register(RDA1846_REG_CTL, &data)) - return; + uint8_t ret = rda1846_read_register(RDA1846_REG_FREQH, &data); + if(ret) + return -1; - data &= RDA1846_CTL_CH_RESET; - data |= RDA1846_CTL_CH_12K5; - rda1846_write_register(RDA1846_REG_CTL, data); + int32_t freq = (((uint32_t)(data & 0x3FFF))<<16); + ret = rda1846_read_register(RDA1846_REG_FREQL, &data); + if(ret) + return -1; + + freq = corr_freq((freq+data)>>3); + return (freq / 8) + ((freq % 8) < 4 ? 0 : 1); } -void rda1846_set_bw_25k(void) + + +void rda1846_powerdown(void) { uint16_t data; if(rda1846_read_register(RDA1846_REG_CTL, &data)) return; - data &= RDA1846_CTL_CH_RESET; - data |= RDA1846_CTL_CH_25K; - rda1846_write_register(RDA1846_REG_CTL, data); + data &= ~(RDA1846_CTL_TX | RDA1846_CTL_RX | RDA1846_CTL_CHIP_CAL | RDA1846_CTL_PDN); + if(!rda1846_write_register(RDA1846_REG_CTL, data)) + state_ = powerdown; } - void rda1846_idle(void) { uint16_t data; @@ -214,7 +282,9 @@ void rda1846_idle(void) return; data &= ~(RDA1846_CTL_TX | RDA1846_CTL_RX | RDA1846_CTL_CHIP_CAL); - rda1846_write_register(RDA1846_REG_CTL, data); + data |= RDA1846_CTL_PDN; + if(!rda1846_write_register(RDA1846_REG_CTL, data)) + state_ = idle; } void rda1846_receive(void) @@ -223,9 +293,10 @@ void rda1846_receive(void) if(rda1846_read_register(RDA1846_REG_CTL, &data)) return; - data |= RDA1846_CTL_RX | RDA1846_CTL_CHIP_CAL; data &= ~(RDA1846_CTL_TX); - rda1846_write_register(RDA1846_REG_CTL, data); + data |= RDA1846_CTL_RX | RDA1846_CTL_CHIP_CAL | RDA1846_CTL_PDN; + if(!rda1846_write_register(RDA1846_REG_CTL, data)) + state_ = receive; } void rda1846_transmit(void) @@ -235,11 +306,18 @@ void rda1846_transmit(void) return; data &= ~(RDA1846_CTL_RX); - data |= RDA1846_CTL_TX | RDA1846_CTL_CHIP_CAL; - rda1846_write_register(RDA1846_REG_CTL, data); + data |= RDA1846_CTL_TX | RDA1846_CTL_CHIP_CAL | RDA1846_CTL_PDN; + if(!rda1846_write_register(RDA1846_REG_CTL, data)) + state_ = transmit; +} + +rda1846_state_t rda1846_get_state(void) +{ + return state_; } + void rda1846_gpio_default(void) { rda1846_write_register(RDA1846_REG_GPIO, RDA1846_GPIO_7_VOX | RDA1846_GPIO_6_SQ | @@ -272,6 +350,7 @@ void rda1846_gpio_off(void) } + int16_t rda1846_get_rssi(void) { uint16_t data; @@ -299,6 +378,8 @@ uint16_t rda1846_get_flags(void) return data & RDA1846_FLAGS_MASK; } + + uint16_t rda1846_get_dtmf(uint8_t* idx1, uint8_t* idx2, uint8_t* code, uint8_t* valid) { uint16_t data; @@ -318,41 +399,9 @@ void rda1846_clear_int(void) rda1846_write_register(0x00, 0x1846); } -int32_t rda1846_get_freq_kHz(void) -{ - int32_t freq; - uint16_t data; - uint8_t ret = rda1846_read_register(RDA1846_REG_FREQH, &data); - if(ret) - return -1; - - freq = (((uint32_t)(data & 0x3FFF))<<16); - ret = rda1846_read_register(RDA1846_REG_FREQL, &data); - if(ret) - return -1; - - freq += data; - return (freq>>3); -} - -#define RDA1846_BAND_LOW 134000 // kHz -#define RDA1846_BAND_HIGH 174000 // kHZ - -uint8_t rda1846_set_freq_kHz(int32_t freq) -{ - /* if(freq < RDA1846_BAND_LOW || freq > RDA1846_BAND_HIGH) */ - /* return 1; */ - - freq = freq<<3; - uint8_t ret = rda1846_write_register(RDA1846_REG_FREQH, ((freq>>16) & 0x00003FFF)); - if(ret) - return 1; - - return rda1846_write_register(RDA1846_REG_FREQL, (freq & 0x0000FFFF)); -} -char* rda1846_regaddr_to_string(uint8_t addr) +static char* rda1846_regaddr_to_string(uint8_t addr) { switch(addr) { case RDA1846_REG_CTL: return "CTL"; diff --git a/software/rda1846dongle/rda1846.h b/software/rda1846dongle/rda1846.h index 35246cb..e25a655 100644 --- a/software/rda1846dongle/rda1846.h +++ b/software/rda1846dongle/rda1846.h @@ -33,21 +33,29 @@ #ifndef MURSAT_rda1846_h_INCLUDED #define MURSAT_rda1846_h_INCLUDED -void rda1846_init(void); +typedef enum { b_2m, b_70cm } rf_band_t; +char* rda1846_rf_band_to_string(rf_band_t); +typedef enum { bw_12k5, bw_25k } channel_bw_t; +char* rda1846_channel_bw_to_string(channel_bw_t); +typedef enum { powerdown, idle, receive, transmit } rda1846_state_t; +char* rda1846_state_to_string(rda1846_state_t); +void rda1846_init(void); void rda1846_reg_init(void); void rda1846_soft_reset(void); -void rda1846_powerdown(void); -void rda1846_wakeup(void); - -void rda1846_set_band_2m(void); -void rda1846_set_band_70cm(void); -void rda1846_set_bw_12k5(void); -void rda1846_set_bw_25k(void); +void rda1846_powerdown(void); void rda1846_idle(void); void rda1846_receive(void); void rda1846_transmit(void); +rda1846_state_t rda1846_get_state(void); + +void rda1846_set_band(rf_band_t); +rf_band_t rda1846_get_band(void); +void rda1846_set_bw(channel_bw_t); +channel_bw_t rda1846_get_bw(void); +uint8_t rda1846_set_freq_kHz(int32_t freq); +int32_t rda1846_get_freq_kHz(void); void rda1846_gpio_default(void); void rda1846_gpio_55(void); @@ -57,12 +65,10 @@ void rda1846_gpio_off(void); int16_t rda1846_get_rssi(void); int16_t rda1846_get_vssi(void); uint16_t rda1846_get_flags(void); + uint16_t rda1846_get_dtmf(uint8_t*, uint8_t*, uint8_t*, uint8_t*); void rda1846_clear_int(void); -int32_t rda1846_get_freq_kHz(void); -uint8_t rda1846_set_freq_kHz(int32_t freq); - void rda1846_dump_register(void); #endif diff --git a/software/rda1846dongle/rda1846_defines.h b/software/rda1846dongle/rda1846_defines.h index 616ee43..403d326 100644 --- a/software/rda1846dongle/rda1846_defines.h +++ b/software/rda1846dongle/rda1846_defines.h @@ -75,10 +75,20 @@ #define RDA1846_REG_DTMF_C67 0x69 #define RDA1846_REG_DTMF_OUT 0x6C +//freq +#define RDA1846_FREQ_CORR_2M 73.1428567759 +#define RDA1846_FREQ_CORR_70CM RDA1846_FREQ_CORR_2M/3.0 + // init values #define RDA1846_RF_BAND_2M 0x00E4 // select 2m Band +#define RDA1846_BAND_2M_LOW 134000 // kHz +#define RDA1846_BAND_2M_HIGH 174000 // kHZ + #define RDA1846_RF_BAND_70CM 0x0024 // select 70cm Band +#define RDA1846_BAND_70CM_LOW 400000 // kHz +#define RDA1846_BAND_70CM_HIGH 520000 // kHZ + #define RDA1846_XTAL_FREQ 12288 // 12.288 MHz #define RDA1846_ADCLK_FREQ 6144 // 12.288/2 MHz #define RDA1846_CLK_MODE 0x0F11 // 12-14 MHz diff --git a/software/rda1846dongle/rda1846dongle.c b/software/rda1846dongle/rda1846dongle.c index 94f4b26..71b79e0 100644 --- a/software/rda1846dongle/rda1846dongle.c +++ b/software/rda1846dongle/rda1846dongle.c @@ -87,50 +87,39 @@ static void update_current_freq(void) { printf("setting frequency to %d.%03d MHz .. ", (uint16_t)(current_freq_kHz / 1000), (uint16_t)(current_freq_kHz % 1000)); - rda1846_powerdown(); + rda1846_state_t old_state = rda1846_get_state(); + if(old_state == receive || old_state == transmit) + rda1846_idle(); if(rda1846_set_freq_kHz(current_freq_kHz)) printf("error\r\n"); else printf("ok\r\n"); - rda1846_wakeup(); - - /* current_freq_kHz = print_actual_freq(); */ - /* if(current_freq_kHz < 0) */ - /* current_freq_kHz = default_freq; */ -} - -static void set_band_2m(void) -{ - printf("setting band to 2m\r\n"); - rda1846_set_band_2m(); - default_freq = DEFAULT_FREQ_2M; - set_default_freq(); + if(old_state == receive) + rda1846_receive(); + else if(old_state == transmit) + rda1846_transmit(); } -static void set_band_70cm(void) +static void set_band(rf_band_t b) { - printf("setting band to 70cm\r\n"); - rda1846_set_band_70cm(); - default_freq = DEFAULT_FREQ_70CM; + printf("setting band to %s\r\n", rda1846_rf_band_to_string(b)); + rda1846_set_band(b); + default_freq = b == b_2m ? DEFAULT_FREQ_2M : DEFAULT_FREQ_70CM; set_default_freq(); } -static void set_bw_12k5(void) +static void set_bw(channel_bw_t bw) { - printf("setting band to 12.5 kHz\r\n"); - rda1846_set_bw_12k5(); -} - -static void set_bw_25k(void) -{ - printf("setting band to 25 kHz\r\n"); - rda1846_set_bw_25k(); + printf("setting bandwidth to %s\r\n", rda1846_channel_bw_to_string(bw)); + rda1846_set_bw(bw); } static void print_status(void) { + printf("current state: %s\r\n", rda1846_state_to_string(rda1846_get_state())); + int16_t rssi = rda1846_get_rssi(); printf("rssi: "); if(rssi < 0) { @@ -178,10 +167,10 @@ static void handle_cmd(uint8_t cmd) case 'i': reinit_rda(); break; case 'F': set_default_freq(); break; - case '2': set_band_2m(); break; - case '7': set_band_70cm(); break; - case 'b': set_bw_12k5(); break; - case 'B': set_bw_25k(); break; + case '2': set_band(b_2m); break; + case '7': set_band(b_70cm); break; + case 'b': set_bw(bw_12k5); break; + case 'B': set_bw(bw_25k); break; case 'g': rda1846_gpio_off(); printf("GPIO off\r\n"); break; case 'G': rda1846_gpio_default(); printf("GPIO to defaults\r\n"); break; @@ -191,12 +180,10 @@ static void handle_cmd(uint8_t cmd) case 'd': print_dtmf(); break; case 'D': rda1846_dump_register(); break; - case 'p': rda1846_powerdown(); printf("powered down.\r\n"); break; - case 'P': rda1846_wakeup(); printf("woke up ...\r\n"); break; - - case 'I': rda1846_idle(); printf("idle.\r\n"); break; - case 'R': rda1846_receive(); printf("receiving ...\r\n"); break; - case 'T': rda1846_transmit(); printf("transmitting ...\r\n"); break; + case 'P': rda1846_powerdown(); print_status(); break; + case 'I': rda1846_idle(); print_status(); break; + case 'R': rda1846_receive(); print_status(); break; + case 'T': rda1846_transmit(); print_status(); break; case '+': current_freq_kHz+=25; update_current_freq(); break; case '-': current_freq_kHz-=25; update_current_freq(); break; -- cgit v1.2.3