This commit is contained in:
2025-05-20 20:33:12 -05:00
parent 8a1a6ea770
commit fcb291590b
104 changed files with 63299 additions and 45045 deletions

View File

@@ -119,10 +119,11 @@ class DataRecorder:
n = self.s.recv_into(self.buffer_view[offset:offset + self.max_packet_size])
if self.write_to_disk:
# print(n)
self.write_queue.put(n)
offset += n
if offset >= len(self.buffer):
if offset > len(self.buffer):
if self.port == 1234:
print('hmmm', n, offset, len(self.buffer))
offset = offset % len(self.buffer)

View File

@@ -1,5 +1,5 @@
import ctypes
from ctypes import Structure, c_uint64, c_uint32, c_uint16, c_uint8, c_float
from ctypes import Structure, c_uint64, c_int64, c_uint32, c_uint16, c_uint8, c_float
AXI_WRITE_REG = 1
AXI_READ_REG = 2
@@ -10,6 +10,9 @@ AXI_WRITE_REG_BURST = 6
RF_SPI_WRITE = 7
SET_AD9081_DAC_NCO = 128
SET_AD9081_ADC_NCO = 129
SET_LANE_MAP = 130
AD9081_REG_WRITE = 131
AD9081_REG_READ = 132
ACK_FLAG_VALID_PACKET = 0x01
ACK_FLAG_VALID_EXECUTION = 0x02
@@ -74,8 +77,8 @@ class WriteRegType(Structure):
("data", c_uint32)
]
def __init__(self):
init_header(self, AXI_WRITE_REG)
def __init__(self, msg_id=AXI_WRITE_REG):
init_header(self, msg_id)
self.address = 0
self.data = 0
@@ -114,8 +117,8 @@ class ReadRequestType(Structure):
("address", c_uint32)
]
def __init__(self):
init_header(self, AXI_READ_REG)
def __init__(self, msg_id=AXI_READ_REG):
init_header(self, msg_id)
self.address = 0
@@ -136,7 +139,7 @@ class DacNcoConfigType(Structure):
_fields_ = [
("header", Header),
("channel", c_uint32),
("frequency", c_float)
("frequency", c_int64)
]
def __init__(self):
@@ -149,7 +152,7 @@ class AdcNcoConfigType(Structure):
_fields_ = [
("header", Header),
("channel", c_uint32),
("frequency", c_float)
("frequency", c_int64)
]
def __init__(self):
@@ -170,4 +173,14 @@ class RfSpiWriteType(Structure):
init_header(self, RF_SPI_WRITE)
self.dev_sel = 0
self.num_bits = 0
self.data = 0
self.data = 0
class LaneMapType(Structure):
_pack_ = 1
_fields_ = [
("header", Header),
("lane_map", c_uint8 * 8)
]
def __init__(self):
init_header(self, SET_LANE_MAP)

View File

