Compare commits
5 Commits
0119c6846c
...
a7327f294e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a7327f294e | ||
![]() |
f034d91fa9 | ||
![]() |
ed9ce3b9ec | ||
![]() |
0d7b9f988b | ||
![]() |
b6725d162d |
BIN
__pycache__/init_regs_value.cpython-311.pyc
Normal file
BIN
__pycache__/init_regs_value.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/regs_addr.cpython-311.pyc
Normal file
BIN
__pycache__/regs_addr.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/util.cpython-311.pyc
Normal file
BIN
__pycache__/util.cpython-311.pyc
Normal file
Binary file not shown.
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"IOCFG0" : { "hex":"0x06", "dec":6},
|
|
||||||
"PKTCTRL0": { "hex":"0x05", "dec":5},
|
|
||||||
"FSCTRL1" : { "hex":"0x0A", "dec":10},
|
|
||||||
"FREQ1" : { "hex":"0x20", "dec":32},
|
|
||||||
"FREQ0" : { "hex":"0x11", "dec":17},
|
|
||||||
"MDMCFG4" : { "hex":"0x2D", "dec":45},
|
|
||||||
"MDMCFG3" : { "hex":"0x3B", "dec":59},
|
|
||||||
"MDMCFG2" : { "hex":"0x73", "dec":115},
|
|
||||||
"DEVIATN" : { "hex":"0x00", "dec":0},
|
|
||||||
"MCSM0" : { "hex":"0x18", "dec":24},
|
|
||||||
"FOCCFG" : { "hex":"0x1D", "dec":29},
|
|
||||||
"BSCFG" : { "hex":"0x1C", "dec":28},
|
|
||||||
"AGCCTRL2": { "hex":"0xC7", "dec":199},
|
|
||||||
"AGCCTRL1": { "hex":"0x00", "dec":0},
|
|
||||||
"AGCCTRL0": { "hex":"0xB0", "dec":176},
|
|
||||||
"FREND1" : { "hex":"0xB6", "dec":182},
|
|
||||||
"FSCAL3" : { "hex":"0xEA", "dec":234},
|
|
||||||
"FSCAL1" : { "hex":"0x00", "dec":0},
|
|
||||||
"FSCAL0" : { "hex":"0x11", "dec":17}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
{
|
|
||||||
"CONFIG_REGS": {
|
|
||||||
"IOCFG2": {"hex": "0x00", "dec": 0},
|
|
||||||
"IOCFG1": {"hex": "0x01", "dec": 1},
|
|
||||||
"IOCFG0": {"hex": "0x02", "dec": 2},
|
|
||||||
"FIFOTHR": {"hex": "0x03", "dec": 3},
|
|
||||||
"SYNC1": {"hex": "0x04", "dec": 4},
|
|
||||||
"SYNC0": {"hex": "0x05", "dec": 5},
|
|
||||||
"PKTLEN": {"hex": "0x06", "dec": 6},
|
|
||||||
"PKTCTRL1": {"hex": "0x07", "dec": 7},
|
|
||||||
"PKTCTRL0": {"hex": "0x08", "dec": 8},
|
|
||||||
"ADDR": {"hex": "0x09", "dec": 9},
|
|
||||||
"CHANNR": {"hex": "0x0A", "dec": 10},
|
|
||||||
"FSCTRL1": {"hex": "0x0B", "dec": 11},
|
|
||||||
"FSCTRL0": {"hex": "0x0C", "dec": 12},
|
|
||||||
"FREQ2": {"hex": "0x0D", "dec": 13},
|
|
||||||
"FREQ1": {"hex": "0x0E", "dec": 14},
|
|
||||||
"FREQ0": {"hex": "0x0F", "dec": 15},
|
|
||||||
"MDMCFG4": {"hex": "0x10", "dec": 16},
|
|
||||||
"MDMCFG3": {"hex": "0x11", "dec": 17},
|
|
||||||
"MDMCFG2": {"hex": "0x12", "dec": 18},
|
|
||||||
"MDMCFG1": {"hex": "0x13", "dec": 19},
|
|
||||||
"MDMCFG0": {"hex": "0x14", "dec": 20},
|
|
||||||
"DEVIATN": {"hex": "0x15", "dec": 21},
|
|
||||||
"MCSM2": {"hex": "0x16", "dec": 22},
|
|
||||||
"MCSM1": {"hex": "0x17", "dec": 23},
|
|
||||||
"MCSM0": {"hex": "0x18", "dec": 24},
|
|
||||||
"FOCCFG": {"hex": "0x19", "dec": 25},
|
|
||||||
"BSCFG": {"hex": "0x1A", "dec": 26},
|
|
||||||
"AGCCTRL2": {"hex": "0x1B", "dec": 27},
|
|
||||||
"AGCCTRL1": {"hex": "0x1C", "dec": 28},
|
|
||||||
"AGCCTRL0": {"hex": "0x1D", "dec": 29},
|
|
||||||
"WOREVT1": {"hex": "0x1E", "dec": 30},
|
|
||||||
"WOREVT0": {"hex": "0x1F", "dec": 31},
|
|
||||||
"WORCTRL": {"hex": "0x20", "dec": 32},
|
|
||||||
"FREND1": {"hex": "0x21", "dec": 33},
|
|
||||||
"FREND0": {"hex": "0x22", "dec": 34},
|
|
||||||
"FSCAL3": {"hex": "0x23", "dec": 35},
|
|
||||||
"FSCAL2": {"hex": "0x24", "dec": 36},
|
|
||||||
"FSCAL1": {"hex": "0x25", "dec": 37},
|
|
||||||
"FSCAL0": {"hex": "0x26", "dec": 38},
|
|
||||||
"RCCTRL1": {"hex": "0x27", "dec": 39},
|
|
||||||
"RCCTRL0": {"hex": "0x28", "dec": 40},
|
|
||||||
"FSTEST": {"hex": "0x29", "dec": 41},
|
|
||||||
"PTEST": {"hex": "0x2A", "dec": 42},
|
|
||||||
"AGCTEST": {"hex": "0x2B", "dec": 43},
|
|
||||||
"TEST2": {"hex": "0x2C", "dec": 44},
|
|
||||||
"TEST1": {"hex": "0x2D", "dec": 45},
|
|
||||||
"TEST0": {"hex": "0x2E", "dec": 46}
|
|
||||||
},
|
|
||||||
"STROBES": {
|
|
||||||
"SRES": {"hex": "0x30", "dec": 48},
|
|
||||||
"SFSTXON": {"hex": "0x31", "dec": 49},
|
|
||||||
"SXOFF": {"hex": "0x32", "dec": 50},
|
|
||||||
"SCAL": {"hex": "0x33", "dec": 51},
|
|
||||||
"SRX": {"hex": "0x34", "dec": 52},
|
|
||||||
"STX": {"hex": "0x35", "dec": 53},
|
|
||||||
"SIDLE": {"hex": "0x36", "dec": 54},
|
|
||||||
"SAFC": {"hex": "0x37", "dec": 55},
|
|
||||||
"SWOR": {"hex": "0x38", "dec": 56},
|
|
||||||
"SPWD": {"hex": "0x39", "dec": 57},
|
|
||||||
"SFRX": {"hex": "0x3A", "dec": 58},
|
|
||||||
"SFTX": {"hex": "0x3B", "dec": 59},
|
|
||||||
"SWORRST": {"hex": "0x3C", "dec": 60},
|
|
||||||
"SNOP": {"hex": "0x3D", "dec": 61}
|
|
||||||
},
|
|
||||||
"STATUS": {
|
|
||||||
"PARTNUM": {"hex": "0x30", "dec": 48},
|
|
||||||
"VERSION": {"hex": "0x31", "dec": 49},
|
|
||||||
"FREQEST": {"hex": "0x32", "dec": 50},
|
|
||||||
"LQI": {"hex": "0x33", "dec": 51},
|
|
||||||
"RSSI": {"hex": "0x34", "dec": 52},
|
|
||||||
"MARCSTATE": {"hex": "0x35", "dec": 53},
|
|
||||||
"WORTIME1": {"hex": "0x36", "dec": 54},
|
|
||||||
"WORTIME0": {"hex": "0x37", "dec": 55},
|
|
||||||
"PKTSTATUS": {"hex": "0x38", "dec": 56},
|
|
||||||
"VCO_VC_DAC": {"hex": "0x39", "dec": 57},
|
|
||||||
"TXBYTES": {"hex": "0x3A", "dec": 58},
|
|
||||||
"RXBYTES": {"hex": "0x3B", "dec": 59},
|
|
||||||
"NUM_RXBYTES": {"hex": "0x7F", "dec": 127}
|
|
||||||
},
|
|
||||||
"MEMORY": {
|
|
||||||
"PATABLE": {"hex": "0x3E", "dec": 62},
|
|
||||||
"TXFIFO": {"hex": "0x3F", "dec": 63},
|
|
||||||
"RXFIFO": {"hex": "0x3F", "dec": 63}
|
|
||||||
},
|
|
||||||
"MASKS": {
|
|
||||||
"LQI_RX": {"hex": "0x01", "dec": 1},
|
|
||||||
"CRC_OK": {"hex": "0x80", "dec": 128}
|
|
||||||
},
|
|
||||||
"ACCESS": {
|
|
||||||
"WRITE_BURST": {"hex": "0x40", "dec": 64},
|
|
||||||
"READ_SINGLE": {"hex": "0x80", "dec": 128},
|
|
||||||
"READ_BURST": {"hex": "0xC0", "dec": 192}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
42
init_regs_value.py
Normal file
42
init_regs_value.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Address Config = No address check
|
||||||
|
# Base Frequency = 2447.256836
|
||||||
|
# CRC Autoflush = false
|
||||||
|
# CRC Enable = true
|
||||||
|
# Carrier Frequency = 2447.256836
|
||||||
|
# Channel Number = 0
|
||||||
|
# Channel Spacing = 199.951172
|
||||||
|
# Data Format = Normal mode
|
||||||
|
# Data Rate = 249.939
|
||||||
|
# Device Address = 0
|
||||||
|
# Manchester Enable = false
|
||||||
|
# Modulated = true
|
||||||
|
# Modulation Format = MSK
|
||||||
|
# Packet Length = 255
|
||||||
|
# Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
|
||||||
|
# Phase Transition Time = 0
|
||||||
|
# Preamble Count = 4
|
||||||
|
# RX Filter BW = 541.666667
|
||||||
|
# Sync Word Qualifier Mode = 30/32 sync word bits detected
|
||||||
|
# TX Power = 0
|
||||||
|
# Whitening = false
|
||||||
|
init_regs_value = {
|
||||||
|
"IOCFG0" : 0x06, # 6 - GDO0OUTPUT PIN CONFIGURATION
|
||||||
|
"PKTCTRL0": 0x05, # 5 - PACKET AUTOMATION CONTROL
|
||||||
|
"FSCTRL1" : 0x12, # 18 - FREQUENCY SYNTHESIZER CONTROL
|
||||||
|
"FREQ1" : 0x20, # 32 - FREQUENCY CONTROL WORD, MIDDLE BYTE
|
||||||
|
"FREQ0" : 0x11, # 17 - FREQUENCY CONTROL WORD, LOW BYTE
|
||||||
|
"MDMCFG4" : 0x2D, # 45 - MODEM CONFIGURATION
|
||||||
|
"MDMCFG3" : 0x3B, # 59 - MODEM CONFIGURATION
|
||||||
|
"MDMCFG2" : 0xF3, # 243 - MODEM CONFIGURATION
|
||||||
|
"DEVIATN" : 0x00, # 0 - MODEM DEVIATION SETTING
|
||||||
|
"MCSM0" : 0x18, # 24 - MAIN RADIO CONTROL STATE MACHINE CONFIGURATION
|
||||||
|
"FOCCFG" : 0x1D, # 29 - FREQUENCY OFFSET COMPENSATION CONFIGURATION
|
||||||
|
"BSCFG" : 0x1C, # 28 - BIT SYNCHRONIZATION CONFIGURATION
|
||||||
|
"AGCCTRL2": 0xC7, # 199 - AGC CONTROL
|
||||||
|
"AGCCTRL1": 0x00, # 0 - AGC CONTROL
|
||||||
|
"AGCCTRL0": 0xB0, # 176 - AGC CONTROL
|
||||||
|
"FREND1" : 0xB6, # 182 - FRONT END RX CONFIGURATION
|
||||||
|
"FSCAL3" : 0xEA, # 234 - FREQUENCY SYNTHESIZER CALIBRATION
|
||||||
|
"FSCAL1" : 0x00, # 0 - FREQUENCY SYNTHESIZER CALIBRATION
|
||||||
|
"FSCAL0" : 0x11, # 17 - FREQUENCY SYNTHESIZER CALIBRATION
|
||||||
|
}
|
73
main.py
Normal file
73
main.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import spidev
|
||||||
|
from util import *
|
||||||
|
from receive import receive_packet
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
def menu():
|
||||||
|
print("\nMenu")
|
||||||
|
print("1: Read Reg by name")
|
||||||
|
print("2: Write reg hex value by name")
|
||||||
|
print("3: Dump registers")
|
||||||
|
print("4: Poll for packets")
|
||||||
|
print("5: Run Read+Write test")
|
||||||
|
print("0: Quit")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
spi = spidev.SpiDev()
|
||||||
|
spi.open(0, 0) # Bus 0, CE0 (Pin 24)
|
||||||
|
spi.max_speed_hz = 8000000 # Safe start speed
|
||||||
|
spi.mode = 0b00 # SPI mode 0
|
||||||
|
stop = False
|
||||||
|
|
||||||
|
print("Sending SRES (reset)...")
|
||||||
|
spi.xfer2([SRES])
|
||||||
|
sleep(0.5)
|
||||||
|
|
||||||
|
print("Sending SNOP (no-op)...")
|
||||||
|
status = spi.xfer2([SNOP])[0]
|
||||||
|
print(f"Status byte: 0x{status:02X}")
|
||||||
|
|
||||||
|
print("Reading VERSION register...")
|
||||||
|
version = read_register(spi, VERSION)
|
||||||
|
print(f"CC2500 VERSION register: 0x{version:02X}")
|
||||||
|
|
||||||
|
test_read_write_reg(spi)
|
||||||
|
|
||||||
|
init_regs(spi)
|
||||||
|
sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reg_name = ""
|
||||||
|
reg_hex_val = ""
|
||||||
|
try:
|
||||||
|
while not stop:
|
||||||
|
menu()
|
||||||
|
cmd = int(input("$: "))
|
||||||
|
if cmd == 0:
|
||||||
|
stop=True
|
||||||
|
elif cmd == 1:
|
||||||
|
reg_name = input("Register name: ")
|
||||||
|
addr = get_addr(reg_name)
|
||||||
|
value = read_register(spi,addr)
|
||||||
|
print("Address: " + hex(addr)+ ", Value: " + hex(value) +" == " + str(value))
|
||||||
|
elif cmd == 2:
|
||||||
|
reg_name = input("Register name: ")
|
||||||
|
addr = get_addr(reg_name)
|
||||||
|
value = int(input("New Register value (hex): "),16)
|
||||||
|
write_reg(spi, addr, value)
|
||||||
|
sleep(0.1)
|
||||||
|
value_check = read_register(spi,addr)
|
||||||
|
print("Updated Value: " + hex(value) +" == " + str(value))
|
||||||
|
elif cmd == 3:
|
||||||
|
dump_regs(spi)
|
||||||
|
elif cmd == 4:
|
||||||
|
receive_packet(spi)
|
||||||
|
elif cmd == 5:
|
||||||
|
res = test_read_write_reg(spi, True)
|
||||||
|
print("Test result : "+str(res))
|
||||||
|
else:
|
||||||
|
print("Invalid command")
|
||||||
|
finally:
|
||||||
|
print("Closing SPI...")
|
||||||
|
spi.close()
|
167
read.py
167
read.py
@ -1,167 +0,0 @@
|
|||||||
import spidev
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
|
|
||||||
# Initialize SPI
|
|
||||||
global spi
|
|
||||||
global init_data
|
|
||||||
# global regs_data
|
|
||||||
global CONFIG_REGS
|
|
||||||
global STROBES
|
|
||||||
global STATUS
|
|
||||||
global MEMORY
|
|
||||||
global MASKS
|
|
||||||
global ACCESS
|
|
||||||
|
|
||||||
def asb (a):
|
|
||||||
return int(a,16)
|
|
||||||
|
|
||||||
def strobe(command):
|
|
||||||
"""Send a command strobe to CC2500"""
|
|
||||||
spi.xfer2([command])
|
|
||||||
|
|
||||||
def write_reg(addr, value):
|
|
||||||
"""Write single byte to a register"""
|
|
||||||
spi.xfer2([addr, value])
|
|
||||||
|
|
||||||
def burst_write(addr, data):
|
|
||||||
"""Write multiple bytes to FIFO or registers"""
|
|
||||||
BURST = 0x40
|
|
||||||
spi.xfer2([addr | BURST] + data)
|
|
||||||
|
|
||||||
def burst_read(addr, length):
|
|
||||||
"""Read multiple bytes"""
|
|
||||||
READ_SINGLE = ACCESS["READ_SINGLE"]["dec"]
|
|
||||||
READ_BURST = ACCESS["READ_BURST"]["dec"]
|
|
||||||
return spi.xfer2([addr | READ_SINGLE | READ_BURST] + [0x00] * length)
|
|
||||||
|
|
||||||
def read_fifo():
|
|
||||||
# Burst read RX FIFO
|
|
||||||
READ_BURST = ACCESS["READ_BURST"]["dec"]
|
|
||||||
RXFIFO = MEMORY["RXFIFI"]["dec"]
|
|
||||||
fifo = spi.xfer2([RXFIFO | READ_BURST] + [0x00]*64) # Max 64 bytes
|
|
||||||
return fifo[1:]
|
|
||||||
|
|
||||||
|
|
||||||
def read_register(addr):
|
|
||||||
READ_SINGLE = ACCESS["READ_SINGLE"]["dec"]
|
|
||||||
# Send address | 0x80 (read), then 0x00 dummy to clock in response
|
|
||||||
response = spi.xfer2([READ_SINGLE | addr, 0x00])
|
|
||||||
return response[1]
|
|
||||||
|
|
||||||
def send_packet(data):
|
|
||||||
# Flush TX FIFO
|
|
||||||
strobe(0x3B) # SFTX
|
|
||||||
|
|
||||||
# Load data to TX FIFO (fixed length)
|
|
||||||
burst_write(0x3F, data) # 0x3F = TX FIFO
|
|
||||||
|
|
||||||
# Strobe STX to transmit
|
|
||||||
strobe(0x35) # STX
|
|
||||||
|
|
||||||
print(f"Sent: {data}")
|
|
||||||
|
|
||||||
|
|
||||||
def receive_packet():
|
|
||||||
# Flush RX FIFO
|
|
||||||
SFRX = STROBES["SFRX"]["dec"]
|
|
||||||
strobe(SFRX) # SFRX
|
|
||||||
|
|
||||||
SRX = STROBES["SRX"]["dec"]
|
|
||||||
# Go into RX mode
|
|
||||||
strobe(SRX) # SRX
|
|
||||||
|
|
||||||
# Wait for data (use GDO0 in real app)
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
# Check RXBYTES
|
|
||||||
RXBYTES = STATUS["RXBYTES"]["dec"]
|
|
||||||
rx_bytes = read_register(RXBYTES) & 0x7F
|
|
||||||
if rx_bytes == 0:
|
|
||||||
print("No data received.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Read data
|
|
||||||
RXFIFO = MEMORY["RXFIFO"]["dec"]
|
|
||||||
data = read_fifo() # 0x3F = RX FIFO
|
|
||||||
print(f"Received: {data}")
|
|
||||||
return data
|
|
||||||
|
|
||||||
def test_read_write_reg():
|
|
||||||
FIFOTHR = CONFIG_REGS["FIFOTHR"]["dec"]
|
|
||||||
print("reg ", hex(FIFOTHR))
|
|
||||||
initial_val = read_register(FIFOTHR)
|
|
||||||
test_value = initial_val + 1
|
|
||||||
write_reg(FIFOTHR, test_value)
|
|
||||||
check = read_register(FIFOTHR)
|
|
||||||
write_reg(FIFOTHR, initial_val)
|
|
||||||
print("initial value ", initial_val)
|
|
||||||
print("test value ", test_value)
|
|
||||||
print("check ",check)
|
|
||||||
return check == test_value
|
|
||||||
|
|
||||||
def disable_crc():
|
|
||||||
spi.xfer2([CONFIG_REGS["PKTCTRL0"]["dec"], 0x01])
|
|
||||||
|
|
||||||
def dump_reg():
|
|
||||||
for reg_name_group, regs in regs_data.items():
|
|
||||||
for reg_name, reg_loc in regs.items():
|
|
||||||
addr = reg_loc['dec']
|
|
||||||
reg_value = read_register(addr)
|
|
||||||
print(reg_name + ":"+str(reg_value))
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
spi = spidev.SpiDev()
|
|
||||||
spi.open(0, 0) # Bus 0, CE0 (Pin 24)
|
|
||||||
spi.max_speed_hz = 2000000 # Safe start speed
|
|
||||||
spi.mode = 0b00 # SPI mode 0
|
|
||||||
|
|
||||||
|
|
||||||
with open("cc2500_init.json", "r") as f:
|
|
||||||
init_data = json.load(f)
|
|
||||||
with open("cc2500_regs.json", "r") as f:
|
|
||||||
regs_data = json.load(f)
|
|
||||||
CONFIG_REGS = regs_data["CONFIG_REGS"]
|
|
||||||
STROBES = regs_data["STROBES"]
|
|
||||||
STATUS = regs_data["STATUS"]
|
|
||||||
MEMORY = regs_data["MEMORY"]
|
|
||||||
MASKS = regs_data["MASKS"]
|
|
||||||
ACCESS = regs_data["ACCESS"]
|
|
||||||
|
|
||||||
SRES = STROBES["SRES"]["dec"]
|
|
||||||
SNOP = STROBES["SNOP"]["dec"]
|
|
||||||
VERSION = STATUS["VERSION"]["dec"]
|
|
||||||
|
|
||||||
print("Sending SRES (reset)...")
|
|
||||||
spi.xfer2([SRES])
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
print("Sending SNOP (no-op)...")
|
|
||||||
status = spi.xfer2([SNOP])[0]
|
|
||||||
print(f"Status byte: 0x{status:02X}")
|
|
||||||
|
|
||||||
print("Reading VERSION register...")
|
|
||||||
version = read_register(VERSION)
|
|
||||||
print(f"CC2500 VERSION register: 0x{version:02X}")
|
|
||||||
|
|
||||||
# dump_reg()
|
|
||||||
|
|
||||||
for reg_name, values in init_data.items():
|
|
||||||
addr_dec = regs_data["CONFIG_REGS"][reg_name]["dec"]
|
|
||||||
addr_hex = regs_data["CONFIG_REGS"][reg_name]["hex"]
|
|
||||||
value_hex = values["hex"]
|
|
||||||
value_dec = values["dec"]
|
|
||||||
# print(addr)
|
|
||||||
# print(values["hex"])
|
|
||||||
# print("writing "+str(addr_hex) + " to "+str(addr_dec))
|
|
||||||
write_reg(addr_dec, value_dec)
|
|
||||||
disable_crc()
|
|
||||||
time.sleep(2)
|
|
||||||
# dump_reg()
|
|
||||||
print("Read + Write test ", test_read_write_reg())
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
receive_packet()
|
|
||||||
time.sleep(1)
|
|
||||||
finally:
|
|
||||||
spi.close()
|
|
45
receive.py
Normal file
45
receive.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from util import *
|
||||||
|
import time
|
||||||
|
|
||||||
|
def burst_read(spi, addr, length):
|
||||||
|
"""Read multiple bytes"""
|
||||||
|
READ_SINGLE = get_addr("READ_SINGLE")
|
||||||
|
READ_BURST = get_addr("READ_BURST")
|
||||||
|
return spi.xfer2([addr | READ_SINGLE | READ_BURST] + [0x00] * length)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def read_fifo(spi):
|
||||||
|
# Burst read RX FIFO
|
||||||
|
READ_BURST = get_addr("READ_BURST")
|
||||||
|
RXFIFO = get_addr("RXFIFO")
|
||||||
|
fifo = spi.xfer2([RXFIFO | READ_BURST] + [0x00]*64) # Max 64 bytes
|
||||||
|
return fifo[1:]
|
||||||
|
|
||||||
|
|
||||||
|
def receive_packet(spi):
|
||||||
|
SFRX = get_addr("SFRX")
|
||||||
|
RXBYTES = get_addr("RXBYTES")
|
||||||
|
SRX = get_addr("SRX")
|
||||||
|
|
||||||
|
# Flush RX FIFO
|
||||||
|
strobe(spi, SFRX)
|
||||||
|
time.sleep(0.5) # 1 ms delay to allow flush
|
||||||
|
# Go into RX mode
|
||||||
|
strobe(spi, SRX)
|
||||||
|
|
||||||
|
# Wait for data (use GDO0 in real app)
|
||||||
|
sleep(0.5)
|
||||||
|
|
||||||
|
# Check RXBYTES
|
||||||
|
|
||||||
|
timeout = time.time() + 2 # 2-second timeout
|
||||||
|
while time.time() < timeout:
|
||||||
|
rx_bytes = read_register(spi, RXBYTES) & 0x7F
|
||||||
|
if rx_bytes > 0:
|
||||||
|
data = read_fifo(spi)
|
||||||
|
print(f"Received: {data}")
|
||||||
|
return data
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
print("Timeout: no data received.")
|
201
regs_addr.py
Normal file
201
regs_addr.py
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
from typing import TypedDict
|
||||||
|
|
||||||
|
class ConfigRegs(TypedDict):
|
||||||
|
IOCFG2: int
|
||||||
|
IOCFG1: int
|
||||||
|
IOCFG0: int
|
||||||
|
FIFOTHR: int
|
||||||
|
SYNC1: int
|
||||||
|
SYNC0: int
|
||||||
|
PKTLEN: int
|
||||||
|
PKTCTRL1: int
|
||||||
|
PKTCTRL0: int
|
||||||
|
ADDR: int
|
||||||
|
CHANNR: int
|
||||||
|
FSCTRL1: int
|
||||||
|
FSCTRL0: int
|
||||||
|
FREQ2: int
|
||||||
|
FREQ1: int
|
||||||
|
FREQ0: int
|
||||||
|
MDMCFG4: int
|
||||||
|
MDMCFG3: int
|
||||||
|
MDMCFG2: int
|
||||||
|
MDMCFG1: int
|
||||||
|
MDMCFG0: int
|
||||||
|
DEVIATN: int
|
||||||
|
MCSM2: int
|
||||||
|
MCSM1: int
|
||||||
|
MCSM0: int
|
||||||
|
FOCCFG: int
|
||||||
|
BSCFG: int
|
||||||
|
AGCCTRL2: int
|
||||||
|
AGCCTRL1: int
|
||||||
|
AGCCTRL0: int
|
||||||
|
WOREVT1: int
|
||||||
|
WOREVT0: int
|
||||||
|
WORCTRL: int
|
||||||
|
FREND1: int
|
||||||
|
FREND0: int
|
||||||
|
FSCAL3: int
|
||||||
|
FSCAL2: int
|
||||||
|
FSCAL1: int
|
||||||
|
FSCAL0: int
|
||||||
|
RCCTRL1: int
|
||||||
|
RCCTRL0: int
|
||||||
|
FSTEST: int
|
||||||
|
PTEST: int
|
||||||
|
AGCTEST: int
|
||||||
|
TEST2: int
|
||||||
|
TEST1: int
|
||||||
|
TEST0: int
|
||||||
|
|
||||||
|
class Strobes(TypedDict):
|
||||||
|
SRES: int
|
||||||
|
SFSTXON: int
|
||||||
|
SXOFF: int
|
||||||
|
SCAL: int
|
||||||
|
SRX: int
|
||||||
|
STX: int
|
||||||
|
SIDLE: int
|
||||||
|
SAFC: int
|
||||||
|
SWOR: int
|
||||||
|
SPWD: int
|
||||||
|
SFRX: int
|
||||||
|
SFTX: int
|
||||||
|
SWORRST: int
|
||||||
|
SNOP: int
|
||||||
|
|
||||||
|
class Status(TypedDict):
|
||||||
|
PARTNUM: int
|
||||||
|
VERSION: int
|
||||||
|
FREQEST: int
|
||||||
|
LQI: int
|
||||||
|
RSSI: int
|
||||||
|
MARCSTATE: int
|
||||||
|
WORTIME1: int
|
||||||
|
WORTIME0: int
|
||||||
|
PKTSTATUS: int
|
||||||
|
VCO_VC_DAC: int
|
||||||
|
TXBYTES: int
|
||||||
|
RXBYTES: int
|
||||||
|
NUM_RXBYTES: int
|
||||||
|
|
||||||
|
class Memory(TypedDict):
|
||||||
|
PATABLE: int
|
||||||
|
TXFIFO: int
|
||||||
|
RXFIFO: int
|
||||||
|
|
||||||
|
class Masks(TypedDict):
|
||||||
|
LQI_RX: int
|
||||||
|
CRC_OK: int
|
||||||
|
|
||||||
|
class Access(TypedDict):
|
||||||
|
WRITE_BURST: int
|
||||||
|
READ_SINGLE: int
|
||||||
|
READ_BURST: int
|
||||||
|
|
||||||
|
class RegsAddr(TypedDict):
|
||||||
|
CONFIG_REGS: ConfigRegs
|
||||||
|
STROBES: Strobes
|
||||||
|
STATUS: Status
|
||||||
|
MEMORY: Memory
|
||||||
|
MASKS: Masks
|
||||||
|
ACCESS: Access
|
||||||
|
|
||||||
|
|
||||||
|
regs_addr: RegsAddr = {
|
||||||
|
"CONFIG_REGS": {
|
||||||
|
"IOCFG2": 0x00,
|
||||||
|
"IOCFG1": 0x01,
|
||||||
|
"IOCFG0": 0x02,
|
||||||
|
"FIFOTHR": 0x03,
|
||||||
|
"SYNC1": 0x04,
|
||||||
|
"SYNC0": 0x05,
|
||||||
|
"PKTLEN": 0x06,
|
||||||
|
"PKTCTRL1": 0x07,
|
||||||
|
"PKTCTRL0": 0x08,
|
||||||
|
"ADDR": 0x09,
|
||||||
|
"CHANNR": 0x0A,
|
||||||
|
"FSCTRL1": 0x0B,
|
||||||
|
"FSCTRL0": 0x0C,
|
||||||
|
"FREQ2": 0x0D,
|
||||||
|
"FREQ1": 0x0E,
|
||||||
|
"FREQ0": 0x0F,
|
||||||
|
"MDMCFG4": 0x10,
|
||||||
|
"MDMCFG3": 0x11,
|
||||||
|
"MDMCFG2": 0x12,
|
||||||
|
"MDMCFG1": 0x13,
|
||||||
|
"MDMCFG0": 0x14,
|
||||||
|
"DEVIATN": 0x15,
|
||||||
|
"MCSM2": 0x16,
|
||||||
|
"MCSM1": 0x17,
|
||||||
|
"MCSM0": 0x18,
|
||||||
|
"FOCCFG": 0x19,
|
||||||
|
"BSCFG": 0x1A,
|
||||||
|
"AGCCTRL2": 0x1B,
|
||||||
|
"AGCCTRL1": 0x1C,
|
||||||
|
"AGCCTRL0": 0x1D,
|
||||||
|
"WOREVT1": 0x1E,
|
||||||
|
"WOREVT0": 0x1F,
|
||||||
|
"WORCTRL": 0x20,
|
||||||
|
"FREND1": 0x21,
|
||||||
|
"FREND0": 0x22,
|
||||||
|
"FSCAL3": 0x23,
|
||||||
|
"FSCAL2": 0x24,
|
||||||
|
"FSCAL1": 0x25,
|
||||||
|
"FSCAL0": 0x26,
|
||||||
|
"RCCTRL1": 0x27,
|
||||||
|
"RCCTRL0": 0x28,
|
||||||
|
"FSTEST": 0x29,
|
||||||
|
"PTEST": 0x2A,
|
||||||
|
"AGCTEST": 0x2B,
|
||||||
|
"TEST2": 0x2C,
|
||||||
|
"TEST1": 0x2D,
|
||||||
|
"TEST0": 0x2E
|
||||||
|
},
|
||||||
|
"STROBES": {
|
||||||
|
"SRES": 0x30,
|
||||||
|
"SFSTXON": 0x31,
|
||||||
|
"SXOFF": 0x32,
|
||||||
|
"SCAL": 0x33,
|
||||||
|
"SRX": 0x34,
|
||||||
|
"STX": 0x35,
|
||||||
|
"SIDLE": 0x36,
|
||||||
|
"SAFC": 0x37,
|
||||||
|
"SWOR": 0x38,
|
||||||
|
"SPWD": 0x39,
|
||||||
|
"SFRX": 0x3A,
|
||||||
|
"SFTX": 0x3B,
|
||||||
|
"SWORRST": 0x3C,
|
||||||
|
"SNOP": 0x3D
|
||||||
|
},
|
||||||
|
"STATUS": {
|
||||||
|
"PARTNUM": 0x30,
|
||||||
|
"VERSION": 0x31,
|
||||||
|
"FREQEST": 0x32,
|
||||||
|
"LQI": 0x33,
|
||||||
|
"RSSI": 0x34,
|
||||||
|
"MARCSTATE": 0x35,
|
||||||
|
"WORTIME1": 0x36,
|
||||||
|
"WORTIME0": 0x37,
|
||||||
|
"PKTSTATUS": 0x38,
|
||||||
|
"VCO_VC_DAC": 0x39,
|
||||||
|
"TXBYTES": 0x3A,
|
||||||
|
"RXBYTES": 0x3B,
|
||||||
|
"NUM_RXBYTES": 0x7F
|
||||||
|
},
|
||||||
|
"MEMORY": {
|
||||||
|
"PATABLE": 0x3E,
|
||||||
|
"TXFIFO": 0x3F,
|
||||||
|
"RXFIFO": 0x3F
|
||||||
|
},
|
||||||
|
"MASKS": {
|
||||||
|
"LQI_RX": 0x01,
|
||||||
|
"CRC_OK": 0x80
|
||||||
|
},
|
||||||
|
"ACCESS": {
|
||||||
|
"WRITE_BURST": 0x40,
|
||||||
|
"READ_SINGLE": 0x80,
|
||||||
|
"READ_BURST": 0xC0
|
||||||
|
}
|
||||||
|
}
|
50
test.py
50
test.py
@ -1,50 +0,0 @@
|
|||||||
import spidev
|
|
||||||
import time
|
|
||||||
|
|
||||||
cc2500_config = {
|
|
||||||
0x00: 0x0B, # IOCFG2
|
|
||||||
0x02: 0x06, # IOCFG0
|
|
||||||
0x03: 0x00, # FIFOTHR
|
|
||||||
0x07: 0x08, # FSCTRL1
|
|
||||||
0x08: 0x00, # FSCTRL0
|
|
||||||
0x0B: 0x06, # IOCFG0 (repeating correct setting)
|
|
||||||
0x0C: 0x00, # FIFOTHR
|
|
||||||
0x0D: 0x5D, # FREQ2
|
|
||||||
0x0E: 0x93, # FREQ1
|
|
||||||
0x0F: 0xB1, # FREQ0
|
|
||||||
0x10: 0x2D, # MDMCFG4
|
|
||||||
0x11: 0x3B, # MDMCFG3
|
|
||||||
0x12: 0x73, # MDMCFG2
|
|
||||||
0x15: 0x00, # DEVIATN
|
|
||||||
0x18: 0x18, # MCSM0
|
|
||||||
0x19: 0x1D, # FOCCFG
|
|
||||||
0x1A: 0x1C, # BSCFG
|
|
||||||
0x1B: 0xC7, # AGCCTRL2
|
|
||||||
0x22: 0x11, # FREND0
|
|
||||||
0x23: 0xE9, # FSCAL3
|
|
||||||
0x24: 0x2A, # FSCAL2
|
|
||||||
0x25: 0x00, # FSCAL1
|
|
||||||
0x26: 0x1F, # FSCAL0
|
|
||||||
0x2C: 0x81, # TEST2
|
|
||||||
0x2D: 0x35, # TEST1
|
|
||||||
0x2E: 0x09, # TEST0
|
|
||||||
0x06: 0x00, # ADDR (only once)
|
|
||||||
0x1E: 0x05, # PKTCTRL0
|
|
||||||
0x07: 0x00, # CHANNR
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
spi = spidev.SpiDev()
|
|
||||||
spi.open(0, 0) # Bus 0, CE0
|
|
||||||
spi.max_speed_hz = 500000 # Adjust if needed
|
|
||||||
spi.mode = 0 # CC2500 usually works in SPI mode 0
|
|
||||||
|
|
||||||
def cc2500_strobe(command):
|
|
||||||
resp = spi.xfer2([command])
|
|
||||||
return resp[0]
|
|
||||||
|
|
||||||
SRES = 0x30 # Reset strobe command
|
|
||||||
|
|
||||||
print("Sending reset to CC2500...")
|
|
||||||
status = cc2500_strobe(SRES)
|
|
||||||
print(f"Status byte: 0x{status:02X}")
|
|
17
transmit.py
Normal file
17
transmit.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
def burst_write(addr, data):
|
||||||
|
"""Write multiple bytes to FIFO or registers"""
|
||||||
|
BURST = 0x40
|
||||||
|
spi.xfer2([addr | BURST] + data)
|
||||||
|
|
||||||
|
|
||||||
|
def send_packet(data):
|
||||||
|
# Flush TX FIFO
|
||||||
|
strobe(0x3B) # SFTX
|
||||||
|
|
||||||
|
# Load data to TX FIFO (fixed length)
|
||||||
|
burst_write(0x3F, data) # 0x3F = TX FIFO
|
||||||
|
|
||||||
|
# Strobe STX to transmit
|
||||||
|
strobe(0x35) # STX
|
||||||
|
|
||||||
|
print(f"Sent: {data}")
|
71
util.py
Normal file
71
util.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from init_regs_value import init_regs_value
|
||||||
|
from regs_addr import regs_addr
|
||||||
|
import time
|
||||||
|
CONFIG_REGS = regs_addr["CONFIG_REGS"]
|
||||||
|
STROBES = regs_addr["STROBES"]
|
||||||
|
STATUS = regs_addr["STATUS"]
|
||||||
|
MEMORY = regs_addr["MEMORY"]
|
||||||
|
MASKS = regs_addr["MASKS"]
|
||||||
|
ACCESS = regs_addr["ACCESS"]
|
||||||
|
SRES = STROBES["SRES"]
|
||||||
|
SNOP = STROBES["SNOP"]
|
||||||
|
VERSION = STATUS["VERSION"]
|
||||||
|
|
||||||
|
def get_addr(name):
|
||||||
|
addr = ""
|
||||||
|
stop = False
|
||||||
|
for reg_type, reg_data in regs_addr.items():
|
||||||
|
for reg_name, reg_addr in reg_data.items():
|
||||||
|
if reg_name == name:
|
||||||
|
stop = True
|
||||||
|
addr = reg_addr
|
||||||
|
if stop == False:
|
||||||
|
raise Exception("Failed to find address for "+name)
|
||||||
|
return addr
|
||||||
|
|
||||||
|
def strobe(spi, command):
|
||||||
|
"""Send a command strobe to CC2500"""
|
||||||
|
spi.xfer2([command])
|
||||||
|
|
||||||
|
def write_reg(spi, addr, value):
|
||||||
|
"""Write single byte to a register"""
|
||||||
|
spi.xfer2([addr, value])
|
||||||
|
|
||||||
|
def read_register(spi, addr):
|
||||||
|
READ_SINGLE = get_addr("READ_SINGLE")
|
||||||
|
# Send address | 0x80 (read), then 0x00 dummy to clock in response
|
||||||
|
response = spi.xfer2([READ_SINGLE | addr, 0x00])
|
||||||
|
return response[1]
|
||||||
|
|
||||||
|
def disable_crc(spi):
|
||||||
|
spi.xfer2([CONFIG_REGS["PKTCTRL0"], 0x01])
|
||||||
|
|
||||||
|
def init_regs(spi):
|
||||||
|
for reg_name, value in init_regs_value.items():
|
||||||
|
addr = get_addr(reg_name)
|
||||||
|
write_reg(spi, addr, value)
|
||||||
|
|
||||||
|
def test_read_write_reg(spi, dbg=False):
|
||||||
|
FIFOTHR = get_addr("FIFOTHR")
|
||||||
|
initial_val = read_register(spi, FIFOTHR)
|
||||||
|
test_value = initial_val + 1
|
||||||
|
write_reg(spi, FIFOTHR, test_value)
|
||||||
|
check = read_register(spi, FIFOTHR)
|
||||||
|
write_reg(spi, FIFOTHR, initial_val)
|
||||||
|
if(dbg):
|
||||||
|
print("initial value ", initial_val)
|
||||||
|
print("test value ", test_value)
|
||||||
|
print("check ",check)
|
||||||
|
elif (not dbg and (check != test_value)):
|
||||||
|
raise Exception("Test Read+Write failed")
|
||||||
|
return check == test_value
|
||||||
|
|
||||||
|
def dump_regs(spi):
|
||||||
|
for reg_type, reg_data in regs_addr.items():
|
||||||
|
for reg_name, reg_addr in reg_data.items():
|
||||||
|
name :str = reg_name
|
||||||
|
value = read_register(spi, reg_addr)
|
||||||
|
print((name+":").ljust(15) +hex(value).ljust(4)+"\t"+str(value))
|
||||||
|
|
||||||
|
def sleep(t):
|
||||||
|
return time.sleep(t)
|
Loading…
Reference in New Issue
Block a user