This commit is contained in:
David Westgate 2025-05-12 14:10:57 -07:00
parent 6c717d5bd7
commit 31d4458d58
7 changed files with 136 additions and 15 deletions

View File

@ -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])

33
src/freqs.py Normal file
View File

@ -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"<Frequency {self.freq_mhz:.4f} MHz → FREQ2:{self.freq2:#04x}, FREQ1:{self.freq1:#04x}, FREQ0:{self.freq0:#04x}>"

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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