@@ -18,8 +18,30 @@ WAVEFORM_GEN_ADDR = 0x40053000
NUM_RX = 2
ADC_SAMPLE_RATE = 187.5e6
DAC_SAMPLE_RATE = 187.5e6
JESD204B = False
BASEBAND_SAMPLE_RATE = 750e6
TIMING_ENGINE_FREQ = BASEBAND_SAMPLE_RATE / 4
# ADC_SAMPLE_RATE = 187.5e6
# DAC_SAMPLE_RATE = 187.5e6
f_dac = 9e9
f_adc = 3e9
# ADC_SAMPLE_RATE = 225e6
# DAC_SAMPLE_RATE = 225e6
# f_dac = 10.8e9
# f_adc = 3.6e9
# JESD204B = True
# # ADC_SAMPLE_RATE = 250e6
# # DAC_SAMPLE_RATE = 250e6
# # f_dac = 12e9
# # f_adc = 4e9
# ADC_SAMPLE_RATE = 187.5e6
# DAC_SAMPLE_RATE = 187.5e6
# f_dac = 9e9
# f_adc = 3e9
def form_chirp(pulsewidth, bw, sample_rate, win=None, ):
@@ -160,11 +182,32 @@ class RadarManager:
return resp.data
def ad9081_write_reg(self, address, data):
# Form message
msg = msg_types.WriteRegType(msg_id=msg_types.AD9081_REG_WRITE)
msg.address = address
msg.data = data
self.send_message(msg)
return
def ad9081_read_reg(self, address):
# Form message
msg = msg_types.ReadRequestType(msg_id=msg_types.AD9081_REG_READ)
msg.address = address
self.send_message(msg, enable_ack=False, wait_for_ack=False)
# Get response
recv_bytes, _ = self.get_response(ctypes.sizeof(msg_types.ReadResponseType))
resp = msg_types.ReadResponseType.from_buffer_copy(recv_bytes)
return resp.data
def set_dac_nco(self, channel, frequency):
# Form message
msg = msg_types.DacNcoConfigType()
msg.channel = channel
msg.frequency = frequency
msg.frequency = int(frequency)
self.send_message(msg)
@@ -174,7 +217,17 @@ class RadarManager:
# Form message
msg = msg_types.AdcNcoConfigType()
msg.channel = channel
msg.frequency = frequency
msg.frequency = int(frequency)
self.send_message(msg)
return
def set_lane_mapping(self, lane_map):
# Form message
msg = msg_types.LaneMapType()
for i in range(8):
msg.lane_map[i] = lane_map[i]
self.send_message(msg)
@@ -249,8 +302,12 @@ class RadarManager:
def setup_rx(self, num_samples, start_sample):
for i in range(NUM_RX):
self.axi_write_register(DIG_RX_ADDR + i*DIG_RX_STRIDE + 0x4, num_samples >> 2)
self.axi_write_register(DIG_RX_ADDR + i*DIG_RX_STRIDE + 0x8, start_sample >> 2)
if JESD204B:
self.axi_write_register(DIG_RX_ADDR + i*DIG_RX_STRIDE + 0x4, num_samples >> 1)
self.axi_write_register(DIG_RX_ADDR + i*DIG_RX_STRIDE + 0x8, start_sample >> 1)
else:
self.axi_write_register(DIG_RX_ADDR + i*DIG_RX_STRIDE + 0x4, num_samples >> 2)
self.axi_write_register(DIG_RX_ADDR + i*DIG_RX_STRIDE + 0x8, start_sample >> 2)
# Setup RX Strobe
# self.axi_write_register(TIMING_ENGINE_ADDR + 0x88 + i * 8, start_sample >> 2)
@@ -259,8 +316,12 @@ class RadarManager:
self.axi_write_register(TIMING_ENGINE_ADDR + 0x88 + i * 8, 0x1FFFFFFF)
def setup_tx(self, num_samples, start_sample):
self.axi_write_register(WAVEFORM_GEN_ADDR + 0x4, num_samples >> 2)
self.axi_write_register(WAVEFORM_GEN_ADDR + 0x8, start_sample >> 2)
if JESD204B:
self.axi_write_register(WAVEFORM_GEN_ADDR + 0x4, num_samples >> 1)
self.axi_write_register(WAVEFORM_GEN_ADDR + 0x8, start_sample >> 1)
else:
self.axi_write_register(WAVEFORM_GEN_ADDR + 0x4, num_samples >> 2)
self.axi_write_register(WAVEFORM_GEN_ADDR + 0x8, start_sample >> 2)
# Setup TX Strobe
# self.axi_write_register(TIMING_ENGINE_ADDR + 0x80, start_sample >> 2)
@@ -298,21 +359,33 @@ class RadarManager:
self.load_waveform(0, 1, 0.1, tx_num_samples)
self.load_waveform(1, 1, 0.1, tx_num_samples)
num_samples_quant = int(self.packet_size / 4)
if num_samples % num_samples_quant > 0:
print('Packet Size Invalid')
num_samples -= (num_samples % num_samples_quant)
if num_samples == 0:
num_samples = num_samples_quant
print('Updated num samples to', num_samples)
rf_atten = [1, 2, 3, 4, 5, 6]
self.setup_rf_attenuators(rf_atten)
# DAC at 5.25 GHz is in second nyquist
# ADC would be in 3rd nyquist
f_dac = 9e9
f_adc = 3e9
tx_lo = 5.25e9 % f_dac
rx_lo = 5.25e9 % f_adc
adc_nco = 5e9 % f_adc
dac_nco = 5.001e9 % f_dac
# adc_nco = 2e9
# adc_nyquist_zone = np.floor(adc_nco / (f_adc / 2))
# adc_nco = adc_nco % f_adc
# if adc_nyquist_zone % 2:
# # In even nyquist
# adc_nco -= f_adc
print(adc_nco)
for i in range(4):
self.set_adc_nco(i, rx_lo)
self.set_dac_nco(0, tx_lo)
self.set_dac_nco(1, tx_lo)
self.set_dac_nco(2, tx_lo + tx_lo_offset)
self.set_dac_nco(3, tx_lo + rx_lo_offset)
self.set_adc_nco(i, adc_nco)
self.set_dac_nco(i, dac_nco)
self.setup_timing_engine(pri, num_pulses, inter_cpi)
self.setup_rx(num_samples, start_sample)
self.setup_tx(tx_num_samples, tx_start_sample)

