# WADARC IC7300 MKII CI-V RF relay control
# Jonathan Hare G1EXG, Jan - August 2026
# after Phil G4UDU tests 4th, 10th March 2026
# after Derek G4HSY (tests and watchdog timer suggestion etc.)
# after Alan G4GNX (edited my typos and made suggestions)  
# add delay LED ident at start, change address to MK II, add UART timeout
# add watchdog timer, fix relay selection bug

# sets RF relays OFF for HF
# sets RF relay 1 ON for 6m band
# sets RF relay 1 and 2 ON for 4m band
# sets RF power to 100 % for 7MHz and up
# sets RF power to 5% for < 7MHz

from machine import UART, Pin
import time
import utime

led_onboard = machine.Pin(25, machine.Pin.OUT)
front_panel = machine.Pin(16, machine.Pin.OUT)
relay_1 = machine.Pin(14, machine.Pin.OUT)   # RF relay 1
relay_2 = machine.Pin(15, machine.Pin.OUT)   # RF relay 2

BAUDRATE = 19200
CTRL_ADDR = 0xE0

IC7300_ADDR = 0xB6  # MK II (B6) address MK I address (94)
#IC9700_ADDR = 0xA2

BUFFER_SIZE = 25    # dont need a large buffer for IC-V data
                    # on pi Pico
freq = 0
        
uart = UART(
    0,
    baudrate=BAUDRATE,
    tx=Pin(0),
    rx=Pin(1),
    bits=8,
    parity=None,
    stop=1,
    timeout=1000 # ms timeout for data to stop blocking 
)

def set_pwr_5(radio_addr):
    cmd = bytes([
        0xFE, 0xFE,
        radio_addr,
        CTRL_ADDR,
        0x14,       # Tx power
        0x0A,       # Tx power
        0x00, 0x15,     # sets power = 5%
        0xFD
    ])
    uart.write(cmd)
    time.sleep_ms(20)
    
def set_pwr_100(radio_addr):
    cmd = bytes([
        0xFE, 0xFE,
        radio_addr,
        CTRL_ADDR,
        0x14,       # Tx power
        0x0A,       # Tx power
        0x02, 0x55,     # sets power = 100%
        0xFD
    ])
    uart.write(cmd)
    time.sleep_ms(20)
    
def freq_request(radio_addr):
    cmd = bytes([
        0xFE, 0xFE,
        radio_addr,
        CTRL_ADDR,
        0x03,       # request freq
        0xFD
    ])
    uart.write(cmd)
    time.sleep_ms(20)

# 5 sec delay before start of main program to allow the transceiver to wake up
# if power has been down etc.
if IC7300_ADDR == 0x94: # one long flash of green led and front panel 'ping'
        led_onboard.value(1)
        front_panel.value(1)
        utime.sleep(4)
        led_onboard.value(0)
        front_panel.value(0)
        utime.sleep(1)

if IC7300_ADDR == 0xB6: # two flashes of green led and front panel 'ping'
        led_onboard.value(1)
        front_panel.value(1)
        utime.sleep(2)
        led_onboard.value(0)
        front_panel.value(0)
        utime.sleep(1)
        led_onboard.value(1)
        front_panel.value(1)
        utime.sleep(2)
        front_panel.value(0)
        led_onboard.value(0)
        utime.sleep(1)
        
# set up watchdog after delay so Thonny can break into code
from machine import WDT
wdt = WDT(timeout=8000)

# MAIN PROGRAM STARTS HERE

relay_1(0) # set relay 1 OFF
relay_2(0) # set relay 2 OFF

while True:
    uart.read()    # empty UART buffer of other CI-V frames
    freq_request(IC7300_ADDR)   # request frequency
    uart.read(6)    # remove freq request frames
                    # and just leave reply from radio   

    if uart.any():                 # ignore empty UART (i.e. = 0)
        data_all = uart.read()     # Read UART data
        bcd = data_all[8]

        freq_mhz = bcd & 15       # calculate integer MHz
        freq_10mhz = int ((bcd & 120)/16)
        freq = freq_mhz + 10*freq_10mhz

# thonny print 'tools' for debuging
#        print("Received (raw):", freq)        
#        print("Received (raw):", data_all[1])
#        print("Received (raw):", data_all)

    if freq >= 1 and freq < 7:
        set_pwr_5(IC7300_ADDR) # set low power
        relay_1(0)
        relay_2(0)
                
    if freq >= 7 and freq < 50:
        set_pwr_100(IC7300_ADDR) # set high power
        relay_1(0) # Both relays off
        relay_2(0) # Routes to HF dipole

    if freq >= 50 and freq < 52:
        set_pwr_100(IC7300_ADDR) # set high power
        relay_1(1) # Routes to 6m antenna
        relay_2(0)

    if freq >= 52 and freq < 70:
        set_pwr_5(IC7300_ADDR) # set low power
        relay_1(0)
        relay_2(0) # Routes to HF dipole

    if freq >= 70 and freq <= 72:
        set_pwr_100(IC7300_ADDR) # set high power
        relay_1(1) # Routes to relay_2
        relay_2(1) # Routes to 4m antenna

    if freq >= 72:
        set_pwr_5(IC7300_ADDR) # set low power
        relay_1(0)
        relay_2(0) # Routes to HF dipole

    led_onboard(1)   # flash on board (green) led
    front_panel(1)   # front panel 'ping' led
    time.sleep_ms(100)        
    led_onboard(0)
    front_panel(0)  
        

    time.sleep_ms(3000) # ping radio once every 3 seconds

    wdt.feed() # feed the watchdog !
