summaryrefslogtreecommitdiff
path: root/software/rda1846dongle/rda1846.c
diff options
context:
space:
mode:
Diffstat (limited to 'software/rda1846dongle/rda1846.c')
-rw-r--r--software/rda1846dongle/rda1846.c175
1 files changed, 112 insertions, 63 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";