View File

@@ -58,6 +58,7 @@ def main():
file_size = os.path.getsize(file)
expected_num_cpis = int(file_size / (ctypes.sizeof(data_structures.CpiHeader) + data_size))
print('File Size', file_size)
print('Expected CPIS:', expected_num_cpis)
@@ -92,6 +93,7 @@ def main():
plt.figure()
plt.plot(np.diff(cpi_times))
plt.ylim([0, .02])
plt.figure()
plt.plot(iq.T.real, '.-')

View File

@@ -28,15 +28,29 @@ def db20n(x):
def main():
print('Hello')
clk = 187.5e6
radar = radar_manager.RadarManager()
clk = radar_manager.TIMING_ENGINE_FREQ
freqs = np.array([16, 21, 13, 3.25, 3.5, 5, 2])*1e9
pri_lsb = 16e-9
print(freqs * pri_lsb)
# Test AD9081 Reg Access
print(hex(radar.ad9081_read_reg(0x0A0A)))
radar.ad9081_write_reg(0x0A0A, 0x60)
print(hex(radar.ad9081_read_reg(0x0A0A)))
# CPI Parameters (timing values are in clk ticks)
num_pulses = 128
num_samples = 8192
start_sample = 0
# Should be multiple of udp packet size, currently 4096 bytes, or 1024 samples
num_samples = 5000
start_sample = 2000
tx_num_samples = 1024
tx_start_sample = start_sample
pri = int(.001 * clk)
pri = int(.0004 * clk)
print(pri)
inter_cpi = 50
tx_lo_offset = 10e6
rx_lo_offset = 0
@@ -46,7 +60,7 @@ def main():
print('PRI', pri_float, 'PRF', 1 / pri_float)
print('Expected Data Rate', num_samples * 4 / pri_float / 1e6)
radar = radar_manager.RadarManager()
recorder0 = DataRecorder("192.168.2.128", 1234, packet_size=radar.packet_size)
recorder1 = DataRecorder("192.168.3.128", 1235, packet_size=radar.packet_size)
@@ -59,7 +73,7 @@ def main():
print('Start Running')
radar.start_running()
# Let it run for a bit
time.sleep(5)
time.sleep(2)
# Stop running
radar.stop_running()
# Stop the data recorder
@@ -84,12 +98,14 @@ def main():
else:
offset += 4
num_cpi = 16
num_cpi = 1
for i in range(num_cpi):
# Get Header
data = plot_recorder.buffer[offset:offset + ctypes.sizeof(data_structures.CpiHeader)]
offset += ctypes.sizeof(data_structures.CpiHeader)
headers.append(data_structures.CpiHeader.from_buffer_copy(data))
num_pulses = headers[i].num_pulses
num_samples = headers[i].num_samples
# Get CPI
data_size = num_pulses * num_samples * 4
@@ -117,15 +133,21 @@ def main():
vmin = -60
vmax = 0
fid, axs = plt.subplots(2)
axs[0].plot(iq.T.real, '.-')
axs[0].plot(iq.T.imag, '--.')
fid, axs = plt.subplots(3)
axs[0].plot(iq.T.real, '-')
axs[0].plot(iq.T.imag, '--')
axs[0].grid()
axs[1].imshow(db20n(iq), aspect='auto', interpolation='nearest', vmin=vmin, vmax=vmax)
# axs[1].imshow(db20n(iq), aspect='auto', interpolation='nearest', vmin=vmin, vmax=vmax)
axs[1].imshow(iq.real, aspect='auto', interpolation='nearest')
axs[1].set_ylabel('Pulse Count')
axs[1].set_xlabel('Sample Count')
iq_freq = np.fft.fftshift(np.fft.fft(iq, axis=1), axes=1)
freq_axis = (np.arange(num_samples)/num_samples - 0.5) * radar_manager.BASEBAND_SAMPLE_RATE / 1e6
axs[2].plot(freq_axis, db20n(iq_freq.T))
axs[2].grid()
plt.show()