from ..core import Endpoint
from .SPIFifoDriven import SPIFifoDriven
import numpy as np
[docs]class AD5453(SPIFifoDriven):
# TODO: add class docstring
bits = 12,
vref = 2.5*2
def __init__(self, fpga, master_config=0x3010, endpoints=None, data_mux=SPIFifoDriven.default_data_mux):
if endpoints is None:
endpoints = Endpoint.get_chip_endpoints('AD5453')
# master_config=0x3010 Sets CHAR_LEN=16, ASS, IE
super().__init__(fpga=fpga, master_config=master_config,
endpoints=endpoints, data_mux=data_mux)
# Default to clocking data into the shift register on the falling edge of the clock
self.clk_edge_bits = 0b00
# TODO: cleanup! 500kHz is within set_filter_coeff
self.filter_coeff = {0: 0x009e1586,
1: 0x20000000,
2: 0x40000000,
3: 0x20000000,
4: 0xbce3be9a,
5: 0x12f3f6b0,
8: 0x7fffffff,
9: 0x20000000,
10: 0x40000000,
11: 0x20000000,
12: 0xab762783,
13: 0x287ecada,
7: 0x7fffffff,
15: 0x0000_2000} # offset=0, scale=1
self.filter_offset = 4
self.filter_len = np.max(
list(self.filter_coeff.keys())) - np.min(list(self.filter_coeff.keys()))
self.current_data_mux = None
self.set_data_mux('host')
[docs] def set_clk_rising_edge(self):
"""Set the signals we write to use the rising edge of the clock.
Default is falling edge. To return to the falling edge, the chip
requires a power cycle (turn it off and back on).
"""
self.clk_edge_bits = 0b11
[docs] def set_ctrl_reg(self, reg_value=0x3010):
"""Configures the SPI Wishbone control register over the registerBridge.
reg_value=0x3010 sets CHAR_LEN=16, ASS, IE
"""
super().set_ctrl_reg(reg_value=reg_value)
def write_filter_coeffs(self):
# TODO: add method docstring
# TODO is this correct? and how to parameterize?
for i in np.arange(self.filter_offset, 1 + self.filter_offset + self.filter_len):
if (i-self.filter_offset) in self.filter_coeff:
addr = int(
self.endpoints['REGBRIDGE_OFFSET'].address + i)
val = int(self.filter_coeff[i-self.filter_offset])
# TODO: ian has first addr of 0x19, second as 0x1a
print(
'Write filter addr=0x{:02X} value=0x{:02X}'.format(addr, val))
self.fpga.xem.WriteRegister(addr, val)
def write_filter_coeffs_simultaneous(self):
# TODO: add method docstring
# https://opalkelly.com/examples/setting-and-getting-multiple-registers/#tab-python
loop_thru = np.arange(self.filter_offset, 1
+ self.filter_offset + self.filter_len)
# ok should already be imported from Endpoint import
regs = ok.okTRegisterEntries((len(loop_thru)))
for i in loop_thru: # TODO is this correct? and how to parameterize?
if (i-self.filter_offset) in self.filter_coeff:
addr = int(
self.endpoints['REGBRIDGE_OFFSET'].address + i)
val = int(self.filter_coeff[i-self.filter_offset])
idx = int(i-self.filter_offset)
regs[idx].address = addr
regs[idx].data = val
# TODO: ian has first addr of 0x19, second as 0x1a
print(
'Write filter addr=0x{:02X} value=0x{:02X}'.format(addr, val))
self.fpga.xem.WriteRegisters(regs)
[docs] def read_coeff_debug(self):
"""
Read two wire outs for coefficients a3 section1, scale 3
debug wires available for filters 0, 1
"""
debug_coeff_0 = self.fpga.read_wire(
self.endpoints[f'COEFF_DEBUG_0'].address)
debug_coeff_1 = self.fpga.read_wire(
self.endpoints[f'COEFF_DEBUG_1'].address)
debug_coeff_2 = self.fpga.read_wire(
self.endpoints[f'COEFF_DEBUG_2'].address)
debug_coeff_3 = self.fpga.read_wire(
self.endpoints[f'COEFF_DEBUG_3'].address)
print(f'Read Coefficients:')
print(' 0:', debug_coeff_0)
print(' 1:', debug_coeff_1)
print(' 2:', debug_coeff_2)
print(' 3:', debug_coeff_3)
return debug_coeff_0, debug_coeff_1, debug_coeff_2, debug_coeff_3
def change_filter_coeff(self, target, value=None):
# TODO: add method docstring
if (target == 'passthru') or (target == 'passthrough'):
self.filter_coeff = {#0: 0x7fff_ffff, # changed for about unity gain
0: 0x80000000,
1: 0x20000000,
2: 0,
3: 0,
4: 0,
5: 0,
8: 0x7fffffff,
9: 0x20000000,
10: 0,
11: 0,
12: 0,
13: 0,
7: 0x7fffffff,
6: 0,
15: 0x0000_0900} # offset=0, scale=1
elif target == '100kHz':
self.filter_coeff = {0: 0x0000_6f84,
1: 0x20000000,
2: 0x40000000,
3: 0x20000000,
4: 0x8e301ca0,
5: 0x32b7759a,
8: 0x7fffffff,
9: 0x20000000,
10: 0x40000000,
11: 0x20000000,
12: 0x86d2475f,
13: 0x3a2447ec,
7: 0x7fffffff,
15: 0x0000_1000} # offset=0, scale=1
elif target == '500kHz':
self.filter_coeff = {#0: 0x009e1586,
0: 0xFF61EA7A,
1: 0x20000000,
2: 0x40000000,
3: 0x20000000,
4: 0xbce3be9a,
5: 0x12f3f6b0,
8: 0x7fffffff,
9: 0x20000000,
10: 0x40000000,
11: 0x20000000,
12: 0xab762783,
13: 0x287ecada,
7: 0x7fffffff,
15: 0x0000_0900}
#15: 0x0000_0B1F} # offset=0, scale=1
else :
self.filter_coeff = value