Skip to content

I2C & Synthesizer

The RS-UV3’s RF section is built around the RDA1846S — a single-chip transceiver that handles frequency synthesis, modulation, demodulation, and audio processing. The PIC18 communicates with it over I2C.

The RDA1846S is a highly integrated FM transceiver IC:

FeatureSpecification
Frequency range134–174 MHz, 200–260 MHz, 400–520 MHz
Channel spacing12.5 kHz or 25 kHz
TX powerAdjustable, up to +8 dBm at chip
RX sensitivity-122 dBm typical
InterfaceI2C (7-bit address 0x2E)
Supply3.3V

The chip contains:

  • Fractional-N PLL frequency synthesizer
  • PA driver (external PA for full power)
  • LNA, mixer, IF filter
  • Audio codec with pre/de-emphasis
  • CTCSS/DCS encoder and decoder
  • RSSI measurement

The RDA1846S uses standard I2C with 7-bit addressing:

┌─────┬───────────────┬─────┬──────────────┬─────┬──────────────┬─────┐
│START│ 0x2E + W (0) │ ACK │ Register Addr│ ACK │ Data (16-bit)│STOP │
└─────┴───────────────┴─────┴──────────────┴─────┴──────────────┴─────┘

All registers are 16 bits. The firmware bit-bangs I2C rather than using the PIC’s MSSP hardware in I2C mode:

; i2c_write_byte — Send one byte over I2C
i2c_write_byte:
movlw 0x08 ; 8 bits
movwf bit_count
write_loop:
bcf LATC, SDA ; Data low (default)
btfsc i2c_data, 7 ; Check MSB
bsf LATC, SDA ; Set data high if bit=1
bsf LATC, SCL ; Clock high
rlcf i2c_data, F ; Shift left
bcf LATC, SCL ; Clock low
decfsz bit_count
bra write_loop
; Read ACK
bsf TRISC, SDA ; SDA as input
bsf LATC, SCL ; Clock high
btfsc PORTC, SDA ; Check ACK (low = ACK)
bsf i2c_status, 0 ; Set error if NACK
bcf LATC, SCL ; Clock low
bcf TRISC, SDA ; SDA as output
return

To tune to a new frequency, the firmware must:

  1. Calculate PLL divider values from the target frequency
  2. Write to the RDA1846S frequency registers
  3. Wait for PLL lock

The RDA1846S uses a fractional-N synthesizer. For a target frequency F:

F = F_ref × (N + K/65536) / 2

Where:

  • F_ref = 12.8 MHz (crystal reference)
  • N = integer divider (11 bits)
  • K = fractional divider (16 bits)

The firmware performs this calculation using 32-bit math:

// Pseudocode for frequency calculation
uint32_t freq_khz = 146520; // 146.52 MHz in kHz
uint32_t divider = (freq_khz * 1000 * 2) / 12800;
uint16_t N = divider >> 16;
uint16_t K = divider & 0xFFFF;

Setting a new RX frequency requires writing several registers:

RegisterAddressPurpose
0x29RX frequency highN divider
0x2ARX frequency lowK divider
0x30ControlPLL enable, band select
; set_rx_frequency — Program new RX frequency
set_rx_frequency:
; Write N divider to register 0x29
movlw 0x29
call i2c_start_write
movff freq_n_hi, i2c_data
call i2c_write_byte
movff freq_n_lo, i2c_data
call i2c_write_byte
call i2c_stop
; Write K divider to register 0x2A
movlw 0x2A
call i2c_start_write
movff freq_k_hi, i2c_data
call i2c_write_byte
movff freq_k_lo, i2c_data
call i2c_write_byte
call i2c_stop
; Trigger PLL recalibration
; ...
return
RegNameBitsDescription
0x29RX_FREQ_H15:0RX frequency high word
0x2ARX_FREQ_L15:0RX frequency low word
0x39TX_FREQ_H15:0TX frequency high word
0x3ATX_FREQ_L15:0TX frequency low word
RegNameDescription
0x44VOLRX audio volume (0–15)
0x45AUDIO_DACDAC configuration
0x59VOICEVoice scrambler settings
RegNameDescription
0x4ACTCSS_FREQCTCSS tone frequency
0x4BCDCSS_CODEDCS code
0x63TONE_SELTone mode select
RegNameDescription
0x5FRSSIReceived signal strength
0x5CSQ_OPENSquelch status

The RR and RS commands provide direct access to RDA1846S registers:

RR29 → Read register 0x29
RS2900FF → Write 0x00FF to register 0x29

At power-on, init_radio (0x000400) performs a lengthy initialization:

  1. Soft reset — Write 0x0001 to register 0x00
  2. Clock config — Set reference divider, enable PLL
  3. Band select — Configure for 2m/1.25m/70cm
  4. Filter setup — Set IF bandwidth (12.5 or 25 kHz)
  5. Audio setup — Configure volume, pre/de-emphasis
  6. CTCSS init — Load default tone (if enabled)
  7. Calibration — Trigger automatic calibration routines
  8. Squelch — Set initial squelch level

The full initialization is about 1,782 bytes of code — roughly 5% of the entire firmware.

The RDA1846S supports three bands:

BandFrequencyRegister 0x30 bits
VHF Low134–174 MHz0x00xx
VHF High200–260 MHz0x01xx
UHF400–520 MHz0x02xx

The firmware automatically selects the correct band based on the programmed frequency:

if (freq_mhz < 200)
band = VHF_LOW;
else if (freq_mhz < 300)
band = VHF_HIGH;
else
band = UHF;

I2C transactions have specific timing requirements:

ParameterValue
Clock frequency~100 kHz
Start setup4.7 µs minimum
Stop setup4.0 µs minimum
Data hold0 µs minimum
PLL lock time~5 ms after frequency change

The firmware inserts appropriate delays between operations. A complete frequency change (command parse → PLL lock → audio enabled) takes approximately 10 ms.