From 31d4458d58a620c7e936176769a67d077d97cca1 Mon Sep 17 00:00:00 2001 From: David Westgate Date: Mon, 12 May 2025 14:10:57 -0700 Subject: [PATCH] progress --- src/common.py | 6 ++-- src/freqs.py | 33 ++++++++++++++++++++++ src/init_regs_value.py | 5 ++-- src/main.py | 62 ++++++++++++++++++++++++++++++++++++------ src/receive.py | 3 +- src/transmit.py | 32 ++++++++++++++++++++-- src/util.py | 10 +++++++ 7 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 src/freqs.py diff --git a/src/common.py b/src/common.py index 12b9c19..bdb6069 100644 --- a/src/common.py +++ b/src/common.py @@ -16,13 +16,15 @@ VERSION = STATUS["VERSION"] MARCSTATE = STATUS["MARCSTATE"] -def write_reg(spi: SpiDev, addr: int, value: int): +def write_reg(spi: SpiDev, addr: int, value: int, dbg=False): """Write single byte to a register""" spi.xfer2([addr, value]) + if dbg: + print("Writing {0} to {1}".format(hex(value),hex(addr))) sleep(0.1) -def read_register(spi: SpiDev, addr: int): +def read_register(spi: SpiDev, addr: int, dbg=False): READ_SINGLE = get_addr("READ_SINGLE") # Send address | 0x80 (read), then 0x00 dummy to clock in response response = spi.xfer2([READ_SINGLE | addr, 0x00]) diff --git a/src/freqs.py b/src/freqs.py new file mode 100644 index 0000000..a712c81 --- /dev/null +++ b/src/freqs.py @@ -0,0 +1,33 @@ + +class Frequency: + XTAL_FREQ = 26_000_000 # 26 MHz default for CC2500 + + def __init__(self, freq_mhz: float, XTAL_FREQ = 26_000_000): + self.freq_mhz = freq_mhz + self.freq_word = self._calculate_freq_word(freq_mhz) + self.freq2 = (self.freq_word >> 16) & 0xFF + self.freq1 = (self.freq_word >> 8) & 0xFF + self.freq0 = self.freq_word & 0xFF + self.XTAL_FREQ = XTAL_FREQ + + @staticmethod + def _calculate_freq_word(freq_mhz: float) -> int: + """Convert frequency in MHz to 24-bit frequency word""" + freq_hz = freq_mhz * 1_000_000 + freq_word = int((freq_hz * (2 ** 16)) / Frequency.XTAL_FREQ) + return freq_word + + @staticmethod + def from_registers(freq2: int, freq1: int, freq0: int) -> "Frequency": + """Create Frequency instance from register values""" + freq_word = (freq2 << 16) | (freq1 << 8) | freq0 + freq_hz = (freq_word * Frequency.XTAL_FREQ) / (2 ** 16) + freq_mhz = freq_hz / 1_000_000 + return Frequency(freq_mhz) + + def as_registers(self) -> tuple: + """Return (FREQ2, FREQ1, FREQ0) as a tuple""" + return (self.freq2, self.freq1, self.freq0) + + def __repr__(self): + return f"" diff --git a/src/init_regs_value.py b/src/init_regs_value.py index a6b0336..07eb3f4 100644 --- a/src/init_regs_value.py +++ b/src/init_regs_value.py @@ -1,3 +1,4 @@ +from .regs_addr import ConfigRegs # Address Config = No address check # Base Frequency = 2447.256836 # CRC Autoflush = false @@ -19,9 +20,9 @@ # Sync Word Qualifier Mode = 30/32 sync word bits detected # TX Power = 0 # Whitening = false -init_regs_value = { +init_regs_value: ConfigRegs = { "IOCFG0" : 0x06, # 6 - GDO0OUTPUT PIN CONFIGURATION - "PKTCTRL0": 0b00000001,# 5 - PACKET AUTOMATION CONTROL + "PKTCTRL0": 0b00000001,# 1 - PACKET AUTOMATION CONTROL "PKTCTRL1": 0b00000100,# 4 - PACKET AUTOMATION CONTROL "FSCTRL1" : 0x12, # 18 - FREQUENCY SYNTHESIZER CONTROL "FREQ1" : 0x20, # 32 - FREQUENCY CONTROL WORD, MIDDLE BYTE diff --git a/src/main.py b/src/main.py index 47983ca..2ef3da4 100644 --- a/src/main.py +++ b/src/main.py @@ -1,7 +1,18 @@ import spidev -from .util import print_gdo_state, sleep, get_addr, dump_regs, debug, GDO0_PIN, GDO2_PIN + +from .freqs import Frequency +from .util import ( + print_gdo_state, + sleep, + get_addr, + dump_regs, + debug, + GDO0_PIN, + GDO2_PIN, + gdo_test, +) from .receive import rx_data_rf -from .transmit import transmit_packet +from .transmit import transmit_saved_packet from .common import ( reset, setup_spi, @@ -10,12 +21,22 @@ from .common import ( test_read_write_reg, init_cc_2500, write_reg, - SRES, - SNOP, - MARCSTATE, - VERSION, + write_burst ) +FREQ0 = get_addr("FREQ0") +FREQ1 = get_addr("FREQ1") +FREQ2 = get_addr("FREQ2") +PATABLE = get_addr("PATABLE") + +frequencies: list[Frequency] = [ + Frequency(2423.257000), + Frequency(2431.258000), + Frequency(2447.257000), + Frequency(2450.225000), + Frequency(2471.275000), +] + def menu(): print("\nMenu") @@ -23,9 +44,11 @@ def menu(): print("2: Write reg hex value by name") print("3: Dump registers") print("4: rx_data_rf") - print("5: transmit_packet") + print("5: transmit_saved_packet") print("6: Run Read+Write test") print("7: Print GDO state") + print("8: GDO Test") + print("9: Set Frequency") print("0: Quit") @@ -40,6 +63,7 @@ if __name__ == "__main__": reset(spi) test_read_write_reg(spi) init_cc_2500(spi) + write_burst(spi, PATABLE, [0xFF]) stop = False while not stop: menu() @@ -72,12 +96,34 @@ if __name__ == "__main__": while True: rx_data_rf(spi) elif cmd == 5: - transmit_packet(spi) + # transmit_test_packet(spi) + pkt_name = input("Enter Packet file name\n") + if pkt_name == "": + pkt_name = "test.bin" + for i in range(20): + transmit_saved_packet(spi, "saved_packets/" + pkt_name) + sleep(0.1) elif cmd == 6: res = test_read_write_reg(spi, True) print("Test result : " + str(res)) elif cmd == 7: print_gdo_state(GDO0_PIN, GDO2_PIN) + elif cmd == 8: + gdo_test(GDO0_PIN, GDO2_PIN) + elif cmd == 9: + print() + for i in range(len(frequencies)): + print(f"{i}: {frequencies[i]}") + sel = int(input("Choose Frequency\n")) % len(frequencies) + + f = frequencies[sel] + + write_reg(spi, FREQ0, f.freq0, True) + write_reg(spi, FREQ1, f.freq1, True) + write_reg(spi, FREQ2, f.freq2, True) + + elif cmd == 0: + stop = True else: print("Invalid command") finally: diff --git a/src/receive.py b/src/receive.py index 56300e5..8bd7a2b 100644 --- a/src/receive.py +++ b/src/receive.py @@ -85,7 +85,8 @@ def rx_data_rf(spi: SpiDev): rssi_raw = get_rssi_from_pkt(packet) strength = get_signal_strength_rssi_raw(rssi_raw) print("Length: {0} bytes\t Signal: {1} dBm".format(packet_length, strength)) - save_packet(packet) + # if packet_length == 249: + # save_packet(packet) # Make sure that the radio is in IDLE state before flushing the FIFO # (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point) strobe(spi, SIDLE) diff --git a/src/transmit.py b/src/transmit.py index 8748476..9a21c17 100644 --- a/src/transmit.py +++ b/src/transmit.py @@ -1,6 +1,7 @@ from .common import strobe, write_burst from .util import get_addr - +from spidev import SpiDev +from pathlib import Path SIDLE = get_addr("SIDLE") SFTX = get_addr("SFTX") @@ -9,7 +10,34 @@ WRITE_BURST = get_addr("WRITE_BURST") TXFIFO_BURST = 0x7F -def transmit_packet(spi): +def transmit_saved_packet(spi: SpiDev, file_path: str): + # Read saved packet from binary file + packet_path = Path(file_path) + if not packet_path.exists(): + print(f"File not found: {file_path}") + return + + with open(packet_path, "rb") as f: + packet = list(f.read()) + + if not packet: + print("Empty packet.") + return + + # Put radio into IDLE and flush TX FIFO + strobe(spi, SIDLE) + strobe(spi, SFTX) + + + write_burst(spi, TXFIFO_BURST, packet[:60]) + + # Start transmission + strobe(spi, STX) + + print(f"Transmitted packet from file: {file_path}") + + +def transmit_test_packet(spi: SpiDev): strobe(spi, SIDLE) strobe(spi, SFTX) data = [0] * 5 diff --git a/src/util.py b/src/util.py index cb95bc2..03ef8a2 100644 --- a/src/util.py +++ b/src/util.py @@ -15,6 +15,16 @@ def rr(spi: SpiDev, addr): sleep(0.1) return response[1] +def gdo_test(GDO0_PIN=17, GDO2_PIN=27): + GPIO.setup(GDO0_PIN, GPIO.OUT) + GPIO.setup(GDO2_PIN, GPIO.OUT) + + GPIO.output(GDO0_PIN, GPIO.HIGH) + GPIO.output(GDO2_PIN,GPIO.HIGH) + + sleep(5) + GPIO.setup(GDO0_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) + GPIO.setup(GDO2_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) def print_gdo_state(GDO0_PIN=17, GDO2_PIN=27): gdo0 = GPIO.input(GDO0_PIN) # Reads 1 or 0