summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--software/rda1846dongle/rda1846.c175
-rw-r--r--software/rda1846dongle/rda1846.h28
-rw-r--r--software/rda1846dongle/rda1846_defines.h10
-rw-r--r--software/rda1846dongle/rda1846dongle.c61
4 files changed, 163 insertions, 111 deletions
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;