updates
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, '.-')
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -231,11 +231,18 @@ set_property PACKAGE_PIN A25 [get_ports fmc_spi0_miso]
|
||||
set_property PACKAGE_PIN B27 [get_ports fmc_spi0_sck]
|
||||
set_property PACKAGE_PIN B25 [get_ports fmc_spi0_ss]
|
||||
|
||||
set_property PULLUP TRUE [get_ports fmc_spi0_mosi]
|
||||
set_property PULLUP TRUE [get_ports fmc_spi0_miso]
|
||||
set_property PULLUP TRUE [get_ports fmc_spi0_sck]
|
||||
|
||||
set_property PACKAGE_PIN C22 [get_ports fmc_spi1_mosi]
|
||||
set_property PACKAGE_PIN D20 [get_ports fmc_spi1_sck]
|
||||
set_property PACKAGE_PIN C21 [get_ports fmc_spi1_ss]
|
||||
set_property PACKAGE_PIN F27 [get_ports resetb]
|
||||
|
||||
set_property PULLUP TRUE [get_ports fmc_spi1_mosi]
|
||||
set_property PULLUP TRUE [get_ports fmc_spi1_sck]
|
||||
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports fmc_spi0_mosi]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports fmc_spi0_miso]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports fmc_spi0_sck]
|
||||
@@ -252,24 +259,42 @@ set_property IOSTANDARD LVDS [get_ports jesd_sysref_p]
|
||||
set_property DIFF_TERM_ADV TERM_100 [get_ports jesd_sysref_p]
|
||||
set_property DQS_BIAS TRUE [get_ports jesd_sysref_p]
|
||||
set_property DQS_BIAS TRUE [get_ports jesd_sysref_n]
|
||||
create_clock -period 64.000 -name jesd_sysref [get_ports jesd_sysref_p]
|
||||
|
||||
|
||||
set_property PACKAGE_PIN E28 [get_ports jesd_sync_in_p]
|
||||
set_property PACKAGE_PIN D29 [get_ports jesd_sync_in_n]
|
||||
set_property IOSTANDARD LVDS [get_ports jesd_sync_in_p]
|
||||
set_property DIFF_TERM_ADV TERM_100 [get_ports jesd_sync_in_p]
|
||||
|
||||
set_property PACKAGE_PIN E22 [get_ports jesd_sync_out_p]
|
||||
set_property PACKAGE_PIN E23 [get_ports jesd_sync_out_n]
|
||||
set_property IOSTANDARD LVDS [get_ports jesd_sync_out_p]
|
||||
|
||||
set_property PACKAGE_PIN K5 [get_ports jesd_qpll0_refclk_n]
|
||||
set_property PACKAGE_PIN K6 [get_ports jesd_qpll0_refclk_p]
|
||||
create_clock -period 5.333 -name jesd_qpll_refclk [get_ports jesd_qpll0_refclk_p]
|
||||
#create_clock -period 4.0 -name jesd_qpll_refclk [get_ports jesd_qpll0_refclk_p]
|
||||
|
||||
#set_property PACKAGE_PIN P5 [get_ports jesd_qpll0_refclk_n]
|
||||
#set_property PACKAGE_PIN P6 [get_ports jesd_qpll0_refclk_p]
|
||||
|
||||
set_property PACKAGE_PIN G10 [get_ports jesd_core_clk_p]
|
||||
set_property PACKAGE_PIN F10 [get_ports jesd_core_clk_n]
|
||||
|
||||
#set_property PACKAGE_PIN D24 [get_ports jesd_core_clk_p]
|
||||
#set_property PACKAGE_PIN C24 [get_ports jesd_core_clk_n]
|
||||
# Works with the board at my house
|
||||
#set_property PACKAGE_PIN G10 [get_ports jesd_core_clk_p]
|
||||
#set_property PACKAGE_PIN F10 [get_ports jesd_core_clk_n]
|
||||
#set_property IOSTANDARD LVDS [get_ports jesd_core_clk_p]
|
||||
#set_property DQS_BIAS TRUE [get_ports jesd_core_clk_p]
|
||||
#set_property DQS_BIAS TRUE [get_ports jesd_core_clk_n]
|
||||
#create_clock -period 5.333 -name jesd_core_clk [get_ports jesd_core_clk_p]
|
||||
|
||||
# Works with the board Chris has
|
||||
set_property PACKAGE_PIN D24 [get_ports jesd_core_clk_p]
|
||||
set_property PACKAGE_PIN C24 [get_ports jesd_core_clk_n]
|
||||
set_property IOSTANDARD LVDS [get_ports jesd_core_clk_p]
|
||||
set_property DQS_BIAS TRUE [get_ports jesd_core_clk_p]
|
||||
set_property DQS_BIAS TRUE [get_ports jesd_core_clk_n]
|
||||
create_clock -period 5.333 -name jesd_core_clk [get_ports jesd_core_clk_n]
|
||||
create_clock -period 5.333 -name jesd_core_clk [get_ports jesd_core_clk_p]
|
||||
#create_clock -period 4.0 -name jesd_core_clk [get_ports jesd_core_clk_p]
|
||||
|
||||
#set_property PACKAGE_PIN F2 [get_ports {jesd_rxp_in[0]}]
|
||||
#set_property PACKAGE_PIN H2 [get_ports {jesd_rxp_in[1]}]
|
||||
@@ -424,34 +449,3 @@ set_property PACKAGE_PIN AE23 [get_ports {ddr_dq[7]}]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect_debug_port u_ila_0/probe1 [get_nets [list pps_q2]]
|
||||
connect_debug_port u_ila_0/probe3 [get_nets [list pps_red_i_1__0_n_0]]
|
||||
|
||||
|
||||
|
||||
connect_debug_port u_ila_0/probe4 [get_nets [list util_reg_i/spi_active]]
|
||||
connect_debug_port u_ila_0/probe5 [get_nets [list util_reg_i/spi_shift_data]]
|
||||
connect_debug_port u_ila_0/probe10 [get_nets [list util_reg_i/le_active]]
|
||||
|
||||
|
||||
|
||||
create_debug_core u_ila_0 ila
|
||||
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
|
||||
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
|
||||
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
|
||||
set_property C_DATA_DEPTH 2048 [get_debug_cores u_ila_0]
|
||||
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
|
||||
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
|
||||
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
|
||||
set_property port_width 1 [get_debug_ports u_ila_0/clk]
|
||||
connect_debug_port u_ila_0/clk [get_nets [list jesd_core_clk]]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
|
||||
set_property port_width 1 [get_debug_ports u_ila_0/probe0]
|
||||
connect_debug_port u_ila_0/probe0 [get_nets [list microblaze_bd_i/jesd/util_ds_buf_1_IBUF_OUT]]
|
||||
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
|
||||
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
|
||||
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
|
||||
connect_debug_port dbg_hub/clk [get_nets clk]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"design": {
|
||||
"design_info": {
|
||||
"boundary_crc": "0xF42ED0D8FE15BA23",
|
||||
"device": "xcku040-ffva1156-1-c",
|
||||
"boundary_crc": "0xD9A446DC95B09871",
|
||||
"device": "xcku040-ffva1156-2-i",
|
||||
"gen_directory": "../../../../radar_alinx_kintex.gen/sources_1/bd/microblaze_bd",
|
||||
"name": "microblaze_bd",
|
||||
"rev_ctrl_bd_flag": "RevCtrlBdOff",
|
||||
@@ -74,7 +74,8 @@
|
||||
"m09_couplers": {},
|
||||
"m10_couplers": {},
|
||||
"m11_couplers": {},
|
||||
"m12_couplers": {}
|
||||
"m12_couplers": {},
|
||||
"m13_couplers": {}
|
||||
},
|
||||
"axi_quad_spi_0": "",
|
||||
"axi_quad_spi_1": "",
|
||||
@@ -609,7 +610,7 @@
|
||||
"value_src": "default"
|
||||
},
|
||||
"FREQ_HZ": {
|
||||
"value": "187500000"
|
||||
"value": "250000000"
|
||||
},
|
||||
"HAS_TKEEP": {
|
||||
"value": "0",
|
||||
@@ -679,7 +680,7 @@
|
||||
"value_src": "default"
|
||||
},
|
||||
"FREQ_HZ": {
|
||||
"value": "187500000"
|
||||
"value": "250000000"
|
||||
},
|
||||
"HAS_TKEEP": {
|
||||
"value": "0",
|
||||
@@ -759,7 +760,7 @@
|
||||
"value_src": "default"
|
||||
},
|
||||
"FREQ_HZ": {
|
||||
"value": "187500000"
|
||||
"value": "250000000"
|
||||
},
|
||||
"HAS_TKEEP": {
|
||||
"value": "0"
|
||||
@@ -820,7 +821,7 @@
|
||||
"value_src": "default"
|
||||
},
|
||||
"FREQ_HZ": {
|
||||
"value": "187500000"
|
||||
"value": "250000000"
|
||||
},
|
||||
"HAS_TKEEP": {
|
||||
"value": "0"
|
||||
@@ -2666,7 +2667,7 @@
|
||||
"value_src": "default"
|
||||
},
|
||||
"FREQ_HZ": {
|
||||
"value": "187500000"
|
||||
"value": "250000000"
|
||||
},
|
||||
"FREQ_TOLERANCE_HZ": {
|
||||
"value": "0",
|
||||
@@ -2745,6 +2746,12 @@
|
||||
"direction": "I",
|
||||
"left": "0",
|
||||
"right": "0"
|
||||
},
|
||||
"jesd_tx_sync": {
|
||||
"direction": "I"
|
||||
},
|
||||
"jesd_rx_sync": {
|
||||
"direction": "O"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -3034,6 +3041,12 @@
|
||||
},
|
||||
"jesd_rx_sys_reset": {
|
||||
"direction": "I"
|
||||
},
|
||||
"jesd_tx_sync": {
|
||||
"direction": "I"
|
||||
},
|
||||
"jesd_rx_sync": {
|
||||
"direction": "O"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -3126,6 +3139,9 @@
|
||||
"AXICLK_FREQ": {
|
||||
"value": "150.0"
|
||||
},
|
||||
"C_ENCODING": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_LANES": {
|
||||
"value": "8"
|
||||
},
|
||||
@@ -3135,6 +3151,9 @@
|
||||
"C_PLL_SELECTION": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_USE_FEC": {
|
||||
"value": "true"
|
||||
},
|
||||
"DRPCLK_FREQ": {
|
||||
"value": "187.5"
|
||||
},
|
||||
@@ -3176,12 +3195,18 @@
|
||||
"AXICLK_FREQ": {
|
||||
"value": "150"
|
||||
},
|
||||
"C_ENCODING": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_LANES": {
|
||||
"value": "8"
|
||||
},
|
||||
"C_PLL_SELECTION": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_USE_FEC": {
|
||||
"value": "true"
|
||||
},
|
||||
"DRPCLK_FREQ": {
|
||||
"value": "187.5"
|
||||
},
|
||||
@@ -3358,6 +3383,12 @@
|
||||
"jesd204_phy_0/gt7_tx"
|
||||
]
|
||||
},
|
||||
"jesd_axis_tx_cmd_1": {
|
||||
"interface_ports": [
|
||||
"jesd_axis_tx_cmd",
|
||||
"jesd204c_1/s_axis_tx_cmd"
|
||||
]
|
||||
},
|
||||
"microblaze_0_axi_periph_M07_AXI": {
|
||||
"interface_ports": [
|
||||
"s_axi_rx",
|
||||
@@ -3381,12 +3412,6 @@
|
||||
"jesd_axis_tx",
|
||||
"jesd204c_1/s_axis_tx"
|
||||
]
|
||||
},
|
||||
"s_axis_tx_cmd_0_1": {
|
||||
"interface_ports": [
|
||||
"jesd_axis_tx_cmd",
|
||||
"jesd204c_1/s_axis_tx_cmd"
|
||||
]
|
||||
}
|
||||
},
|
||||
"nets": {
|
||||
@@ -3985,8 +4010,8 @@
|
||||
"components": {
|
||||
"xbar": {
|
||||
"vlnv": "xilinx.com:ip:axi_crossbar:2.1",
|
||||
"xci_name": "microblaze_bd_xbar_3",
|
||||
"xci_path": "ip/microblaze_bd_xbar_3/microblaze_bd_xbar_3.xci",
|
||||
"xci_name": "microblaze_bd_xbar_6",
|
||||
"xci_path": "ip/microblaze_bd_xbar_6/microblaze_bd_xbar_6.xci",
|
||||
"inst_hier_path": "axi_interconnect_0/xbar",
|
||||
"parameters": {
|
||||
"NUM_MI": {
|
||||
@@ -4969,7 +4994,7 @@
|
||||
"xci_name": "microblaze_bd_axi_interconnect_1_0",
|
||||
"parameters": {
|
||||
"NUM_MI": {
|
||||
"value": "13"
|
||||
"value": "14"
|
||||
}
|
||||
},
|
||||
"interface_ports": {
|
||||
@@ -5042,6 +5067,11 @@
|
||||
"mode": "Master",
|
||||
"vlnv_bus_definition": "xilinx.com:interface:aximm:1.0",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
},
|
||||
"M13_AXI": {
|
||||
"mode": "Master",
|
||||
"vlnv_bus_definition": "xilinx.com:interface:aximm:1.0",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
@@ -5281,17 +5311,33 @@
|
||||
"M12_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
},
|
||||
"M13_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "M13_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "M13_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"M13_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"xbar": {
|
||||
"vlnv": "xilinx.com:ip:axi_crossbar:2.1",
|
||||
"xci_name": "microblaze_bd_xbar_4",
|
||||
"xci_path": "ip/microblaze_bd_xbar_4/microblaze_bd_xbar_4.xci",
|
||||
"xci_name": "microblaze_bd_xbar_7",
|
||||
"xci_path": "ip/microblaze_bd_xbar_7/microblaze_bd_xbar_7.xci",
|
||||
"inst_hier_path": "axi_interconnect_1/xbar",
|
||||
"parameters": {
|
||||
"NUM_MI": {
|
||||
"value": "13"
|
||||
"value": "14"
|
||||
},
|
||||
"NUM_SI": {
|
||||
"value": "1"
|
||||
@@ -5317,7 +5363,8 @@
|
||||
"M09_AXI",
|
||||
"M10_AXI",
|
||||
"M11_AXI",
|
||||
"M12_AXI"
|
||||
"M12_AXI",
|
||||
"M13_AXI"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -6105,6 +6152,62 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"m13_couplers": {
|
||||
"interface_ports": {
|
||||
"M_AXI": {
|
||||
"mode": "Master",
|
||||
"vlnv_bus_definition": "xilinx.com:interface:aximm:1.0",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
},
|
||||
"S_AXI": {
|
||||
"mode": "Slave",
|
||||
"vlnv_bus_definition": "xilinx.com:interface:aximm:1.0",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
"M_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "M_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "M_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"M_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
},
|
||||
"S_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "S_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "S_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"S_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
"m13_couplers_to_m13_couplers": {
|
||||
"interface_ports": [
|
||||
"S_AXI",
|
||||
"M_AXI"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
@@ -6192,6 +6295,12 @@
|
||||
"m12_couplers/M_AXI"
|
||||
]
|
||||
},
|
||||
"m13_couplers_to_axi_interconnect_1": {
|
||||
"interface_ports": [
|
||||
"M13_AXI",
|
||||
"m13_couplers/M_AXI"
|
||||
]
|
||||
},
|
||||
"s00_couplers_to_xbar": {
|
||||
"interface_ports": [
|
||||
"s00_couplers/M_AXI",
|
||||
@@ -6275,6 +6384,12 @@
|
||||
"xbar/M12_AXI",
|
||||
"m12_couplers/S_AXI"
|
||||
]
|
||||
},
|
||||
"xbar_to_m13_couplers": {
|
||||
"interface_ports": [
|
||||
"xbar/M13_AXI",
|
||||
"m13_couplers/S_AXI"
|
||||
]
|
||||
}
|
||||
},
|
||||
"nets": {
|
||||
@@ -6297,6 +6412,7 @@
|
||||
"m10_couplers/M_ACLK",
|
||||
"m11_couplers/M_ACLK",
|
||||
"m12_couplers/M_ACLK",
|
||||
"m13_couplers/M_ACLK",
|
||||
"m00_couplers/S_ACLK",
|
||||
"m01_couplers/S_ACLK",
|
||||
"m02_couplers/S_ACLK",
|
||||
@@ -6309,7 +6425,8 @@
|
||||
"m09_couplers/S_ACLK",
|
||||
"m10_couplers/S_ACLK",
|
||||
"m11_couplers/S_ACLK",
|
||||
"m12_couplers/S_ACLK"
|
||||
"m12_couplers/S_ACLK",
|
||||
"m13_couplers/S_ACLK"
|
||||
]
|
||||
},
|
||||
"axi_interconnect_1_ARESETN_net": {
|
||||
@@ -6331,6 +6448,7 @@
|
||||
"m10_couplers/M_ARESETN",
|
||||
"m11_couplers/M_ARESETN",
|
||||
"m12_couplers/M_ARESETN",
|
||||
"m13_couplers/M_ARESETN",
|
||||
"m00_couplers/S_ARESETN",
|
||||
"m01_couplers/S_ARESETN",
|
||||
"m02_couplers/S_ARESETN",
|
||||
@@ -6343,7 +6461,8 @@
|
||||
"m09_couplers/S_ARESETN",
|
||||
"m10_couplers/S_ARESETN",
|
||||
"m11_couplers/S_ARESETN",
|
||||
"m12_couplers/S_ARESETN"
|
||||
"m12_couplers/S_ARESETN",
|
||||
"m13_couplers/S_ARESETN"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -6583,7 +6702,18 @@
|
||||
"vlnv": "xilinx.com:ip:mdm:3.2",
|
||||
"xci_name": "microblaze_bd_mdm_1_0",
|
||||
"xci_path": "ip/microblaze_bd_mdm_1_0/microblaze_bd_mdm_1_0.xci",
|
||||
"inst_hier_path": "mdm_1"
|
||||
"inst_hier_path": "mdm_1",
|
||||
"parameters": {
|
||||
"C_ADDR_SIZE": {
|
||||
"value": "32"
|
||||
},
|
||||
"C_M_AXI_ADDR_WIDTH": {
|
||||
"value": "32"
|
||||
},
|
||||
"C_USE_UART": {
|
||||
"value": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"microblaze_0": {
|
||||
"vlnv": "xilinx.com:ip:microblaze:11.0",
|
||||
@@ -7104,8 +7234,8 @@
|
||||
"components": {
|
||||
"xbar": {
|
||||
"vlnv": "xilinx.com:ip:axi_crossbar:2.1",
|
||||
"xci_name": "microblaze_bd_xbar_5",
|
||||
"xci_path": "ip/microblaze_bd_xbar_5/microblaze_bd_xbar_5.xci",
|
||||
"xci_name": "microblaze_bd_xbar_8",
|
||||
"xci_path": "ip/microblaze_bd_xbar_8/microblaze_bd_xbar_8.xci",
|
||||
"inst_hier_path": "microblaze_0_axi_periph/xbar",
|
||||
"parameters": {
|
||||
"NUM_MI": {
|
||||
@@ -8429,6 +8559,12 @@
|
||||
"axi_iic_0/S_AXI"
|
||||
]
|
||||
},
|
||||
"axi_interconnect_1_M13_AXI": {
|
||||
"interface_ports": [
|
||||
"axi_interconnect_1/M13_AXI",
|
||||
"mdm_1/S_AXI"
|
||||
]
|
||||
},
|
||||
"axi_quad_spi_0_SPI_0": {
|
||||
"interface_ports": [
|
||||
"fmc_spi0",
|
||||
@@ -8758,9 +8894,9 @@
|
||||
"axi_ethernet_0_dma/m_axi_s2mm_aclk",
|
||||
"axi_interconnect_0/ACLK",
|
||||
"axi_interconnect_0/S00_ACLK",
|
||||
"axi_interconnect_0/M00_ACLK",
|
||||
"axi_interconnect_0/S01_ACLK",
|
||||
"axi_interconnect_0/S02_ACLK",
|
||||
"axi_interconnect_0/M00_ACLK",
|
||||
"rst_ddr/slowest_sync_clk"
|
||||
]
|
||||
},
|
||||
@@ -8825,6 +8961,12 @@
|
||||
"common1_qpll1_lock_out"
|
||||
]
|
||||
},
|
||||
"jesd_rx_sync_0": {
|
||||
"ports": [
|
||||
"jesd/jesd_rx_sync",
|
||||
"jesd_rx_sync"
|
||||
]
|
||||
},
|
||||
"mdm_1_debug_sys_rst": {
|
||||
"ports": [
|
||||
"mdm_1/Debug_SYS_Rst",
|
||||
@@ -8885,7 +9027,9 @@
|
||||
"microblaze_0_axi_periph/M09_ACLK",
|
||||
"microblaze_0_axi_periph/M10_ACLK",
|
||||
"rst_150/slowest_sync_clk",
|
||||
"system_management_wiz_0/s_axi_aclk"
|
||||
"system_management_wiz_0/s_axi_aclk",
|
||||
"axi_interconnect_1/M13_ACLK",
|
||||
"mdm_1/S_AXI_ACLK"
|
||||
]
|
||||
},
|
||||
"microblaze_0_intr": {
|
||||
@@ -8959,7 +9103,9 @@
|
||||
"microblaze_0_axi_periph/M08_ARESETN",
|
||||
"microblaze_0_axi_periph/M09_ARESETN",
|
||||
"microblaze_0_axi_periph/M10_ARESETN",
|
||||
"system_management_wiz_0/s_axi_aresetn"
|
||||
"system_management_wiz_0/s_axi_aresetn",
|
||||
"axi_interconnect_1/M13_ARESETN",
|
||||
"mdm_1/S_AXI_ARESETN"
|
||||
]
|
||||
},
|
||||
"rst_ddr_mb_reset": {
|
||||
@@ -8973,9 +9119,9 @@
|
||||
"rst_ddr/peripheral_aresetn",
|
||||
"axi_interconnect_0/ARESETN",
|
||||
"axi_interconnect_0/S00_ARESETN",
|
||||
"axi_interconnect_0/M00_ARESETN",
|
||||
"axi_interconnect_0/S01_ARESETN",
|
||||
"axi_interconnect_0/S02_ARESETN",
|
||||
"axi_interconnect_0/M00_ARESETN",
|
||||
"ddr4_0/c0_ddr4_aresetn"
|
||||
]
|
||||
},
|
||||
@@ -9033,6 +9179,12 @@
|
||||
"jesd/jesd_tx_core_reset"
|
||||
]
|
||||
},
|
||||
"tx_sync_0_1": {
|
||||
"ports": [
|
||||
"jesd_tx_sync",
|
||||
"jesd/jesd_tx_sync"
|
||||
]
|
||||
},
|
||||
"tx_sys_reset_0_1": {
|
||||
"ports": [
|
||||
"jesd_tx_sys_reset",
|
||||
@@ -9237,6 +9389,11 @@
|
||||
"offset": "0x40070000",
|
||||
"range": "64K"
|
||||
},
|
||||
"SEG_mdm_1_Reg": {
|
||||
"address_block": "/mdm_1/S_AXI/Reg",
|
||||
"offset": "0x41400000",
|
||||
"range": "4K"
|
||||
},
|
||||
"SEG_microblaze_0_axi_intc_Reg": {
|
||||
"address_block": "/microblaze_0_axi_intc/S_AXI/Reg",
|
||||
"offset": "0x40010000",
|
||||
|
||||
@@ -9,7 +9,9 @@ module digital_rx_chain #
|
||||
parameter START_SAMPLE_REG_ADDR = 32'h00000008,
|
||||
|
||||
parameter integer AXI_ADDR_WIDTH = 32,
|
||||
parameter integer AXI_DATA_WIDTH = 32
|
||||
parameter integer AXI_DATA_WIDTH = 32,
|
||||
parameter integer JESD_DATA_WIDTH = 64
|
||||
// parameter integer JESD_DATA_WIDTH = 32
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
@@ -21,8 +23,8 @@ module digital_rx_chain #
|
||||
|
||||
// Input Data
|
||||
input wire in_tvalid,
|
||||
input wire [63:0] in_tdata_i,
|
||||
input wire [63:0] in_tdata_q,
|
||||
input wire [JESD_DATA_WIDTH-1:0] in_tdata_i,
|
||||
input wire [JESD_DATA_WIDTH-1:0] in_tdata_q,
|
||||
|
||||
// Output Data
|
||||
axi4s_intf.master rx_out
|
||||
@@ -38,8 +40,8 @@ wire out_tstart_r;
|
||||
// ------------------------------
|
||||
reg in_tstart_reg;
|
||||
reg in_tvalid_reg;
|
||||
reg [63:0] in_tdata_i_reg;
|
||||
reg [63:0] in_tdata_q_reg;
|
||||
reg [JESD_DATA_WIDTH-1:0] in_tdata_i_reg;
|
||||
reg [JESD_DATA_WIDTH-1:0] in_tdata_q_reg;
|
||||
always @ (posedge clk) begin
|
||||
in_tstart_reg <= start_of_pulse;
|
||||
in_tvalid_reg <= in_tvalid;
|
||||
@@ -212,7 +214,6 @@ always @ (posedge clk) begin
|
||||
pulse_active_fed <= ~pulse_active && pulse_active_q;
|
||||
pulse_active_fed_q <= pulse_active_fed;
|
||||
|
||||
// if (in_tstart_reg && in_tvalid_reg) begin
|
||||
if (delay_active_fed && in_tvalid_reg) begin
|
||||
sample_cnt <= 0;
|
||||
pulse_active <= 1;
|
||||
@@ -236,7 +237,7 @@ assign out_tvalid_r = in_tvalid_reg && (pulse_active || delay_active_fed);
|
||||
// Buffer
|
||||
// ------------------------------
|
||||
axi4s_intf # (
|
||||
.AXI_DATA_WIDTH(128),
|
||||
.AXI_DATA_WIDTH(JESD_DATA_WIDTH * 2),
|
||||
.AXI_USER_WIDTH(1)
|
||||
)
|
||||
axis_odec_out (
|
||||
@@ -245,7 +246,7 @@ axi4s_intf # (
|
||||
);
|
||||
|
||||
axi4s_intf # (
|
||||
.AXI_DATA_WIDTH(128),
|
||||
.AXI_DATA_WIDTH(JESD_DATA_WIDTH * 2),
|
||||
.AXI_USER_WIDTH(1)
|
||||
)
|
||||
axis_pulse_buffer_out (
|
||||
@@ -266,6 +267,7 @@ assign axis_odec_out.tvalid = out_tvalid_r && (pulse_active || delay_active_fed)
|
||||
assign axis_odec_out.tlast = out_tlast_r;
|
||||
assign axis_odec_out.tuser = out_tstart_r;
|
||||
|
||||
//204C
|
||||
assign axis_odec_out.tdata[15:0] = in_tdata_i_reg[63:48];
|
||||
assign axis_odec_out.tdata[31:16] = in_tdata_q_reg[63:48];
|
||||
assign axis_odec_out.tdata[47:32] = in_tdata_i_reg[47:32];
|
||||
@@ -275,18 +277,6 @@ assign axis_odec_out.tdata[95:80] = in_tdata_q_reg[31:16];
|
||||
assign axis_odec_out.tdata[111:96] = in_tdata_i_reg[15:0];
|
||||
assign axis_odec_out.tdata[127:112] = in_tdata_q_reg[15:0];
|
||||
|
||||
//assign axis_odec_out.tdata[15:0] = in_tdata_i_reg[15:0];
|
||||
//assign axis_odec_out.tdata[31:16] = in_tdata_q_reg[15:0];
|
||||
//assign axis_odec_out.tdata[47:32] = in_tdata_i_reg[31:16];
|
||||
//assign axis_odec_out.tdata[63:48] = in_tdata_q_reg[31:16];
|
||||
//assign axis_odec_out.tdata[79:64] = in_tdata_i_reg[47:32];
|
||||
//assign axis_odec_out.tdata[95:80] = in_tdata_q_reg[47:32];
|
||||
//assign axis_odec_out.tdata[111:96] = in_tdata_i_reg[63:48];
|
||||
//assign axis_odec_out.tdata[127:112] = in_tdata_q_reg[63:48];
|
||||
|
||||
// assign axis_odec_out.tdata[63:0] = in_tdata_i_reg[63:0];
|
||||
// assign axis_odec_out.tdata[127:64] = in_tdata_q_reg[63:0];
|
||||
|
||||
pulse_buffer_fifo pulse_buffer_fifo_i (
|
||||
.s_axis_aresetn(~reset),
|
||||
.s_axis_aclk(clk),
|
||||
@@ -345,8 +335,33 @@ dig_rx_clock_converter dig_rx_clock_converter_i (
|
||||
.m_axis_tuser(rx_out.tuser)
|
||||
);
|
||||
|
||||
|
||||
//204B
|
||||
//assign axis_odec_out.tdata[15:0] = in_tdata_i_reg[31:16];
|
||||
//assign axis_odec_out.tdata[31:16] = in_tdata_q_reg[31:16];
|
||||
//assign axis_odec_out.tdata[47:32] = in_tdata_i_reg[15:0];
|
||||
//assign axis_odec_out.tdata[63:48] = in_tdata_q_reg[15:0];
|
||||
|
||||
|
||||
//pulse_buffer_204B_fifo pulse_buffer_fifo_i (
|
||||
// .s_axis_aresetn(~reset),
|
||||
// .s_axis_aclk(clk),
|
||||
|
||||
// .s_axis_tvalid(axis_odec_out.tvalid),
|
||||
// .s_axis_tready(),
|
||||
// .s_axis_tdata(axis_odec_out.tdata),
|
||||
// .s_axis_tlast(axis_odec_out.tlast),
|
||||
// .s_axis_tuser(axis_odec_out.tuser),
|
||||
|
||||
// .m_axis_aclk(rx_out.clk),
|
||||
// .m_axis_tvalid(rx_out.tvalid),
|
||||
// .m_axis_tready(rx_out.tready),
|
||||
// .m_axis_tdata(rx_out.tdata),
|
||||
// .m_axis_tlast(rx_out.tlast),
|
||||
// .m_axis_tuser(rx_out.tuser)
|
||||
//);
|
||||
|
||||
assign rx_out.tkeep = '1;
|
||||
// assign rx_out.tuser = reg_num_samples;
|
||||
assign rx_out.tdest = 1;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -115,8 +115,16 @@ module top #
|
||||
input wire jesd_sysref_p,
|
||||
input wire jesd_sysref_n,
|
||||
|
||||
input wire jesd_sync_in_p,
|
||||
input wire jesd_sync_in_n,
|
||||
|
||||
output wire jesd_sync_out_p,
|
||||
output wire jesd_sync_out_n,
|
||||
|
||||
input wire jesd_core_clk_p,
|
||||
input wire jesd_core_clk_n,
|
||||
// input wire jesd_core_clk2_p,
|
||||
// input wire jesd_core_clk2_n,
|
||||
|
||||
input wire jesd_qpll0_refclk_p,
|
||||
input wire jesd_qpll0_refclk_n,
|
||||
@@ -168,20 +176,26 @@ module top #
|
||||
wire jesd_axis_rx_cmd_tready;
|
||||
wire [7:0]jesd_axis_rx_cmd_tuser;
|
||||
wire jesd_axis_rx_cmd_tvalid;
|
||||
wire [511:0]jesd_axis_rx_tdata;
|
||||
wire jesd_axis_rx_tvalid;
|
||||
wire [255:0]jesd_axis_tx_cmd_tdata;
|
||||
wire jesd_axis_tx_cmd_tready;
|
||||
wire jesd_axis_tx_cmd_tvalid;
|
||||
wire [511:0]jesd_axis_tx_tdata;
|
||||
wire jesd_axis_tx_tready;
|
||||
|
||||
// 204C
|
||||
wire [511:0]jesd_axis_tx_tdata;
|
||||
wire [511:0]jesd_axis_rx_tdata;
|
||||
//204B
|
||||
// wire [255:0]jesd_axis_tx_tdata;
|
||||
// wire [255:0]jesd_axis_rx_tdata;
|
||||
|
||||
wire jesd_rx_core_reset;
|
||||
wire jesd_rx_sys_reset;
|
||||
wire jesd_tx_core_reset;
|
||||
wire jesd_tx_sys_reset;
|
||||
wire jesd_core_clk;
|
||||
wire jesd_core_clk_in;
|
||||
wire jesd_core_clk2_in;
|
||||
|
||||
wire [14:0] dac0_wf_bram_addr;
|
||||
wire dac0_wf_bram_clk;
|
||||
@@ -234,10 +248,55 @@ module top #
|
||||
.O (jesd_core_clk_in)
|
||||
);
|
||||
|
||||
// IBUFDS #(
|
||||
// .DIFF_TERM("TRUE"), // Differential Termination
|
||||
// .IBUF_LOW_PWR("FALSE"), // Low power="TRUE", Highest performance="FALSE"
|
||||
// .IOSTANDARD("LVDS") // Specify the input I/O standard
|
||||
// ) core_clk2_ibufds_c (
|
||||
// .I (jesd_core_clk2_p),
|
||||
// .IB (jesd_core_clk2_n),
|
||||
// .O (jesd_core_clk2_in)
|
||||
// );
|
||||
|
||||
BUFG BUFG_inst (
|
||||
.O(jesd_core_clk),
|
||||
.I(jesd_core_clk_in)
|
||||
);
|
||||
);
|
||||
|
||||
wire jesd_core_clk_locked;
|
||||
|
||||
// jesd_core_clk_wiz jesd_core_clk_wiz
|
||||
// (
|
||||
// .clk_out1(jesd_core_clk),
|
||||
//// .clk_in_sel(jesd_clk_sel),
|
||||
// .locked(jesd_core_clk_locked),
|
||||
//// .clk_in1_p(jesd_core_clk_p),
|
||||
//// .clk_in1_n(jesd_core_clk_n),
|
||||
//// .clk_in2_p(jesd_core_clk2_p),
|
||||
//// .clk_in2_n(jesd_core_clk2_n)
|
||||
// .clk_in1(jesd_core_clk_in)
|
||||
//// .clk_in2(jesd_core_clk2_in)
|
||||
// );
|
||||
|
||||
|
||||
|
||||
wire jesd_sync_in;
|
||||
IBUFDS #(
|
||||
.DIFF_TERM("TRUE"), // Differential Termination
|
||||
.IBUF_LOW_PWR("FALSE"), // Low power="TRUE", Highest performance="FALSE"
|
||||
.IOSTANDARD("LVDS") // Specify the input I/O standard
|
||||
) jesd_sync_in_ibufds (
|
||||
.I (jesd_sync_in_p),
|
||||
.IB (jesd_sync_in_n),
|
||||
.O (jesd_sync_in)
|
||||
);
|
||||
|
||||
wire jesd_sync_out;
|
||||
OBUFDS jesd_sync_out_ibufds (
|
||||
.O (jesd_sync_out_p),
|
||||
.OB (jesd_sync_out_n),
|
||||
.I (jesd_sync_out)
|
||||
);
|
||||
|
||||
IOBUF mdio_mdio_iobuf
|
||||
(.I(mdio_mdio_o),
|
||||
@@ -579,15 +638,8 @@ module top #
|
||||
.common1_qpll1_lock_out(common1_qpll1_lock_out),
|
||||
.jesd_axis_tx_aresetn(jesd_axis_tx_aresetn),
|
||||
.jesd_axis_rx_aresetn(jesd_axis_rx_aresetn),
|
||||
.jesd_axis_rx_cmd_tdata(jesd_axis_rx_cmd_tdata),
|
||||
.jesd_axis_rx_cmd_tready(jesd_axis_rx_cmd_tready),
|
||||
.jesd_axis_rx_cmd_tuser(jesd_axis_rx_cmd_tuser),
|
||||
.jesd_axis_rx_cmd_tvalid(jesd_axis_rx_cmd_tvalid),
|
||||
.jesd_axis_rx_tdata(jesd_axis_rx_tdata),
|
||||
.jesd_axis_rx_tvalid(jesd_axis_rx_tvalid),
|
||||
.jesd_axis_tx_cmd_tdata(jesd_axis_tx_cmd_tdata),
|
||||
.jesd_axis_tx_cmd_tready(jesd_axis_tx_cmd_tready),
|
||||
.jesd_axis_tx_cmd_tvalid(jesd_axis_tx_cmd_tvalid),
|
||||
.jesd_axis_tx_tdata(jesd_axis_tx_tdata),
|
||||
.jesd_axis_tx_tready(jesd_axis_tx_tready),
|
||||
.jesd_qpll0_refclk_clk_n(jesd_qpll0_refclk_n),
|
||||
@@ -604,6 +656,17 @@ module top #
|
||||
.jesd_rx_sys_reset(jesd_rx_sys_reset),
|
||||
.jesd_core_clk(jesd_core_clk),
|
||||
|
||||
.jesd_axis_rx_cmd_tdata(jesd_axis_rx_cmd_tdata),
|
||||
.jesd_axis_rx_cmd_tready(jesd_axis_rx_cmd_tready),
|
||||
.jesd_axis_rx_cmd_tuser(jesd_axis_rx_cmd_tuser),
|
||||
.jesd_axis_rx_cmd_tvalid(jesd_axis_rx_cmd_tvalid),
|
||||
.jesd_axis_tx_cmd_tdata(jesd_axis_tx_cmd_tdata),
|
||||
.jesd_axis_tx_cmd_tready(jesd_axis_tx_cmd_tready),
|
||||
.jesd_axis_tx_cmd_tvalid(jesd_axis_tx_cmd_tvalid),
|
||||
|
||||
// .jesd_tx_sync(jesd_sync_in),
|
||||
// .jesd_rx_sync(jesd_sync_out),
|
||||
|
||||
.eth_clk(eth_clk[0]),
|
||||
.eth_resetn(eth_resetn[0]),
|
||||
.udp_rx_tdata(rx_udp_axis[0].tdata),
|
||||
@@ -661,7 +724,9 @@ module top #
|
||||
wire eth_reset;
|
||||
|
||||
|
||||
assign leds = gpo[3:0];
|
||||
assign leds[1:0] = gpo[1:0];
|
||||
assign leds[2] = 0;
|
||||
assign leds[3] = jesd_core_clk_locked;
|
||||
assign fmc_power_en = gpo[4];
|
||||
assign resetb = gpo[5];
|
||||
assign jesd_rx_core_reset = gpo[6];
|
||||
@@ -669,11 +734,13 @@ module top #
|
||||
assign jesd_rx_sys_reset = gpo[8];
|
||||
assign jesd_tx_sys_reset = gpo[9];
|
||||
assign qspi_flash_aresetn = ~gpo[10];
|
||||
assign jesd_clk_sel = gpo[11];
|
||||
assign eth_reset = gpo[15];
|
||||
|
||||
assign gpi[31:3] = 0;
|
||||
assign gpi[31:4] = 0;
|
||||
// assign gpi[31] = start_of_cpi;
|
||||
// assign gpi[30] = start_of_pulse;
|
||||
assign gpi[3] = jesd_core_clk_locked;
|
||||
assign gpi[2] = common1_qpll1_lock_out;
|
||||
assign gpi[1] = common0_qpll1_lock_out;
|
||||
assign gpi[0] = ddr_init_calib_complete;
|
||||
@@ -806,6 +873,8 @@ module top #
|
||||
.in_tvalid(jesd_axis_rx_tvalid),
|
||||
.in_tdata_i(jesd_axis_rx_tdata[i*128+63 :i*128+0]),
|
||||
.in_tdata_q(jesd_axis_rx_tdata[i*128+127 :i*128+64]),
|
||||
// .in_tdata_i(jesd_axis_rx_tdata[i*64+31 :i*64+0]),
|
||||
// .in_tdata_q(jesd_axis_rx_tdata[i*64+63 :i*64+32]),
|
||||
|
||||
.rx_out(rx_axis[i])
|
||||
);
|
||||
|
||||
@@ -53,6 +53,7 @@ module waveform_gen #
|
||||
|
||||
|
||||
output wire [511:0] jesd_tx
|
||||
// output wire [255:0] jesd_tx
|
||||
);
|
||||
|
||||
|
||||
@@ -179,6 +180,9 @@ reg delay_active_fed;
|
||||
|
||||
reg [255:0] jesd_out_reg;
|
||||
reg [255:0] all_brams_out;
|
||||
//reg [127:0] jesd_out_reg;
|
||||
//reg [127:0] all_brams_out;
|
||||
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset == 1'b1) begin
|
||||
@@ -248,24 +252,12 @@ always @ (posedge clk) begin
|
||||
end
|
||||
|
||||
|
||||
//assign all_brams_out[16*0+15 + 384 : 16*0 + 384] = dac3_bram_dout[16*6+15:16*6];
|
||||
//assign all_brams_out[16*1+15 + 384 : 16*1 + 384] = dac3_bram_dout[16*4+15:16*4];
|
||||
//assign all_brams_out[16*2+15 + 384 : 16*2 + 384] = dac3_bram_dout[16*2+15:16*2];
|
||||
//assign all_brams_out[16*3+15 + 384 : 16*3 + 384] = dac3_bram_dout[16*0+15:16*0];
|
||||
//assign all_brams_out[16*4+15 + 384 : 16*4 + 384] = dac3_bram_dout[16*7+15:16*7];
|
||||
//assign all_brams_out[16*5+15 + 384 : 16*5 + 384] = dac3_bram_dout[16*5+15:16*5];
|
||||
//assign all_brams_out[16*6+15 + 384 : 16*6 + 384] = dac3_bram_dout[16*3+15:16*3];
|
||||
//assign all_brams_out[16*7+15 + 384 : 16*7 + 384] = dac3_bram_dout[16*1+15:16*1];
|
||||
|
||||
//assign all_brams_out[16*0+15 + 256 : 16*0 + 256] = dac2_bram_dout[16*6+15:16*6];
|
||||
//assign all_brams_out[16*1+15 + 256 : 16*1 + 256] = dac2_bram_dout[16*4+15:16*4];
|
||||
//assign all_brams_out[16*2+15 + 256 : 16*2 + 256] = dac2_bram_dout[16*2+15:16*2];
|
||||
//assign all_brams_out[16*3+15 + 256 : 16*3 + 256] = dac2_bram_dout[16*0+15:16*0];
|
||||
//assign all_brams_out[16*4+15 + 256 : 16*4 + 256] = dac2_bram_dout[16*7+15:16*7];
|
||||
//assign all_brams_out[16*5+15 + 256 : 16*5 + 256] = dac2_bram_dout[16*5+15:16*5];
|
||||
//assign all_brams_out[16*6+15 + 256 : 16*6 + 256] = dac2_bram_dout[16*3+15:16*3];
|
||||
//assign all_brams_out[16*7+15 + 256 : 16*7 + 256] = dac2_bram_dout[16*1+15:16*1];
|
||||
|
||||
|
||||
assign dac1_bram_addr = dac0_bram_addr;
|
||||
|
||||
|
||||
// 204C
|
||||
// remap data for easier software loading of BRAMs
|
||||
assign all_brams_out[16*0+15 + 128 : 16*0 + 128] = dac1_bram_dout[16*6+15:16*6];
|
||||
assign all_brams_out[16*1+15 + 128 : 16*1 + 128] = dac1_bram_dout[16*4+15:16*4];
|
||||
assign all_brams_out[16*2+15 + 128 : 16*2 + 128] = dac1_bram_dout[16*2+15:16*2];
|
||||
@@ -284,11 +276,6 @@ assign all_brams_out[16*5+15 + 0 : 16*5 + 0] = dac0_bram_dout[16*5+15:16*5
|
||||
assign all_brams_out[16*6+15 + 0 : 16*6 + 0] = dac0_bram_dout[16*3+15:16*3];
|
||||
assign all_brams_out[16*7+15 + 0 : 16*7 + 0] = dac0_bram_dout[16*1+15:16*1];
|
||||
|
||||
assign dac1_bram_addr = dac0_bram_addr;
|
||||
//assign dac2_bram_addr = dac0_bram_addr;
|
||||
//assign dac3_bram_addr = dac0_bram_addr;
|
||||
|
||||
|
||||
// dac2 and dac3 are used for LOs, so just need a constant 1 + j0 output. The NCO
|
||||
// inside the AD9081 will be used to turn this into a tone
|
||||
|
||||
@@ -296,6 +283,23 @@ assign jesd_tx[511:384] = {16'h0000, 16'h0000, 16'h0000, 16'h0000, 16'h7FFF, 16'
|
||||
assign jesd_tx[383:256] = {16'h0000, 16'h0000, 16'h0000, 16'h0000, 16'h7FFF, 16'h7FFF, 16'h7FFF, 16'h7FFF};
|
||||
assign jesd_tx[255:0] = jesd_out_reg;
|
||||
|
||||
//204B
|
||||
|
||||
//assign all_brams_out[16*0+15 + 64 : 16*0 + 64] = dac1_bram_dout[16*2+15:16*2];
|
||||
//assign all_brams_out[16*1+15 + 64 : 16*1 + 64] = dac1_bram_dout[16*0+15:16*0];
|
||||
//assign all_brams_out[16*2+15 + 64 : 16*2 + 64] = dac1_bram_dout[16*3+15:16*3];
|
||||
//assign all_brams_out[16*3+15 + 64 : 16*3 + 64] = dac1_bram_dout[16*1+15:16*1];
|
||||
|
||||
//assign all_brams_out[16*0+15 + 0 : 16*0 + 0] = dac0_bram_dout[16*2+15:16*2];
|
||||
//assign all_brams_out[16*1+15 + 0 : 16*1 + 0] = dac0_bram_dout[16*0+15:16*0];
|
||||
//assign all_brams_out[16*2+15 + 0 : 16*2 + 0] = dac0_bram_dout[16*3+15:16*3];
|
||||
//assign all_brams_out[16*3+15 + 0 : 16*3 + 0] = dac0_bram_dout[16*1+15:16*1];
|
||||
|
||||
//assign jesd_tx[255:192] = {16'h0000, 16'h0000, 16'h7FFF, 16'h7FFF};
|
||||
//assign jesd_tx[191:128] = {16'h0000, 16'h0000, 16'h7FFF, 16'h7FFF};
|
||||
//assign jesd_tx[127:0] = jesd_out_reg;
|
||||
|
||||
|
||||
wf_memory dac0_wf_mem (
|
||||
.clka(dac0_wf_bram_clk),
|
||||
.ena(dac0_wf_bram_en),
|
||||
@@ -327,38 +331,7 @@ wf_memory dac1_wf_mem (
|
||||
.dinb(0),
|
||||
.doutb(dac1_bram_dout)
|
||||
);
|
||||
|
||||
//wf_memory dac2_wf_mem (
|
||||
// .clka(dac2_wf_bram_clk),
|
||||
// .ena(dac2_wf_bram_en),
|
||||
// .wea(dac2_wf_bram_we),
|
||||
// .addra(dac2_wf_bram_addr[14:2]),
|
||||
// .dina(dac2_wf_bram_din),
|
||||
// .douta(dac2_wf_bram_dout),
|
||||
|
||||
// .clkb(clk),
|
||||
// .enb(1'b1),
|
||||
// .web(1'b0),
|
||||
// .addrb(dac2_bram_addr),
|
||||
// .dinb(0),
|
||||
// .doutb(dac2_bram_dout)
|
||||
//);
|
||||
|
||||
//wf_memory dac3_wf_mem (
|
||||
// .clka(dac3_wf_bram_clk),
|
||||
// .ena(dac3_wf_bram_en),
|
||||
// .wea(dac3_wf_bram_we),
|
||||
// .addra(dac3_wf_bram_addr[14:2]),
|
||||
// .dina(dac3_wf_bram_din),
|
||||
// .douta(dac3_wf_bram_dout),
|
||||
|
||||
// .clkb(clk),
|
||||
// .enb(1'b1),
|
||||
// .web(1'b0),
|
||||
// .addrb(dac3_bram_addr),
|
||||
// .dinb(0),
|
||||
// .doutb(dac3_bram_dout)
|
||||
//);
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -350,9 +350,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -830,9 +830,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -830,9 +830,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -166,9 +166,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,658 @@
|
||||
{
|
||||
"schema": "xilinx.com:schema:json_instance:1.0",
|
||||
"ip_inst": {
|
||||
"xci_name": "jesd_core_clk_wiz",
|
||||
"component_reference": "xilinx.com:ip:clk_wiz:6.0",
|
||||
"ip_revision": "11",
|
||||
"gen_directory": "../../../../radar_alinx_kintex.gen/sources_1/ip/jesd_core_clk_wiz",
|
||||
"parameters": {
|
||||
"component_parameters": {
|
||||
"Component_Name": [ { "value": "jesd_core_clk_wiz", "resolve_type": "user", "usage": "all" } ],
|
||||
"USER_CLK_FREQ0": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"USER_CLK_FREQ1": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"USER_CLK_FREQ2": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"USER_CLK_FREQ3": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"ENABLE_CLOCK_MONITOR": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"OPTIMIZE_CLOCKING_STRUCTURE_EN": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"ENABLE_USER_CLOCK0": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"ENABLE_USER_CLOCK1": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"ENABLE_USER_CLOCK2": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"ENABLE_USER_CLOCK3": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"Enable_PLL0": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"Enable_PLL1": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"REF_CLK_FREQ": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PRECISION": [ { "value": "1", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PRIMITIVE": [ { "value": "Auto", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"PRIMTYPE_SEL": [ { "value": "mmcm_adv", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLOCK_MGR_TYPE": [ { "value": "auto", "resolve_type": "user", "usage": "all" } ],
|
||||
"USE_FREQ_SYNTH": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_SPREAD_SPECTRUM": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_PHASE_ALIGNMENT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_MIN_POWER": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_DYN_PHASE_SHIFT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_DYN_RECONFIG": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"JITTER_SEL": [ { "value": "No_Jitter", "resolve_type": "user", "usage": "all" } ],
|
||||
"PRIM_IN_FREQ": [ { "value": "187.5", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PRIM_IN_TIMEPERIOD": [ { "value": "10.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"IN_FREQ_UNITS": [ { "value": "Units_MHz", "resolve_type": "user", "usage": "all" } ],
|
||||
"PHASESHIFT_MODE": [ { "value": "WAVEFORM", "resolve_type": "user", "usage": "all" } ],
|
||||
"IN_JITTER_UNITS": [ { "value": "Units_UI", "resolve_type": "user", "usage": "all" } ],
|
||||
"RELATIVE_INCLK": [ { "value": "REL_PRIMARY", "resolve_type": "user", "usage": "all" } ],
|
||||
"USE_INCLK_SWITCHOVER": [ { "value": "false", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"SECONDARY_IN_FREQ": [ { "value": "187.5", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"SECONDARY_IN_TIMEPERIOD": [ { "value": "10.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"SECONDARY_PORT": [ { "value": "clk_in2", "resolve_type": "user", "usage": "all" } ],
|
||||
"SECONDARY_SOURCE": [ { "value": "Global_buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"JITTER_OPTIONS": [ { "value": "UI", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKIN1_UI_JITTER": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKIN2_UI_JITTER": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PRIM_IN_JITTER": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"SECONDARY_IN_JITTER": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKIN1_JITTER_PS": [ { "value": "53.330000000000005", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKIN2_JITTER_PS": [ { "value": "53.330000000000005", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT1_USED": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT2_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT3_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT4_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT5_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT6_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT7_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"NUM_OUT_CLKS": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLK_OUT1_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_OUT2_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_OUT3_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_OUT4_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_OUT5_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_OUT6_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_OUT7_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"PRIMARY_PORT": [ { "value": "clk_in1", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT1_PORT": [ { "value": "clk_out1", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT2_PORT": [ { "value": "clk_out2", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT3_PORT": [ { "value": "clk_out3", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT4_PORT": [ { "value": "clk_out4", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT5_PORT": [ { "value": "clk_out5", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT6_PORT": [ { "value": "clk_out6", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_OUT7_PORT": [ { "value": "clk_out7", "resolve_type": "user", "usage": "all" } ],
|
||||
"DADDR_PORT": [ { "value": "daddr", "resolve_type": "user", "usage": "all" } ],
|
||||
"DCLK_PORT": [ { "value": "dclk", "resolve_type": "user", "usage": "all" } ],
|
||||
"DRDY_PORT": [ { "value": "drdy", "resolve_type": "user", "usage": "all" } ],
|
||||
"DWE_PORT": [ { "value": "dwe", "resolve_type": "user", "usage": "all" } ],
|
||||
"DIN_PORT": [ { "value": "din", "resolve_type": "user", "usage": "all" } ],
|
||||
"DOUT_PORT": [ { "value": "dout", "resolve_type": "user", "usage": "all" } ],
|
||||
"DEN_PORT": [ { "value": "den", "resolve_type": "user", "usage": "all" } ],
|
||||
"PSCLK_PORT": [ { "value": "psclk", "resolve_type": "user", "usage": "all" } ],
|
||||
"PSEN_PORT": [ { "value": "psen", "resolve_type": "user", "usage": "all" } ],
|
||||
"PSINCDEC_PORT": [ { "value": "psincdec", "resolve_type": "user", "usage": "all" } ],
|
||||
"PSDONE_PORT": [ { "value": "psdone", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT1_REQUESTED_OUT_FREQ": [ { "value": "187.5", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT1_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT1_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT2_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT2_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT2_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT3_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT3_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT3_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT4_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT4_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT4_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT5_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT5_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT5_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT6_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT6_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT6_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT7_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT7_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT7_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"USE_MAX_I_JITTER": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_MIN_O_JITTER": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT1_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT2_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT3_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT4_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT5_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT6_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT7_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"PRIM_SOURCE": [ { "value": "Global_buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT1_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT2_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT3_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT4_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT5_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT6_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKOUT7_DRIVES": [ { "value": "Buffer", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"FEEDBACK_SOURCE": [ { "value": "FDBK_AUTO", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_IN_SIGNALING": [ { "value": "SINGLE", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_IN_PORT": [ { "value": "clkfb_in", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_IN_P_PORT": [ { "value": "clkfb_in_p", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_IN_N_PORT": [ { "value": "clkfb_in_n", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_OUT_PORT": [ { "value": "clkfb_out", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_OUT_P_PORT": [ { "value": "clkfb_out_p", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_OUT_N_PORT": [ { "value": "clkfb_out_n", "resolve_type": "user", "usage": "all" } ],
|
||||
"PLATFORM": [ { "value": "UNKNOWN", "resolve_type": "user", "usage": "all" } ],
|
||||
"SUMMARY_STRINGS": [ { "value": "empty", "resolve_type": "user", "usage": "all" } ],
|
||||
"USE_LOCKED": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CALC_DONE": [ { "value": "empty", "resolve_type": "user", "usage": "all" } ],
|
||||
"USE_RESET": [ { "value": "false", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_POWER_DOWN": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_STATUS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_FREEZE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_CLK_VALID": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_INCLK_STOPPED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_CLKFB_STOPPED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"RESET_PORT": [ { "value": "reset", "resolve_type": "user", "usage": "all" } ],
|
||||
"LOCKED_PORT": [ { "value": "locked", "resolve_type": "user", "usage": "all" } ],
|
||||
"POWER_DOWN_PORT": [ { "value": "power_down", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_VALID_PORT": [ { "value": "CLK_VALID", "resolve_type": "user", "usage": "all" } ],
|
||||
"STATUS_PORT": [ { "value": "STATUS", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_IN_SEL_PORT": [ { "value": "clk_in_sel", "resolve_type": "user", "usage": "all" } ],
|
||||
"INPUT_CLK_STOPPED_PORT": [ { "value": "input_clk_stopped", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLKFB_STOPPED_PORT": [ { "value": "clkfb_stopped", "resolve_type": "user", "usage": "all" } ],
|
||||
"SS_MODE": [ { "value": "CENTER_HIGH", "resolve_type": "user", "usage": "all" } ],
|
||||
"SS_MOD_FREQ": [ { "value": "250", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"SS_MOD_TIME": [ { "value": "0.004", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"OVERRIDE_MMCM": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_NOTES": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
|
||||
"MMCM_DIVCLK_DIVIDE": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_BANDWIDTH": [ { "value": "OPTIMIZED", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"MMCM_CLKFBOUT_MULT_F": [ { "value": "4", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKFBOUT_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKIN1_PERIOD": [ { "value": "5.333", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKIN2_PERIOD": [ { "value": "5.333", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT4_CASCADE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLOCK_HOLD": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_COMPENSATION": [ { "value": "AUTO", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"MMCM_REF_JITTER1": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_REF_JITTER2": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_STARTUP_WAIT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT0_DIVIDE_F": [ { "value": "4", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT0_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT0_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT1_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_CLKOUT1_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT1_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT2_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_CLKOUT2_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT2_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT3_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_CLKOUT3_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT3_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_CLKOUT4_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT4_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_CLKOUT5_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT5_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"MMCM_CLKOUT6_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"MMCM_CLKOUT6_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"MMCM_CLKOUT6_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"OVERRIDE_PLL": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"PLL_NOTES": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
|
||||
"PLL_BANDWIDTH": [ { "value": "OPTIMIZED", "resolve_type": "user", "usage": "all" } ],
|
||||
"PLL_CLKFBOUT_MULT": [ { "value": "4", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLK_FEEDBACK": [ { "value": "CLKFBOUT", "resolve_type": "user", "usage": "all" } ],
|
||||
"PLL_DIVCLK_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKIN_PERIOD": [ { "value": "10.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_COMPENSATION": [ { "value": "SYSTEM_SYNCHRONOUS", "resolve_type": "user", "usage": "all" } ],
|
||||
"PLL_REF_JITTER": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT0_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKOUT0_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT1_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKOUT1_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT2_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKOUT2_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT3_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKOUT3_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKOUT4_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PLL_CLKOUT5_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"PLL_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"RESET_TYPE": [ { "value": "ACTIVE_HIGH", "resolve_type": "user", "usage": "all" } ],
|
||||
"USE_SAFE_CLOCK_STARTUP": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"USE_CLOCK_SEQUENCING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUT1_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLKOUT2_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLKOUT3_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLKOUT4_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLKOUT5_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLKOUT6_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"CLKOUT7_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"USE_BOARD_FLOW": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLK_IN1_BOARD_INTERFACE": [ { "value": "Custom", "resolve_type": "user", "usage": "all" } ],
|
||||
"CLK_IN2_BOARD_INTERFACE": [ { "value": "Custom", "resolve_type": "user", "usage": "all" } ],
|
||||
"DIFF_CLK_IN1_BOARD_INTERFACE": [ { "value": "Custom", "resolve_type": "user", "usage": "all" } ],
|
||||
"DIFF_CLK_IN2_BOARD_INTERFACE": [ { "value": "Custom", "resolve_type": "user", "usage": "all" } ],
|
||||
"AUTO_PRIMITIVE": [ { "value": "PLL", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||
"RESET_BOARD_INTERFACE": [ { "value": "Custom", "resolve_type": "user", "usage": "all" } ],
|
||||
"ENABLE_CDDC": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CDDCDONE_PORT": [ { "value": "cddcdone", "resolve_type": "user", "usage": "all" } ],
|
||||
"CDDCREQ_PORT": [ { "value": "cddcreq", "resolve_type": "user", "usage": "all" } ],
|
||||
"ENABLE_CLKOUTPHY": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"CLKOUTPHY_REQUESTED_FREQ": [ { "value": "600.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT1_JITTER": [ { "value": "103.275", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT1_PHASE_ERROR": [ { "value": "101.676", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT2_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT2_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT3_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT3_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT4_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT4_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT5_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT5_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT6_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT6_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT7_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"CLKOUT7_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||
"INPUT_MODE": [ { "value": "frequency", "resolve_type": "user", "usage": "all" } ],
|
||||
"INTERFACE_SELECTION": [ { "value": "Enable_AXI", "resolve_type": "user", "usage": "all" } ],
|
||||
"AXI_DRP": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||
"PHASE_DUTY_CONFIG": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ]
|
||||
},
|
||||
"model_parameters": {
|
||||
"C_CLKOUT2_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USER_CLK_FREQ0": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_AUTO_PRIMITIVE": [ { "value": "PLL", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_USER_CLK_FREQ1": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_USER_CLK_FREQ2": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_USER_CLK_FREQ3": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_ENABLE_CLOCK_MONITOR": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_ENABLE_USER_CLOCK0": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_ENABLE_USER_CLOCK1": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_ENABLE_USER_CLOCK2": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_ENABLE_USER_CLOCK3": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_Enable_PLL0": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_Enable_PLL1": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_REF_CLK_FREQ": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PRECISION": [ { "value": "1", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT4_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT5_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT6_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT7_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_CLKOUT1_BAR": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_CLKOUT2_BAR": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_CLKOUT3_BAR": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_CLKOUT4_BAR": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"c_component_name": [ { "value": "jesd_core_clk_wiz", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLATFORM": [ { "value": "UNKNOWN", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_USE_FREQ_SYNTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_PHASE_ALIGNMENT": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PRIM_IN_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_SECONDARY_IN_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_JITTER_SEL": [ { "value": "No_Jitter", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_USE_MIN_POWER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_MIN_O_JITTER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_MAX_I_JITTER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_DYN_PHASE_SHIFT": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_OPTIMIZE_CLOCKING_STRUCTURE_EN": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_INCLK_SWITCHOVER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_DYN_RECONFIG": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_SPREAD_SPECTRUM": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_FAST_SIMULATION": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PRIMTYPE_SEL": [ { "value": "AUTO", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_USE_CLK_VALID": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PRIM_IN_FREQ": [ { "value": "187.5", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PRIM_IN_TIMEPERIOD": [ { "value": "10.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_IN_FREQ_UNITS": [ { "value": "Units_MHz", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_SECONDARY_IN_FREQ": [ { "value": "187.5", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_SECONDARY_IN_TIMEPERIOD": [ { "value": "10.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_FEEDBACK_SOURCE": [ { "value": "FDBK_AUTO", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PRIM_SOURCE": [ { "value": "Global_buffer", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PHASESHIFT_MODE": [ { "value": "WAVEFORM", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_SECONDARY_SOURCE": [ { "value": "Global_buffer", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_IN_SIGNALING": [ { "value": "SINGLE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_USE_RESET": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_RESET_LOW": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_LOCKED": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_INCLK_STOPPED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_CLKFB_STOPPED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_POWER_DOWN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_STATUS": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_FREEZE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_NUM_OUT_CLKS": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT1_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT2_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT3_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT4_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT5_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT6_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT7_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_INCLK_SUM_ROW0": [ { "value": "Input Clock Freq (MHz) Input Jitter (UI)", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_INCLK_SUM_ROW1": [ { "value": "__primary___________187.5____________0.010", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_INCLK_SUM_ROW2": [ { "value": "no_secondary_input_clock ", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW0A": [ { "value": " Output Output Phase Duty Cycle Pk-to-Pk Phase", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW0B": [ { "value": " Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW1": [ { "value": "clk_out1__187.50000______0.000______50.0______103.275____101.676", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW2": [ { "value": "no_CLK_OUT2_output", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW3": [ { "value": "no_CLK_OUT3_output", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW4": [ { "value": "no_CLK_OUT4_output", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW5": [ { "value": "no_CLK_OUT5_output", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW6": [ { "value": "no_CLK_OUT6_output", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OUTCLK_SUM_ROW7": [ { "value": "no_CLK_OUT7_output", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT1_REQUESTED_OUT_FREQ": [ { "value": "187.5", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT2_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT4_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT5_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT6_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT7_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT1_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT2_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT4_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT5_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT6_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT7_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT1_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT2_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT4_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT5_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT6_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT7_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT1_OUT_FREQ": [ { "value": "187.50000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT2_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT4_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT5_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT6_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT7_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT7_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT1_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT2_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT3_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT4_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT5_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT6_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKOUT7_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_USE_SAFE_CLOCK_STARTUP": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_USE_CLOCK_SEQUENCING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT1_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT2_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT3_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT4_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT5_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT6_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CLKOUT7_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_NOTES": [ { "value": "None", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_BANDWIDTH": [ { "value": "OPTIMIZED", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKFBOUT_MULT_F": [ { "value": "4.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKIN1_PERIOD": [ { "value": "5.333", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKIN2_PERIOD": [ { "value": "5.333", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT4_CASCADE": [ { "value": "FALSE", "resolve_type": "generated", "format": "bool", "usage": "all" } ],
|
||||
"C_MMCM_CLOCK_HOLD": [ { "value": "FALSE", "resolve_type": "generated", "format": "bool", "usage": "all" } ],
|
||||
"C_MMCM_COMPENSATION": [ { "value": "AUTO", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_DIVCLK_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_REF_JITTER1": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_REF_JITTER2": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_STARTUP_WAIT": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT0_DIVIDE_F": [ { "value": "4.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT1_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT2_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT3_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT6_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT0_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT1_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT2_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT3_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT4_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT5_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT6_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_MMCM_CLKFBOUT_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT0_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT1_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT2_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT3_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT4_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT5_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCM_CLKOUT6_USE_FINE_PS": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLL_NOTES": [ { "value": "No notes", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLL_BANDWIDTH": [ { "value": "OPTIMIZED", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLL_CLK_FEEDBACK": [ { "value": "CLKFBOUT", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLL_CLKFBOUT_MULT": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKIN_PERIOD": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_COMPENSATION": [ { "value": "SYSTEM_SYNCHRONOUS", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLL_DIVCLK_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_REF_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT0_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT1_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT2_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT3_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT0_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT1_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT2_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT3_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT4_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT5_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PLL_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLOCK_MGR_TYPE": [ { "value": "NA", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_OVERRIDE_MMCM": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_OVERRIDE_PLL": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PRIMARY_PORT": [ { "value": "clk_in1", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_SECONDARY_PORT": [ { "value": "clk_in2", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT1_PORT": [ { "value": "clk_out1", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT2_PORT": [ { "value": "clk_out2", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT3_PORT": [ { "value": "clk_out3", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT4_PORT": [ { "value": "clk_out4", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT5_PORT": [ { "value": "clk_out5", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT6_PORT": [ { "value": "clk_out6", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_OUT7_PORT": [ { "value": "clk_out7", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_RESET_PORT": [ { "value": "reset", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_LOCKED_PORT": [ { "value": "locked", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_IN_PORT": [ { "value": "clkfb_in", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_IN_P_PORT": [ { "value": "clkfb_in_p", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_IN_N_PORT": [ { "value": "clkfb_in_n", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_OUT_PORT": [ { "value": "clkfb_out", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_OUT_P_PORT": [ { "value": "clkfb_out_p", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_OUT_N_PORT": [ { "value": "clkfb_out_n", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_POWER_DOWN_PORT": [ { "value": "power_down", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DADDR_PORT": [ { "value": "daddr", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DCLK_PORT": [ { "value": "dclk", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DRDY_PORT": [ { "value": "drdy", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DWE_PORT": [ { "value": "dwe", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIN_PORT": [ { "value": "din", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DOUT_PORT": [ { "value": "dout", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DEN_PORT": [ { "value": "den", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PSCLK_PORT": [ { "value": "psclk", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PSEN_PORT": [ { "value": "psen", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PSINCDEC_PORT": [ { "value": "psincdec", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PSDONE_PORT": [ { "value": "psdone", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_VALID_PORT": [ { "value": "CLK_VALID", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_STATUS_PORT": [ { "value": "STATUS", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLK_IN_SEL_PORT": [ { "value": "clk_in_sel", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_INPUT_CLK_STOPPED_PORT": [ { "value": "input_clk_stopped", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFB_STOPPED_PORT": [ { "value": "clkfb_stopped", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKIN1_JITTER_PS": [ { "value": "53.330000000000005", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_CLKIN2_JITTER_PS": [ { "value": "53.330000000000005", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_PRIMITIVE": [ { "value": "Auto", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_SS_MODE": [ { "value": "CENTER_HIGH", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_SS_MOD_PERIOD": [ { "value": "4000", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_SS_MOD_TIME": [ { "value": "0.004", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_HAS_CDDC": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_CDDCDONE_PORT": [ { "value": "cddcdone", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CDDCREQ_PORT": [ { "value": "cddcreq", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUTPHY_MODE": [ { "value": "VCO", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_ENABLE_CLKOUTPHY": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_INTERFACE_SELECTION": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_S_AXI_ADDR_WIDTH": [ { "value": "11", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_S_AXI_DATA_WIDTH": [ { "value": "32", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_POWER_REG": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT0_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT0_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT1_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT1_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT2_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT2_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT3_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT3_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT4_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT4_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT5_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT5_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT6_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT6_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFBOUT_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKFBOUT_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVCLK": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_LOCK_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_LOCK_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_LOCK_3": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_FILTER_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_FILTER_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE1_AUTO": [ { "value": "1", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE2_AUTO": [ { "value": "0.25", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE3_AUTO": [ { "value": "0.25", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE4_AUTO": [ { "value": "0.25", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE5_AUTO": [ { "value": "0.25", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE6_AUTO": [ { "value": "0.25", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_DIVIDE7_AUTO": [ { "value": "0.25", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLLBUFGCEDIV": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLLBUFGCEDIV1": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLLBUFGCEDIV2": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLLBUFGCEDIV3": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_PLLBUFGCEDIV4": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV1": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV2": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV3": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV4": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV5": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV6": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_MMCMBUFGCEDIV7": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT1_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT2_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT3_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT4_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT5_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT6_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT7_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT0_ACTUAL_FREQ": [ { "value": "187.50000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT1_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT2_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT3_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT4_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT5_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_CLKOUT6_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_M_MAX": [ { "value": "64.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_M_MIN": [ { "value": "2.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_D_MAX": [ { "value": "93.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_D_MIN": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_O_MAX": [ { "value": "128.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_O_MIN": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_VCO_MIN": [ { "value": "600.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||
"C_VCO_MAX": [ { "value": "1335.000", "resolve_type": "generated", "format": "float", "usage": "all" } ]
|
||||
},
|
||||
"project_parameters": {
|
||||
"ARCHITECTURE": [ { "value": "kintexu" } ],
|
||||
"BASE_BOARD_PART": [ { "value": "" } ],
|
||||
"BOARD_CONNECTIONS": [ { "value": "" } ],
|
||||
"DEVICE": [ { "value": "xcku040" } ],
|
||||
"PACKAGE": [ { "value": "ffva1156" } ],
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
"runtime_parameters": {
|
||||
"IPCONTEXT": [ { "value": "IP_Flow" } ],
|
||||
"IPREVISION": [ { "value": "11" } ],
|
||||
"MANAGED": [ { "value": "TRUE" } ],
|
||||
"OUTPUTDIR": [ { "value": "../../../../radar_alinx_kintex.gen/sources_1/ip/jesd_core_clk_wiz" } ],
|
||||
"SELECTEDSIMMODEL": [ { "value": "" } ],
|
||||
"SHAREDDIR": [ { "value": "." } ],
|
||||
"SWVERSION": [ { "value": "2022.2" } ],
|
||||
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
|
||||
}
|
||||
},
|
||||
"boundary": {
|
||||
"ports": {
|
||||
"clk_in1": [ { "direction": "in" } ],
|
||||
"clk_out1": [ { "direction": "out" } ],
|
||||
"locked": [ { "direction": "out" } ]
|
||||
},
|
||||
"interfaces": {
|
||||
"clock_CLK_IN1": {
|
||||
"vlnv": "xilinx.com:signal:clock:1.0",
|
||||
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
|
||||
"mode": "slave",
|
||||
"parameters": {
|
||||
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_BUSIF": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_RESET": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"BOARD.ASSOCIATED_PARAM": [ { "value": "CLK_IN1_BOARD_INTERFACE", "usage": "all", "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"CLK_IN1": [ { "physical_name": "clk_in1" } ]
|
||||
}
|
||||
},
|
||||
"clock_CLK_OUT1": {
|
||||
"vlnv": "xilinx.com:signal:clock:1.0",
|
||||
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
|
||||
"mode": "master",
|
||||
"parameters": {
|
||||
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_BUSIF": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_RESET": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"CLK_OUT1": [ { "physical_name": "clk_out1" } ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
{
|
||||
"schema": "xilinx.com:schema:json_instance:1.0",
|
||||
"ip_inst": {
|
||||
"xci_name": "pulse_buffer_204B_fifo",
|
||||
"component_reference": "xilinx.com:ip:axis_data_fifo:2.0",
|
||||
"ip_revision": "9",
|
||||
"gen_directory": "../../../../radar_alinx_kintex.gen/sources_1/ip/pulse_buffer_204B_fifo",
|
||||
"parameters": {
|
||||
"component_parameters": {
|
||||
"TDATA_NUM_BYTES": [ { "value": "8", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"TID_WIDTH": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"TDEST_WIDTH": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"TUSER_WIDTH": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"FIFO_DEPTH": [ { "value": "16384", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"FIFO_MODE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"IS_ACLK_ASYNC": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"ACLKEN_CONV_MODE": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_TREADY": [ { "value": "1", "resolve_type": "user", "format": "long", "enabled": false, "usage": "all" } ],
|
||||
"HAS_TSTRB": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_TKEEP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_TLAST": [ { "value": "1", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"SYNCHRONIZATION_STAGES": [ { "value": "3", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_WR_DATA_COUNT": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_RD_DATA_COUNT": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_AEMPTY": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_PROG_EMPTY": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PROG_EMPTY_THRESH": [ { "value": "5", "resolve_type": "user", "format": "long", "enabled": false, "usage": "all" } ],
|
||||
"HAS_AFULL": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"HAS_PROG_FULL": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"PROG_FULL_THRESH": [ { "value": "11", "resolve_type": "user", "format": "long", "enabled": false, "usage": "all" } ],
|
||||
"ENABLE_ECC": [ { "value": "0", "resolve_type": "user", "format": "long", "enabled": false, "usage": "all" } ],
|
||||
"HAS_ECC_ERR_INJECT": [ { "value": "0", "resolve_type": "user", "format": "long", "enabled": false, "usage": "all" } ],
|
||||
"FIFO_MEMORY_TYPE": [ { "value": "auto", "resolve_type": "user", "usage": "all" } ],
|
||||
"Component_Name": [ { "value": "pulse_buffer_204B_fifo", "resolve_type": "user", "usage": "all" } ]
|
||||
},
|
||||
"model_parameters": {
|
||||
"C_FAMILY": [ { "value": "kintexu", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_AXIS_TDATA_WIDTH": [ { "value": "64", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_AXIS_TID_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_AXIS_TDEST_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_AXIS_TUSER_WIDTH": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_AXIS_SIGNAL_SET": [ { "value": "0b00000000000000000000000010010011", "resolve_type": "generated", "format": "bitString", "usage": "all" } ],
|
||||
"C_FIFO_DEPTH": [ { "value": "16384", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_FIFO_MODE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_IS_ACLK_ASYNC": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_SYNCHRONIZER_STAGE": [ { "value": "3", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_ACLKEN_CONV_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_ECC_MODE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_FIFO_MEMORY_TYPE": [ { "value": "auto", "resolve_type": "generated", "usage": "all" } ],
|
||||
"C_USE_ADV_FEATURES": [ { "value": "825241648", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PROG_EMPTY_THRESH": [ { "value": "5", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||
"C_PROG_FULL_THRESH": [ { "value": "11", "resolve_type": "generated", "format": "long", "usage": "all" } ]
|
||||
},
|
||||
"project_parameters": {
|
||||
"ARCHITECTURE": [ { "value": "kintexu" } ],
|
||||
"BASE_BOARD_PART": [ { "value": "" } ],
|
||||
"BOARD_CONNECTIONS": [ { "value": "" } ],
|
||||
"DEVICE": [ { "value": "xcku040" } ],
|
||||
"PACKAGE": [ { "value": "ffva1156" } ],
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
"runtime_parameters": {
|
||||
"IPCONTEXT": [ { "value": "IP_Flow" } ],
|
||||
"IPREVISION": [ { "value": "9" } ],
|
||||
"MANAGED": [ { "value": "TRUE" } ],
|
||||
"OUTPUTDIR": [ { "value": "../../../../radar_alinx_kintex.gen/sources_1/ip/pulse_buffer_204B_fifo" } ],
|
||||
"SELECTEDSIMMODEL": [ { "value": "" } ],
|
||||
"SHAREDDIR": [ { "value": "." } ],
|
||||
"SWVERSION": [ { "value": "2022.2" } ],
|
||||
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
|
||||
}
|
||||
},
|
||||
"boundary": {
|
||||
"ports": {
|
||||
"s_axis_aresetn": [ { "direction": "in", "driver_value": "0x0" } ],
|
||||
"s_axis_aclk": [ { "direction": "in", "driver_value": "0x0" } ],
|
||||
"s_axis_tvalid": [ { "direction": "in", "driver_value": "0x0" } ],
|
||||
"s_axis_tready": [ { "direction": "out" } ],
|
||||
"s_axis_tdata": [ { "direction": "in", "size_left": "63", "size_right": "0", "driver_value": "0x0000000000000000" } ],
|
||||
"s_axis_tlast": [ { "direction": "in", "driver_value": "0x1" } ],
|
||||
"s_axis_tuser": [ { "direction": "in", "size_left": "0", "size_right": "0", "driver_value": "0x0" } ],
|
||||
"m_axis_aclk": [ { "direction": "in", "driver_value": "0x0" } ],
|
||||
"m_axis_tvalid": [ { "direction": "out" } ],
|
||||
"m_axis_tready": [ { "direction": "in", "driver_value": "0x1" } ],
|
||||
"m_axis_tdata": [ { "direction": "out", "size_left": "63", "size_right": "0" } ],
|
||||
"m_axis_tlast": [ { "direction": "out" } ],
|
||||
"m_axis_tuser": [ { "direction": "out", "size_left": "0", "size_right": "0" } ]
|
||||
},
|
||||
"interfaces": {
|
||||
"S_AXIS": {
|
||||
"vlnv": "xilinx.com:interface:axis:1.0",
|
||||
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
|
||||
"mode": "slave",
|
||||
"parameters": {
|
||||
"TDATA_NUM_BYTES": [ { "value": "8", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"TDEST_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"TID_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"TUSER_WIDTH": [ { "value": "1", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TREADY": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TSTRB": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TKEEP": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TLAST": [ { "value": "1", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"TDATA": [ { "physical_name": "s_axis_tdata" } ],
|
||||
"TLAST": [ { "physical_name": "s_axis_tlast" } ],
|
||||
"TREADY": [ { "physical_name": "s_axis_tready" } ],
|
||||
"TUSER": [ { "physical_name": "s_axis_tuser" } ],
|
||||
"TVALID": [ { "physical_name": "s_axis_tvalid" } ]
|
||||
}
|
||||
},
|
||||
"M_AXIS": {
|
||||
"vlnv": "xilinx.com:interface:axis:1.0",
|
||||
"abstraction_type": "xilinx.com:interface:axis_rtl:1.0",
|
||||
"mode": "master",
|
||||
"parameters": {
|
||||
"TDATA_NUM_BYTES": [ { "value": "8", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"TDEST_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"TID_WIDTH": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"TUSER_WIDTH": [ { "value": "1", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TREADY": [ { "value": "1", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TSTRB": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TKEEP": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"HAS_TLAST": [ { "value": "1", "value_src": "auto", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"LAYERED_METADATA": [ { "value": "undef", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"TDATA": [ { "physical_name": "m_axis_tdata" } ],
|
||||
"TLAST": [ { "physical_name": "m_axis_tlast" } ],
|
||||
"TREADY": [ { "physical_name": "m_axis_tready" } ],
|
||||
"TUSER": [ { "physical_name": "m_axis_tuser" } ],
|
||||
"TVALID": [ { "physical_name": "m_axis_tvalid" } ]
|
||||
}
|
||||
},
|
||||
"S_RSTIF": {
|
||||
"vlnv": "xilinx.com:signal:reset:1.0",
|
||||
"abstraction_type": "xilinx.com:signal:reset_rtl:1.0",
|
||||
"mode": "slave",
|
||||
"parameters": {
|
||||
"POLARITY": [ { "value": "ACTIVE_LOW", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"RST": [ { "physical_name": "s_axis_aresetn" } ]
|
||||
}
|
||||
},
|
||||
"S_CLKIF": {
|
||||
"vlnv": "xilinx.com:signal:clock:1.0",
|
||||
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
|
||||
"mode": "slave",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": [ { "value": "S_AXIS", "value_src": "constant", "usage": "all" } ],
|
||||
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_RESET": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"CLK": [ { "physical_name": "s_axis_aclk" } ]
|
||||
}
|
||||
},
|
||||
"M_CLKIF": {
|
||||
"vlnv": "xilinx.com:signal:clock:1.0",
|
||||
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
|
||||
"mode": "slave",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": [ { "value": "M_AXIS", "value_src": "constant", "usage": "all" } ],
|
||||
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"ASSOCIATED_RESET": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||
},
|
||||
"port_maps": {
|
||||
"CLK": [ { "physical_name": "m_axis_aclk" } ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,9 +60,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -166,9 +166,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
||||
"SILICON_REVISION": [ { "value": "" } ],
|
||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
||||
"SPEEDGRADE": [ { "value": "-2" } ],
|
||||
"STATIC_POWER": [ { "value": "" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "C" } ],
|
||||
"TEMPERATURE_GRADE": [ { "value": "I" } ],
|
||||
"USE_RDI_CUSTOMIZATION": [ { "value": "TRUE" } ],
|
||||
"USE_RDI_GENERATION": [ { "value": "TRUE" } ]
|
||||
},
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
<DefaultLaunch Dir="$PRUNDIR"/>
|
||||
<Configuration>
|
||||
<Option Name="Id" Val="c179ea77804d47eabf9d7773e858daa9"/>
|
||||
<Option Name="Part" Val="xcku040-ffva1156-1-c"/>
|
||||
<Option Name="Part" Val="xcku040-ffva1156-2-i"/>
|
||||
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
|
||||
<Option Name="CompiledLibDirXSim" Val=""/>
|
||||
<Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
|
||||
@@ -63,13 +63,13 @@
|
||||
<Option Name="WTVcsLaunchSim" Val="0"/>
|
||||
<Option Name="WTRivieraLaunchSim" Val="0"/>
|
||||
<Option Name="WTActivehdlLaunchSim" Val="0"/>
|
||||
<Option Name="WTXSimExportSim" Val="31"/>
|
||||
<Option Name="WTModelSimExportSim" Val="31"/>
|
||||
<Option Name="WTQuestaExportSim" Val="31"/>
|
||||
<Option Name="WTXSimExportSim" Val="47"/>
|
||||
<Option Name="WTModelSimExportSim" Val="47"/>
|
||||
<Option Name="WTQuestaExportSim" Val="47"/>
|
||||
<Option Name="WTIesExportSim" Val="0"/>
|
||||
<Option Name="WTVcsExportSim" Val="31"/>
|
||||
<Option Name="WTRivieraExportSim" Val="31"/>
|
||||
<Option Name="WTActivehdlExportSim" Val="31"/>
|
||||
<Option Name="WTVcsExportSim" Val="47"/>
|
||||
<Option Name="WTRivieraExportSim" Val="47"/>
|
||||
<Option Name="WTActivehdlExportSim" Val="47"/>
|
||||
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
|
||||
<Option Name="XSimRadix" Val="hex"/>
|
||||
<Option Name="XSimTimeUnit" Val="ns"/>
|
||||
@@ -568,20 +568,6 @@
|
||||
<Option Name="TopAutoSet" Val="TRUE"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="microblaze_bd" Type="BlockSrcs" RelSrcDir="$PSRCDIR/microblaze_bd" RelGenDir="$PGENDIR/microblaze_bd">
|
||||
<File Path="$PSRCDIR/sources_1/bd/microblaze_bd/microblaze_bd.bd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="TopModule" Val="microblaze_bd"/>
|
||||
<Option Name="dataflowViewerSettings" Val="min_width=16"/>
|
||||
<Option Name="UseBlackboxStub" Val="1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="axis_switch_0" Type="BlockSrcs" RelSrcDir="$PSRCDIR/axis_switch_0" RelGenDir="$PGENDIR/axis_switch_0">
|
||||
<File Path="$PSRCDIR/sources_1/ip/axis_switch_0/axis_switch_0.xci">
|
||||
<FileInfo>
|
||||
@@ -708,6 +694,50 @@
|
||||
<Option Name="UseBlackboxStub" Val="1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="pulse_buffer_204B_fifo" Type="BlockSrcs" RelSrcDir="$PSRCDIR/pulse_buffer_204B_fifo" RelGenDir="$PGENDIR/pulse_buffer_204B_fifo">
|
||||
<File Path="$PSRCDIR/sources_1/ip/pulse_buffer_204B_fifo/pulse_buffer_204B_fifo.xci">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="TopModule" Val="pulse_buffer_204B_fifo"/>
|
||||
<Option Name="dataflowViewerSettings" Val="min_width=16"/>
|
||||
<Option Name="UseBlackboxStub" Val="1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="microblaze_bd" Type="BlockSrcs" RelSrcDir="$PSRCDIR/microblaze_bd" RelGenDir="$PGENDIR/microblaze_bd">
|
||||
<File Path="$PSRCDIR/sources_1/bd/microblaze_bd/microblaze_bd.bd">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="TopModule" Val="microblaze_bd"/>
|
||||
<Option Name="dataflowViewerSettings" Val="min_width=16"/>
|
||||
<Option Name="UseBlackboxStub" Val="1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="jesd_core_clk_wiz" Type="BlockSrcs" RelSrcDir="$PSRCDIR/jesd_core_clk_wiz" RelGenDir="$PGENDIR/jesd_core_clk_wiz">
|
||||
<File Path="$PSRCDIR/sources_1/ip/jesd_core_clk_wiz/jesd_core_clk_wiz.xci">
|
||||
<FileInfo>
|
||||
<Attr Name="AutoDisabled" Val="1"/>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="TopModule" Val="jesd_core_clk_wiz"/>
|
||||
<Option Name="dataflowViewerSettings" Val="min_width=16"/>
|
||||
<Option Name="UseBlackboxStub" Val="1"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
</FileSets>
|
||||
<Simulators>
|
||||
<Simulator Name="XSim">
|
||||
@@ -731,7 +761,7 @@
|
||||
</Simulator>
|
||||
</Simulators>
|
||||
<Runs Version="1" Minor="19">
|
||||
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xcku040-ffva1156-1-c" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" IncrementalCheckpoint="$PSRCDIR/utils_1/imports/synth_1/top.dcp" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1">
|
||||
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xcku040-ffva1156-2-i" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" IncrementalCheckpoint="$PSRCDIR/utils_1/imports/synth_1/top.dcp" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -741,7 +771,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="microblaze_bd_synth_1" Type="Ft3:Synth" SrcSet="microblaze_bd" Part="xcku040-ffva1156-1-c" ConstrsSet="microblaze_bd" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/microblaze_bd_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/microblaze_bd_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/microblaze_bd_synth_1">
|
||||
<Run Id="axis_switch_0_synth_1" Type="Ft3:Synth" SrcSet="axis_switch_0" Part="xcku040-ffva1156-2-i" ConstrsSet="axis_switch_0" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/axis_switch_0_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/axis_switch_0_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/axis_switch_0_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -751,7 +781,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="axis_switch_0_synth_1" Type="Ft3:Synth" SrcSet="axis_switch_0" Part="xcku040-ffva1156-1-c" ConstrsSet="axis_switch_0" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/axis_switch_0_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/axis_switch_0_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/axis_switch_0_synth_1">
|
||||
<Run Id="hdr_mem_synth_1" Type="Ft3:Synth" SrcSet="hdr_mem" Part="xcku040-ffva1156-2-i" ConstrsSet="hdr_mem" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hdr_mem_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_mem_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_mem_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -761,7 +791,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="hdr_mem_synth_1" Type="Ft3:Synth" SrcSet="hdr_mem" Part="xcku040-ffva1156-1-c" ConstrsSet="hdr_mem" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hdr_mem_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_mem_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_mem_synth_1">
|
||||
<Run Id="dig_rx_clock_converter_synth_1" Type="Ft3:Synth" SrcSet="dig_rx_clock_converter" Part="xcku040-ffva1156-2-i" ConstrsSet="dig_rx_clock_converter" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/dig_rx_clock_converter_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -771,7 +801,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="dig_rx_clock_converter_synth_1" Type="Ft3:Synth" SrcSet="dig_rx_clock_converter" Part="xcku040-ffva1156-1-c" ConstrsSet="dig_rx_clock_converter" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/dig_rx_clock_converter_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_synth_1">
|
||||
<Run Id="dig_rx_dwidth_converter_synth_1" Type="Ft3:Synth" SrcSet="dig_rx_dwidth_converter" Part="xcku040-ffva1156-2-i" ConstrsSet="dig_rx_dwidth_converter" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/dig_rx_dwidth_converter_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -781,7 +811,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="dig_rx_dwidth_converter_synth_1" Type="Ft3:Synth" SrcSet="dig_rx_dwidth_converter" Part="xcku040-ffva1156-1-c" ConstrsSet="dig_rx_dwidth_converter" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/dig_rx_dwidth_converter_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_synth_1">
|
||||
<Run Id="pulse_buffer_fifo_synth_1" Type="Ft3:Synth" SrcSet="pulse_buffer_fifo" Part="xcku040-ffva1156-2-i" ConstrsSet="pulse_buffer_fifo" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/pulse_buffer_fifo_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -791,7 +821,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="pulse_buffer_fifo_synth_1" Type="Ft3:Synth" SrcSet="pulse_buffer_fifo" Part="xcku040-ffva1156-1-c" ConstrsSet="pulse_buffer_fifo" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/pulse_buffer_fifo_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_synth_1">
|
||||
<Run Id="eth_xcvr_gt_channel_synth_1" Type="Ft3:Synth" SrcSet="eth_xcvr_gt_channel" Part="xcku040-ffva1156-2-i" ConstrsSet="eth_xcvr_gt_channel" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/eth_xcvr_gt_channel_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -801,7 +831,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="eth_xcvr_gt_channel_synth_1" Type="Ft3:Synth" SrcSet="eth_xcvr_gt_channel" Part="xcku040-ffva1156-1-c" ConstrsSet="eth_xcvr_gt_channel" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/eth_xcvr_gt_channel_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_synth_1">
|
||||
<Run Id="eth_xcvr_gt_full_synth_1" Type="Ft3:Synth" SrcSet="eth_xcvr_gt_full" Part="xcku040-ffva1156-2-i" ConstrsSet="eth_xcvr_gt_full" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/eth_xcvr_gt_full_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -811,7 +841,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="eth_xcvr_gt_full_synth_1" Type="Ft3:Synth" SrcSet="eth_xcvr_gt_full" Part="xcku040-ffva1156-1-c" ConstrsSet="eth_xcvr_gt_full" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/eth_xcvr_gt_full_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_synth_1">
|
||||
<Run Id="wf_memory_synth_1" Type="Ft3:Synth" SrcSet="wf_memory" Part="xcku040-ffva1156-2-i" ConstrsSet="wf_memory" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/wf_memory_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/wf_memory_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/wf_memory_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -821,7 +851,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="wf_memory_synth_1" Type="Ft3:Synth" SrcSet="wf_memory" Part="xcku040-ffva1156-1-c" ConstrsSet="wf_memory" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/wf_memory_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/wf_memory_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/wf_memory_synth_1">
|
||||
<Run Id="hdr_fifo_synth_1" Type="Ft3:Synth" SrcSet="hdr_fifo" Part="xcku040-ffva1156-2-i" ConstrsSet="hdr_fifo" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hdr_fifo_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_fifo_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_fifo_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -831,7 +861,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="hdr_fifo_synth_1" Type="Ft3:Synth" SrcSet="hdr_fifo" Part="xcku040-ffva1156-1-c" ConstrsSet="hdr_fifo" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/hdr_fifo_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_fifo_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_fifo_synth_1">
|
||||
<Run Id="pulse_buffer_204B_fifo_synth_1" Type="Ft3:Synth" SrcSet="pulse_buffer_204B_fifo" Part="xcku040-ffva1156-2-i" ConstrsSet="pulse_buffer_204B_fifo" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/pulse_buffer_204B_fifo_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/pulse_buffer_204B_fifo_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/pulse_buffer_204B_fifo_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
@@ -841,7 +871,27 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1">
|
||||
<Run Id="microblaze_bd_synth_1" Type="Ft3:Synth" SrcSet="microblaze_bd" Part="xcku040-ffva1156-2-i" ConstrsSet="microblaze_bd" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/microblaze_bd_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/microblaze_bd_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/microblaze_bd_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
|
||||
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2022"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="jesd_core_clk_wiz_synth_1" Type="Ft3:Synth" SrcSet="jesd_core_clk_wiz" Part="xcku040-ffva1156-2-i" ConstrsSet="jesd_core_clk_wiz" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/jesd_core_clk_wiz_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/jesd_core_clk_wiz_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/jesd_core_clk_wiz_synth_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
|
||||
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2022"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -859,7 +909,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="microblaze_bd_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="microblaze_bd" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="microblaze_bd_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/microblaze_bd_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/microblaze_bd_impl_1">
|
||||
<Run Id="axis_switch_0_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="axis_switch_0" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="axis_switch_0_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/axis_switch_0_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/axis_switch_0_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -876,7 +926,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="axis_switch_0_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="axis_switch_0" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="axis_switch_0_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/axis_switch_0_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/axis_switch_0_impl_1">
|
||||
<Run Id="hdr_mem_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="hdr_mem" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hdr_mem_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_mem_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_mem_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -893,7 +943,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="hdr_mem_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="hdr_mem" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hdr_mem_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_mem_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_mem_impl_1">
|
||||
<Run Id="dig_rx_clock_converter_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="dig_rx_clock_converter" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="dig_rx_clock_converter_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -910,7 +960,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="dig_rx_clock_converter_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="dig_rx_clock_converter" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="dig_rx_clock_converter_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_clock_converter_impl_1">
|
||||
<Run Id="dig_rx_dwidth_converter_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="dig_rx_dwidth_converter" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="dig_rx_dwidth_converter_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -927,7 +977,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="dig_rx_dwidth_converter_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="dig_rx_dwidth_converter" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="dig_rx_dwidth_converter_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/dig_rx_dwidth_converter_impl_1">
|
||||
<Run Id="pulse_buffer_fifo_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="pulse_buffer_fifo" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="pulse_buffer_fifo_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -944,7 +994,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="pulse_buffer_fifo_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="pulse_buffer_fifo" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="pulse_buffer_fifo_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/pulse_buffer_fifo_impl_1">
|
||||
<Run Id="eth_xcvr_gt_channel_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="eth_xcvr_gt_channel" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="eth_xcvr_gt_channel_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -961,7 +1011,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="eth_xcvr_gt_channel_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="eth_xcvr_gt_channel" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="eth_xcvr_gt_channel_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_channel_impl_1">
|
||||
<Run Id="eth_xcvr_gt_full_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="eth_xcvr_gt_full" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="eth_xcvr_gt_full_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -978,7 +1028,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="eth_xcvr_gt_full_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="eth_xcvr_gt_full" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="eth_xcvr_gt_full_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/eth_xcvr_gt_full_impl_1">
|
||||
<Run Id="wf_memory_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="wf_memory" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="wf_memory_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/wf_memory_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/wf_memory_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -995,7 +1045,7 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="wf_memory_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="wf_memory" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="wf_memory_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/wf_memory_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/wf_memory_impl_1">
|
||||
<Run Id="hdr_fifo_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="hdr_fifo" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hdr_fifo_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_fifo_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_fifo_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -1012,7 +1062,41 @@
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="hdr_fifo_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-1-c" ConstrsSet="hdr_fifo" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="hdr_fifo_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/hdr_fifo_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/hdr_fifo_impl_1">
|
||||
<Run Id="pulse_buffer_204B_fifo_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="pulse_buffer_204B_fifo" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="pulse_buffer_204B_fifo_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/pulse_buffer_204B_fifo_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/pulse_buffer_204B_fifo_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
<Step Id="place_design"/>
|
||||
<Step Id="post_place_power_opt_design"/>
|
||||
<Step Id="phys_opt_design"/>
|
||||
<Step Id="route_design"/>
|
||||
<Step Id="post_route_phys_opt_design"/>
|
||||
<Step Id="write_bitstream"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2022"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="microblaze_bd_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="microblaze_bd" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="microblaze_bd_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/microblaze_bd_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/microblaze_bd_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
<Step Id="place_design"/>
|
||||
<Step Id="post_place_power_opt_design"/>
|
||||
<Step Id="phys_opt_design"/>
|
||||
<Step Id="route_design"/>
|
||||
<Step Id="post_route_phys_opt_design"/>
|
||||
<Step Id="write_bitstream"/>
|
||||
</Strategy>
|
||||
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2022"/>
|
||||
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
<Run Id="jesd_core_clk_wiz_impl_1" Type="Ft2:EntireDesign" Part="xcku040-ffva1156-2-i" ConstrsSet="jesd_core_clk_wiz" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="jesd_core_clk_wiz_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/jesd_core_clk_wiz_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/jesd_core_clk_wiz_impl_1">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>
|
||||
<Step Id="init_design"/>
|
||||
@@ -1030,6 +1114,62 @@
|
||||
<RQSFiles/>
|
||||
</Run>
|
||||
</Runs>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="0"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="ANY"/>
|
||||
<MsgAttr Name="Id" Val="[BD 41-1306]"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="1"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="0"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="ANY"/>
|
||||
<MsgAttr Name="Id" Val="[BD 41-1271]"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="10"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="0"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="ANY"/>
|
||||
<MsgAttr Name="Id" Val="[BD 41-1306]"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="11"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="0"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
<MsgAttr Name="NewSeverity" Val="ANY"/>
|
||||
<MsgAttr Name="Id" Val="[BD 41-1271]"/>
|
||||
<MsgAttr Name="Severity" Val="ANY"/>
|
||||
<MsgAttr Name="ShowRule" Val="1"/>
|
||||
<MsgAttr Name="RuleSource" Val="2"/>
|
||||
<MsgAttr Name="StringIsRegExp" Val="0"/>
|
||||
<MsgAttr Name="RuleId" Val="12"/>
|
||||
<MsgAttr Name="Note" Val=""/>
|
||||
<MsgAttr Name="Author" Val=""/>
|
||||
<MsgAttr Name="CreatedTimestamp" Val=""/>
|
||||
</MsgRule>
|
||||
<MsgRule>
|
||||
<MsgAttr Name="RuleType" Val="0"/>
|
||||
<MsgAttr Name="Limit" Val="-1"/>
|
||||
|
||||
@@ -13,49 +13,49 @@
|
||||
<AddressSpace Name="microblaze_bd_i_microblaze_0.microblaze_bd_i_microblaze_0_local_memory_dlmb_bram_if_cntlr" Begin="0" End="32767">
|
||||
<AddressSpaceRange Name="microblaze_bd_i_microblaze_0.microblaze_bd_i_microblaze_0_local_memory_dlmb_bram_if_cntlr" Begin="0" End="32767" CoreMemory_Width="0" MemoryType="RAM_SP" MemoryConfiguration="">
|
||||
<BusBlock>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y46" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y9" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="7" LSB="4"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X5Y44" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y10" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="3" LSB="0"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y44" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y14" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="15" LSB="12"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y43" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="11" LSB="8"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X5Y46" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y6" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="23" LSB="20"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X5Y45" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y5" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="19" LSB="16"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y45" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y11" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="31" LSB="28"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y41" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y7" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="27" LSB="24"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
@@ -69,97 +69,97 @@
|
||||
<AddressSpace Name="microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_microblaze_I.microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_dlmb_cntlr" Begin="0" End="65535">
|
||||
<AddressSpaceRange Name="microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_microblaze_I.microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_dlmb_cntlr" Begin="0" End="65535" CoreMemory_Width="0" MemoryType="RAM_SP" MemoryConfiguration="">
|
||||
<BusBlock>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y9" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y24" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="7" LSB="6"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y7" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y25" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="5" LSB="4"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y11" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y24" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="3" LSB="2"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y14" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y22" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="1" LSB="0"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y6" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y25" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="15" LSB="14"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y5" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y24" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="13" LSB="12"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y7" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y26" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="11" LSB="10"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y6" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y25" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="9" LSB="8"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y19" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="23" LSB="22"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y19" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="21" LSB="20"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y10" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y17" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="19" LSB="18"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y9" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y20" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="17" LSB="16"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y21" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="31" LSB="30"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y12" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y18" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="29" LSB="28"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y14" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y22" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="27" LSB="26"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y11" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y18" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="25" LSB="24"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2759812199
|
||||
2843589716
|
||||
@@ -16,7 +16,7 @@
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uihw.bit.file" value="/home/bkiedinger/projects/castelion/radar_alinx_kintex/radar_alinx_kintex.runs/impl_1/top.bit"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uihw.init.tcl" value=""/>
|
||||
<booleanAttribute key="com.xilinx.sdk.tcf.debug.uipl.powerup" value="false"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproc.appl.map" value="{"microblaze_0":{"xilinx.tcf.application":"Debug/radar.elf","xilinx.tcf.datafiles":"","xilinx.tcf.no_download":false,"xilinx.tcf.profile_enabled":false,"xilinx.tcf.profile_frequency":"10000","xilinx.tcf.profile_non_int_frequency":"150000000","xilinx.tcf.profile_non_int_high_addr":"","xilinx.tcf.profile_non_int_low_addr":"","xilinx.tcf.profile_non_int_use_count_instr":false,"xilinx.tcf.profile_non_int_use_cumulate":false,"xilinx.tcf.profile_non_intrusive_support":false,"xilinx.tcf.profile_store_address":"0x0","xilinx.tcf.profile_use_intrusive":false,"xilinx.tcf.project":"radar","xilinx.tcf.relocate":false,"xilinx.tcf.relocate_addr":"","xilinx.tcf.reset":true,"xilinx.tcf.stop_at_entry":false}}"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproc.appl.map" value="{"microblaze_0":{"xilinx.tcf.application":"Debug/radar.elf","xilinx.tcf.datafiles":"","xilinx.tcf.no_download":false,"xilinx.tcf.profile_enabled":false,"xilinx.tcf.profile_frequency":"10000","xilinx.tcf.profile_non_int_frequency":"125000000","xilinx.tcf.profile_non_int_high_addr":"","xilinx.tcf.profile_non_int_low_addr":"","xilinx.tcf.profile_non_int_use_count_instr":false,"xilinx.tcf.profile_non_int_use_cumulate":false,"xilinx.tcf.profile_non_intrusive_support":false,"xilinx.tcf.profile_store_address":"0x0","xilinx.tcf.profile_use_intrusive":false,"xilinx.tcf.project":"radar","xilinx.tcf.relocate":false,"xilinx.tcf.relocate_addr":"","xilinx.tcf.reset":true,"xilinx.tcf.stop_at_entry":false}}"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproc.selection" value="microblaze_0"/>
|
||||
<booleanAttribute key="com.xilinx.sdk.tcf.debug.uiprogram.fpga" value="true"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproject.name" value="radar"/>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uihw.bit.file" value="/home/bkiedinger/projects/castelion/radar_alinx_kintex/radar_alinx_kintex.runs/impl_1/top.bit"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uihw.init.tcl" value=""/>
|
||||
<booleanAttribute key="com.xilinx.sdk.tcf.debug.uipl.powerup" value="false"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproc.appl.map" value="{"microblaze_0":{"xilinx.tcf.application":"Debug/radar.elf","xilinx.tcf.datafiles":"","xilinx.tcf.no_download":false,"xilinx.tcf.profile_enabled":false,"xilinx.tcf.profile_frequency":"10000","xilinx.tcf.profile_non_int_frequency":"150000000","xilinx.tcf.profile_non_int_high_addr":"","xilinx.tcf.profile_non_int_low_addr":"","xilinx.tcf.profile_non_int_use_count_instr":false,"xilinx.tcf.profile_non_int_use_cumulate":false,"xilinx.tcf.profile_non_intrusive_support":false,"xilinx.tcf.profile_store_address":"0x0","xilinx.tcf.profile_use_intrusive":false,"xilinx.tcf.project":"radar","xilinx.tcf.relocate":false,"xilinx.tcf.relocate_addr":"","xilinx.tcf.reset":true,"xilinx.tcf.stop_at_entry":false}}"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproc.appl.map" value="{"microblaze_0":{"xilinx.tcf.application":"Debug/radar.elf","xilinx.tcf.datafiles":"","xilinx.tcf.no_download":false,"xilinx.tcf.profile_enabled":false,"xilinx.tcf.profile_frequency":"10000","xilinx.tcf.profile_non_int_frequency":"125000000","xilinx.tcf.profile_non_int_high_addr":"","xilinx.tcf.profile_non_int_low_addr":"","xilinx.tcf.profile_non_int_use_count_instr":false,"xilinx.tcf.profile_non_int_use_cumulate":false,"xilinx.tcf.profile_non_intrusive_support":false,"xilinx.tcf.profile_store_address":"0x0","xilinx.tcf.profile_use_intrusive":false,"xilinx.tcf.project":"radar","xilinx.tcf.relocate":false,"xilinx.tcf.relocate_addr":"","xilinx.tcf.reset":true,"xilinx.tcf.stop_at_entry":false}}"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproc.selection" value="microblaze_0"/>
|
||||
<booleanAttribute key="com.xilinx.sdk.tcf.debug.uiprogram.fpga" value="false"/>
|
||||
<stringAttribute key="com.xilinx.sdk.tcf.debug.uiproject.name" value="radar"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<sdkproject:SdkProject xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sdkproject="http://www.xilinx.com/sdkproject" name="radar" location="/home/bkiedinger/projects/castelion/radar_alinx_kintex/vitis/radar" platform="/home/bkiedinger/projects/castelion/radar_alinx_kintex/vitis/top/export/top/top.xpfm" platformUID="xilinx:::0.0(custom)" systemProject="radar_system" sysConfig="top" runtime="C/C++" cpu="freertos10_xilinx_microblaze_0" cpuInstance="microblaze_0" os="freertos10_xilinx" mssSignature="8781df679aa71a5344fa22cfacec20c4">
|
||||
<sdkproject:SdkProject xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sdkproject="http://www.xilinx.com/sdkproject" name="radar" location="/home/bkiedinger/projects/castelion/radar_alinx_kintex/vitis/radar" platform="/home/bkiedinger/projects/castelion/radar_alinx_kintex/vitis/top/export/top/top.xpfm" platformUID="xilinx:::0.0(custom)" systemProject="radar_system" sysConfig="top" runtime="C/C++" cpu="freertos10_xilinx_microblaze_0" cpuInstance="microblaze_0" os="freertos10_xilinx" mssSignature="31c4a066f121f9dfdf4b2a6e46d178c9">
|
||||
<configuration name="Debug" id="xilinx.gnu.mb.exe.debug.245787499">
|
||||
<configBuildOptions xsi:type="sdkproject:SdkOptions"/>
|
||||
<lastBuildOptions xsi:type="sdkproject:SdkOptions"/>
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#define AD9081_SERDES_RST_WAIT 50000
|
||||
#define AD9081_DESER_MODE_204B_BR_TRESH 8000000000ULL
|
||||
#define AD9081_DESER_MODE_204C_BR_TRESH 16000000000ULL
|
||||
//#define AD9081_DESER_MODE_204C_BR_TRESH 14000000000ULL
|
||||
#define AD9081_IL_CTLE_UPPER_DB_THRESH 10
|
||||
|
||||
/* var error report */
|
||||
|
||||
@@ -1081,6 +1081,7 @@ int32_t adi_ad9081_adc_ddc_coarse_nco_set(adi_ad9081_device_t *device, uint8_t c
|
||||
|
||||
err = adi_ad9081_hal_calc_rx_nco_ftw(device, device->dev_info.adc_freq_hz, cddc_shift_hz, &ftw);
|
||||
AD9081_ERROR_RETURN(err);
|
||||
xil_printf("ADC FTW 0x%08x 0x%08x\r\n", (uint32_t)(ftw >> 32), (uint32_t)(ftw & 0xFFFFFFFF));
|
||||
err = adi_ad9081_adc_ddc_coarse_nco_ftw_set(device, cddcs, ftw, 0, 0);
|
||||
AD9081_ERROR_RETURN(err);
|
||||
|
||||
|
||||
@@ -534,6 +534,7 @@ int32_t adi_ad9081_dac_duc_nco_set(adi_ad9081_device_t *device, uint8_t dacs, ui
|
||||
AD9081_ERROR_RETURN(err);
|
||||
err = adi_ad9081_hal_calc_tx_nco_ftw(device, device->dev_info.dac_freq_hz, nco_shift_hz, &ftw);
|
||||
AD9081_ERROR_RETURN(err);
|
||||
xil_printf("DAC FTW 0x%08x 0x%08x\r\n", (uint32_t)(ftw >> 32), (uint32_t)(ftw & 0xFFFFFFFF));
|
||||
err = adi_ad9081_dac_duc_nco_ftw_set(device, dacs, AD9081_DAC_CH_NONE, ftw, 0, 0);
|
||||
AD9081_ERROR_RETURN(err);
|
||||
}
|
||||
@@ -1811,4 +1812,4 @@ int32_t adi_ad9081_dac_run_startup_cal(adi_ad9081_device_t *device, uint8_t dacs
|
||||
}
|
||||
return API_CMS_ERROR_OK;
|
||||
}
|
||||
/*! @} */
|
||||
/*! @} */
|
||||
|
||||
@@ -665,6 +665,7 @@ int32_t adi_ad9081_device_reg8_access_check(adi_ad9081_device_t *device)
|
||||
AD9081_ERROR_RETURN(err);
|
||||
return API_CMS_ERROR_TEST_FAILED;
|
||||
}
|
||||
|
||||
err = adi_ad9081_hal_reg_set(device, REG_PAGEINDX_DAC_CHAN_ADDR, reg8);
|
||||
AD9081_ERROR_RETURN(err);
|
||||
|
||||
|
||||
@@ -737,6 +737,7 @@ int32_t adi_ad9081_jesd_rx_ctle_filter_set(adi_ad9081_device_t *device, uint8_t
|
||||
AD9081_INVALID_PARAM_RETURN(ctle_filter < 1 || ctle_filter > 4) /*Range 1-4 corresponding CTLE cutoff frequency to channel insertion loss*/
|
||||
|
||||
err = adi_ad9081_hal_cbusjrx_reg_set(device, 0xfd, (1 << ctle_filter) - 1, lanes); /* @ADDR_CBUS_RX_DFE_CTL55 */
|
||||
// err = adi_ad9081_hal_cbusjrx_reg_set(device, 0xfd, 0, lanes); /* @ADDR_CBUS_RX_DFE_CTL55 */
|
||||
AD9081_ERROR_RETURN(err);
|
||||
|
||||
return API_CMS_ERROR_OK;
|
||||
|
||||
@@ -284,7 +284,8 @@
|
||||
#define AD9081_ADC_CLK_FREQ_HZ_MAX 4000000000ULL
|
||||
#define AD9081_REF_CLK_FREQ_HZ_MIN 25000000ULL
|
||||
#define AD9081_REF_CLK_FREQ_HZ_MAX 3000000000ULL
|
||||
#define AD9081_JESDRX_204C_CAL_THRESH 16000000000ULL
|
||||
//#define AD9081_JESDRX_204C_CAL_THRESH 16000000000ULL
|
||||
#define AD9081_JESDRX_204C_CAL_THRESH 12000000000ULL
|
||||
#define AD9081_JESD_SER_COUNT 8
|
||||
#define AD9081_JESD_DESER_COUNT 8
|
||||
|
||||
@@ -6049,4 +6050,4 @@ int32_t adi_ad9081_device_cbuspll_register_get(adi_ad9081_device_t *device, uint
|
||||
#endif
|
||||
|
||||
#endif /* __ADI_AD9081_H__ */
|
||||
/*! @} */
|
||||
/*! @} */
|
||||
|
||||
@@ -37,7 +37,7 @@ extern adi_cms_jesd_param_t jrx_param[];
|
||||
extern adi_cms_jesd_param_t jtx_param[][2];
|
||||
extern uint8_t jtx_chip_dcm[][2];
|
||||
/*============= END DATA ====================*/
|
||||
void set_lane_cal(int lane, int pre, int post) {
|
||||
void set_lane_cal(int lane, int pre, int post, int swing) {
|
||||
// Select Lane
|
||||
Xil_Out32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x24, lane);
|
||||
|
||||
@@ -45,6 +45,10 @@ void set_lane_cal(int lane, int pre, int post) {
|
||||
Xil_Out32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x418, pre);
|
||||
// Update Postcursor 0 - 32 Valid (~0.22dB steps)
|
||||
Xil_Out32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x414, post);
|
||||
// UPdate Drive Strength
|
||||
Xil_Out32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x508, swing);
|
||||
|
||||
|
||||
// Update RX Equalizer Setting 0 = DFE 1 = LPM
|
||||
Xil_Out32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x608, 0);
|
||||
Xil_Out32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x60C, 1);
|
||||
@@ -57,20 +61,79 @@ void set_lane_cal(int lane, int pre, int post) {
|
||||
}
|
||||
|
||||
|
||||
void print_rx_ila() {
|
||||
xil_printf(" CFG0 CFG1 CFG2 CFG3 CFG4 CFG5 CFG6 CFG7 \r\n");
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
xil_printf("Lane %2d ILA: ", i);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
xil_printf("0x%08x ", Xil_In32(JESD_RX + 0x400 + i * 0x080 + 0x30 + j*4));
|
||||
}
|
||||
xil_printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void reset_jesd() {
|
||||
uint32_t gpo = Xil_In32(GPO_REG);
|
||||
Xil_Out32(GPO_REG, gpo | ALL_JESD_RST);
|
||||
vTaskDelay(100);
|
||||
Xil_Out32(GPO_REG, gpo);
|
||||
|
||||
// Wait for reset to complete
|
||||
xil_printf("Wait for RX to complete reset\r\n");
|
||||
int val = 1;
|
||||
while (val) {
|
||||
val = Xil_In32(JESD_RX + RESET_REG);
|
||||
xil_printf("rx reset state: 0x%x\r\n", val);
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(GPI_REG));
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
xil_printf("Wait for TX to complete reset\r\n");
|
||||
val = 1;
|
||||
while (val) {
|
||||
val = Xil_In32(JESD_TX + RESET_REG);
|
||||
xil_printf("tx reset state: 0x%x\r\n", val);
|
||||
vTaskDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
void check_jesd_core_clk() {
|
||||
uint32_t gpi = Xil_In32(GPI_REG);
|
||||
uint32_t jesd_core_clk_locked = gpi & 0x8;
|
||||
if (jesd_core_clk_locked == 0) {
|
||||
// Not locked, try the other clock input
|
||||
xil_printf("JESD Core Clk not locked!!! Trying other clock 0x%x\r\n", gpi);
|
||||
uint32_t gpo = Xil_In32(GPO_REG);
|
||||
gpo |= JESD_CORE_CLK_SEL;
|
||||
Xil_Out32(GPO_REG, gpo);
|
||||
vTaskDelay(100);
|
||||
uint32_t gpi = Xil_In32(GPI_REG);
|
||||
jesd_core_clk_locked = gpi & 0x8;
|
||||
}
|
||||
|
||||
if (jesd_core_clk_locked) {
|
||||
xil_printf("JESD Core Clk Locked!\r\n");
|
||||
} else {
|
||||
xil_printf("JESD Core Clk Locked FAILED!\r\n");
|
||||
vTaskDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
adi_ad9081_device_t * ad9081_dev_ptr;
|
||||
|
||||
void setup_data_converter() {
|
||||
|
||||
// Reset Ethernet
|
||||
setBit(0x40050008, 15);
|
||||
setBit(GPO_REG, 15);
|
||||
vTaskDelay(1);
|
||||
clearBit(0x40050008, 15);
|
||||
clearBit(GPO_REG, 15);
|
||||
|
||||
ad9081_hal_init();
|
||||
hmc7044_init();
|
||||
|
||||
// select use case
|
||||
int uc = 1;
|
||||
int uc = 0;
|
||||
|
||||
uint64_t app_jrx_lane_rate = 0;
|
||||
uint64_t app_jtx_lane_rate[2] = {0};
|
||||
@@ -139,19 +202,27 @@ void setup_data_converter() {
|
||||
|
||||
.invert_mask = 0x00,
|
||||
.lane_mapping = { { 5, 7, 0, 1, 2, 3, 4, 6 }, { 2, 0, 7, 7, 7, 7, 3, 1 } }, /* link0, link1 */
|
||||
|
||||
// .lane_mapping = { { 5, 7, 0, 1, 2, 3, 4, 6 }, { 2, 0, 7, 7, 7, 7, 3, 1 } }, /* link0, link1 */ //204B // 5, 7, 0, 1, 2, 3, 4, 6
|
||||
// .lane_mapping = { { 0, 1, 2, 3, 4, 5, 6, 7 }, { 2, 0, 7, 7, 7, 7, 3, 1 } }, /* link0, link1 */ //204B // 2, 3, 4, 5, 6, 0, 7, 1
|
||||
// .lane_mapping = { { 2, 1, 0, 3, 4, 5, 6, 7 }, { 2, 0, 7, 7, 7, 7, 3, 1 } }, /* link0, link1 */ //204B // 2, 3, 4, 5, 6, 0, 7, 1
|
||||
// .lane_mapping = { { 2, 3, 0, 1, 4, 5, 6, 7 }, { 2, 0, 7, 7, 7, 7, 3, 1 } }, /* link0, link1 */ //204B // 2, 3, 4, 5, 6, 0, 7, 1
|
||||
// .lane_mapping = { { 0, 1, 4, 5, 2, 3, 6, 7 }, { 2, 0, 7, 7, 7, 7, 3, 1 } }, /* link0, link1 */ //204B
|
||||
},
|
||||
.des_settings = { /* ad9081 jrx */
|
||||
.boost_mask = 0xff,
|
||||
.boost_mask = 0xFF,
|
||||
.invert_mask = 0x00,
|
||||
.ctle_filter = { 2, 2, 2, 2, 2, 2, 2, 2 },
|
||||
// .ctle_filter = { 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||
.cal_mode = AD9081_CAL_MODE_RUN,
|
||||
.ctle_coeffs = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, /* CTLE 1-4 for lanes 0-7 */
|
||||
.lane_mapping = { { 7, 5, 0, 1, 6, 2, 3, 4 }, { 4, 5, 6, 7, 0, 1, 2, 3 } }, /* link0, link1 */
|
||||
}
|
||||
},
|
||||
.clk_info = {
|
||||
// .sysref_mode = SYSREF_NONE,
|
||||
.sysref_mode = SYSREF_CONT,
|
||||
.sysref_mode = SYSREF_NONE,
|
||||
// .sysref_mode = SYSREF_ONESHOT,
|
||||
// .sysref_mode = SYSREF_CONT,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -183,33 +254,52 @@ void setup_data_converter() {
|
||||
// configure 7044 to generate clock
|
||||
uint64_t ad9081_clk = clk_hz[uc][0];
|
||||
uint64_t fpga_clk = clk_hz[uc][1];
|
||||
uint64_t sysref_clk_204c = fpga_clk/32;
|
||||
uint64_t sysref_clk_204 = fpga_clk/32;
|
||||
if (((jrx_param[uc].jesd_jesdv == 0) && (jtx_param[uc][0].jesd_jesdv == 0))) {
|
||||
sysref_clk_204 = fpga_clk/16;
|
||||
}
|
||||
uint64_t hmc7044_crystal_input = 100e6;
|
||||
// uint64_t jesd_core_clk = 125e6;
|
||||
// uint64_t jesd_core_clk = 237.5e6;
|
||||
uint64_t jesd_core_clk = fpga_clk;
|
||||
|
||||
/* Configure HMC7044 SYSREF frequency output channels for SC1 Use Case */
|
||||
ad9081_dev.clk_info.sysref_clk = &hmc7044_dev;
|
||||
ad9081_dev.clk_info.sysref_ctrl = app_sysref_clk_src_sel;
|
||||
/* Calculate SYSREF Freq for SC1 Use cases*/
|
||||
ad9081_dev.clk_info.sysref_mode = SYSREF_CONT;
|
||||
if (err = adi_ad9081_sync_sysref_frequency_set(&ad9081_dev, &sysref_clk_204c, ad9081_clk, clk_hz[uc][2], clk_hz[uc][3], tx_interp[uc][0], tx_interp[uc][1], rx_cddc_dcm[uc], rx_fddc_dcm[uc], jtx_param[uc][0].jesd_duallink, &jrx_param[uc], jtx_param[uc]), err != API_CMS_ERROR_OK)
|
||||
if (((jrx_param[uc].jesd_subclass == 1) && (jtx_param[uc][0].jesd_subclass == 1))) {
|
||||
ad9081_dev.clk_info.sysref_mode = SYSREF_CONT;
|
||||
}
|
||||
if (err = adi_ad9081_sync_sysref_frequency_set(&ad9081_dev, &sysref_clk_204, ad9081_clk, clk_hz[uc][2], clk_hz[uc][3], tx_interp[uc][0], tx_interp[uc][1], rx_cddc_dcm[uc], rx_fddc_dcm[uc], jtx_param[uc][0].jesd_duallink, &jrx_param[uc], jtx_param[uc]), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
printf("APP: SYSREF Clk: %lld\n", sysref_clk_204c);
|
||||
printf("APP: SYSREF Clk: %lld\n", sysref_clk_204);
|
||||
|
||||
/*Configure HMC7044 to Provide Clocks For Txfe & FPGA*/
|
||||
uint8_t hmc_priority[] = { 1, 0, 2, 3 };
|
||||
uint16_t hmc_out_ch = HMC7044_OP_CH_0 | HMC7044_OP_CH_2 | HMC7044_OP_CH_3 | HMC7044_OP_CH_6 | HMC7044_OP_CH_8 | HMC7044_OP_CH_10 | HMC7044_OP_CH_12 | HMC7044_OP_CH_13;
|
||||
uint64_t hmc_out_204c[14] = { fpga_clk, 0, ad9081_clk, sysref_clk_204c, 0, 0, jesd_core_clk, 0, fpga_clk, 0, jesd_core_clk, 0, fpga_clk, sysref_clk_204c };
|
||||
uint64_t hmc_out_204[14];
|
||||
|
||||
hmc_out_204[0] = fpga_clk;
|
||||
hmc_out_204[1] = 0;
|
||||
hmc_out_204[2] = ad9081_clk;
|
||||
hmc_out_204[3] = sysref_clk_204;
|
||||
hmc_out_204[4] = 0;
|
||||
hmc_out_204[5] = 0;
|
||||
hmc_out_204[6] = jesd_core_clk;
|
||||
hmc_out_204[7] = 0;
|
||||
hmc_out_204[8] = fpga_clk;
|
||||
hmc_out_204[9] = 0;
|
||||
hmc_out_204[10] = jesd_core_clk;
|
||||
hmc_out_204[11] = 0;
|
||||
hmc_out_204[12] = fpga_clk;
|
||||
hmc_out_204[13] = sysref_clk_204;
|
||||
|
||||
/* Disable SYSREF signal channels for Subclass 0 */
|
||||
if (((jrx_param[uc].jesd_subclass == 0) && (jtx_param[uc][0].jesd_subclass == 0))) {
|
||||
hmc_out_ch &= ~(HMC7044_OP_CH_3 | HMC7044_OP_CH_13);
|
||||
hmc_out_204c[3] = 0;
|
||||
hmc_out_204c[13] = 0;
|
||||
hmc_out_204[3] = 0;
|
||||
hmc_out_204[13] = 0;
|
||||
xil_printf("Disabling Sysref!!!!!!!\r\n");
|
||||
}
|
||||
|
||||
if (err = adi_hmc7044_device_init(&hmc7044_dev), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_hmc7044_device_reset(&hmc7044_dev, 0), err != API_CMS_ERROR_OK)
|
||||
@@ -241,7 +331,7 @@ void setup_data_converter() {
|
||||
if (err = adi_hmc7044_sysref_config_set(&hmc7044_dev, HMC7044_SYSREF_CONTINUOUS_MODE), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
|
||||
if (err = adi_hmc7044_clk_config(&hmc7044_dev, HMC7044_CLK_IN_0, hmc_priority, hmc7044_crystal_input, hmc7044_crystal_input, hmc_out_ch, hmc_out_204c), err != API_CMS_ERROR_OK) {
|
||||
if (err = adi_hmc7044_clk_config(&hmc7044_dev, HMC7044_CLK_IN_0, hmc_priority, hmc7044_crystal_input, hmc7044_crystal_input, hmc_out_ch, hmc_out_204), err != API_CMS_ERROR_OK) {
|
||||
if (err == API_CMS_ERROR_INVALID_PARAM)
|
||||
printf("APP: HMC7044: Invalid param passed.\n");
|
||||
error_print(__LINE__, err);
|
||||
@@ -263,6 +353,7 @@ void setup_data_converter() {
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
printf("APP: Reference Clocks Configured\n");
|
||||
// check_jesd_core_clk();
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
/* AD9081 Device Data Path Configuration Sequenece
|
||||
@@ -321,11 +412,18 @@ void setup_data_converter() {
|
||||
|
||||
// // DAC NCO TEST MODE!!!!!!
|
||||
// xil_printf("!!!!!!!!!!! DAC NCO TEST MODE !!!!!!!!!!!!!!!!!!!!!!!\r\n");
|
||||
// if (err = adi_ad9081_device_startup_nco_test_mode(&ad9081_dev, tx_interp[uc][0], tx_interp[uc][1], tx_dac_chan_xbar[uc],
|
||||
// tx_main_shift[uc], tx_chan_shift[uc], &jrx_param[uc], (uint16_t)pow(10, ((0 + 20 * log10(0x5a82)) / 20))), err != API_CMS_ERROR_OK)
|
||||
// return err;
|
||||
|
||||
|
||||
// // DC Offset from examples was 0x5a82
|
||||
// err = adi_ad9081_device_startup_nco_test_mode(&ad9081_dev,
|
||||
// tx_interp[uc][0],
|
||||
// tx_interp[uc][1],
|
||||
// tx_dac_chan_xbar[uc],
|
||||
// tx_main_shift[uc],
|
||||
// tx_chan_shift[uc],
|
||||
// &jrx_param[uc],
|
||||
// (uint16_t)pow(10, ((0 + 20 * log10(0x5a82)) / 20)));
|
||||
// if (err != API_CMS_ERROR_OK) {
|
||||
// error_print(__LINE__, err);
|
||||
// }
|
||||
|
||||
/* start ad9081 tx */
|
||||
if (err = adi_ad9081_device_startup_tx(&ad9081_dev, tx_interp[uc][0], tx_interp[uc][1], tx_dac_chan_xbar[uc],
|
||||
@@ -351,42 +449,40 @@ void setup_data_converter() {
|
||||
}
|
||||
|
||||
/* Configure Synchronization Options as per Application Use-case*/
|
||||
/* By Default Application uses Subclass 0 and Internal Sysref Synchronization*/
|
||||
/* Note 21/26/27 Are examples of Subclass 1*/
|
||||
printf("APP: JESD RX Synchronization Mode: %s\n", ((jrx_param[uc].jesd_subclass == JESD_SUBCLASS_1) ? "JESD_SUBCLASS_1" : "JESD_SUBCLASS_0"));
|
||||
/* Configure Sysref Receiver and Input mode */
|
||||
if (err = adi_ad9081_sync_sysref_input_config_set(&ad9081_dev, COUPLING_AC, SIGNAL_CML, 0, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
/* Configure cddc nco sync */
|
||||
if (err = adi_ad9081_adc_ddc_coarse_sync_enable_set(&ad9081_dev, AD9081_ADC_CDDC_ALL, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_adc_ddc_coarse_sync_next_set(&ad9081_dev, AD9081_ADC_CDDC_ALL, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_adc_ddc_coarse_trig_nco_reset_enable_set(&ad9081_dev, AD9081_ADC_CDDC_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
/* Perform oneshot sync */
|
||||
if (err = adi_ad9081_jesd_oneshot_sync(&ad9081_dev, 1), err != API_CMS_ERROR_OK){
|
||||
if (err == API_CMS_ERROR_JESD_SYNC_NOT_DONE) {
|
||||
printf("APP: JESD Oneshot Synchronization Not Completed\n");
|
||||
xil_printf("APP: JESD RX Synchronization Mode: %s\r\n", ((jrx_param[uc].jesd_subclass == JESD_SUBCLASS_1) ? "JESD_SUBCLASS_1" : "JESD_SUBCLASS_0"));
|
||||
if (jtx_param[uc][0].jesd_subclass == 1) {
|
||||
/* Configure Sysref Receiver and Input mode */
|
||||
if (err = adi_ad9081_sync_sysref_input_config_set(&ad9081_dev, COUPLING_AC, SIGNAL_CML, 0, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
/* Configure cddc nco sync */
|
||||
if (err = adi_ad9081_adc_ddc_coarse_sync_enable_set(&ad9081_dev, AD9081_ADC_CDDC_ALL, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_adc_ddc_coarse_sync_next_set(&ad9081_dev, AD9081_ADC_CDDC_ALL, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_adc_ddc_coarse_trig_nco_reset_enable_set(&ad9081_dev, AD9081_ADC_CDDC_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
/* Perform oneshot sync */
|
||||
if (err = adi_ad9081_jesd_oneshot_sync(&ad9081_dev, 1), err != API_CMS_ERROR_OK){
|
||||
if (err == API_CMS_ERROR_JESD_SYNC_NOT_DONE) {
|
||||
printf("APP: JESD Oneshot Synchronization Not Completed\n");
|
||||
}
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
if (err = adi_ad9081_jesd_sysref_monitor_phase_get(&ad9081_dev, &phase), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
printf("APP: Phase offset between incoming SYSREF and internal LMFC/LEMC: %d DAC clock units\n", phase);
|
||||
} else {
|
||||
/* Power down Sysref Receiver circuitry*/
|
||||
if (err = adi_ad9081_jesd_sysref_input_mode_set(&ad9081_dev, jrx_param[uc].jesd_subclass > 0 ? 1 : 0, jrx_param[uc].jesd_subclass > 0 ? 1 : 0, COUPLING_AC), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
/* Perform oneshot sync */
|
||||
if (err = adi_ad9081_jesd_oneshot_sync(&ad9081_dev, 0), err != API_CMS_ERROR_OK){
|
||||
if (err == API_CMS_ERROR_JESD_SYNC_NOT_DONE) {
|
||||
xil_printf("APP: JESD Oneshot Synchronization Not Completed\r\n");
|
||||
}
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
if (err = adi_ad9081_jesd_sysref_monitor_phase_get(&ad9081_dev, &phase), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
printf("APP: Phase offset between incoming SYSREF and internal LMFC/LEMC: %d DAC clock units\n", phase);
|
||||
|
||||
|
||||
printf("APP: JESD RX Synchronization Mode: %s\n", ((jrx_param[uc].jesd_subclass == JESD_SUBCLASS_1) ? "JESD_SUBCLASS_1" : "JESD_SUBCLASS_0"));
|
||||
/* Power down Sysref Receiver circuitry*/
|
||||
if (err = adi_ad9081_jesd_sysref_input_mode_set(&ad9081_dev, jrx_param[uc].jesd_subclass > 0 ? 1 : 0, jrx_param[uc].jesd_subclass > 0 ? 1 : 0, COUPLING_AC), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
/* Perform oneshot sync */
|
||||
if (err = adi_ad9081_jesd_oneshot_sync(&ad9081_dev, 0), err != API_CMS_ERROR_OK){
|
||||
if (err == API_CMS_ERROR_JESD_SYNC_NOT_DONE) {
|
||||
printf("APP: JESD Oneshot Synchronization Not Completed");
|
||||
}
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
|
||||
/* SYSTEM Link Bring Up Sequenece
|
||||
* Check AD9081 JESD PLL Lock Status
|
||||
@@ -406,32 +502,21 @@ void setup_data_converter() {
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
|
||||
// Enable RX and TX Link
|
||||
if (err = adi_ad9081_jesd_tx_link_enable_set(&ad9081_dev, (jtx_param[uc][0].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
|
||||
vTaskDelay(100);
|
||||
uint16_t status;
|
||||
if (err = adi_ad9081_jesd_tx_link_status_get(&ad9081_dev, AD9081_LINK_0, &status), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
xil_printf("Link Status 0x%x\r\n", status);
|
||||
|
||||
// // ILA TEST MODE
|
||||
// adi_ad9081_jesd_tx_ilas_test_mode_enable_set(&ad9081_dev, AD9081_LINK_0, 1);
|
||||
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
//
|
||||
// /* calibrate jrx when lane rate is high for 204c */
|
||||
// printf("APP: Run JESD RX 204C Calibration & Enable TX Path Links\n");
|
||||
// if ((jrx_param[uc].jesd_l > 0) && (jrx_param[uc].jesd_jesdv == 2) && ((clk_hz[uc][1] * 66) > AD9081_JESDRX_204C_CAL_THRESH)) {
|
||||
// if (err = adi_ad9081_jesd_rx_calibrate_204c(&ad9081_dev, 1, 0x00, (ad9081_dev.serdes_info.des_settings.cal_mode == AD9081_CAL_MODE_RUN_AND_SAVE) ? 0 : 1), err != API_CMS_ERROR_OK) {
|
||||
// printf("APP: ad9081 JESD RX Calibration Error\n");
|
||||
// error_print(__LINE__, err);
|
||||
// }
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// }
|
||||
|
||||
#ifdef IBERT_TESTING
|
||||
adi_ad9081_jesd_tx_phy_prbs_test(&ad9081_dev, AD9081_LINK_ALL, PRBS31);
|
||||
@@ -440,70 +525,71 @@ void setup_data_converter() {
|
||||
#ifndef IBERT_TESTING
|
||||
|
||||
// Update FPGA TX Transceiver settings
|
||||
set_lane_cal(0, 0, 0);
|
||||
set_lane_cal(1, 10, 5);
|
||||
set_lane_cal(2, 5, 0);
|
||||
set_lane_cal(3, 0, 0);
|
||||
set_lane_cal(4, 0, 0);
|
||||
set_lane_cal(5, 0, 0);
|
||||
set_lane_cal(6, 12, 0);
|
||||
set_lane_cal(7, 0, 0);
|
||||
set_lane_cal(0, 0, 0, 11);
|
||||
set_lane_cal(1, 10, 5, 11);
|
||||
set_lane_cal(2, 5, 0, 11);
|
||||
set_lane_cal(3, 0, 0, 11);
|
||||
set_lane_cal(4, 0, 0, 11);
|
||||
set_lane_cal(5, 0, 0, 11);
|
||||
set_lane_cal(6, 12, 0, 11);
|
||||
set_lane_cal(7, 0, 0, 11);
|
||||
|
||||
// set_lane_cal(0, 9, 0, 7);
|
||||
// set_lane_cal(1, 9, 0, 7);
|
||||
// set_lane_cal(2, 9, 0, 7);
|
||||
// set_lane_cal(3, 9, 0, 7);
|
||||
// set_lane_cal(4, 9, 0, 7);
|
||||
// set_lane_cal(5, 9, 0, 7);
|
||||
// set_lane_cal(6, 9, 0, 7);
|
||||
// set_lane_cal(7, 9, 0, 7);
|
||||
|
||||
vTaskDelay(100);
|
||||
int subclass = jtx_param[uc][0].jesd_subclass;
|
||||
int jesd_version = jtx_param[uc][0].jesd_jesdv;
|
||||
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(0x40050000 + 0x00C));
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(GPI_REG));
|
||||
|
||||
xil_printf("Reset FPGA JESD Cores\r\n");
|
||||
Xil_Out32(0x40050000 + 0x008, 0x31 | 0x300 | 0xC0);
|
||||
vTaskDelay(100);
|
||||
Xil_Out32(0x40050000 + 0x008, 0x31);
|
||||
reset_jesd();
|
||||
|
||||
// Wait for reset to complete
|
||||
xil_printf("Wait for RX to complete reset\r\n");
|
||||
int val = 1;
|
||||
while (val) {
|
||||
val = Xil_In32(JESD_RX + RESET_REG);
|
||||
xil_printf("rx reset state: 0x%x\r\n", val);
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(0x40050000 + 0x00C));
|
||||
vTaskDelay(10);
|
||||
}
|
||||
xil_printf("RX IP Config 0x%x\r\n", Xil_In32(JESD_RX + 4));
|
||||
xil_printf("TX IP Config 0x%x\r\n", Xil_In32(JESD_TX + 4));
|
||||
|
||||
xil_printf("Wait for TX to complete reset\r\n");
|
||||
val = 1;
|
||||
while (val) {
|
||||
val = Xil_In32(JESD_TX + RESET_REG);
|
||||
xil_printf("tx reset state: 0x%x\r\n", val);
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
// for (int i = 0; i < 8; i++){
|
||||
// uint32_t val0 = Xil_In32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x418);
|
||||
// uint32_t val1 = Xil_In32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x414);
|
||||
// uint32_t val2 = Xil_In32(XPAR_JESD_JESD204_PHY_0_BASEADDR + 0x608);
|
||||
// xil_printf("Lane %d, Pre %d, Post %d, RX %d\r\n", i, val0, val1, val2);
|
||||
// }
|
||||
|
||||
xil_printf("Changing MB in EMB\r\n");
|
||||
Xil_Out32(JESD_TX + CTRL_MB_IN_EMB, 1);
|
||||
Xil_Out32(JESD_RX + CTRL_MB_IN_EMB, 1);
|
||||
|
||||
xil_printf("Changing Subclass\r\n");
|
||||
Xil_Out32(JESD_TX + 0x34, subclass);
|
||||
Xil_Out32(JESD_RX + 0x34, subclass);
|
||||
|
||||
xil_printf("Changing Meta\r\n");
|
||||
Xil_Out32(JESD_TX + 0x34, 0);
|
||||
Xil_Out32(JESD_RX + 0x34, 0);
|
||||
|
||||
xil_printf("Changing Ctrl Sysref\r\n");
|
||||
Xil_Out32(JESD_TX + 0x50, 2);
|
||||
Xil_Out32(JESD_RX + 0x50, 2);
|
||||
Xil_Out32(JESD_TX + 0x50, 0);
|
||||
Xil_Out32(JESD_RX + 0x50, 0);
|
||||
if (subclass == 1) {
|
||||
Xil_Out32(JESD_TX + 0x50, 2);
|
||||
Xil_Out32(JESD_RX + 0x50, 2);
|
||||
}
|
||||
|
||||
if (jesd_version == JESD_204C) {
|
||||
// 204C
|
||||
xil_printf("Changing MB in EMB\r\n");
|
||||
Xil_Out32(JESD_TX + CTRL_MB_IN_EMB, 1);
|
||||
Xil_Out32(JESD_RX + CTRL_MB_IN_EMB, 1);
|
||||
|
||||
xil_printf("Changing Meta\r\n");
|
||||
Xil_Out32(JESD_TX + 0x34, 0);
|
||||
Xil_Out32(JESD_RX + 0x34, 0);
|
||||
// Xil_Out32(JESD_TX + 0x34, 3); // FEC
|
||||
// Xil_Out32(JESD_RX + 0x34, 3); // FEC
|
||||
}
|
||||
|
||||
if (jesd_version == JESD_204B) {
|
||||
//204B
|
||||
xil_printf("204B CTRL_8B10B_CFG\r\n");
|
||||
Xil_Out32(JESD_TX + 0x3C, 0x03031F01);
|
||||
Xil_Out32(JESD_RX + 0x3C, 0x03031F01);
|
||||
}
|
||||
|
||||
Xil_Out32(JESD_RX + CTRL_RX_BUF_ADV, 0);
|
||||
val = Xil_In32(JESD_RX + CTRL_RX_BUF_ADV);
|
||||
uint32_t val = Xil_In32(JESD_RX + CTRL_RX_BUF_ADV);
|
||||
if (val != 0) {
|
||||
xil_printf("ERROR. Buffer Advance (RX) not updated.\r\n");
|
||||
val = Xil_In32(JESD_RX + STAT_STATUS_REG);
|
||||
@@ -511,57 +597,67 @@ void setup_data_converter() {
|
||||
}
|
||||
|
||||
xil_printf("Reset both modules to update configuration\r\n");
|
||||
Xil_Out32(0x40050000 + 0x008, 0x31 | 0x300 | 0xC0);
|
||||
vTaskDelay(100);
|
||||
Xil_Out32(0x40050000 + 0x008, 0x31);
|
||||
reset_jesd();
|
||||
|
||||
// Wait for reset to complete
|
||||
xil_printf("Wait for RX to complete reset\r\n");
|
||||
val = 1;
|
||||
while (val) {
|
||||
val = Xil_In32(JESD_RX + RESET_REG);
|
||||
xil_printf("rx reset state: 0x%x\r\n", val);
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(0x40050000 + 0x00C));
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
xil_printf("Wait for TX to complete reset\r\n");
|
||||
val = 1;
|
||||
while (val) {
|
||||
val = Xil_In32(JESD_TX + RESET_REG);
|
||||
xil_printf("tx reset state: 0x%x\r\n", val);
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
xil_printf("Wait for Block Sync\r\n");
|
||||
val = 0;
|
||||
while ((val & STATUS_SH_LOCK_BIT) != STATUS_SH_LOCK_BIT) {
|
||||
val = Xil_In32(JESD_RX + STAT_STATUS_REG);
|
||||
if (jesd_version == JESD_204C) {
|
||||
xil_printf("Wait for Block Sync\r\n");
|
||||
val = 0;
|
||||
while ((val & STATUS_SH_LOCK_BIT) != STATUS_SH_LOCK_BIT) {
|
||||
val = Xil_In32(JESD_RX + STAT_STATUS_REG);
|
||||
xil_printf("STAT_STATUS_REG 0x%x\r\n", val);
|
||||
xil_printf("RX STAT_LOCK_DEBUG: 0x%x\r\n", Xil_In32(JESD_RX + 0x54));
|
||||
vTaskDelay(200);
|
||||
}
|
||||
xil_printf("* Block sync achieved\r\n");
|
||||
xil_printf("STAT_STATUS_REG 0x%x\r\n", val);
|
||||
xil_printf("RX STAT_LOCK_DEBUG: 0x%x\r\n", Xil_In32(JESD_RX + 0x54));
|
||||
vTaskDelay(100);
|
||||
|
||||
xil_printf("Wait for Extended Multiblock lock\r\n");
|
||||
val = 0;
|
||||
while ((val & STATUS_EMB_LOCK_BIT) != STATUS_EMB_LOCK_BIT) {
|
||||
val = Xil_In32(JESD_RX + STAT_STATUS_REG);
|
||||
xil_printf("STAT_STATUS_REG 0x%x\r\n", val);
|
||||
xil_printf("RX STAT_LOCK_DEBUG: 0x%x\r\n", Xil_In32(JESD_RX + 0x54));
|
||||
xil_printf("RX EMB: 0x%x\r\n", Xil_In32(JESD_RX + CTRL_MB_IN_EMB));
|
||||
uint8_t data;
|
||||
// adi_ad9081_hal_bf_set(&ad9081_dev, 0x00000667, BF_JTX_CRC_FEC_REVERSE_CFG_INFO, 1);
|
||||
adi_ad9081_hal_reg_get(&ad9081_dev, 0x00000667, &data);
|
||||
xil_printf("0x00000667: 0x%x\r\n", data);
|
||||
|
||||
|
||||
// for (int i = 0; i < 8; i++) {
|
||||
// // Clear Error Counts
|
||||
// uint32_t err_cnt = Xil_In32(JESD_RX + 0x400 + i * 0x080 + 0x10);
|
||||
// xil_printf(" Lane %d STAT_RX_ERROR_CNT0 = 0x%x\r\n", err_cnt);
|
||||
// }
|
||||
vTaskDelay(100);
|
||||
}
|
||||
xil_printf("* Extended Multiblock lock achieved\r\n");
|
||||
}
|
||||
xil_printf("* Block sync achieved\r\n");
|
||||
xil_printf("STAT_STATUS_REG 0x%x\r\n", val);
|
||||
xil_printf("RX STAT_LOCK_DEBUG: 0x%x\r\n", Xil_In32(JESD_RX + 0x54));
|
||||
if (jesd_version == JESD_204B) {
|
||||
// xil_printf("Enable TX data and command stream\r\n");
|
||||
// Xil_Out32(JESD_TX + CTRL_ENABLE_REG, ENABLE_DATA_CMD);
|
||||
//
|
||||
// xil_printf("Enable RX data and command stream\r\n");
|
||||
// Xil_Out32(JESD_RX + CTRL_ENABLE_REG, ENABLE_DATA_CMD);
|
||||
|
||||
xil_printf("Wait for Extended Multiblock lock\r\n");
|
||||
val = 0;
|
||||
while ((val & STATUS_EMB_LOCK_BIT) != STATUS_EMB_LOCK_BIT) {
|
||||
val = Xil_In32(JESD_RX + STAT_STATUS_REG);
|
||||
xil_printf("STAT_STATUS_REG 0x%x\r\n", val);
|
||||
xil_printf("RX STAT_LOCK_DEBUG: 0x%x\r\n", Xil_In32(JESD_RX + 0x54));
|
||||
xil_printf("RX EMB: 0x%x\r\n", Xil_In32(JESD_RX + CTRL_MB_IN_EMB));
|
||||
val = 0;
|
||||
while ((val & 0x7000) != 0x7000) {
|
||||
val = Xil_In32(JESD_RX + STAT_STATUS_REG);
|
||||
xil_printf("STAT_STATUS_REG 0x%x\r\n", val);
|
||||
xil_printf("RX 204B STAT_RX_ERR: 0x%x\r\n", Xil_In32(JESD_RX + 0x58));
|
||||
xil_printf("RX 204B STAT_RX_DEBUG: 0x%x\r\n", Xil_In32(JESD_RX + 0x5C));
|
||||
uint16_t status;
|
||||
if (err = adi_ad9081_jesd_tx_link_status_get(&ad9081_dev, AD9081_LINK_0, &status), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
xil_printf("Link Status 0x%x\r\n", status);
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(GPI_REG));
|
||||
|
||||
print_rx_ila();
|
||||
|
||||
// for (int i = 0; i < 8; i++) {
|
||||
// // Clear Error Counts
|
||||
// uint32_t err_cnt = Xil_In32(JESD_RX + 0x400 + i * 0x100 + 0x10);
|
||||
// xil_printf(" Lane %d STAT_RX_ERROR_CNT0 = 0x%x\r\n", err_cnt);
|
||||
// }
|
||||
vTaskDelay(100);
|
||||
vTaskDelay(400);
|
||||
}
|
||||
}
|
||||
xil_printf("* Extended Multiblock lock achieved\r\n");
|
||||
|
||||
xil_printf("Enable TX data and command stream\r\n");
|
||||
Xil_Out32(JESD_TX + CTRL_ENABLE_REG, ENABLE_DATA_CMD);
|
||||
@@ -572,7 +668,7 @@ void setup_data_converter() {
|
||||
|
||||
vTaskDelay(100);
|
||||
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(0x40050000 + 0x00C));
|
||||
xil_printf("GPI: 0x%x\r\n", Xil_In32(GPI_REG));
|
||||
|
||||
xil_printf("RX Version: 0x%x\r\n", Xil_In32(JESD_RX + 0x000));
|
||||
xil_printf("RX Config: 0x%x\r\n", Xil_In32(JESD_RX + 0x004));
|
||||
@@ -601,42 +697,56 @@ void setup_data_converter() {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Toggle JESD RX Enable
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
|
||||
/* calibrate jrx when lane rate is high for 204c */
|
||||
printf("APP: Run JESD RX 204C Calibration & Enable TX Path Links\n");
|
||||
if ((jrx_param[uc].jesd_l > 0) && (jrx_param[uc].jesd_jesdv == 2) && ((clk_hz[uc][1] * 66) > AD9081_JESDRX_204C_CAL_THRESH)) {
|
||||
if (err = adi_ad9081_jesd_rx_calibrate_204c(&ad9081_dev, 1, 0x00, (ad9081_dev.serdes_info.des_settings.cal_mode == AD9081_CAL_MODE_RUN_AND_SAVE) ? 0 : 1), err != API_CMS_ERROR_OK) {
|
||||
printf("APP: ad9081 JESD RX Calibration Error\n");
|
||||
// if (1) {
|
||||
xil_printf("APP: Run JESD RX 204C Calibration & Enable TX Path Links\r\n");
|
||||
// if (err = adi_ad9081_jesd_rx_calibrate_204c(&ad9081_dev, 1, 0x00, (ad9081_dev.serdes_info.des_settings.cal_mode == AD9081_CAL_MODE_RUN_AND_SAVE) ? 0 : 1), err != API_CMS_ERROR_OK) {
|
||||
// xil_printf("APP: ad9081 JESD RX Calibration Error\r\n");
|
||||
// error_print(__LINE__, err);
|
||||
// }
|
||||
//
|
||||
if (err = adi_ad9081_jesd_rx_calibrate_204c(&ad9081_dev, 1, 0x00, 1), err != API_CMS_ERROR_OK) {
|
||||
xil_printf("APP: ad9081 JESD RX Calibration Error\r\n");
|
||||
error_print(__LINE__, err);
|
||||
}
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_calibrate_204c(&ad9081_dev, 1, 0xFF, 1), err != API_CMS_ERROR_OK) {
|
||||
// xil_printf("APP: ad9081 JESD RX Calibration Error\r\n");
|
||||
// error_print(__LINE__, err);
|
||||
// }
|
||||
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, AD9081_LINK_ALL, 0), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
// if (err = adi_ad9081_jesd_rx_link_enable_set(&ad9081_dev, (jrx_param[uc].jesd_duallink > 0) ? AD9081_LINK_ALL : AD9081_LINK_0, 1), err != API_CMS_ERROR_OK)
|
||||
// error_print(__LINE__, err);
|
||||
}
|
||||
|
||||
#ifndef IBERT_TESTING
|
||||
for (int i = 0; i < 8; i++) {
|
||||
// Clear Error Counts
|
||||
Xil_In32(JESD_RX + 0x400 + i * 0x100 + 0x10);
|
||||
Xil_In32(JESD_RX + 0x400 + i * 0x080 + 0x10);
|
||||
}
|
||||
vTaskDelay(100);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
xil_printf("Lane %d Buf Level: 0x%x\r\n", i, Xil_In32(JESD_RX + 0x400 + i * 0x100 + 0x0));
|
||||
xil_printf("Lane %d Stat 0: 0x%x\r\n", i, Xil_In32(JESD_RX + 0x400 + i * 0x100 + 0x10));
|
||||
xil_printf("Lane %d Stat 1: 0x%x\r\n", i, Xil_In32(JESD_RX + 0x400 + i * 0x100 + 0x14));
|
||||
xil_printf("Lane %d Buf Level: 0x%x\r\n", i, Xil_In32(JESD_RX + 0x400 + i * 0x080 + 0x0));
|
||||
xil_printf("Lane %d Stat 0: 0x%x\r\n", i, Xil_In32(JESD_RX + 0x400 + i * 0x080 + 0x10));
|
||||
xil_printf("Lane %d Stat 1: 0x%x\r\n", i, Xil_In32(JESD_RX + 0x400 + i * 0x080 + 0x14));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef IBERT_TESTING
|
||||
int cal_count = 0;
|
||||
while (1) {
|
||||
adi_ad9081_jesd_rx_phy_prbs_test(&ad9081_dev, PRBS31, 100);
|
||||
xil_printf("Check PRBS Errors\r\n");
|
||||
@@ -645,6 +755,17 @@ void setup_data_converter() {
|
||||
adi_ad9081_jesd_rx_phy_prbs_test_result_get(&ad9081_dev, i, &prbs_res);
|
||||
xil_printf(" Lane %d, Errors %d\r\n", i, prbs_res.phy_prbs_err_cnt);
|
||||
}
|
||||
|
||||
cal_count++;
|
||||
|
||||
// if (cal_count > 9) {
|
||||
// cal_count = 0;
|
||||
// if (err = adi_ad9081_jesd_rx_calibrate_204c(&ad9081_dev, 1, 0x00, 1), err != API_CMS_ERROR_OK) {
|
||||
// xil_printf("APP: ad9081 JESD RX Calibration Error\r\n");
|
||||
// error_print(__LINE__, err);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ void main_task( void *pvParameters ) {
|
||||
setup_data_converter();
|
||||
|
||||
while (1) {
|
||||
toggleBit(0x40050008, 0); // Toggle LED
|
||||
toggleBit(GPO_REG, 0); // Toggle LED
|
||||
vTaskDelay(100);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ void main_task( void *pvParameters ) {
|
||||
int main(void) {
|
||||
xil_printf("\n\r\n\r================= Start ====================\n\r\n\r");
|
||||
|
||||
Xil_Out32(0x40050008, 0x11);
|
||||
Xil_Out32(GPO_REG, 0x11);
|
||||
|
||||
xTaskCreate( status_task,
|
||||
( const char * ) "status",
|
||||
|
||||
@@ -78,6 +78,9 @@ extern adi_ad9081_device_t * ad9081_dev_ptr;
|
||||
#define STAT_RX_BUF_LVL6 0x700
|
||||
#define STAT_RX_BUF_LVL7 0x780
|
||||
|
||||
#define JESD_204B 1
|
||||
#define JESD_204C 2
|
||||
|
||||
int32_t rf_spi_write(int dev_sel, int num_bits, int data);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -122,7 +122,7 @@ void radar_manager_parse_message(u8 * msgBuffer)
|
||||
case SET_AD9081_DAC_NCO:
|
||||
{
|
||||
ncoConfigType *msg = (ncoConfigType *)msgBuffer;
|
||||
xil_printf("Set DAC NCO, Ch %d, Freq %d\r\n", msg->channel, (int)msg->frequency);
|
||||
xil_printf("Set DAC NCO, Ch %d, Freq %d\r\n", msg->channel, (int)(msg->frequency / 1e3));
|
||||
adi_ad9081_dac_duc_nco_set(ad9081_dev_ptr, AD9081_DAC_0 << msg->channel, AD9081_DAC_CH_NONE, msg->frequency);
|
||||
}
|
||||
break;
|
||||
@@ -130,7 +130,7 @@ void radar_manager_parse_message(u8 * msgBuffer)
|
||||
case SET_AD9081_ADC_NCO:
|
||||
{
|
||||
ncoConfigType *msg = (ncoConfigType *)msgBuffer;
|
||||
xil_printf("Set ADC NCO, Ch %d, Freq %d\r\n", msg->channel, (int)msg->frequency);
|
||||
xil_printf("Set ADC NCO, Ch %d, Freq %d\r\n", msg->channel, (int)(msg->frequency / 1e3));
|
||||
adi_ad9081_adc_ddc_coarse_nco_set(ad9081_dev_ptr, AD9081_ADC_CDDC_0 << msg->channel, msg->frequency);
|
||||
}
|
||||
break;
|
||||
@@ -142,6 +142,42 @@ void radar_manager_parse_message(u8 * msgBuffer)
|
||||
}
|
||||
break;
|
||||
|
||||
case SET_LANE_MAPPING:
|
||||
{
|
||||
laneMappingType *msg = (laneMappingType *)msgBuffer;
|
||||
adi_ad9081_jesd_tx_link_enable_set(ad9081_dev_ptr, AD9081_LINK_0, 0);
|
||||
adi_ad9081_jesd_tx_lanes_xbar_set(ad9081_dev_ptr, AD9081_LINK_0, msg->lane_map);
|
||||
adi_ad9081_jesd_tx_link_enable_set(ad9081_dev_ptr, AD9081_LINK_0, 1);
|
||||
reset_jesd();
|
||||
}
|
||||
break;
|
||||
|
||||
case AD9081_REG_WRITE:
|
||||
{
|
||||
writeRegType *msg = (writeRegType *)msgBuffer;
|
||||
adi_ad9081_hal_reg_set(ad9081_dev_ptr, msg->addr, msg->data);
|
||||
}
|
||||
break;
|
||||
|
||||
case AD9081_REG_READ:
|
||||
{
|
||||
readRegType *msg = (readRegType *)msgBuffer;
|
||||
readRespType resp;
|
||||
|
||||
uint8_t val;
|
||||
adi_ad9081_hal_reg_get(ad9081_dev_ptr, msg->addr, &val);
|
||||
|
||||
resp.header.fsync = FSYNC;
|
||||
resp.header.type = AXI_READ_RESP;
|
||||
resp.header.length = sizeof(resp);
|
||||
|
||||
resp.data = val;
|
||||
|
||||
send_data((u8 *)&resp, sizeof(resp));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_PRINT("Unknown Type 0x%04X!\r\n", header->type);
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,9 @@ void radar_manager_parse_message(u8 * msgBuffer);
|
||||
#define RF_SPI_WRITE 7
|
||||
#define SET_AD9081_DAC_NCO 128
|
||||
#define SET_AD9081_ADC_NCO 129
|
||||
#define SET_LANE_MAPPING 130
|
||||
#define AD9081_REG_WRITE 131
|
||||
#define AD9081_REG_READ 132
|
||||
|
||||
#define HDR_FLAG_REQ_ACK 0x01
|
||||
|
||||
@@ -63,7 +66,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
headerType header;
|
||||
unsigned int channel;
|
||||
float frequency;
|
||||
int64_t frequency;
|
||||
} ncoConfigType;
|
||||
|
||||
typedef struct {
|
||||
@@ -73,6 +76,11 @@ typedef struct {
|
||||
unsigned int data;
|
||||
} rfSpiWriteType;
|
||||
|
||||
typedef struct {
|
||||
headerType header;
|
||||
uint8_t lane_map[8];
|
||||
} laneMappingType;
|
||||
|
||||
//typedef struct {
|
||||
// uint32_t num_pulses;
|
||||
// uint32_t num_pulses;
|
||||
|
||||
@@ -2,11 +2,29 @@
|
||||
#define __REGISTERS_H__
|
||||
|
||||
|
||||
#define UTIL_ADDR 0x40050000
|
||||
#define UTIL_ADDR 0x40050000
|
||||
#define GPO_REG (UTIL_ADDR + 0x08)
|
||||
#define ETH_10G_RST 0x8000
|
||||
#define JESD_CORE_CLK_SEL 0x0800
|
||||
#define QSPI_FLASH_RST 0x0400
|
||||
#define JESD_TX_SYS_RST 0x0200
|
||||
#define JESD_RX_SYS_RST 0x0100
|
||||
#define JESD_TX_CORE_RST 0x0080
|
||||
#define JESD_RX_CORE_RST 0x0040
|
||||
#define RESETB 0x0020
|
||||
#define FMC_PWR_EN 0x0010
|
||||
#define ALL_JESD_RST (JESD_TX_SYS_RST | JESD_RX_SYS_RST | JESD_TX_CORE_RST | JESD_RX_CORE_RST)
|
||||
#define GPI_REG (UTIL_ADDR + 0x0C)
|
||||
|
||||
|
||||
|
||||
#define TIMING_ENGINE_ADDR 0x40051000
|
||||
#define DIG_RX_ADDR 0x20000000
|
||||
#define DIG_RX_STRIDE 0x10000
|
||||
#define WAVEFORM_GEN_ADDR 0x40053000
|
||||
|
||||
|
||||
|
||||
|
||||
#define TIMING_ENGINE_ADDR 0x40051000
|
||||
#define DIG_RX_ADDR 0x20000000
|
||||
#define DIG_RX_STRIDE 0x10000
|
||||
#define WAVEFORM_GEN_ADDR 0x40053000
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,12 @@ build a usecase parameters for a custom application.
|
||||
uint64_t clk_hz[][4] = {
|
||||
/*dev_ref, fpga_ref, dac_clk, adc_clk */
|
||||
{ 93.75e6, 187.5e6, 9000e6, 3000e6 },
|
||||
{ 118.75e6, 237.5e6, 11400e6, 3800e6 },
|
||||
{ 112.5e6, 225e6, 10800e6, 3600e6 },
|
||||
{ 125e6, 250e6, 6000e6, 3000e6 },
|
||||
// { 125e6, 250e6, 12000e6, 4000e6 },
|
||||
{ 93.75e6, 187.5e6, 9000e6, 3000e6 },
|
||||
// { 100e6, 250e6, 12000e6, 4000e6 },
|
||||
|
||||
}; // 204B
|
||||
|
||||
#if !defined(AD9207_ID) && !defined(AD9209_ID)
|
||||
@@ -95,32 +100,42 @@ uint64_t clk_hz[][4] = {
|
||||
*
|
||||
*/
|
||||
|
||||
#define tx_if_freq 500e6
|
||||
#define rx_if_freq 500e6
|
||||
#define tx_if_freq 1010e6
|
||||
#define rx_if_freq 1000e6
|
||||
//#define if_freq 10e6
|
||||
|
||||
uint8_t tx_dac_chan_xbar[][4] = { /* dac0, dac1, dac2, dac3 */
|
||||
{ AD9081_DAC_CH_0, AD9081_DAC_CH_1, AD9081_DAC_CH_2, AD9081_DAC_CH_3 },
|
||||
{ AD9081_DAC_CH_0, AD9081_DAC_CH_1, AD9081_DAC_CH_2, AD9081_DAC_CH_3 },
|
||||
{ AD9081_DAC_CH_0, AD9081_DAC_CH_1, AD9081_DAC_CH_2, AD9081_DAC_CH_3 },
|
||||
{ AD9081_DAC_CH_0, AD9081_DAC_CH_1, AD9081_DAC_CH_2, AD9081_DAC_CH_3 },
|
||||
};
|
||||
|
||||
int64_t tx_main_shift[][4] = { /* dac0, dac1, dac2, dac3 */
|
||||
{ tx_if_freq, tx_if_freq, tx_if_freq, tx_if_freq }, /* uc13*/
|
||||
{ tx_if_freq, tx_if_freq, tx_if_freq, tx_if_freq }, /* uc13*/
|
||||
{ tx_if_freq, tx_if_freq, tx_if_freq, tx_if_freq }, /* uc13*/
|
||||
{ tx_if_freq, tx_if_freq, tx_if_freq, tx_if_freq }, /* uc13*/
|
||||
};
|
||||
|
||||
int64_t tx_chan_shift[][8] = { /* ch0, ch1, ch2, ch3, ch4, ch5, ch6, ch7 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
};
|
||||
int8_t tx_chan_gain[][8] = { /* ch0, ch1, ch2, ch3, ch4, ch5, ch6, ch7 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
};
|
||||
uint8_t tx_interp[][2] = {
|
||||
/* {main DUC Interpolation, Channelizer DUC Interpolation} */
|
||||
{ 12, 1 }, /* uc13*/
|
||||
{ 12, 1 }, /* uc13*/
|
||||
{ 8, 3 }, /* uc13*/
|
||||
{ 12, 2 }, /* uc13*/
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -134,6 +149,8 @@ uint8_t tx_interp[][2] = {
|
||||
uint8_t rx_cddc_select[] = {
|
||||
AD9081_ADC_CDDC_0 | AD9081_ADC_CDDC_1 | AD9081_ADC_CDDC_2 | AD9081_ADC_CDDC_3, /* uc13*/
|
||||
AD9081_ADC_CDDC_0 | AD9081_ADC_CDDC_1 | AD9081_ADC_CDDC_2 | AD9081_ADC_CDDC_3, /* uc13*/
|
||||
AD9081_ADC_CDDC_0 | AD9081_ADC_CDDC_1 | AD9081_ADC_CDDC_2 | AD9081_ADC_CDDC_3, /* uc13*/
|
||||
AD9081_ADC_CDDC_0 | AD9081_ADC_CDDC_1 | AD9081_ADC_CDDC_2 | AD9081_ADC_CDDC_3, /* uc13*/
|
||||
};
|
||||
|
||||
/* RX Main Path DDC NCO Frequency Configuration
|
||||
@@ -148,6 +165,8 @@ int64_t rx_cddc_shift[][4] = {
|
||||
/* {cddc0, cddc1, cddc2, cddc3 }*/
|
||||
{ rx_if_freq, rx_if_freq, rx_if_freq, rx_if_freq}, /* uc13*/
|
||||
{ rx_if_freq, rx_if_freq, rx_if_freq, rx_if_freq}, /* uc13*/
|
||||
{ rx_if_freq, rx_if_freq, rx_if_freq, rx_if_freq}, /* uc13*/
|
||||
{ rx_if_freq, rx_if_freq, rx_if_freq, rx_if_freq}, /* uc13*/
|
||||
};
|
||||
/* RX Main Path DDC Data Decimation
|
||||
* List the ADC_Coarse DDCs desired data decimation
|
||||
@@ -162,6 +181,8 @@ uint8_t rx_cddc_dcm[][4] = {
|
||||
/*{cddc0, cddc1, cddc2, cddc3} */
|
||||
{ AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4 }, /* uc13*/
|
||||
{ AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4 }, /* uc13*/
|
||||
{ AD9081_CDDC_DCM_6, AD9081_CDDC_DCM_6, AD9081_CDDC_DCM_6, AD9081_CDDC_DCM_6 }, /* uc13*/
|
||||
{ AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4, AD9081_CDDC_DCM_4 }, /* uc13*/
|
||||
};
|
||||
/* RX Main Path DDC Has Optional Complex to Real Convertor
|
||||
* rx_cddc_c2r sets the enable for Complex to Real Converter per Main/Coarse DDC
|
||||
@@ -176,6 +197,8 @@ uint8_t rx_cddc_dcm[][4] = {
|
||||
uint8_t rx_cddc_c2r[][4] = { /* cddc0, cddc1, cddc2, cddc3 */
|
||||
{ 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0 }, /* uc13*/
|
||||
};
|
||||
/* RX Channelizer/Fine DDC Datapath Selection
|
||||
* List the ADC Fine DDCs data path for routing Data from Main/ Coarse DDC Datapth to the JESD Tx
|
||||
@@ -193,6 +216,8 @@ uint8_t rx_cddc_c2r[][4] = { /* cddc0, cddc1, cddc2, cddc3 */
|
||||
uint8_t rx_fddc_select[] = {
|
||||
AD9081_ADC_FDDC_0 | AD9081_ADC_FDDC_1 | AD9081_ADC_FDDC_4 | AD9081_ADC_FDDC_5, /* uc13*/
|
||||
AD9081_ADC_FDDC_0 | AD9081_ADC_FDDC_1 | AD9081_ADC_FDDC_4 | AD9081_ADC_FDDC_5, /* uc13*/
|
||||
AD9081_ADC_FDDC_0 | AD9081_ADC_FDDC_1 | AD9081_ADC_FDDC_4 | AD9081_ADC_FDDC_5, /* uc13*/
|
||||
AD9081_ADC_FDDC_0 | AD9081_ADC_FDDC_1 | AD9081_ADC_FDDC_4 | AD9081_ADC_FDDC_5, /* uc13*/
|
||||
};
|
||||
/* RX Channelizer Path DDC NCO Frequency Configuration
|
||||
* List the ADC_Fine DDCs desired Frequency Shift
|
||||
@@ -206,6 +231,8 @@ int64_t rx_fddc_shift[][8] = {
|
||||
/* fddc0, fddc1, fddc2, fddc3, fddc4, fddc5, fdddc6, fddc7 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* uc13*/
|
||||
};
|
||||
/* RX Channelizer Data Decimation
|
||||
* List the ADC Fine DDCs desired data decimation
|
||||
@@ -220,6 +247,8 @@ int64_t rx_fddc_shift[][8] = {
|
||||
uint8_t rx_fddc_dcm[][8] = { /* fddc0, fddc1, fddc2, fddc3, fddc4, fddc5, fdddc6, fddc7 */
|
||||
{ AD9081_FDDC_DCM_1, AD9081_FDDC_DCM_1, 0, 0, AD9081_FDDC_DCM_1, AD9081_FDDC_DCM_1, 0, 0 }, /* uc13*/
|
||||
{ AD9081_FDDC_DCM_1, AD9081_FDDC_DCM_1, 0, 0, AD9081_FDDC_DCM_1, AD9081_FDDC_DCM_1, 0, 0 }, /* uc13*/
|
||||
{ AD9081_FDDC_DCM_1, AD9081_FDDC_DCM_1, 0, 0, AD9081_FDDC_DCM_1, AD9081_FDDC_DCM_1, 0, 0 }, /* uc13*/
|
||||
{ AD9081_FDDC_DCM_2, AD9081_FDDC_DCM_2, 0, 0, AD9081_FDDC_DCM_2, AD9081_FDDC_DCM_2, 0, 0 }, /* uc13*/
|
||||
};
|
||||
uint8_t rx_fddc_c2r[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* uc */
|
||||
|
||||
@@ -243,6 +272,8 @@ uint8_t rx_fddc_c2r[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* uc */
|
||||
adi_ad9081_jtx_conv_sel_t jtx_conv_sel[][2] = {
|
||||
{ { AD9081_FDDC_0_I, AD9081_FDDC_0_Q, AD9081_FDDC_1_I, AD9081_FDDC_1_Q, AD9081_FDDC_4_I, AD9081_FDDC_4_Q, AD9081_FDDC_5_I, AD9081_FDDC_5_Q } }, /* uc13.link0 */
|
||||
{ { AD9081_FDDC_0_I, AD9081_FDDC_0_Q, AD9081_FDDC_1_I, AD9081_FDDC_1_Q, AD9081_FDDC_4_I, AD9081_FDDC_4_Q, AD9081_FDDC_5_I, AD9081_FDDC_5_Q } }, /* uc13.link0 */
|
||||
{ { AD9081_FDDC_0_I, AD9081_FDDC_0_Q, AD9081_FDDC_1_I, AD9081_FDDC_1_Q, AD9081_FDDC_4_I, AD9081_FDDC_4_Q, AD9081_FDDC_5_I, AD9081_FDDC_5_Q } }, /* uc13.link0 */
|
||||
{ { AD9081_FDDC_0_I, AD9081_FDDC_0_Q, AD9081_FDDC_1_I, AD9081_FDDC_1_Q, AD9081_FDDC_4_I, AD9081_FDDC_4_Q, AD9081_FDDC_5_I, AD9081_FDDC_5_Q } }, /* uc13.link0 */
|
||||
};
|
||||
|
||||
/* Total Decimation Settings */
|
||||
@@ -260,16 +291,23 @@ adi_ad9081_jtx_conv_sel_t jtx_conv_sel[][2] = {
|
||||
uint8_t jtx_chip_dcm[][2] = {
|
||||
{ 4 }, /* uc13.link0 */
|
||||
{ 4 }, /* uc13.link0 */
|
||||
{ 6 }, /* uc13.link0 */
|
||||
{ 8 }, /* uc13.link0 */
|
||||
};
|
||||
|
||||
adi_cms_jesd_param_t jrx_param[] = {
|
||||
/*L F M S HD K N N' CF CS DID BID LID SC SCR Dual V Mode */
|
||||
{ 8, 2, 8, 1, 0, 128, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 2, 15 }, /* uc13: txmode = 378 */
|
||||
{ 8, 2, 8, 1, 0, 128, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 2, 15 }, /* uc13: txmode = 378 */
|
||||
{ 8, 2, 8, 1, 0, 32, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 1, 15 }, // 204B
|
||||
{ 8, 2, 8, 1, 0, 32, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 1, 15 }, // 204B
|
||||
};
|
||||
adi_cms_jesd_param_t jtx_param[][2] = {
|
||||
/*L F M S HD K N N' CF CS DID BID LID SC SCR Dual V Mode C2R ModeS */
|
||||
{ { 8, 2, 8, 1, 0, 128, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 2, 16, 0, 0 } }, /* uc13: rxmode = 227, link0 */
|
||||
{ { 8, 2, 8, 1, 0, 128, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 2, 16, 0, 0 } }, /* uc13: rxmode = 227, link0 */
|
||||
{ { 8, 2, 8, 1, 0, 32, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 1, 16, 0, 0 } }, // 204B
|
||||
{ { 8, 2, 8, 1, 0, 32, 16, 16, 0, 0, 0, 0, 0, 1, 1, 0, 1, 16, 0, 0 } }, // 204B
|
||||
// { { 8, 4, 8, 2, 0, 32, 16, 16, 0, 0, 0, 0, 0, 0, 1, 0, 1, 16, 0, 1 } }, // 204B
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,49 +13,49 @@
|
||||
<AddressSpace Name="microblaze_bd_i_microblaze_0.microblaze_bd_i_microblaze_0_local_memory_dlmb_bram_if_cntlr" Begin="0" End="32767">
|
||||
<AddressSpaceRange Name="microblaze_bd_i_microblaze_0.microblaze_bd_i_microblaze_0_local_memory_dlmb_bram_if_cntlr" Begin="0" End="32767" CoreMemory_Width="0" MemoryType="RAM_SP" MemoryConfiguration="">
|
||||
<BusBlock>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y46" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y9" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="7" LSB="4"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X5Y44" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y10" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="3" LSB="0"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y44" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y14" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="15" LSB="12"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y43" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="11" LSB="8"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X5Y46" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y6" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="23" LSB="20"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X5Y45" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y5" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="19" LSB="16"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y45" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y11" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="31" LSB="28"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X6Y41" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X6Y7" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="27" LSB="24"/>
|
||||
<AddressRange Begin="0" End="8191"/>
|
||||
<BitLayout pattern=""/>
|
||||
@@ -69,97 +69,97 @@
|
||||
<AddressSpace Name="microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_microblaze_I.microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_dlmb_cntlr" Begin="0" End="65535">
|
||||
<AddressSpaceRange Name="microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_microblaze_I.microblaze_bd_i_ddr4_0_inst_u_ddr4_mem_intfc_u_ddr_cal_riu_mcs0_inst_dlmb_cntlr" Begin="0" End="65535" CoreMemory_Width="0" MemoryType="RAM_SP" MemoryConfiguration="">
|
||||
<BusBlock>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y9" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y24" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="7" LSB="6"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y7" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y25" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="5" LSB="4"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y11" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y24" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="3" LSB="2"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y14" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y22" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="1" LSB="0"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y6" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y25" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="15" LSB="14"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y5" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y24" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="13" LSB="12"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y7" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y26" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="11" LSB="10"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y6" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y25" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="9" LSB="8"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X0Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y19" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="23" LSB="22"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y19" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="21" LSB="20"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y10" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y17" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="19" LSB="18"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y9" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y20" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="17" LSB="16"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y13" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X2Y21" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="31" LSB="30"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y12" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y18" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="29" LSB="28"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y14" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X0Y22" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="27" LSB="26"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y11" Read_Width="0" SLR_INDEX="-1">
|
||||
<BitLane MemType="RAMB36" Placement="X1Y18" Read_Width="0" SLR_INDEX="-1">
|
||||
<DataWidth MSB="25" LSB="24"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<BitLayout pattern=""/>
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,589 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* XIic is the driver for an IIC master or slave device.
|
||||
*
|
||||
* In order to reduce the memory requirements of the driver the driver is
|
||||
* partitioned such that there are optional parts of the driver.
|
||||
* Slave, master, and multimaster features are optional such that all these files
|
||||
* are not required at the same time.
|
||||
* In order to use the slave and multimaster features of the driver, the user
|
||||
* must call functions (XIic_SlaveInclude and XIic_MultiMasterInclude)
|
||||
* to dynamically include the code. These functions may be called at any time.
|
||||
*
|
||||
* Two sets of higher level API's are available in the XIic driver that can
|
||||
* be used for Transmission/Reception in Master mode :
|
||||
* - XIic_MasterSend()/ XIic_MasterRecv() which is used in normal mode.
|
||||
* - XIic_DynMasterSend()/ XIic_DynMasterRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* Similarly two sets of lower level API's are available in XIic driver that
|
||||
* can be used for Transmission/Reception in Master mode:
|
||||
* - XIic_Send()/ XIic_Recv() which is used in normal mode
|
||||
* - XIic_DynSend()/ XIic_DynRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* The user should use a single set of APIs as per his requirement and
|
||||
* should not intermix them.
|
||||
*
|
||||
* All the driver APIs can be used for read, write and combined mode of
|
||||
* operations on the IIC bus.
|
||||
*
|
||||
* In the normal mode IIC support both 7-bit and 10-bit addressing, and in
|
||||
* the dynamic mode support only 7-bit addressing.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XIic_Config structure is used by the driver to configure itself. This
|
||||
* configuration structure is typically created by the tool-chain based on HW
|
||||
* build properties.
|
||||
*
|
||||
* To support multiple runtime loading and initialization strategies employed
|
||||
* by various operating systems, the driver instance can be initialized in one
|
||||
* of the following ways:
|
||||
*
|
||||
* - XIic_Initialize() - The driver looks up its own
|
||||
* configuration structure created by the tool-chain based on an ID provided
|
||||
* by the tool-chain.
|
||||
*
|
||||
* - XIic_CfgInitialize() - The driver uses a configuration structure provided
|
||||
* by the caller. If running in a system with address translation, the
|
||||
* provided virtual memory base address replaces the physical address present
|
||||
* in the configuration structure.
|
||||
*
|
||||
* <b>General Purpose Output</b>
|
||||
* The IIC hardware provides a General Purpose Output Register that allows the
|
||||
* user to connect general purpose outputs to devices, such as a write protect,
|
||||
* for an EEPROM. This register is parameterizable in the hardware such that
|
||||
* there could be zero bits in this register and in this case it will cause
|
||||
* a bus error if read or written.
|
||||
*
|
||||
* <b>Bus Throttling</b>
|
||||
*
|
||||
* The IIC hardware provides bus throttling which allows either the device, as
|
||||
* either a master or a slave, to stop the clock on the IIC bus. This feature
|
||||
* allows the software to perform the appropriate processing for each interrupt
|
||||
* without an unreasonable response restriction. With this design, it is
|
||||
* important for the user to understand the implications of bus throttling.
|
||||
*
|
||||
* <b>Repeated Start</b>
|
||||
*
|
||||
* An application can send multiple messages, as a master, to a slave device
|
||||
* and re-acquire the IIC bus each time a message is sent. The repeated start
|
||||
* option allows the application to send multiple messages without re-acquiring
|
||||
* the IIC bus for each message. The transactions involving repeated start
|
||||
* are also called combined transfers if there is Read and Write in the
|
||||
* same transaction.
|
||||
*
|
||||
* The repeated start feature works with all the API's in XIic driver.
|
||||
*
|
||||
* The Repeated Start feature also could cause the application to lock up, or
|
||||
* monopolize the IIC bus, should repeated start option be enabled and sequences
|
||||
* of messages never end(periodic data collection).
|
||||
* Also when repeated start is not disable before the last master message is
|
||||
* sent or received, will leave the bus captive to the master, but unused.
|
||||
*
|
||||
* <b>Addressing</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built for 7 or 10
|
||||
* bit addresses. The driver provides the ability to control which address
|
||||
* size is sent in messages as a master to a slave device. The address size
|
||||
* which the hardware responds to as a slave is parameterized as 7 or 10 bits
|
||||
* but fixed by the hardware build.
|
||||
*
|
||||
* Addresses are represented as hex values with no adjustment for the data
|
||||
* direction bit as the software manages address bit placement. This is
|
||||
* especially important as the bit placement is not handled the same depending
|
||||
* on which options are used such as repeated start and 7 vs 10 bit addressing.
|
||||
*
|
||||
* <b>Data Rates</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built to support
|
||||
* data rates from DC to 400KBit. The frequency of the interrupts which
|
||||
* occur is proportional to the data rate.
|
||||
*
|
||||
* <b>Polled Mode Operation</b>
|
||||
*
|
||||
* This driver does not provide a polled mode of operation primarily because
|
||||
* polled mode which is non-blocking is difficult with the amount of
|
||||
* interaction with the hardware that is necessary.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The device has many interrupts which allow IIC data transactions as well
|
||||
* as bus status processing to occur.
|
||||
*
|
||||
* The interrupts are divided into two types, data and status. Data interrupts
|
||||
* indicate data has been received or transmitted while the status interrupts
|
||||
* indicate the status of the IIC bus. Some of the interrupts, such as Not
|
||||
* Addressed As Slave and Bus Not Busy, are only used when these specific
|
||||
* events must be recognized as opposed to being enabled at all times.
|
||||
*
|
||||
* Many of the interrupts are not a single event in that they are continuously
|
||||
* present such that they must be disabled after recognition or when undesired.
|
||||
* Some of these interrupts, which are data related, may be acknowledged by the
|
||||
* software by reading or writing data to the appropriate register, or must
|
||||
* be disabled. The following interrupts can be continuous rather than single
|
||||
* events.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Bus Not Busy
|
||||
* - Addressed As Slave
|
||||
* - Not Addressed As Slave
|
||||
*
|
||||
* The following interrupts are not passed directly to the application through the
|
||||
* status callback. These are only used internally for the driver processing
|
||||
* and may result in the receive and send handlers being called to indicate
|
||||
* completion of an operation. The following interrupts are data related
|
||||
* rather than status.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Slave Transmit Complete
|
||||
*
|
||||
* <b>Interrupt To Event Mapping</b>
|
||||
*
|
||||
* The following table provides a mapping of the interrupts to the events which
|
||||
* are passed to the status handler and the intended role (master or slave) for
|
||||
* the event. Some interrupts can cause multiple events which are combined
|
||||
* together into a single status event such as XII_MASTER_WRITE_EVENT and
|
||||
* XII_GENERAL_CALL_EVENT
|
||||
* <pre>
|
||||
* Interrupt Event(s) Role
|
||||
*
|
||||
* Arbitration Lost Interrupt XII_ARB_LOST_EVENT Master
|
||||
* Transmit Error XII_SLAVE_NO_ACK_EVENT Master
|
||||
* IIC Bus Not Busy XII_BUS_NOT_BUSY_EVENT Master
|
||||
* Addressed As Slave XII_MASTER_READ_EVENT, Slave
|
||||
* XII_MASTER_WRITE_EVENT, Slave
|
||||
* XII_GENERAL_CALL_EVENT Slave
|
||||
* </pre>
|
||||
* <b>Not Addressed As Slave Interrupt</b>
|
||||
*
|
||||
* The Not Addressed As Slave interrupt is not passed directly to the
|
||||
* application through the status callback. It is used to determine the end of
|
||||
* a message being received by a slave when there was no stop condition
|
||||
* (repeated start). It will cause the receive handler to be called to
|
||||
* indicate completion of the operation.
|
||||
*
|
||||
* <b>RTOS Independence</b>
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works
|
||||
* with physical addresses only. Any needs for dynamic memory management,
|
||||
* threads or thread mutual exclusion, virtual memory, or cache control must
|
||||
* be satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.01d sv 05/09/05 Changed the data being written to the Address/Control
|
||||
* Register and removed the code for testing the
|
||||
* Receive Data Register in XIic_SelfTest function of
|
||||
* xiic_selftest.c source file
|
||||
* 1.02a jvb 12/14/05 I separated dependency on the static config table and
|
||||
* xparameters.h from the driver initialization by moving
|
||||
* _Initialize and _LookupConfig to _sinit.c. I also added
|
||||
* the new _CfgInitialize routine.
|
||||
* 1.02a mta 03/09/06 Added a new function XIic_IsIicBusy() which returns
|
||||
* whether IIC Bus is Busy or Free.
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 07/17/06 Added files to support Dynamic IIC controller in High
|
||||
* level driver. Added xiic_dyn_master.c. Added support
|
||||
* for IIC Dynamic controller in Low level driver in xiic_l.c
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.13b ecm 11/29/07 added BB polling loops to the DynSend and DynRecv
|
||||
* routines to handle the race condition with BNB in IISR.
|
||||
* 1.14a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
|
||||
* file
|
||||
* 1.14a ecm 11/13/08 changed BB polling loops in DynRecv to handle race
|
||||
* condition, CR491889. DynSend was correct from v1.13.b
|
||||
* 1.15a ktn 02/17/09 Fixed XIic_GetAddress() to return correct device address.
|
||||
* 1.16a ktn 07/17/09 Updated the XIic_SelfTest() to test only Interrupt
|
||||
* Registers.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.,
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Removed the XIIC_CLEAR_STATS macro, XIic_ClearStats API
|
||||
* should be used in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name see the xiic_i.h and xiic_l.h file for further
|
||||
* information (Example XIic_mClearIntr is now
|
||||
* XIic_ClearIntr).
|
||||
* Some of the macros have been renamed to be consistent,
|
||||
* see the xiic_l.h file for further information
|
||||
* (Example XIIC_WRITE_IIER is renamed as XIic_WriteIier).
|
||||
* The driver has been updated to use the HAL APIs/macros
|
||||
* (Example XASSERT_NONVOID is now Xil_AssertNonvoid)
|
||||
* 2.01a ktn 04/09/10 Updated TxErrorhandler in xiic_intr.c to be called for
|
||||
* Master Transmitter case based on Addressed As Slave (AAS)
|
||||
* bit rather than MSMS bit(CR 540199).
|
||||
* 2.02a sdm 10/08/10 Updated to disable the device at the end of the transfer,
|
||||
* using Addressed As Slave (AAS) bit when addressed as
|
||||
* slave in XIic_Send for CR565373.
|
||||
* 2.03a rkv 01/25/11 Updated in NAAS interrupt handler to support data
|
||||
* received less than FIFO size prior to NAAS interrupt.
|
||||
* Fixed for CR590212.
|
||||
* 2.04a sdm 07/22/11 Added IsSlaveSetAckOff flag to the instance structure.
|
||||
* This flag is set when the Slave has set the Ack Off in the
|
||||
* RecvSlaveData function (xiic_slave.c) and
|
||||
* is cleared in the NotAddrAsSlaveHandler (xiic_slave.c)
|
||||
* when the master has released the bus. This flag is
|
||||
* to be used by slave applications for recovering when it
|
||||
* has gone out of sync with the master for CR 615004.
|
||||
* Removed a compiler warning in XIic_Send (xiic_l.c)
|
||||
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
|
||||
* SendBufferPtr in XIic_MasterRecv to NULL in xiic_master.c
|
||||
* 2.06a bss 02/14/13 Modified TxErrorHandler in xiic_intr.c to fix CR #686483
|
||||
* Modified xiic_eeprom_example.c to fix CR# 683509.
|
||||
* Modified bitwise OR to logical OR in
|
||||
* XIic_InterruptHandler API in xiic_intr.c.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
* 2.08a adk 29/07/13 In Low level driver In repeated start condition the
|
||||
* Direction of Tx bit must be disabled in recv condition
|
||||
* It Fixes the CR:685759 Changes are done in the file
|
||||
* xiic_l.c in the function XIic_Recv.
|
||||
* 3.0 adk 19/12/13 Updated as per the New Tcl API's
|
||||
* 3.1 adk 01/08/15 When configured as a slave return the actual number of
|
||||
* bytes have been received/sent by the Master
|
||||
* to the user callback (CR: 828504). Changes are made in the
|
||||
* file xiic_slave.c.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XIic_CfgInitialize API.
|
||||
* 3.2 sd 18/02/16 In Low level driver in repeated start condition
|
||||
* NACK for last byte is added. Changes are done in
|
||||
* XIic_Recv for CR# 862303
|
||||
* 3.3 sk 06/17/16 Added bus busy checks for slave send/recv and master
|
||||
* send/recv.
|
||||
* 3.3 als 06/27/16 XIic_IsIicBusy now a wrapper for XIic_CheckIsBusBusy.
|
||||
* 3.4 ms 01/23/17 Added xil_printf statement in main function for all
|
||||
* examples to ensure that "Successfully ran" and "Failed"
|
||||
* strings are available in all examples. This is a fix
|
||||
* for CR-965028.
|
||||
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
|
||||
* generation.
|
||||
* ms 04/05/17 Modified Comment lines in functions of iic
|
||||
* examples to recognize it as documentation block
|
||||
* for doxygen generation.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XIIC_H /* prevent circular inclusions */
|
||||
#define XIIC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* The following options may be specified or retrieved for the device and
|
||||
* enable/disable additional features of the IIC bus. Each of the options
|
||||
* are bit fields such that more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XII_GENERAL_CALL_OPTION The general call option allows an IIC slave to
|
||||
* recognized the general call address. The status
|
||||
* handler is called as usual indicating the device
|
||||
* has been addressed as a slave with a general
|
||||
* call. It is the application's responsibility to
|
||||
* perform any special processing for the general
|
||||
* call.
|
||||
*
|
||||
* XII_REPEATED_START_OPTION The repeated start option allows multiple
|
||||
* messages to be sent/received on the IIC bus
|
||||
* without rearbitrating for the bus. The messages
|
||||
* are sent as a series of messages such that the
|
||||
* option must be enabled before the 1st message of
|
||||
* the series, to prevent an stop condition from
|
||||
* being generated on the bus, and disabled before
|
||||
* the last message of the series, to allow the
|
||||
* stop condition to be generated.
|
||||
*
|
||||
* XII_SEND_10_BIT_OPTION The send 10 bit option allows 10 bit addresses
|
||||
* to be sent on the bus when the device is a
|
||||
* master. The device can be configured to respond
|
||||
* as to 7 bit addresses even though it may be
|
||||
* communicating with other devices that support 10
|
||||
* bit addresses. When this option is not enabled,
|
||||
* only 7 bit addresses are sent on the bus.
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
#define XII_GENERAL_CALL_OPTION 0x00000001
|
||||
#define XII_REPEATED_START_OPTION 0x00000002
|
||||
#define XII_SEND_10_BIT_OPTION 0x00000004
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Status events
|
||||
*
|
||||
* The following status events occur during IIC bus processing and are passed
|
||||
* to the status callback. Each event is only valid during the appropriate
|
||||
* processing of the IIC bus. Each of these events are bit fields such that
|
||||
* more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
#define XII_BUS_NOT_BUSY_EVENT 0x00000001 /**< Bus transitioned to not busy */
|
||||
#define XII_ARB_LOST_EVENT 0x00000002 /**< Arbitration was lost */
|
||||
#define XII_SLAVE_NO_ACK_EVENT 0x00000004 /**< Slave did not ACK (had error) */
|
||||
#define XII_MASTER_READ_EVENT 0x00000008 /**< Master reading from slave */
|
||||
#define XII_MASTER_WRITE_EVENT 0x00000010 /**< Master writing to slave */
|
||||
#define XII_GENERAL_CALL_EVENT 0x00000020 /**< General call to all slaves */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/*
|
||||
* The following address types are used when setting and getting the addresses
|
||||
* of the driver. These are mutually exclusive such that only one or the other
|
||||
* may be specified.
|
||||
*/
|
||||
#define XII_ADDR_TO_SEND_TYPE 1 /**< Bus address of slave device */
|
||||
#define XII_ADDR_TO_RESPOND_TYPE 2 /**< This device's bus address as slave */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< Does device have 10 bit address decoding */
|
||||
u8 GpOutWidth; /**< Number of bits in general purpose output */
|
||||
} XIic_Config;
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of sent and received data of the IIC driver. The application
|
||||
* using this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handlers are called in an interrupt context such
|
||||
* that minimal processing should be performed. The handler data type is
|
||||
* utilized for both send and receive handlers.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param ByteCount indicates the number of bytes remaining to be sent or
|
||||
* received. A value of zero indicates that the requested number
|
||||
* of bytes were sent or received.
|
||||
*
|
||||
******************************************************************************/
|
||||
typedef void (*XIic_Handler) (void *CallBackRef, int ByteCount);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of status events of the IIC driver. The application using
|
||||
* this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handler is called in an interrupt context such
|
||||
* that minimal processing should be performed.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param StatusEvent indicates one or more status events that occurred.
|
||||
* See the definition of the status events above.
|
||||
*
|
||||
********************************************************************************/
|
||||
typedef void (*XIic_StatusHandler) (void *CallBackRef, int StatusEvent);
|
||||
|
||||
/**
|
||||
* XIic statistics
|
||||
*/
|
||||
typedef struct {
|
||||
u8 ArbitrationLost;/**< Number of times arbitration was lost */
|
||||
u8 RepeatedStarts; /**< Number of repeated starts */
|
||||
u8 BusBusy; /**< Number of times bus busy status returned */
|
||||
u8 RecvBytes; /**< Number of bytes received */
|
||||
u8 RecvInterrupts; /**< Number of receive interrupts */
|
||||
u8 SendBytes; /**< Number of transmit bytes received */
|
||||
u8 SendInterrupts; /**< Number of transmit interrupts */
|
||||
u8 TxErrors; /**< Number of transmit errors (no ack) */
|
||||
u8 IicInterrupts; /**< Number of IIC (device) interrupts */
|
||||
} XIicStats;
|
||||
|
||||
/**
|
||||
* The XIic driver instance data. The user is required to allocate a
|
||||
* variable of this type for every IIC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XIicStats Stats; /**< Statistics */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< TRUE when 10 bit addressing in design */
|
||||
int IsReady; /**< Device is initialized and ready */
|
||||
int IsStarted; /**< Device has been started */
|
||||
int AddrOfSlave; /**< Slave Address writing to */
|
||||
|
||||
u32 Options; /**< Current operating options */
|
||||
u8 *SendBufferPtr; /**< Buffer to send (state) */
|
||||
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
|
||||
u8 TxAddrMode; /**< State of Tx Address transmission */
|
||||
int SendByteCount; /**< Number of data bytes in buffer (state) */
|
||||
int RecvByteCount; /**< Number of empty bytes in buffer (state) */
|
||||
|
||||
u32 BNBOnly; /**< TRUE when BNB interrupt needs to */
|
||||
/**< call callback */
|
||||
u8 GpOutWidth; /**< General purpose output width */
|
||||
|
||||
XIic_StatusHandler StatusHandler; /**< Status Handler */
|
||||
void *StatusCallBackRef; /**< Callback reference for status handler */
|
||||
XIic_Handler RecvHandler; /**< Receive Handler */
|
||||
void *RecvCallBackRef; /**< Callback reference for Recv handler */
|
||||
XIic_Handler SendHandler; /**< Send Handler */
|
||||
void *SendCallBackRef; /**< Callback reference for send handler */
|
||||
int IsDynamic; /**< TRUE when Dynamic control is used */
|
||||
int IsSlaveSetAckOff; /**< TRUE when Slave has set the ACK Off */
|
||||
|
||||
} XIic;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a function which tells whether the I2C bus is busy or free.
|
||||
*
|
||||
* @param InstancePtr points to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the bus is busy.
|
||||
* - FALSE if the bus is NOT busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static inline u32 XIic_IsIicBusy(XIic *InstancePtr)
|
||||
{
|
||||
return XIic_CheckIsBusBusy(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization functions in xiic_sinit.c
|
||||
*/
|
||||
int XIic_Initialize(XIic *InstancePtr, u16 DeviceId);
|
||||
XIic_Config *XIic_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions in xiic.c
|
||||
*/
|
||||
int XIic_CfgInitialize(XIic *InstancePtr, XIic_Config *Config,
|
||||
UINTPTR EffectiveAddr);
|
||||
|
||||
int XIic_Start(XIic *InstancePtr);
|
||||
int XIic_Stop(XIic *InstancePtr);
|
||||
|
||||
void XIic_Reset(XIic *InstancePtr);
|
||||
|
||||
int XIic_SetAddress(XIic *InstancePtr, int AddressType, int Address);
|
||||
u16 XIic_GetAddress(XIic *InstancePtr, int AddressType);
|
||||
|
||||
int XIic_SetGpOutput(XIic *InstancePtr, u8 OutputValue);
|
||||
int XIic_GetGpOutput(XIic *InstancePtr, u8 *OutputValuePtr);
|
||||
|
||||
u32 XIic_IsSlave(XIic *InstancePtr);
|
||||
|
||||
void XIic_SetRecvHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetSendHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetStatusHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_StatusHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xiic_intr.c
|
||||
*/
|
||||
void XIic_InterruptHandler(void *InstancePtr);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in normal mode in xiic_master.c
|
||||
*/
|
||||
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in dynamic mode in xiic_master.c
|
||||
*/
|
||||
int XIic_DynMasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, u8 ByteCount);
|
||||
int XIic_DynMasterSend(XIic *InstancePtr, u8 *TxMsgPtr, u8 ByteCount);
|
||||
|
||||
/*
|
||||
* Dynamic IIC Core Initialization.
|
||||
*/
|
||||
int XIic_DynamicInitialize(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Slave send and receive functions in xiic_slave.c
|
||||
*/
|
||||
void XIic_SlaveInclude(void);
|
||||
int XIic_SlaveRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_SlaveSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Statistics functions in xiic_stats.c
|
||||
*/
|
||||
void XIic_GetStats(XIic *InstancePtr, XIicStats *StatsPtr);
|
||||
void XIic_ClearStats(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Self test functions in xiic_selftest.c
|
||||
*/
|
||||
int XIic_SelfTest(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Bus busy Function in xiic.c
|
||||
*/
|
||||
u32 XIic_IsIicBusy(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Options functions in xiic_options.c
|
||||
*/
|
||||
void XIic_SetOptions(XIic *InstancePtr, u32 Options);
|
||||
u32 XIic_GetOptions(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Multi-master functions in xiic_multi_master.c
|
||||
*/
|
||||
void XIic_MultiMasterInclude(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,369 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_i.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains internal identifiers, which are those shared
|
||||
* between XIic components. The identifiers in this file are not intended for
|
||||
* use external to the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Removed the macro XIIC_CLEAR_STATS, user has to
|
||||
* use the the XIic_ClearStats API in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Removed the _m prefix from all the macros
|
||||
* XIic_mSend10BitAddrByte1 is now XIic_Send10BitAddrByte1
|
||||
* XIic_mSend10BitAddrByte2 is now XIic_Send10BitAddrByte2
|
||||
* XIic_mSend7BitAddr is now XIic_Send7BitAddr
|
||||
* XIic_mDisableIntr is now XIic_DisableIntr
|
||||
* XIic_mEnableIntr is now XIic_EnableIntr
|
||||
* XIic_mClearIntr is now XIic_ClearIntr
|
||||
* XIic_mClearEnableIntr is now XIic_ClearEnableIntr
|
||||
* XIic_mFlushRxFifo is now XIic_FlushRxFifo
|
||||
* XIic_mFlushTxFifo is now XIic_FlushTxFifo
|
||||
* XIic_mReadRecvByte is now XIic_ReadRecvByte
|
||||
* XIic_mWriteSendByte is now XIic_WriteSendByte
|
||||
* XIic_mSetControlRegister is now XIic_SetControlRegister
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings when
|
||||
* compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIIC_I_H /* prevent circular inclusions */
|
||||
#define XIIC_I_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the first byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* address = 1111_0xxD xx = address MSBits
|
||||
* D = Tx direction = 0 = write
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send10BitAddrByte1(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte1(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)((SlaveAddress) >> 7); \
|
||||
LocalAddr = (LocalAddr & 0xF6) | 0xF0 | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the second byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature: void XIic_Send10BitAddrByte2(u16 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte2(SlaveAddress) \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32)(SlaveAddress)); \
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send7BitAddr(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddr(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro disables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_DisableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DisableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) & ~(InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro enables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_EnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_EnableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) | (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears and enables the specified interrupt in the Interrupt
|
||||
* status and enable registers. It is non-destructive in that the registers are
|
||||
* read and only the interrupt specified is modified.
|
||||
* Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be cleared and enabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearEnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearEnableIntr(BaseAddress, InterruptMask) \
|
||||
{ \
|
||||
XIic_WriteIisr(BaseAddress, \
|
||||
(XIic_ReadIisr(BaseAddress) & (InterruptMask))); \
|
||||
\
|
||||
XIic_WriteIier(BaseAddress, \
|
||||
(XIic_ReadIier(BaseAddress) | (InterruptMask))); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the receive FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushRxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushRxFifo(InstancePtr) \
|
||||
{ \
|
||||
int LoopCnt; \
|
||||
u8 BytesToRead = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_RFO_REG_OFFSET) + 1; \
|
||||
for(LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) \
|
||||
{ \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_DRR_REG_OFFSET); \
|
||||
} \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the transmit FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushTxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushTxFifo(InstancePtr); \
|
||||
{ \
|
||||
u32 CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_CR_REG_OFFSET); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg | XIIC_CR_TX_FIFO_RESET_MASK); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro reads the next available received byte from the receive FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ReadRecvByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadRecvByte(InstancePtr) \
|
||||
{ \
|
||||
*InstancePtr->RecvBufferPtr++ = \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, XIIC_DRR_REG_OFFSET); \
|
||||
InstancePtr->RecvByteCount--; \
|
||||
InstancePtr->Stats.RecvBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro writes the next byte to be sent to the transmit FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_WriteSendByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteSendByte(InstancePtr) \
|
||||
{ \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
*InstancePtr->SendBufferPtr++); \
|
||||
InstancePtr->SendByteCount--; \
|
||||
InstancePtr->Stats.SendBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sets up the control register for a master receive operation.
|
||||
* A write is necessary if a 10 bit operation is being performed.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
* @param ControlRegister contains the contents of the IIC device control
|
||||
* register
|
||||
* @param ByteCount contains the number of bytes to be received for the
|
||||
* master receive operation
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_SetControlRegister(XIic *InstancePtr,
|
||||
* u8 ControlRegister,
|
||||
* int ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_SetControlRegister(InstancePtr, ControlRegister, ByteCount) \
|
||||
{ \
|
||||
(ControlRegister) &= ~(XIIC_CR_NO_ACK_MASK | XIIC_CR_DIR_IS_TX_MASK); \
|
||||
if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) { \
|
||||
(ControlRegister) |= XIIC_CR_DIR_IS_TX_MASK; \
|
||||
} else { \
|
||||
if ((ByteCount) == 1) \
|
||||
{ \
|
||||
(ControlRegister) |= XIIC_CR_NO_ACK_MASK; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
extern XIic_Config XIic_ConfigTable[];
|
||||
|
||||
/* The following variables are shared across files of the driver and
|
||||
* are function pointers that are necessary to break dependencies allowing
|
||||
* optional parts of the driver to be used without condition compilation
|
||||
*/
|
||||
extern void (*XIic_AddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_NotAddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_ArbLostFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_BusNotBusyFuncPtr) (XIic *InstancePtr);
|
||||
|
||||
void XIic_TransmitFifoFill(XIic *InstancePtr, int Role);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,571 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_l.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and driver functions (or
|
||||
* macros) that can be used to access the device in normal and dynamic
|
||||
* controller mode. High-level driver functions are defined in xiic.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 05/07/02 First release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 04/04/06 Implemented Dynamic IIC core routines.
|
||||
* 1.03a rpm 09/08/06 Added include of xstatus.h for completeness
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.16a ktn 07/18/09 Updated the notes in XIIC_RESET macro to clearly indicate
|
||||
* that only the Interrupt Registers are reset.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIIC_RESET macro to mention
|
||||
* that the complete IIC core is Reset on giving a software
|
||||
* reset to the IIC core. Some previous versions of the
|
||||
* core only reset the Interrupt Logic/Registers, please
|
||||
* refer to the HW specification for further details.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access,
|
||||
* the register offsets are defined to be on 32 bit boundary.
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Some of the macros have been renamed to be consistent -
|
||||
* XIIC_GINTR_DISABLE is renamed as XIic_IntrGlobalDisable,
|
||||
* XIIC_GINTR_ENABLE is renamed as XIic_IntrGlobalEnable,
|
||||
* XIIC_IS_GINTR_ENABLED is renamed as
|
||||
* XIic_IsIntrGlobalEnabled,
|
||||
* XIIC_WRITE_IISR is renamed as XIic_WriteIisr,
|
||||
* XIIC_READ_IISR is renamed as XIic_ReadIisr,
|
||||
* XIIC_WRITE_IIER is renamed as XIic_WriteIier
|
||||
* The _m prefix in the name of the macros has been removed -
|
||||
* XIic_mClearIisr is now XIic_ClearIisr,
|
||||
* XIic_mSend7BitAddress is now XIic_Send7BitAddress,
|
||||
* XIic_mDynSend7BitAddress is now XIic_DynSend7BitAddress,
|
||||
* XIic_mDynSendStartStopAddress is now
|
||||
* XIic_DynSendStartStopAddress,
|
||||
* XIic_mDynSendStop is now XIic_DynSendStop.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototypes of XIic_Recv, XIic_Send,
|
||||
* XIic_DynRecv, XIic_DynSend and XIic_DynInit APIs.
|
||||
* 3.3 als 06/27/16 Added Low-level XIic_CheckIsBusBusy API.
|
||||
* 3.3 als 06/27/16 Added low-level XIic_WaitBusFree API.
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef XIIC_L_H /* prevent circular inclusions */
|
||||
#define XIIC_L_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
/** @name Register Map
|
||||
*
|
||||
* Register offsets for the XIic device.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_DGIER_OFFSET 0x1C /**< Global Interrupt Enable Register */
|
||||
#define XIIC_IISR_OFFSET 0x20 /**< Interrupt Status Register */
|
||||
#define XIIC_IIER_OFFSET 0x28 /**< Interrupt Enable Register */
|
||||
#define XIIC_RESETR_OFFSET 0x40 /**< Reset Register */
|
||||
#define XIIC_CR_REG_OFFSET 0x100 /**< Control Register */
|
||||
#define XIIC_SR_REG_OFFSET 0x104 /**< Status Register */
|
||||
#define XIIC_DTR_REG_OFFSET 0x108 /**< Data Tx Register */
|
||||
#define XIIC_DRR_REG_OFFSET 0x10C /**< Data Rx Register */
|
||||
#define XIIC_ADR_REG_OFFSET 0x110 /**< Address Register */
|
||||
#define XIIC_TFO_REG_OFFSET 0x114 /**< Tx FIFO Occupancy */
|
||||
#define XIIC_RFO_REG_OFFSET 0x118 /**< Rx FIFO Occupancy */
|
||||
#define XIIC_TBA_REG_OFFSET 0x11C /**< 10 Bit Address reg */
|
||||
#define XIIC_RFD_REG_OFFSET 0x120 /**< Rx FIFO Depth reg */
|
||||
#define XIIC_GPO_REG_OFFSET 0x124 /**< Output Register */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Device Global Interrupt Enable Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_GINTR_ENABLE_MASK 0x80000000 /**< Global Interrupt Enable Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Device Interrupt Status/Enable (INTR) Register Masks
|
||||
*
|
||||
* <b> Interrupt Status Register (IISR) </b>
|
||||
*
|
||||
* This register holds the interrupt status flags for the Spi device.
|
||||
*
|
||||
* <b> Interrupt Enable Register (IIER) </b>
|
||||
*
|
||||
* This register is used to enable interrupt sources for the IIC device.
|
||||
* Writing a '1' to a bit in this register enables the corresponding Interrupt.
|
||||
* Writing a '0' to a bit in this register disables the corresponding Interrupt.
|
||||
*
|
||||
* IISR/IIER registers have the same bit definitions and are only defined once.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_INTR_ARB_LOST_MASK 0x00000001 /**< 1 = Arbitration lost */
|
||||
#define XIIC_INTR_TX_ERROR_MASK 0x00000002 /**< 1 = Tx error/msg complete */
|
||||
#define XIIC_INTR_TX_EMPTY_MASK 0x00000004 /**< 1 = Tx FIFO/reg empty */
|
||||
#define XIIC_INTR_RX_FULL_MASK 0x00000008 /**< 1 = Rx FIFO/reg=OCY level */
|
||||
#define XIIC_INTR_BNB_MASK 0x00000010 /**< 1 = Bus not busy */
|
||||
#define XIIC_INTR_AAS_MASK 0x00000020 /**< 1 = When addr as slave */
|
||||
#define XIIC_INTR_NAAS_MASK 0x00000040 /**< 1 = Not addr as slave */
|
||||
#define XIIC_INTR_TX_HALF_MASK 0x00000080 /**< 1 = Tx FIFO half empty */
|
||||
|
||||
/**
|
||||
* All Tx interrupts commonly used.
|
||||
*/
|
||||
#define XIIC_TX_INTERRUPTS (XIIC_INTR_TX_ERROR_MASK | \
|
||||
XIIC_INTR_TX_EMPTY_MASK | \
|
||||
XIIC_INTR_TX_HALF_MASK)
|
||||
|
||||
/**
|
||||
* All interrupts commonly used
|
||||
*/
|
||||
#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
|
||||
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Reset Register mask
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_RESET_MASK 0x0000000A /**< RESET Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Control Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_CR_ENABLE_DEVICE_MASK 0x00000001 /**< Device enable = 1 */
|
||||
#define XIIC_CR_TX_FIFO_RESET_MASK 0x00000002 /**< Transmit FIFO reset=1 */
|
||||
#define XIIC_CR_MSMS_MASK 0x00000004 /**< Master starts Txing=1 */
|
||||
#define XIIC_CR_DIR_IS_TX_MASK 0x00000008 /**< Dir of Tx. Txing=1 */
|
||||
#define XIIC_CR_NO_ACK_MASK 0x00000010 /**< Tx Ack. NO ack = 1 */
|
||||
#define XIIC_CR_REPEATED_START_MASK 0x00000020 /**< Repeated start = 1 */
|
||||
#define XIIC_CR_GENERAL_CALL_MASK 0x00000040 /**< Gen Call enabled = 1 */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Status Register masks (SR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_SR_GEN_CALL_MASK 0x00000001 /**< 1 = A Master issued
|
||||
* a GC */
|
||||
#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x00000002 /**< 1 = When addressed as
|
||||
* slave */
|
||||
#define XIIC_SR_BUS_BUSY_MASK 0x00000004 /**< 1 = Bus is busy */
|
||||
#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x00000008 /**< 1 = Dir: Master <--
|
||||
* slave */
|
||||
#define XIIC_SR_TX_FIFO_FULL_MASK 0x00000010 /**< 1 = Tx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_FULL_MASK 0x00000020 /**< 1 = Rx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x00000040 /**< 1 = Rx FIFO empty */
|
||||
#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x00000080 /**< 1 = Tx FIFO empty */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Tx Register (DTR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_TX_DYN_START_MASK 0x00000100 /**< 1 = Set dynamic start */
|
||||
#define XIIC_TX_DYN_STOP_MASK 0x00000200 /**< 1 = Set dynamic stop */
|
||||
#define IIC_TX_FIFO_DEPTH 16 /**< Tx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Rx Register (DRR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define IIC_RX_FIFO_DEPTH 16 /**< Rx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
|
||||
#define XIIC_TX_ADDR_SENT 0x00
|
||||
#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02
|
||||
|
||||
|
||||
/**
|
||||
* The following constants are used to specify whether to do
|
||||
* Read or a Write operation on IIC bus.
|
||||
*/
|
||||
#define XIIC_READ_OPERATION 1 /**< Read operation on the IIC bus */
|
||||
#define XIIC_WRITE_OPERATION 0 /**< Write operation on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with the transmit FIFO fill function to
|
||||
* specify the role which the IIC device is acting as, a master or a slave.
|
||||
*/
|
||||
#define XIIC_MASTER_ROLE 1 /**< Master on the IIC bus */
|
||||
#define XIIC_SLAVE_ROLE 0 /**< Slave on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with Transmit Function (XIic_Send) to
|
||||
* specify whether to STOP after the current transfer of data or own the bus
|
||||
* with a Repeated start.
|
||||
*/
|
||||
#define XIIC_STOP 0x00 /**< Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
#define XIIC_REPEATED_START 0x01 /**< Donot Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define XIic_In32 Xil_In32
|
||||
#define XIic_Out32 Xil_Out32
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read from the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the device to
|
||||
* select the specific register.
|
||||
*
|
||||
* @return The value read from the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadReg(u32 BaseAddress, u32 RegOffset);
|
||||
*
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadReg(BaseAddress, RegOffset) \
|
||||
XIic_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write to the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the
|
||||
* device to select the specific register.
|
||||
* @param RegisterValue is the value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteReg(u32 BaseAddress, u32 RegOffset,
|
||||
* u32 RegisterValue);
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
XIic_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro disables all interrupts for the device by writing to the Global
|
||||
* interrupt enable register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalDisable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalDisable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, 0)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro writes to the global interrupt enable register to enable
|
||||
* interrupts from the device. This function does not enable individual
|
||||
* interrupts as the Interrupt Enable Register must be set appropriately.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalEnable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalEnable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function determines if interrupts are enabled at the global level by
|
||||
* reading the global interrupt register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the global interrupt is enabled.
|
||||
* - FALSE if global interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* int XIic_IsIntrGlobalEnabled(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IsIntrGlobalEnabled(BaseAddress) \
|
||||
(XIic_ReadReg((BaseAddress), XIIC_DGIER_OFFSET) == \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the Interrupt status register to the specified value.
|
||||
*
|
||||
* This register implements a toggle on write functionality. The interrupt is
|
||||
* cleared by writing to this register with the bits to be cleared set to a one
|
||||
* and all others to zero. Setting a bit which is zero within this register
|
||||
* causes an interrupt to be generated.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some status bits may be set and others cleared. It is the caller's
|
||||
* responsibility to get the value of the register prior to setting the value
|
||||
* to prevent an destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Status is the value to be written to the Interrupt
|
||||
* status register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIisr(u32 BaseAddress, u32 Status);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIisr(BaseAddress, Status) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IISR_OFFSET, (Status))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the contents of the Interrupt Status Register.
|
||||
* This register indicates the status of interrupt sources for the device.
|
||||
* The status is independent of whether interrupts are enabled such
|
||||
* that the status register may also be polled when interrupts are not enabled.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The value read from the Interrupt Status Register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIisr(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIisr(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IISR_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the contents of the Interrupt Enable Register.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some interrupt sources may be enabled and others disabled. It is the
|
||||
* caller's responsibility to get the value of the interrupt enable register
|
||||
* prior to setting the value to prevent a destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Enable is the value to be written to the Interrupt Enable
|
||||
* Register. Bit positions of 1 will be enabled. Bit positions of 0
|
||||
* will be disabled.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIier(u32 BaseAddress, u32 Enable);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIier(BaseAddress, Enable) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IIER_OFFSET, (Enable))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This function gets the Interrupt Enable Register contents.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The contents read from the Interrupt Enable Register.
|
||||
* Bit positions of 1 indicate that the corresponding interrupt
|
||||
* is enabled. Bit positions of 0 indicate that the corresponding
|
||||
* interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIier(u32 BaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIier(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IIER_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask is the bit mask of the interrupts to be cleared.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_ClearIisr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIisr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_Send7BitAddress(u32 BaseAddress, u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers for Dynamic
|
||||
* controller functionality.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSend7BitAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSend7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address, start and stop for a 7 bit address during both
|
||||
* write operations. It takes care of the details to format the address
|
||||
* correctly. This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStartStopAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStartStopAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | XIIC_TX_DYN_STOP_MASK | \
|
||||
LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends a stop condition on IIC bus for Dynamic logic.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param ByteCount is the number of Rx bytes received before the master.
|
||||
* doesn't respond with ACK.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStop(u32 BaseAddress, u32 ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStop(BaseAddress, ByteCount) \
|
||||
{ \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_STOP_MASK | ByteCount); \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_Send(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_DynRecv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, u8 ByteCount);
|
||||
|
||||
unsigned XIic_DynSend(UINTPTR BaseAddress, u16 Address, u8 *BufferPtr,
|
||||
u8 ByteCount, u8 Option);
|
||||
|
||||
int XIic_DynInit(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_WaitBusFree(UINTPTR BaseAddress);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -2,14 +2,14 @@
|
||||
#define XPARAMETERS_H /* by using protection macros */
|
||||
|
||||
/* Definitions for bus frequencies */
|
||||
#define XPAR_CPU_M_AXI_DP_FREQ_HZ 150000000
|
||||
#define XPAR_CPU_M_AXI_DP_FREQ_HZ 125000000
|
||||
/******************************************************************/
|
||||
|
||||
/* Canonical definitions for bus frequencies */
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_CPU_CORE_CLOCK_FREQ_HZ 150000000
|
||||
#define XPAR_MICROBLAZE_CORE_CLOCK_FREQ_HZ 150000000
|
||||
#define XPAR_CPU_CORE_CLOCK_FREQ_HZ 125000000
|
||||
#define XPAR_MICROBLAZE_CORE_CLOCK_FREQ_HZ 125000000
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#define XPAR_MICROBLAZE_0_ENDIANNESS 1
|
||||
#define XPAR_MICROBLAZE_0_FAULT_TOLERANT 0
|
||||
#define XPAR_MICROBLAZE_0_FPU_EXCEPTION 1
|
||||
#define XPAR_MICROBLAZE_0_FREQ 150000000
|
||||
#define XPAR_MICROBLAZE_0_FREQ 125000000
|
||||
#define XPAR_MICROBLAZE_0_FSL_EXCEPTION 0
|
||||
#define XPAR_MICROBLAZE_0_FSL_LINKS 0
|
||||
#define XPAR_MICROBLAZE_0_IADDR_SIZE 32
|
||||
@@ -288,7 +288,7 @@
|
||||
#define XPAR_MICROBLAZE_ENDIANNESS 1
|
||||
#define XPAR_MICROBLAZE_FAULT_TOLERANT 0
|
||||
#define XPAR_MICROBLAZE_FPU_EXCEPTION 1
|
||||
#define XPAR_MICROBLAZE_FREQ 150000000
|
||||
#define XPAR_MICROBLAZE_FREQ 125000000
|
||||
#define XPAR_MICROBLAZE_FSL_EXCEPTION 0
|
||||
#define XPAR_MICROBLAZE_FSL_LINKS 0
|
||||
#define XPAR_MICROBLAZE_IADDR_SIZE 32
|
||||
@@ -496,8 +496,8 @@
|
||||
#define PLATFORM_MB
|
||||
|
||||
/******************************************************************/
|
||||
#define STDIN_BASEADDRESS 0x40000000
|
||||
#define STDOUT_BASEADDRESS 0x40000000
|
||||
#define STDIN_BASEADDRESS 0x41400000
|
||||
#define STDOUT_BASEADDRESS 0x41400000
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -909,7 +909,30 @@
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13
|
||||
/* Definitions for driver IIC */
|
||||
#define XPAR_XIIC_NUM_INSTANCES 1
|
||||
|
||||
/* Definitions for peripheral AXI_IIC_0 */
|
||||
#define XPAR_AXI_IIC_0_DEVICE_ID 0
|
||||
#define XPAR_AXI_IIC_0_BASEADDR 0x40110000
|
||||
#define XPAR_AXI_IIC_0_HIGHADDR 0x4011FFFF
|
||||
#define XPAR_AXI_IIC_0_TEN_BIT_ADR 0
|
||||
#define XPAR_AXI_IIC_0_GPO_WIDTH 1
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
/* Canonical definitions for peripheral AXI_IIC_0 */
|
||||
#define XPAR_IIC_0_DEVICE_ID XPAR_AXI_IIC_0_DEVICE_ID
|
||||
#define XPAR_IIC_0_BASEADDR 0x40110000
|
||||
#define XPAR_IIC_0_HIGHADDR 0x4011FFFF
|
||||
#define XPAR_IIC_0_TEN_BIT_ADR 0
|
||||
#define XPAR_IIC_0_GPO_WIDTH 1
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_INTC_MAX_NUM_INTR_INPUTS 14
|
||||
#define XPAR_XINTC_HAS_IPR 1
|
||||
#define XPAR_XINTC_HAS_SIE 1
|
||||
#define XPAR_XINTC_HAS_CIE 1
|
||||
@@ -921,10 +944,10 @@
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_DEVICE_ID 0
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_BASEADDR 0x40010000
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_HIGHADDR 0x4001FFFF
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_KIND_OF_INTR 0xFFFFFBC9
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_KIND_OF_INTR 0xFFFFDBC9
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_HAS_FAST 1
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_IVAR_RESET_VALUE 0x0000000000000010
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_NUM_INTR_INPUTS 13
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_NUM_INTR_INPUTS 14
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_NUM_SW_INTR 0
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_ADDR_WIDTH 32
|
||||
|
||||
@@ -961,6 +984,8 @@
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_QSPI_FLASH_IP2INTC_IRPT_INTR 11U
|
||||
#define XPAR_SYSTEM_PPS_MASK 0X001000U
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_SYSTEM_PPS_INTR 12U
|
||||
#define XPAR_AXI_IIC_0_IIC2INTC_IRPT_MASK 0X002000U
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_AXI_IIC_0_IIC2INTC_IRPT_INTR 13U
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -968,10 +993,10 @@
|
||||
#define XPAR_INTC_0_DEVICE_ID XPAR_MICROBLAZE_0_AXI_INTC_DEVICE_ID
|
||||
#define XPAR_INTC_0_BASEADDR 0x40010000U
|
||||
#define XPAR_INTC_0_HIGHADDR 0x4001FFFFU
|
||||
#define XPAR_INTC_0_KIND_OF_INTR 0xFFFFFBC9U
|
||||
#define XPAR_INTC_0_KIND_OF_INTR 0xFFFFDBC9U
|
||||
#define XPAR_INTC_0_HAS_FAST 1U
|
||||
#define XPAR_INTC_0_IVAR_RESET_VALUE 0x0000000000000010U
|
||||
#define XPAR_INTC_0_NUM_INTR_INPUTS 13U
|
||||
#define XPAR_INTC_0_NUM_INTR_INPUTS 14U
|
||||
#define XPAR_INTC_0_NUM_SW_INTR 0U
|
||||
#define XPAR_INTC_0_ADDR_WIDTH 32U
|
||||
#define XPAR_INTC_0_INTC_TYPE 0U
|
||||
@@ -986,6 +1011,7 @@
|
||||
#define XPAR_INTC_0_SPI_1_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_QUAD_SPI_1_IP2INTC_IRPT_INTR
|
||||
#define XPAR_INTC_0_LLFIFO_0_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_FIFO_MM_S_0_INTERRUPT_INTR
|
||||
#define XPAR_INTC_0_SPI_2_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_QSPI_FLASH_IP2INTC_IRPT_INTR
|
||||
#define XPAR_INTC_0_IIC_0_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_IIC_0_IIC2INTC_IRPT_INTR
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -1161,7 +1187,7 @@
|
||||
#define XPAR_AXI_TIMER_0_DEVICE_ID 0U
|
||||
#define XPAR_AXI_TIMER_0_BASEADDR 0x40030000U
|
||||
#define XPAR_AXI_TIMER_0_HIGHADDR 0x4003FFFFU
|
||||
#define XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ 150000000U
|
||||
#define XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ 125000000U
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
@@ -1175,7 +1201,7 @@
|
||||
/******************************************************************/
|
||||
|
||||
/* Definitions for driver UARTLITE */
|
||||
#define XPAR_XUARTLITE_NUM_INSTANCES 1U
|
||||
#define XPAR_XUARTLITE_NUM_INSTANCES 2U
|
||||
|
||||
/* Definitions for peripheral AXI_UARTLITE_0 */
|
||||
#define XPAR_AXI_UARTLITE_0_DEVICE_ID 0U
|
||||
@@ -1196,5 +1222,25 @@
|
||||
#define XPAR_UARTLITE_0_DATA_BITS 8U
|
||||
|
||||
|
||||
|
||||
/* Definitions for peripheral MDM_1 */
|
||||
#define XPAR_MDM_1_DEVICE_ID 1U
|
||||
#define XPAR_MDM_1_BASEADDR 0x41400000U
|
||||
#define XPAR_MDM_1_HIGHADDR 0x41400FFFU
|
||||
#define XPAR_MDM_1_BAUDRATE 0U
|
||||
#define XPAR_MDM_1_USE_PARITY 0U
|
||||
#define XPAR_MDM_1_ODD_PARITY 0U
|
||||
#define XPAR_MDM_1_DATA_BITS 0U
|
||||
|
||||
/* Canonical definitions for peripheral MDM_1 */
|
||||
#define XPAR_UARTLITE_1_DEVICE_ID 1U
|
||||
#define XPAR_UARTLITE_1_BASEADDR 0x41400000U
|
||||
#define XPAR_UARTLITE_1_HIGHADDR 0x41400FFFU
|
||||
#define XPAR_UARTLITE_1_BAUDRATE 0U
|
||||
#define XPAR_UARTLITE_1_USE_PARITY 0U
|
||||
#define XPAR_UARTLITE_1_ODD_PARITY 0U
|
||||
#define XPAR_UARTLITE_1_DATA_BITS 0U
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
#endif /* end of protection macro */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,39 @@
|
||||
DRIVER_LIB_VERSION = 1.0
|
||||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
|
||||
CC_FLAGS = $(COMPILER_FLAGS)
|
||||
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
|
||||
|
||||
RELEASEDIR=../../../lib/
|
||||
INCLUDEDIR=../../../include/
|
||||
INCLUDES=-I./. -I$(INCLUDEDIR)
|
||||
|
||||
SRCFILES:=$(wildcard *.c)
|
||||
|
||||
OBJECTS = $(addprefix $(RELEASEDIR), $(addsuffix .o, $(basename $(wildcard *.c))))
|
||||
|
||||
libs: $(OBJECTS)
|
||||
|
||||
DEPFILES := $(SRCFILES:%.c=$(RELEASEDIR)%.d)
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
|
||||
include $(wildcard ../../../../dep.mk)
|
||||
|
||||
$(RELEASEDIR)%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) $(DEPENDENCY_FLAGS) $< -o $@
|
||||
|
||||
.PHONY: include
|
||||
include: $(addprefix $(INCLUDEDIR),$(wildcard *.h))
|
||||
|
||||
$(INCLUDEDIR)%.h: %.h
|
||||
$(CP) $< $@
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
||||
rm -rf $(DEPFILES)
|
||||
@@ -0,0 +1,722 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains required functions for the XIic component. See xiic.h for more
|
||||
* information on the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01c rmm 05/14/03 Fixed diab compiler warnings relating to asserts.
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.02a jvb 12/13/05 Added CfgInitialize(), and made CfgInitialize() take
|
||||
* a pointer to a config structure instead of a device id.
|
||||
* Moved Initialize() into xiic_sinit.c, and have
|
||||
* Initialize() call CfgInitialize() after it retrieved the
|
||||
* config structure using the device id. Removed include of
|
||||
* xparameters.h along with any dependencies on xparameters.h
|
||||
* and the _g.c config table.
|
||||
* 1.02a mta 03/09/06 Added a new function XIic_IsIicBusy() which returns
|
||||
* whether IIC Bus is Busy or Free.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.15a ktn 02/17/09 Fixed XIic_GetAddress() to return correct device address.
|
||||
* 1.16a ktn 07/18/09 Updated the notes in XIic_Reset function to clearly
|
||||
* indicate that only the Interrupt Registers are reset.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIic_SelfTest() API to mention
|
||||
* that the complete IIC core is Reset on giving a software
|
||||
* reset to the IIC core. This issue is fixed in the latest
|
||||
* version of the IIC core (some previous versions of the
|
||||
* core only reset the Interrupt Logic/Registers), please
|
||||
* see the Hw specification for further information.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name see the xiic_i.h and xiic_l.h file for further
|
||||
* information (Example XIic_mClearIntr is now
|
||||
* XIic_ClearIntr).
|
||||
* Some of the macros have been renamed to be consistent,
|
||||
* see the xiic_l.h file for further information
|
||||
* (Example XIIC_WRITE_IIER is renamed as XIic_WriteIier).
|
||||
* The driver has been updated to use the HAL APIs/macros.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* Changes done if files xiic.c and xiic_i.h. CR:705001.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XIic_CfgInitialize API.
|
||||
* 3.3 als 06/27/16 XIic_IsIicBusy now static inline in xiic.h.
|
||||
* 3.8 rna 11/30/20 Corrected the order of Assert in XIic_SetRecvHandler.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void XIic_StubStatusHandler(void *CallBackRef, int ErrorCode);
|
||||
|
||||
static void XIic_StubHandler(void *CallBackRef, int ByteCount);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initializes a specific XIic instance. The initialization entails:
|
||||
*
|
||||
* - Initialize the driver to allow access to the device registers and
|
||||
* initialize other subcomponents necessary for the operation of the device.
|
||||
* - Default options to:
|
||||
* - 7-bit slave addressing
|
||||
* - Send messages as a slave device
|
||||
* - Repeated start off
|
||||
* - General call recognition disabled
|
||||
* - Clear messageing and error statistics
|
||||
*
|
||||
* The XIic_Start() function must be called after this function before the device
|
||||
* is ready to send and receive data on the IIC bus.
|
||||
*
|
||||
* Before XIic_Start() is called, the interrupt control must connect the ISR
|
||||
* routine to the interrupt handler. This is done by the user, and not
|
||||
* XIic_Start() to allow the user to use an interrupt controller of their choice.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param Config is a reference to a structure containing information
|
||||
* about a specific IIC device. This function can initialize
|
||||
* multiple instance objects with the use of multiple calls giving
|
||||
* different Config information on each call.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory
|
||||
* address space. The caller is responsible for keeping the
|
||||
* address mapping from EffectiveAddr to the device physical base
|
||||
* address unchanged once this function is invoked. Unexpected
|
||||
* errors may occur if the address mapping changes after this
|
||||
* function is called. If address translation is not used, use
|
||||
* Config->BaseAddress for this parameters, passing the physical
|
||||
* address instead.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS when successful
|
||||
* - XST_DEVICE_IS_STARTED indicates the device is started
|
||||
* (i.e. interrupts enabled and messaging is possible). Must stop
|
||||
* before re-initialization is allowed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_CfgInitialize(XIic *InstancePtr, XIic_Config * Config,
|
||||
UINTPTR EffectiveAddr)
|
||||
{
|
||||
/*
|
||||
* Asserts test the validity of selected input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
InstancePtr->IsReady = 0;
|
||||
|
||||
/*
|
||||
* If the device is started, disallow the initialize and return a Status
|
||||
* indicating it is started. This allows the user to stop the device
|
||||
* and reinitialize, but prevents a user from inadvertently
|
||||
* initializing.
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set default values and configuration data, including setting the
|
||||
* callback handlers to stubs so the system will not crash should the
|
||||
* application not assign its own callbacks.
|
||||
*/
|
||||
InstancePtr->IsStarted = 0;
|
||||
InstancePtr->BaseAddress = EffectiveAddr;
|
||||
InstancePtr->RecvHandler = XIic_StubHandler;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
InstancePtr->SendHandler = XIic_StubHandler;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
InstancePtr->StatusHandler = XIic_StubStatusHandler;
|
||||
InstancePtr->Has10BitAddr = Config->Has10BitAddr;
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
InstancePtr->Options = 0;
|
||||
InstancePtr->BNBOnly = FALSE;
|
||||
InstancePtr->GpOutWidth = Config->GpOutWidth;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
InstancePtr->IsSlaveSetAckOff = FALSE;
|
||||
|
||||
/*
|
||||
* Reset the device.
|
||||
*/
|
||||
XIic_Reset(InstancePtr);
|
||||
|
||||
XIic_ClearStats(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function starts the IIC device and driver by enabling the proper
|
||||
* interrupts such that data may be sent and received on the IIC bus.
|
||||
* This function must be called before the functions to send and receive data.
|
||||
*
|
||||
* Before XIic_Start() is called, the interrupt control must connect the ISR
|
||||
* routine to the interrupt handler. This is done by the user, and not
|
||||
* XIic_Start() to allow the user to use an interrupt controller of their choice.
|
||||
*
|
||||
* Start enables:
|
||||
* - IIC device
|
||||
* - Interrupts:
|
||||
* - Addressed as slave to allow messages from another master
|
||||
* - Arbitration Lost to detect Tx arbitration errors
|
||||
* - Global IIC interrupt
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return XST_SUCCESS always.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The device interrupt is connected to the interrupt controller, but no
|
||||
* "messaging" interrupts are enabled. Addressed as Slave is enabled to
|
||||
* reception of messages when this devices address is written to the bus.
|
||||
* The correct messaging interrupts are enabled when sending or receiving
|
||||
* via the IicSend() and IicRecv() functions. No action is required
|
||||
* by the user to control any IIC interrupts as the driver completely
|
||||
* manages all 8 interrupts. Start and Stop control the ability
|
||||
* to use the device. Stopping the device completely stops all device
|
||||
* interrupts from the processor.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_Start(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Mask off all interrupts, each is enabled when needed.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress, 0);
|
||||
|
||||
/*
|
||||
* Clear all interrupts by reading and rewriting exact value back.
|
||||
* Only those bits set will get written as 1 (writing 1 clears intr).
|
||||
*/
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress, 0xFFFFFFFF);
|
||||
|
||||
/*
|
||||
* Enable the device.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
XIIC_CR_ENABLE_DEVICE_MASK);
|
||||
/*
|
||||
* Set Rx FIFO Occupancy depth to throttle at
|
||||
* first byte(after reset = 0).
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Clear and enable the interrupts needed.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
|
||||
|
||||
InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
|
||||
/*
|
||||
* Enable the Global interrupt enable.
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function stops the IIC device and driver such that data is no longer
|
||||
* sent or received on the IIC bus. This function stops the device by
|
||||
* disabling interrupts. This function only disables interrupts within the
|
||||
* device such that the caller is responsible for disconnecting the interrupt
|
||||
* handler of the device from the interrupt source and disabling interrupts
|
||||
* at other levels.
|
||||
*
|
||||
* Due to bus throttling that could hold the bus between messages when using
|
||||
* repeated start option, stop will not occur when the device is actively
|
||||
* sending or receiving data from the IIC bus or the bus is being throttled
|
||||
* by this device, but instead return XST_IIC_BUS_BUSY.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates all IIC interrupts are disabled.
|
||||
* No messages can be received or transmitted until XIic_Start()
|
||||
* is called.
|
||||
* - XST_IIC_BUS_BUSY indicates this device is currently engaged
|
||||
* in message traffic and cannot be stopped.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_Stop(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 CntlReg;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Disable all interrupts globally.
|
||||
*/
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
if ((CntlReg & XIIC_CR_MSMS_MASK) ||
|
||||
(Status & XIIC_SR_ADDR_AS_SLAVE_MASK)) {
|
||||
/*
|
||||
* When this device is using the bus
|
||||
* - re-enable interrupts to finish current messaging
|
||||
* - return bus busy
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
InstancePtr->IsStarted = 0;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Resets the IIC device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The complete IIC core is Reset on giving a software reset to
|
||||
* the IIC core. Some previous versions of the core only reset
|
||||
* the Interrupt Logic/Registers, please refer to the HW specification
|
||||
* for further details about this.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_Reset(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RESETR_OFFSET,
|
||||
XIIC_RESET_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the bus addresses. The addresses include the device
|
||||
* address that the device responds to as a slave, or the slave address
|
||||
* to communicate with on the bus. The IIC device hardware is built to
|
||||
* allow either 7 or 10 bit slave addressing only at build time rather
|
||||
* than at run time. When this device is a master, slave addressing can
|
||||
* be selected at run time to match addressing modes for other bus devices.
|
||||
*
|
||||
* Addresses are represented as hex values with no adjustment for the data
|
||||
* direction bit as the software manages address bit placement.
|
||||
* Example: For a 7 address written to the device of 1010 011X where X is
|
||||
* the transfer direction (send/recv), the address parameter for this function
|
||||
* needs to be 01010011 or 0x53 where the correct bit alllignment will be
|
||||
* handled for 7 as well as 10 bit devices. This is especially important as
|
||||
* the bit placement is not handled the same depending on which options are
|
||||
* used such as repeated start.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param AddressType indicates which address is being modified, the
|
||||
* address which this device responds to on the IIC bus as a slave,
|
||||
* or the slave address to communicate with when this device is a
|
||||
* master. One of the following values must be contained in
|
||||
* this argument.
|
||||
* <pre>
|
||||
* XII_ADDR_TO_SEND_TYPE Slave being addressed by a this master
|
||||
* XII_ADDR_TO_RESPOND_TYPE Address to respond to as a slave device
|
||||
* </pre>
|
||||
*
|
||||
* @param Address contains the address to be set, 7 bit or 10 bit address.
|
||||
* A ten bit address must be within the range: 0 - 1023 and a 7 bit
|
||||
* address must be within the range 0 - 127.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS is returned if the address was successfully set.
|
||||
* - XST_IIC_NO_10_BIT_ADDRESSING indicates only 7 bit addressing
|
||||
* supported.
|
||||
* - XST_INVALID_PARAM indicates an invalid parameter was
|
||||
* specified.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Upper bits of 10-bit address is written only when current device is built
|
||||
* as a ten bit device.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_SetAddress(XIic *InstancePtr, int AddressType, int Address)
|
||||
{
|
||||
u32 SendAddr;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address < 1023);
|
||||
|
||||
/*
|
||||
* Set address to respond to for this device into address registers.
|
||||
*/
|
||||
if (AddressType == XII_ADDR_TO_RESPOND_TYPE) {
|
||||
/*
|
||||
* Address in upper 7 bits.
|
||||
*/
|
||||
SendAddr = ((Address & 0x007F) << 1);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_ADR_REG_OFFSET,
|
||||
SendAddr);
|
||||
|
||||
if (InstancePtr->Has10BitAddr == TRUE) {
|
||||
/*
|
||||
* Write upper 3 bits of addr to DTR only when 10 bit
|
||||
* option included in design i.e. register exists.
|
||||
*/
|
||||
SendAddr = ((Address & 0x0380) >> 7);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_TBA_REG_OFFSET, SendAddr);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store address of slave device being read from.
|
||||
*/
|
||||
if (AddressType == XII_ADDR_TO_SEND_TYPE) {
|
||||
InstancePtr->AddrOfSlave = Address;
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
return XST_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the addresses for the IIC device driver. The addresses
|
||||
* include the device address that the device responds to as a slave, or the
|
||||
* slave address to communicate with on the bus. The address returned has the
|
||||
* same format whether 7 or 10 bits.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param AddressType indicates which address, the address which this
|
||||
* responds to on the IIC bus as a slave, or the slave address to
|
||||
* communicate with when this device is a master. One of the
|
||||
* following values must be contained in this argument.
|
||||
* <pre>
|
||||
* XII_ADDR_TO_SEND_TYPE Slave being addressed as a master
|
||||
* XII_ADDR_TO_RESPOND_TYPE Slave address to respond to as a slave
|
||||
* </pre>
|
||||
* If neither of the two valid arguments are used, the function returns
|
||||
* the address of the slave device
|
||||
*
|
||||
* @return The address retrieved.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u16 XIic_GetAddress(XIic *InstancePtr, int AddressType)
|
||||
{
|
||||
u8 LowAddr;
|
||||
u16 HighAddr = 0;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Return this device's address.
|
||||
*/
|
||||
if (AddressType == XII_ADDR_TO_RESPOND_TYPE) {
|
||||
|
||||
LowAddr = (u8) XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_ADR_REG_OFFSET);
|
||||
|
||||
if (InstancePtr->Has10BitAddr == TRUE) {
|
||||
HighAddr = (u16) XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_TBA_REG_OFFSET);
|
||||
}
|
||||
return ((HighAddr << 8) | (u16) LowAddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise return address of slave device on the IIC bus.
|
||||
*/
|
||||
return InstancePtr->AddrOfSlave;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the contents of the General Purpose Output register
|
||||
* for the IIC device driver. Note that the number of bits in this register is
|
||||
* parameterizable in the hardware such that it may not exist. This function
|
||||
* checks to ensure that it does exist to prevent bus errors, but does not
|
||||
* ensure that the number of bits in the register are sufficient for the
|
||||
* value being written (won't cause a bus error).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param OutputValue contains the value to be written to the register.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the given data is written to the GPO register.
|
||||
* - XST_NO_FEATURE if the hardware is configured such that this
|
||||
* register does not contain any bits to read or write.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_SetGpOutput(XIic *InstancePtr, u8 OutputValue)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* If the general purpose output register is implemented by the hardware
|
||||
* then write the specified value to it, otherwise indicate an error.
|
||||
*/
|
||||
if (InstancePtr->GpOutWidth > 0) {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_GPO_REG_OFFSET,
|
||||
OutputValue);
|
||||
return XST_SUCCESS;
|
||||
} else {
|
||||
return XST_NO_FEATURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the contents of the General Purpose Output register
|
||||
* for the IIC device driver. Note that the number of bits in this register is
|
||||
* parameterizable in the hardware such that it may not exist. This function
|
||||
* checks to ensure that it does exist to prevent bus errors.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param OutputValuePtr contains the value which was read from the
|
||||
* register.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the given data is read from the GPO register.
|
||||
* - XST_NO_FEATURE if the hardware is configured such that this
|
||||
* register does not contain any bits to read or write.
|
||||
*
|
||||
* The OutputValuePtr is also an output as it contains the value read.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_GetGpOutput(XIic *InstancePtr, u8 *OutputValuePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(OutputValuePtr != NULL);
|
||||
|
||||
/*
|
||||
* If the general purpose output register is implemented by the hardware
|
||||
* then read the value from it, otherwise indicate an error.
|
||||
*/
|
||||
if (InstancePtr->GpOutWidth > 0) {
|
||||
*OutputValuePtr = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_GPO_REG_OFFSET);
|
||||
return XST_SUCCESS;
|
||||
} else {
|
||||
return XST_NO_FEATURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* A function to determine if the device is currently addressed as a slave.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the device is addressed as slave.
|
||||
* - FALSE if the device is NOT addressed as slave.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 XIic_IsSlave(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
if ((XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET) &
|
||||
XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the receive callback function, the receive handler, which the driver
|
||||
* calls when it finishes receiving data. The number of bytes used to signal
|
||||
* when the receive is complete is the number of bytes set in the XIic_Recv
|
||||
* function.
|
||||
*
|
||||
* The handler executes in an interrupt context such that it must minimize
|
||||
* the amount of processing performed such as transferring data to a thread
|
||||
* context.
|
||||
*
|
||||
* The number of bytes received is passed to the handler as an argument.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The handler is called within interrupt context .
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetRecvHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
|
||||
InstancePtr->RecvHandler = FuncPtr;
|
||||
InstancePtr->RecvCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the send callback function, the send handler, which the driver calls when
|
||||
* it receives confirmation of sent data. The handler executes in an interrupt
|
||||
* context such that it must minimize the amount of processing performed such
|
||||
* as transferring data to a thread context.
|
||||
*
|
||||
* @param InstancePtr the pointer to the XIic instance to be worked on.
|
||||
* @param CallBackRef the upper layer callback reference passed back when
|
||||
* the callback function is invoked.
|
||||
* @param FuncPtr the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The handler is called within interrupt context .
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetSendHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
|
||||
InstancePtr->SendHandler = FuncPtr;
|
||||
InstancePtr->SendCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the status callback function, the status handler, which the driver calls
|
||||
* when it encounters conditions which are not data related. The handler
|
||||
* executes in an interrupt context such that it must minimize the amount of
|
||||
* processing performed such as transferring data to a thread context. The
|
||||
* status events that can be returned are described in xiic.h.
|
||||
*
|
||||
* @param InstancePtr points to the XIic instance to be worked on.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The handler is called within interrupt context .
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetStatusHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_StatusHandler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
|
||||
InstancePtr->StatusHandler = FuncPtr;
|
||||
InstancePtr->StatusCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a stub for the send and recv callbacks. The stub is here in case the
|
||||
* upper layers forget to set the handlers.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
* @param ByteCount is the number of bytes sent or received
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XIic_StubHandler(void *CallBackRef, int ByteCount)
|
||||
{
|
||||
(void) ByteCount;
|
||||
(void) CallBackRef;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a stub for the asynchronous error callback. The stub is here in case
|
||||
* the upper layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference.
|
||||
* @param ErrorCode is the Xilinx error code, indicating the cause of
|
||||
* the error.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XIic_StubStatusHandler(void *CallBackRef, int ErrorCode)
|
||||
{
|
||||
(void) ErrorCode;
|
||||
(void) CallBackRef;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,589 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* XIic is the driver for an IIC master or slave device.
|
||||
*
|
||||
* In order to reduce the memory requirements of the driver the driver is
|
||||
* partitioned such that there are optional parts of the driver.
|
||||
* Slave, master, and multimaster features are optional such that all these files
|
||||
* are not required at the same time.
|
||||
* In order to use the slave and multimaster features of the driver, the user
|
||||
* must call functions (XIic_SlaveInclude and XIic_MultiMasterInclude)
|
||||
* to dynamically include the code. These functions may be called at any time.
|
||||
*
|
||||
* Two sets of higher level API's are available in the XIic driver that can
|
||||
* be used for Transmission/Reception in Master mode :
|
||||
* - XIic_MasterSend()/ XIic_MasterRecv() which is used in normal mode.
|
||||
* - XIic_DynMasterSend()/ XIic_DynMasterRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* Similarly two sets of lower level API's are available in XIic driver that
|
||||
* can be used for Transmission/Reception in Master mode:
|
||||
* - XIic_Send()/ XIic_Recv() which is used in normal mode
|
||||
* - XIic_DynSend()/ XIic_DynRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* The user should use a single set of APIs as per his requirement and
|
||||
* should not intermix them.
|
||||
*
|
||||
* All the driver APIs can be used for read, write and combined mode of
|
||||
* operations on the IIC bus.
|
||||
*
|
||||
* In the normal mode IIC support both 7-bit and 10-bit addressing, and in
|
||||
* the dynamic mode support only 7-bit addressing.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XIic_Config structure is used by the driver to configure itself. This
|
||||
* configuration structure is typically created by the tool-chain based on HW
|
||||
* build properties.
|
||||
*
|
||||
* To support multiple runtime loading and initialization strategies employed
|
||||
* by various operating systems, the driver instance can be initialized in one
|
||||
* of the following ways:
|
||||
*
|
||||
* - XIic_Initialize() - The driver looks up its own
|
||||
* configuration structure created by the tool-chain based on an ID provided
|
||||
* by the tool-chain.
|
||||
*
|
||||
* - XIic_CfgInitialize() - The driver uses a configuration structure provided
|
||||
* by the caller. If running in a system with address translation, the
|
||||
* provided virtual memory base address replaces the physical address present
|
||||
* in the configuration structure.
|
||||
*
|
||||
* <b>General Purpose Output</b>
|
||||
* The IIC hardware provides a General Purpose Output Register that allows the
|
||||
* user to connect general purpose outputs to devices, such as a write protect,
|
||||
* for an EEPROM. This register is parameterizable in the hardware such that
|
||||
* there could be zero bits in this register and in this case it will cause
|
||||
* a bus error if read or written.
|
||||
*
|
||||
* <b>Bus Throttling</b>
|
||||
*
|
||||
* The IIC hardware provides bus throttling which allows either the device, as
|
||||
* either a master or a slave, to stop the clock on the IIC bus. This feature
|
||||
* allows the software to perform the appropriate processing for each interrupt
|
||||
* without an unreasonable response restriction. With this design, it is
|
||||
* important for the user to understand the implications of bus throttling.
|
||||
*
|
||||
* <b>Repeated Start</b>
|
||||
*
|
||||
* An application can send multiple messages, as a master, to a slave device
|
||||
* and re-acquire the IIC bus each time a message is sent. The repeated start
|
||||
* option allows the application to send multiple messages without re-acquiring
|
||||
* the IIC bus for each message. The transactions involving repeated start
|
||||
* are also called combined transfers if there is Read and Write in the
|
||||
* same transaction.
|
||||
*
|
||||
* The repeated start feature works with all the API's in XIic driver.
|
||||
*
|
||||
* The Repeated Start feature also could cause the application to lock up, or
|
||||
* monopolize the IIC bus, should repeated start option be enabled and sequences
|
||||
* of messages never end(periodic data collection).
|
||||
* Also when repeated start is not disable before the last master message is
|
||||
* sent or received, will leave the bus captive to the master, but unused.
|
||||
*
|
||||
* <b>Addressing</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built for 7 or 10
|
||||
* bit addresses. The driver provides the ability to control which address
|
||||
* size is sent in messages as a master to a slave device. The address size
|
||||
* which the hardware responds to as a slave is parameterized as 7 or 10 bits
|
||||
* but fixed by the hardware build.
|
||||
*
|
||||
* Addresses are represented as hex values with no adjustment for the data
|
||||
* direction bit as the software manages address bit placement. This is
|
||||
* especially important as the bit placement is not handled the same depending
|
||||
* on which options are used such as repeated start and 7 vs 10 bit addressing.
|
||||
*
|
||||
* <b>Data Rates</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built to support
|
||||
* data rates from DC to 400KBit. The frequency of the interrupts which
|
||||
* occur is proportional to the data rate.
|
||||
*
|
||||
* <b>Polled Mode Operation</b>
|
||||
*
|
||||
* This driver does not provide a polled mode of operation primarily because
|
||||
* polled mode which is non-blocking is difficult with the amount of
|
||||
* interaction with the hardware that is necessary.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The device has many interrupts which allow IIC data transactions as well
|
||||
* as bus status processing to occur.
|
||||
*
|
||||
* The interrupts are divided into two types, data and status. Data interrupts
|
||||
* indicate data has been received or transmitted while the status interrupts
|
||||
* indicate the status of the IIC bus. Some of the interrupts, such as Not
|
||||
* Addressed As Slave and Bus Not Busy, are only used when these specific
|
||||
* events must be recognized as opposed to being enabled at all times.
|
||||
*
|
||||
* Many of the interrupts are not a single event in that they are continuously
|
||||
* present such that they must be disabled after recognition or when undesired.
|
||||
* Some of these interrupts, which are data related, may be acknowledged by the
|
||||
* software by reading or writing data to the appropriate register, or must
|
||||
* be disabled. The following interrupts can be continuous rather than single
|
||||
* events.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Bus Not Busy
|
||||
* - Addressed As Slave
|
||||
* - Not Addressed As Slave
|
||||
*
|
||||
* The following interrupts are not passed directly to the application through the
|
||||
* status callback. These are only used internally for the driver processing
|
||||
* and may result in the receive and send handlers being called to indicate
|
||||
* completion of an operation. The following interrupts are data related
|
||||
* rather than status.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Slave Transmit Complete
|
||||
*
|
||||
* <b>Interrupt To Event Mapping</b>
|
||||
*
|
||||
* The following table provides a mapping of the interrupts to the events which
|
||||
* are passed to the status handler and the intended role (master or slave) for
|
||||
* the event. Some interrupts can cause multiple events which are combined
|
||||
* together into a single status event such as XII_MASTER_WRITE_EVENT and
|
||||
* XII_GENERAL_CALL_EVENT
|
||||
* <pre>
|
||||
* Interrupt Event(s) Role
|
||||
*
|
||||
* Arbitration Lost Interrupt XII_ARB_LOST_EVENT Master
|
||||
* Transmit Error XII_SLAVE_NO_ACK_EVENT Master
|
||||
* IIC Bus Not Busy XII_BUS_NOT_BUSY_EVENT Master
|
||||
* Addressed As Slave XII_MASTER_READ_EVENT, Slave
|
||||
* XII_MASTER_WRITE_EVENT, Slave
|
||||
* XII_GENERAL_CALL_EVENT Slave
|
||||
* </pre>
|
||||
* <b>Not Addressed As Slave Interrupt</b>
|
||||
*
|
||||
* The Not Addressed As Slave interrupt is not passed directly to the
|
||||
* application through the status callback. It is used to determine the end of
|
||||
* a message being received by a slave when there was no stop condition
|
||||
* (repeated start). It will cause the receive handler to be called to
|
||||
* indicate completion of the operation.
|
||||
*
|
||||
* <b>RTOS Independence</b>
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works
|
||||
* with physical addresses only. Any needs for dynamic memory management,
|
||||
* threads or thread mutual exclusion, virtual memory, or cache control must
|
||||
* be satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.01d sv 05/09/05 Changed the data being written to the Address/Control
|
||||
* Register and removed the code for testing the
|
||||
* Receive Data Register in XIic_SelfTest function of
|
||||
* xiic_selftest.c source file
|
||||
* 1.02a jvb 12/14/05 I separated dependency on the static config table and
|
||||
* xparameters.h from the driver initialization by moving
|
||||
* _Initialize and _LookupConfig to _sinit.c. I also added
|
||||
* the new _CfgInitialize routine.
|
||||
* 1.02a mta 03/09/06 Added a new function XIic_IsIicBusy() which returns
|
||||
* whether IIC Bus is Busy or Free.
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 07/17/06 Added files to support Dynamic IIC controller in High
|
||||
* level driver. Added xiic_dyn_master.c. Added support
|
||||
* for IIC Dynamic controller in Low level driver in xiic_l.c
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.13b ecm 11/29/07 added BB polling loops to the DynSend and DynRecv
|
||||
* routines to handle the race condition with BNB in IISR.
|
||||
* 1.14a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
|
||||
* file
|
||||
* 1.14a ecm 11/13/08 changed BB polling loops in DynRecv to handle race
|
||||
* condition, CR491889. DynSend was correct from v1.13.b
|
||||
* 1.15a ktn 02/17/09 Fixed XIic_GetAddress() to return correct device address.
|
||||
* 1.16a ktn 07/17/09 Updated the XIic_SelfTest() to test only Interrupt
|
||||
* Registers.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.,
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Removed the XIIC_CLEAR_STATS macro, XIic_ClearStats API
|
||||
* should be used in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name see the xiic_i.h and xiic_l.h file for further
|
||||
* information (Example XIic_mClearIntr is now
|
||||
* XIic_ClearIntr).
|
||||
* Some of the macros have been renamed to be consistent,
|
||||
* see the xiic_l.h file for further information
|
||||
* (Example XIIC_WRITE_IIER is renamed as XIic_WriteIier).
|
||||
* The driver has been updated to use the HAL APIs/macros
|
||||
* (Example XASSERT_NONVOID is now Xil_AssertNonvoid)
|
||||
* 2.01a ktn 04/09/10 Updated TxErrorhandler in xiic_intr.c to be called for
|
||||
* Master Transmitter case based on Addressed As Slave (AAS)
|
||||
* bit rather than MSMS bit(CR 540199).
|
||||
* 2.02a sdm 10/08/10 Updated to disable the device at the end of the transfer,
|
||||
* using Addressed As Slave (AAS) bit when addressed as
|
||||
* slave in XIic_Send for CR565373.
|
||||
* 2.03a rkv 01/25/11 Updated in NAAS interrupt handler to support data
|
||||
* received less than FIFO size prior to NAAS interrupt.
|
||||
* Fixed for CR590212.
|
||||
* 2.04a sdm 07/22/11 Added IsSlaveSetAckOff flag to the instance structure.
|
||||
* This flag is set when the Slave has set the Ack Off in the
|
||||
* RecvSlaveData function (xiic_slave.c) and
|
||||
* is cleared in the NotAddrAsSlaveHandler (xiic_slave.c)
|
||||
* when the master has released the bus. This flag is
|
||||
* to be used by slave applications for recovering when it
|
||||
* has gone out of sync with the master for CR 615004.
|
||||
* Removed a compiler warning in XIic_Send (xiic_l.c)
|
||||
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
|
||||
* SendBufferPtr in XIic_MasterRecv to NULL in xiic_master.c
|
||||
* 2.06a bss 02/14/13 Modified TxErrorHandler in xiic_intr.c to fix CR #686483
|
||||
* Modified xiic_eeprom_example.c to fix CR# 683509.
|
||||
* Modified bitwise OR to logical OR in
|
||||
* XIic_InterruptHandler API in xiic_intr.c.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
* 2.08a adk 29/07/13 In Low level driver In repeated start condition the
|
||||
* Direction of Tx bit must be disabled in recv condition
|
||||
* It Fixes the CR:685759 Changes are done in the file
|
||||
* xiic_l.c in the function XIic_Recv.
|
||||
* 3.0 adk 19/12/13 Updated as per the New Tcl API's
|
||||
* 3.1 adk 01/08/15 When configured as a slave return the actual number of
|
||||
* bytes have been received/sent by the Master
|
||||
* to the user callback (CR: 828504). Changes are made in the
|
||||
* file xiic_slave.c.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XIic_CfgInitialize API.
|
||||
* 3.2 sd 18/02/16 In Low level driver in repeated start condition
|
||||
* NACK for last byte is added. Changes are done in
|
||||
* XIic_Recv for CR# 862303
|
||||
* 3.3 sk 06/17/16 Added bus busy checks for slave send/recv and master
|
||||
* send/recv.
|
||||
* 3.3 als 06/27/16 XIic_IsIicBusy now a wrapper for XIic_CheckIsBusBusy.
|
||||
* 3.4 ms 01/23/17 Added xil_printf statement in main function for all
|
||||
* examples to ensure that "Successfully ran" and "Failed"
|
||||
* strings are available in all examples. This is a fix
|
||||
* for CR-965028.
|
||||
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
|
||||
* generation.
|
||||
* ms 04/05/17 Modified Comment lines in functions of iic
|
||||
* examples to recognize it as documentation block
|
||||
* for doxygen generation.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XIIC_H /* prevent circular inclusions */
|
||||
#define XIIC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* The following options may be specified or retrieved for the device and
|
||||
* enable/disable additional features of the IIC bus. Each of the options
|
||||
* are bit fields such that more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XII_GENERAL_CALL_OPTION The general call option allows an IIC slave to
|
||||
* recognized the general call address. The status
|
||||
* handler is called as usual indicating the device
|
||||
* has been addressed as a slave with a general
|
||||
* call. It is the application's responsibility to
|
||||
* perform any special processing for the general
|
||||
* call.
|
||||
*
|
||||
* XII_REPEATED_START_OPTION The repeated start option allows multiple
|
||||
* messages to be sent/received on the IIC bus
|
||||
* without rearbitrating for the bus. The messages
|
||||
* are sent as a series of messages such that the
|
||||
* option must be enabled before the 1st message of
|
||||
* the series, to prevent an stop condition from
|
||||
* being generated on the bus, and disabled before
|
||||
* the last message of the series, to allow the
|
||||
* stop condition to be generated.
|
||||
*
|
||||
* XII_SEND_10_BIT_OPTION The send 10 bit option allows 10 bit addresses
|
||||
* to be sent on the bus when the device is a
|
||||
* master. The device can be configured to respond
|
||||
* as to 7 bit addresses even though it may be
|
||||
* communicating with other devices that support 10
|
||||
* bit addresses. When this option is not enabled,
|
||||
* only 7 bit addresses are sent on the bus.
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
#define XII_GENERAL_CALL_OPTION 0x00000001
|
||||
#define XII_REPEATED_START_OPTION 0x00000002
|
||||
#define XII_SEND_10_BIT_OPTION 0x00000004
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Status events
|
||||
*
|
||||
* The following status events occur during IIC bus processing and are passed
|
||||
* to the status callback. Each event is only valid during the appropriate
|
||||
* processing of the IIC bus. Each of these events are bit fields such that
|
||||
* more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
#define XII_BUS_NOT_BUSY_EVENT 0x00000001 /**< Bus transitioned to not busy */
|
||||
#define XII_ARB_LOST_EVENT 0x00000002 /**< Arbitration was lost */
|
||||
#define XII_SLAVE_NO_ACK_EVENT 0x00000004 /**< Slave did not ACK (had error) */
|
||||
#define XII_MASTER_READ_EVENT 0x00000008 /**< Master reading from slave */
|
||||
#define XII_MASTER_WRITE_EVENT 0x00000010 /**< Master writing to slave */
|
||||
#define XII_GENERAL_CALL_EVENT 0x00000020 /**< General call to all slaves */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/*
|
||||
* The following address types are used when setting and getting the addresses
|
||||
* of the driver. These are mutually exclusive such that only one or the other
|
||||
* may be specified.
|
||||
*/
|
||||
#define XII_ADDR_TO_SEND_TYPE 1 /**< Bus address of slave device */
|
||||
#define XII_ADDR_TO_RESPOND_TYPE 2 /**< This device's bus address as slave */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< Does device have 10 bit address decoding */
|
||||
u8 GpOutWidth; /**< Number of bits in general purpose output */
|
||||
} XIic_Config;
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of sent and received data of the IIC driver. The application
|
||||
* using this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handlers are called in an interrupt context such
|
||||
* that minimal processing should be performed. The handler data type is
|
||||
* utilized for both send and receive handlers.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param ByteCount indicates the number of bytes remaining to be sent or
|
||||
* received. A value of zero indicates that the requested number
|
||||
* of bytes were sent or received.
|
||||
*
|
||||
******************************************************************************/
|
||||
typedef void (*XIic_Handler) (void *CallBackRef, int ByteCount);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of status events of the IIC driver. The application using
|
||||
* this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handler is called in an interrupt context such
|
||||
* that minimal processing should be performed.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param StatusEvent indicates one or more status events that occurred.
|
||||
* See the definition of the status events above.
|
||||
*
|
||||
********************************************************************************/
|
||||
typedef void (*XIic_StatusHandler) (void *CallBackRef, int StatusEvent);
|
||||
|
||||
/**
|
||||
* XIic statistics
|
||||
*/
|
||||
typedef struct {
|
||||
u8 ArbitrationLost;/**< Number of times arbitration was lost */
|
||||
u8 RepeatedStarts; /**< Number of repeated starts */
|
||||
u8 BusBusy; /**< Number of times bus busy status returned */
|
||||
u8 RecvBytes; /**< Number of bytes received */
|
||||
u8 RecvInterrupts; /**< Number of receive interrupts */
|
||||
u8 SendBytes; /**< Number of transmit bytes received */
|
||||
u8 SendInterrupts; /**< Number of transmit interrupts */
|
||||
u8 TxErrors; /**< Number of transmit errors (no ack) */
|
||||
u8 IicInterrupts; /**< Number of IIC (device) interrupts */
|
||||
} XIicStats;
|
||||
|
||||
/**
|
||||
* The XIic driver instance data. The user is required to allocate a
|
||||
* variable of this type for every IIC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XIicStats Stats; /**< Statistics */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< TRUE when 10 bit addressing in design */
|
||||
int IsReady; /**< Device is initialized and ready */
|
||||
int IsStarted; /**< Device has been started */
|
||||
int AddrOfSlave; /**< Slave Address writing to */
|
||||
|
||||
u32 Options; /**< Current operating options */
|
||||
u8 *SendBufferPtr; /**< Buffer to send (state) */
|
||||
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
|
||||
u8 TxAddrMode; /**< State of Tx Address transmission */
|
||||
int SendByteCount; /**< Number of data bytes in buffer (state) */
|
||||
int RecvByteCount; /**< Number of empty bytes in buffer (state) */
|
||||
|
||||
u32 BNBOnly; /**< TRUE when BNB interrupt needs to */
|
||||
/**< call callback */
|
||||
u8 GpOutWidth; /**< General purpose output width */
|
||||
|
||||
XIic_StatusHandler StatusHandler; /**< Status Handler */
|
||||
void *StatusCallBackRef; /**< Callback reference for status handler */
|
||||
XIic_Handler RecvHandler; /**< Receive Handler */
|
||||
void *RecvCallBackRef; /**< Callback reference for Recv handler */
|
||||
XIic_Handler SendHandler; /**< Send Handler */
|
||||
void *SendCallBackRef; /**< Callback reference for send handler */
|
||||
int IsDynamic; /**< TRUE when Dynamic control is used */
|
||||
int IsSlaveSetAckOff; /**< TRUE when Slave has set the ACK Off */
|
||||
|
||||
} XIic;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a function which tells whether the I2C bus is busy or free.
|
||||
*
|
||||
* @param InstancePtr points to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the bus is busy.
|
||||
* - FALSE if the bus is NOT busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static inline u32 XIic_IsIicBusy(XIic *InstancePtr)
|
||||
{
|
||||
return XIic_CheckIsBusBusy(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization functions in xiic_sinit.c
|
||||
*/
|
||||
int XIic_Initialize(XIic *InstancePtr, u16 DeviceId);
|
||||
XIic_Config *XIic_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions in xiic.c
|
||||
*/
|
||||
int XIic_CfgInitialize(XIic *InstancePtr, XIic_Config *Config,
|
||||
UINTPTR EffectiveAddr);
|
||||
|
||||
int XIic_Start(XIic *InstancePtr);
|
||||
int XIic_Stop(XIic *InstancePtr);
|
||||
|
||||
void XIic_Reset(XIic *InstancePtr);
|
||||
|
||||
int XIic_SetAddress(XIic *InstancePtr, int AddressType, int Address);
|
||||
u16 XIic_GetAddress(XIic *InstancePtr, int AddressType);
|
||||
|
||||
int XIic_SetGpOutput(XIic *InstancePtr, u8 OutputValue);
|
||||
int XIic_GetGpOutput(XIic *InstancePtr, u8 *OutputValuePtr);
|
||||
|
||||
u32 XIic_IsSlave(XIic *InstancePtr);
|
||||
|
||||
void XIic_SetRecvHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetSendHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetStatusHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_StatusHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xiic_intr.c
|
||||
*/
|
||||
void XIic_InterruptHandler(void *InstancePtr);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in normal mode in xiic_master.c
|
||||
*/
|
||||
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in dynamic mode in xiic_master.c
|
||||
*/
|
||||
int XIic_DynMasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, u8 ByteCount);
|
||||
int XIic_DynMasterSend(XIic *InstancePtr, u8 *TxMsgPtr, u8 ByteCount);
|
||||
|
||||
/*
|
||||
* Dynamic IIC Core Initialization.
|
||||
*/
|
||||
int XIic_DynamicInitialize(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Slave send and receive functions in xiic_slave.c
|
||||
*/
|
||||
void XIic_SlaveInclude(void);
|
||||
int XIic_SlaveRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_SlaveSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Statistics functions in xiic_stats.c
|
||||
*/
|
||||
void XIic_GetStats(XIic *InstancePtr, XIicStats *StatsPtr);
|
||||
void XIic_ClearStats(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Self test functions in xiic_selftest.c
|
||||
*/
|
||||
int XIic_SelfTest(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Bus busy Function in xiic.c
|
||||
*/
|
||||
u32 XIic_IsIicBusy(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Options functions in xiic_options.c
|
||||
*/
|
||||
void XIic_SetOptions(XIic *InstancePtr, u32 Options);
|
||||
u32 XIic_GetOptions(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Multi-master functions in xiic_multi_master.c
|
||||
*/
|
||||
void XIic_MultiMasterInclude(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,603 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2006 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_dyn_master.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains master functions for the XIic component in Dynamic controller mode.
|
||||
* This file is necessary to send or receive as a master on the IIC bus.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------------------
|
||||
* 1.03a mta 04/10/06 Created.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros. The macros
|
||||
* XIic_mDynSend7BitAddress and XIic_mDynSendStop have
|
||||
* been removed from this file as they were already
|
||||
* defined in a header file.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and Some of the macros have been renamed to be
|
||||
* consistent, see the xiic_l.h file for further information.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro includes dynamic master code such that dynamic master operations,
|
||||
* sending and receiving data, may be used. This function hooks the dynamic
|
||||
* master processing to the driver such that events are handled properly and
|
||||
* allows dynamic master processing to be optional. It must be called before any
|
||||
* functions which are contained in this file are called, such as after the
|
||||
* driver is initialized.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIC_DYN_MASTER_INCLUDE \
|
||||
{ \
|
||||
XIic_RecvMasterFuncPtr = DynRecvMasterData; \
|
||||
XIic_SendMasterFuncPtr = DynSendMasterData; \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void DynRecvMasterData(XIic *InstancePtr);
|
||||
static void DynSendMasterData(XIic *InstancePtr);
|
||||
static int IsBusBusy(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function sends data as a Dynamic master on the IIC bus. If the bus is
|
||||
* busy, it will indicate so and then enable an interrupt such that the status
|
||||
* handler will be called when the bus is no longer busy. The slave address is
|
||||
* sent by using XIic_DynSend7BitAddress().
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
* @param TxMsgPtr points to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_DynMasterSend(XIic *InstancePtr, u8 *TxMsgPtr, u8 ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the Dynamic master processing has been included such that
|
||||
* events will be properly handled.
|
||||
*/
|
||||
XIIC_DYN_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = TRUE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus not to be busy. The function enables the BusNotBusy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it is already a master on the bus (repeated start), the direction
|
||||
* was set to Tx which is throttling bus. The control register needs to
|
||||
* be set before putting data into the FIFO.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
CntlReg &= ~XIIC_CR_NO_ACK_MASK;
|
||||
CntlReg |= XIIC_CR_DIR_IS_TX_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state.
|
||||
*/
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = TxMsgPtr;
|
||||
|
||||
/*
|
||||
* Send the Seven Bit address. Only 7 bit addressing is supported in
|
||||
* Dynamic mode.
|
||||
*/
|
||||
XIic_DynSend7BitAddress(InstancePtr->BaseAddress,
|
||||
InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
|
||||
/*
|
||||
* Set the transmit address state to indicate the address has been sent
|
||||
* for communication with event driven processing.
|
||||
*/
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
|
||||
/*
|
||||
* Fill the Tx FIFO.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* After filling fifo, if data yet to send > 1, enable Tx <20> empty
|
||||
* interrupt.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear any pending Tx empty, Tx Error and then enable them.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK |
|
||||
XIIC_INTR_TX_EMPTY_MASK);
|
||||
|
||||
/*
|
||||
* Enable the Interrupts.
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* When the IIC Tx FIFO/register goes empty, this routine is called by the
|
||||
* interrupt service routine to fill the transmit FIFO with data to be sent.
|
||||
*
|
||||
* This function also is called by the Tx <20> empty interrupt as the data handling
|
||||
* is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
|
||||
* register to indicate the available free FIFO bytes.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DynSendMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* In between 1st and last byte of message, fill the FIFO with more data
|
||||
* to send, disable the 1/2 empty interrupt based upon data left to
|
||||
* send.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
|
||||
if (InstancePtr->SendByteCount < 2) {
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is only one byte left to send, processing differs between
|
||||
* repeated start and normal messages.
|
||||
*/
|
||||
else if (InstancePtr->SendByteCount == 1) {
|
||||
/*
|
||||
* When using repeated start, another interrupt is expected
|
||||
* after the last byte has been sent, so the message is not
|
||||
* done yet.
|
||||
*/
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
} else {
|
||||
XIic_DynSendStop(InstancePtr->BaseAddress,
|
||||
*InstancePtr->SendBufferPtr);
|
||||
|
||||
/*
|
||||
* Wait for bus to not be busy before declaring message
|
||||
* has been sent for the no repeated start operation.
|
||||
* The callback will be called from the BusNotBusy part
|
||||
* of the Interrupt handler to ensure that the message
|
||||
* is completely sent. Disable the Tx interrupts and
|
||||
* enable the BNB interrupt.
|
||||
*/
|
||||
InstancePtr->BNBOnly = FALSE;
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
XIic_EnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
}
|
||||
} else {
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
/*
|
||||
* The message being sent has completed. When using
|
||||
* repeated start with no more bytes to send repeated
|
||||
* start needs to be set in the control register so
|
||||
* that the bus will still be held by this master.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
/*
|
||||
* If the message that was being sent has finished,
|
||||
* disable all transmit interrupts and call the callback
|
||||
* that was setup to indicate the message was sent,
|
||||
* with 0 bytes remaining.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function receives data as a master from a slave device on the IIC bus.
|
||||
* If the bus is busy, it will indicate so and then enable an interrupt such
|
||||
* that the status handler will be called when the bus is no longer busy. The
|
||||
* slave address which has been set with the XIic_SetAddress() function is the
|
||||
* address from which data is received. Receiving data on the bus performs a
|
||||
* read operation.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the Iic instance to be worked on.
|
||||
* @param RxMsgPtr is a pointer to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return - XST_SUCCESS indicates the message reception processes has been
|
||||
* initiated.
|
||||
* - XST_IIC_BUS_BUSY indicates the bus was in use and that the
|
||||
* BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
* - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address is
|
||||
* set to the general call address. This is not allowed for Master
|
||||
* receive mode.
|
||||
*
|
||||
* @note The receive FIFO threshold is a zero based count such that 1
|
||||
* must be subtracted from the desired count to get the correct
|
||||
* value. When receiving data it is also necessary to not receive
|
||||
* the last byte with the prior bytes because the acknowledge must
|
||||
* be setup before the last byte is received.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_DynMasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, u8 ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u32 RxFifoOccy;
|
||||
|
||||
/*
|
||||
* If the slave address is zero (general call) the master can't perform
|
||||
* receive operations, indicate an error.
|
||||
*/
|
||||
if (InstancePtr->AddrOfSlave == 0) {
|
||||
return XST_IIC_GENERAL_CALL_ADDRESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the Interrupts.
|
||||
*/
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the master processing has been included such that events
|
||||
* will be properly handled.
|
||||
*/
|
||||
XIIC_DYN_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = TRUE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus to not be busy, the function enables the bus not busy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state for event driven processing.
|
||||
*/
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = RxMsgPtr;
|
||||
|
||||
/*
|
||||
* Clear and enable Rx full interrupt.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
/*
|
||||
* If already a master on the bus, the direction was set by Rx Interrupt
|
||||
* routine to Tx which is throttling bus because during Rxing, Tx reg is
|
||||
* empty = throttle. CR needs setting before putting data or the address
|
||||
* written will go out as Tx instead of receive. Start Master Rx by
|
||||
* setting CR Bits MSMS to Master and msg direction.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
/*
|
||||
* Set the Repeated Start bit in CR.
|
||||
*/
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
|
||||
|
||||
/*
|
||||
* Increment stats counts.
|
||||
*/
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set receive FIFO occupancy depth which must be done prior to writing
|
||||
* the address in the FIFO because the transmitter will immediately
|
||||
* start when in repeated start mode followed by the receiver such
|
||||
* that the number of bytes to receive should be set 1st.
|
||||
*/
|
||||
if (ByteCount == 1) {
|
||||
RxFifoOccy = 0;
|
||||
}
|
||||
else {
|
||||
if (ByteCount <= IIC_RX_FIFO_DEPTH) {
|
||||
RxFifoOccy = ByteCount - 2;
|
||||
} else {
|
||||
RxFifoOccy = IIC_RX_FIFO_DEPTH - 1;
|
||||
}
|
||||
}
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
RxFifoOccy);
|
||||
|
||||
/*
|
||||
* Send the Seven Bit address. Only 7 bit addressing is supported in
|
||||
* Dynamic mode and mark that the address has been sent.
|
||||
*/
|
||||
XIic_DynSend7BitAddress(InstancePtr->BaseAddress,
|
||||
InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
|
||||
/*
|
||||
* Send the bytecount to be received and set the stop bit.
|
||||
*/
|
||||
XIic_DynSendStop(InstancePtr->BaseAddress, ByteCount);
|
||||
|
||||
/*
|
||||
* Tx error is enabled in case the address has no device to answer
|
||||
* with Ack. When only one byte of data, must set NO ACK before address
|
||||
* goes out therefore Tx error must not be enabled as it will go off
|
||||
* immediately and the Rx full interrupt will be checked. If full, then
|
||||
* the one byte was received and the Tx error will be disabled without
|
||||
* sending an error callback msg.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* Enable the Interrupts.
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the receive register is full. The number
|
||||
* of bytes received to cause the interrupt is adjustable using the Receive FIFO
|
||||
* Depth register. The number of bytes in the register is read in the Receive
|
||||
* FIFO occupancy register. Both these registers are zero based values (0-15)
|
||||
* such that a value of zero indicates 1 byte.
|
||||
*
|
||||
* For a Master Receiver to properly signal the end of a message, the data must
|
||||
* be read in up to the message length - 1, where control register bits will be
|
||||
* set for bus controls to occur on reading of the last byte.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DynRecvMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u8 LoopCnt;
|
||||
u8 BytesInFifo;
|
||||
u8 BytesToRead;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* Device is a master receiving, get the contents of the control
|
||||
* register and determine the number of bytes in fifo to be read out.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
BytesInFifo = (u8) XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET) + 1;
|
||||
|
||||
/*
|
||||
* If data in FIFO holds all data to be retrieved - 1, set NOACK and
|
||||
* disable the Tx error.
|
||||
*/
|
||||
if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
|
||||
/*
|
||||
* Disable Tx error interrupt to prevent interrupt as this
|
||||
* device will cause it when it set NO ACK next.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* Read one byte to clear a place for the last byte to be read
|
||||
* which will set the NO ACK.
|
||||
*/
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If data in FIFO is all the data to be received then get the data and
|
||||
* also leave the device in a good state for the next transaction.
|
||||
*/
|
||||
else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from the FIFO then set zero based FIFO read depth
|
||||
* for a byte.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Disable Rx full interrupt and write the control reg with ACK
|
||||
* allowing next byte sent to be acknowledged automatically.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
/*
|
||||
* Send notification of msg Rx complete in RecvHandler callback.
|
||||
*/
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Fifo data not at n-1, read all but the last byte of data
|
||||
* from the slave, if more than a FIFO full yet to receive
|
||||
* read a FIFO full.
|
||||
*/
|
||||
BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
|
||||
if (BytesToRead > IIC_RX_FIFO_DEPTH) {
|
||||
BytesToRead = IIC_RX_FIFO_DEPTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in data from the FIFO.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function checks to see if the IIC bus is busy. If so, it will enable
|
||||
* the bus not busy interrupt such that the driver is notified when the bus
|
||||
* is no longer busy.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
*
|
||||
* @return FALSE if the IIC bus is not busy else TRUE.
|
||||
*
|
||||
* @note The BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int IsBusBusy(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u32 StatusReg;
|
||||
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
StatusReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* If this device is already master of the bus as when using the
|
||||
* repeated start and the bus is busy setup to wait for it to not
|
||||
* be busy.
|
||||
*/
|
||||
if (((CntlReg & XIIC_CR_MSMS_MASK) == 0) && /* Not master */
|
||||
(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { /* Is busy */
|
||||
/*
|
||||
* The bus is busy, clear pending BNB interrupt in case
|
||||
* previously set and then enable BusNotBusy interrupt.
|
||||
*/
|
||||
InstancePtr->BNBOnly = TRUE;
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
InstancePtr->Stats.BusBusy++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Initialize the IIC core for Dynamic Functionality.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
*
|
||||
* @return XST_SUCCESS if Successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_DynamicInitialize(XIic *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
Status = XIic_DynInit(InstancePtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version: 2022.2
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2025 Xilinx, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xiic.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XIic_Config XIic_ConfigTable[XPAR_XIIC_NUM_INSTANCES] =
|
||||
{
|
||||
{
|
||||
XPAR_AXI_IIC_0_DEVICE_ID,
|
||||
XPAR_AXI_IIC_0_BASEADDR,
|
||||
XPAR_AXI_IIC_0_TEN_BIT_ADR,
|
||||
XPAR_AXI_IIC_0_GPO_WIDTH
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_i.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains internal identifiers, which are those shared
|
||||
* between XIic components. The identifiers in this file are not intended for
|
||||
* use external to the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Removed the macro XIIC_CLEAR_STATS, user has to
|
||||
* use the the XIic_ClearStats API in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Removed the _m prefix from all the macros
|
||||
* XIic_mSend10BitAddrByte1 is now XIic_Send10BitAddrByte1
|
||||
* XIic_mSend10BitAddrByte2 is now XIic_Send10BitAddrByte2
|
||||
* XIic_mSend7BitAddr is now XIic_Send7BitAddr
|
||||
* XIic_mDisableIntr is now XIic_DisableIntr
|
||||
* XIic_mEnableIntr is now XIic_EnableIntr
|
||||
* XIic_mClearIntr is now XIic_ClearIntr
|
||||
* XIic_mClearEnableIntr is now XIic_ClearEnableIntr
|
||||
* XIic_mFlushRxFifo is now XIic_FlushRxFifo
|
||||
* XIic_mFlushTxFifo is now XIic_FlushTxFifo
|
||||
* XIic_mReadRecvByte is now XIic_ReadRecvByte
|
||||
* XIic_mWriteSendByte is now XIic_WriteSendByte
|
||||
* XIic_mSetControlRegister is now XIic_SetControlRegister
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings when
|
||||
* compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIIC_I_H /* prevent circular inclusions */
|
||||
#define XIIC_I_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the first byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* address = 1111_0xxD xx = address MSBits
|
||||
* D = Tx direction = 0 = write
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send10BitAddrByte1(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte1(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)((SlaveAddress) >> 7); \
|
||||
LocalAddr = (LocalAddr & 0xF6) | 0xF0 | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the second byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature: void XIic_Send10BitAddrByte2(u16 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte2(SlaveAddress) \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32)(SlaveAddress)); \
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send7BitAddr(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddr(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro disables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_DisableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DisableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) & ~(InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro enables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_EnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_EnableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) | (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears and enables the specified interrupt in the Interrupt
|
||||
* status and enable registers. It is non-destructive in that the registers are
|
||||
* read and only the interrupt specified is modified.
|
||||
* Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be cleared and enabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearEnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearEnableIntr(BaseAddress, InterruptMask) \
|
||||
{ \
|
||||
XIic_WriteIisr(BaseAddress, \
|
||||
(XIic_ReadIisr(BaseAddress) & (InterruptMask))); \
|
||||
\
|
||||
XIic_WriteIier(BaseAddress, \
|
||||
(XIic_ReadIier(BaseAddress) | (InterruptMask))); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the receive FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushRxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushRxFifo(InstancePtr) \
|
||||
{ \
|
||||
int LoopCnt; \
|
||||
u8 BytesToRead = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_RFO_REG_OFFSET) + 1; \
|
||||
for(LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) \
|
||||
{ \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_DRR_REG_OFFSET); \
|
||||
} \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the transmit FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushTxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushTxFifo(InstancePtr); \
|
||||
{ \
|
||||
u32 CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_CR_REG_OFFSET); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg | XIIC_CR_TX_FIFO_RESET_MASK); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro reads the next available received byte from the receive FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ReadRecvByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadRecvByte(InstancePtr) \
|
||||
{ \
|
||||
*InstancePtr->RecvBufferPtr++ = \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, XIIC_DRR_REG_OFFSET); \
|
||||
InstancePtr->RecvByteCount--; \
|
||||
InstancePtr->Stats.RecvBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro writes the next byte to be sent to the transmit FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_WriteSendByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteSendByte(InstancePtr) \
|
||||
{ \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
*InstancePtr->SendBufferPtr++); \
|
||||
InstancePtr->SendByteCount--; \
|
||||
InstancePtr->Stats.SendBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sets up the control register for a master receive operation.
|
||||
* A write is necessary if a 10 bit operation is being performed.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
* @param ControlRegister contains the contents of the IIC device control
|
||||
* register
|
||||
* @param ByteCount contains the number of bytes to be received for the
|
||||
* master receive operation
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_SetControlRegister(XIic *InstancePtr,
|
||||
* u8 ControlRegister,
|
||||
* int ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_SetControlRegister(InstancePtr, ControlRegister, ByteCount) \
|
||||
{ \
|
||||
(ControlRegister) &= ~(XIIC_CR_NO_ACK_MASK | XIIC_CR_DIR_IS_TX_MASK); \
|
||||
if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) { \
|
||||
(ControlRegister) |= XIIC_CR_DIR_IS_TX_MASK; \
|
||||
} else { \
|
||||
if ((ByteCount) == 1) \
|
||||
{ \
|
||||
(ControlRegister) |= XIIC_CR_NO_ACK_MASK; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
extern XIic_Config XIic_ConfigTable[];
|
||||
|
||||
/* The following variables are shared across files of the driver and
|
||||
* are function pointers that are necessary to break dependencies allowing
|
||||
* optional parts of the driver to be used without condition compilation
|
||||
*/
|
||||
extern void (*XIic_AddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_NotAddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_ArbLostFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_BusNotBusyFuncPtr) (XIic *InstancePtr);
|
||||
|
||||
void XIic_TransmitFifoFill(XIic *InstancePtr, int Role);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,431 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2006 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_intr.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains interrupt functions of the XIic driver. This file is required
|
||||
* for the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01c rmm 05/14/03 Fixed diab compiler warnings relating to asserts.
|
||||
* 1.03a ecm 06/22/06 Added a call to the status handler in the TxErrorHandler
|
||||
* even if the Rx buffer pointer is not set. This fix is as
|
||||
* a result of a Sony use model which did not set the Rx
|
||||
* pointer while in Master mode so it checks if MSMS == 1.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and Some of the macros have been renamed to be
|
||||
* consistent, see the xiic_l.h file for further information.
|
||||
* 2.01a ktn 04/09/10 Updated TxErrorhandler to be called for Master Transmitter
|
||||
* case based on Addressed As Slave (AAS) bit rather than
|
||||
* MSMS bit(CR 540199).
|
||||
* 2.06a bss 02/14/13 Modified TxErrorHandler in xiic_intr.c to fix CR #686483
|
||||
* Modified bitwise OR to logical OR in
|
||||
* XIic_InterruptHandler API.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* In the file xiic.c and xiic_i.h. CR:705001
|
||||
* 3.9 gm 08/02/22 Modified handling of XIIC_INTR_RX_FULL_MASK in xiic_intr.c
|
||||
* to fix CR #1119930 handling RX FULL interrupt before
|
||||
* TX error interrupt and clearing TX error interrupt while
|
||||
* handling RX FULL interrupt when receive byte count is one,
|
||||
* because here the TX error interrupt indicate NACK, not
|
||||
* actually TX error.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions ******************/
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void StubFunction(XIic *InstancePtr);
|
||||
static void TxErrorHandler(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/* The following function pointers are used to help allow finer partitioning
|
||||
* of the driver such that some parts of it are optional. These pointers are
|
||||
* setup by functions in the optional parts of the driver.
|
||||
*/
|
||||
void (*XIic_AddrAsSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_NotAddrAsSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_RecvSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_SendSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_RecvMasterFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_SendMasterFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_ArbLostFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_BusNotBusyFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the interrupt handler for the XIic driver. This function
|
||||
* should be connected to the interrupt system.
|
||||
*
|
||||
* Only one interrupt source is handled for each interrupt allowing
|
||||
* higher priority system interrupts quicker response time.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The XIIC_INTR_ARB_LOST_MASK and XIIC_INTR_TX_ERROR_MASK interrupts must have
|
||||
* higher priority than the other device interrupts so that the IIC device does
|
||||
* not get into a potentially confused state. The remaining interrupts may be
|
||||
* rearranged with no harm.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_InterruptHandler(void *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 IntrStatus;
|
||||
u32 IntrPending;
|
||||
u32 IntrEnable;
|
||||
XIic *IicPtr = NULL;
|
||||
u32 Clear = 0;
|
||||
|
||||
/*
|
||||
* Verify that each of the inputs are valid.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Convert the non-typed pointer to an IIC instance pointer
|
||||
*/
|
||||
IicPtr = (XIic *) InstancePtr;
|
||||
|
||||
/*
|
||||
* Get the interrupt Status.
|
||||
*/
|
||||
IntrPending = XIic_ReadIisr(IicPtr->BaseAddress);
|
||||
IntrEnable = XIic_ReadIier(IicPtr->BaseAddress);
|
||||
IntrStatus = IntrPending & IntrEnable;
|
||||
|
||||
/*
|
||||
* Do not processes a devices interrupts if the device has no
|
||||
* interrupts pending or the global interrupts have been disabled.
|
||||
*/
|
||||
if ((IntrStatus == 0) ||
|
||||
(XIic_IsIntrGlobalEnabled(IicPtr->BaseAddress) == FALSE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update interrupt stats and get the contents of the status register.
|
||||
*/
|
||||
IicPtr->Stats.IicInterrupts++;
|
||||
Status = XIic_ReadReg(IicPtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* Service requesting interrupt.
|
||||
*/
|
||||
if (IntrStatus & XIIC_INTR_ARB_LOST_MASK) {
|
||||
/* Bus Arbritration Lost */
|
||||
|
||||
IicPtr->Stats.ArbitrationLost++;
|
||||
XIic_ArbLostFuncPtr(IicPtr);
|
||||
|
||||
Clear = XIIC_INTR_ARB_LOST_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
|
||||
/* Receive register/FIFO is full */
|
||||
|
||||
if((IicPtr->RecvByteCount == 1) && (IntrStatus & XIIC_INTR_TX_ERROR_MASK)) {
|
||||
XIic_WriteIisr(IicPtr->BaseAddress, XIIC_INTR_TX_ERROR_MASK);
|
||||
}
|
||||
|
||||
IicPtr->Stats.RecvInterrupts++;
|
||||
|
||||
if (Status & XIIC_SR_ADDR_AS_SLAVE_MASK) {
|
||||
XIic_RecvSlaveFuncPtr(IicPtr);
|
||||
} else {
|
||||
XIic_RecvMasterFuncPtr(IicPtr);
|
||||
}
|
||||
|
||||
Clear = XIIC_INTR_RX_FULL_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_TX_ERROR_MASK) {
|
||||
/* Transmit errors (no acknowledge) received */
|
||||
IicPtr->Stats.TxErrors++;
|
||||
TxErrorHandler(IicPtr);
|
||||
|
||||
Clear = XIIC_INTR_TX_ERROR_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_NAAS_MASK) {
|
||||
/* Not Addressed As Slave */
|
||||
|
||||
XIic_NotAddrAsSlaveFuncPtr(IicPtr);
|
||||
Clear = XIIC_INTR_NAAS_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_AAS_MASK) {
|
||||
/* Addressed As Slave */
|
||||
|
||||
XIic_AddrAsSlaveFuncPtr(IicPtr);
|
||||
Clear = XIIC_INTR_AAS_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_BNB_MASK) {
|
||||
/* IIC bus has transitioned to not busy */
|
||||
|
||||
/* Check if send callback needs to run */
|
||||
if (IicPtr->BNBOnly == TRUE) {
|
||||
XIic_BusNotBusyFuncPtr(IicPtr);
|
||||
IicPtr->BNBOnly = FALSE;
|
||||
} else {
|
||||
IicPtr->SendHandler(IicPtr->SendCallBackRef, 0);
|
||||
}
|
||||
|
||||
Clear = XIIC_INTR_BNB_MASK;
|
||||
|
||||
/* The bus is not busy, disable BusNotBusy interrupt */
|
||||
XIic_DisableIntr(IicPtr->BaseAddress, XIIC_INTR_BNB_MASK);
|
||||
|
||||
} else if ((IntrStatus & XIIC_INTR_TX_EMPTY_MASK) ||
|
||||
(IntrStatus & XIIC_INTR_TX_HALF_MASK)) {
|
||||
/* Transmit register/FIFO is empty or <20> empty */
|
||||
IicPtr->Stats.SendInterrupts++;
|
||||
|
||||
if (Status & XIIC_SR_ADDR_AS_SLAVE_MASK) {
|
||||
XIic_SendSlaveFuncPtr(IicPtr);
|
||||
} else {
|
||||
XIic_SendMasterFuncPtr(IicPtr);
|
||||
}
|
||||
|
||||
IntrStatus = XIic_ReadIisr(IicPtr->BaseAddress);
|
||||
Clear = IntrStatus & (XIIC_INTR_TX_EMPTY_MASK |
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear Interrupts.
|
||||
*/
|
||||
XIic_WriteIisr(IicPtr->BaseAddress, Clear);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function fills the FIFO using the occupancy register to determine the
|
||||
* available space to be filled. When the repeated start option is on, the last
|
||||
* byte is withheld to allow the control register to be properly set on the last
|
||||
* byte.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @param Role indicates the role of this IIC device, a slave or a master,
|
||||
* on the IIC bus (XIIC_SLAVE_ROLE or XIIC_MASTER_ROLE).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_TransmitFifoFill(XIic *InstancePtr, int Role)
|
||||
{
|
||||
u8 AvailBytes;
|
||||
int LoopCnt;
|
||||
int NumBytesToSend;
|
||||
|
||||
/*
|
||||
* Determine number of bytes to write to FIFO. Number of bytes that
|
||||
* can be put into the FIFO is (FIFO depth) - (current occupancy + 1)
|
||||
* When more room in FIFO than msg bytes put all of message in the FIFO.
|
||||
*/
|
||||
AvailBytes = IIC_TX_FIFO_DEPTH -
|
||||
(u8) (XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_TFO_REG_OFFSET) + 1);
|
||||
|
||||
if (InstancePtr->SendByteCount > AvailBytes) {
|
||||
NumBytesToSend = AvailBytes;
|
||||
} else {
|
||||
/*
|
||||
* More space in FIFO than bytes in message.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_REPEATED_START_OPTION) ||
|
||||
(Role == XIIC_SLAVE_ROLE)) {
|
||||
NumBytesToSend = InstancePtr->SendByteCount;
|
||||
} else {
|
||||
NumBytesToSend = InstancePtr->SendByteCount - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill FIFO with amount determined above.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < NumBytesToSend; LoopCnt++) {
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This interrupt occurs four different ways: Two as master and two as slave.
|
||||
* Master:
|
||||
* <pre>
|
||||
* (1) Transmitter (IMPLIES AN ERROR)
|
||||
* The slave receiver did not acknowledge properly.
|
||||
* (2) Receiver (Implies Tx complete)
|
||||
* Interrupt caused by setting TxAck high in the IIC to indicate to the
|
||||
* the last byte has been transmitted.
|
||||
* </pre>
|
||||
*
|
||||
* Slave:
|
||||
* <pre>
|
||||
* (3) Transmitter (Implies Tx complete)
|
||||
* Interrupt caused by master device indicating last byte of the message
|
||||
* has been transmitted.
|
||||
* (4) Receiver (IMPLIES AN ERROR)
|
||||
* Interrupt caused by setting TxAck high in the IIC to indicate Rx
|
||||
* IIC had a problem - set by this device and condition already known
|
||||
* and interrupt is not enabled.
|
||||
* </pre>
|
||||
*
|
||||
* This interrupt is enabled during Master send and receive and disabled
|
||||
* when this device knows it is going to send a negative acknowledge (Ack = No).
|
||||
*
|
||||
* Signals user of Tx error via status callback sending: XII_TX_ERROR_EVENT
|
||||
*
|
||||
* When MasterRecv has no message to send and only receives one byte of data
|
||||
* from the salve device, the TxError must be enabled to catch addressing
|
||||
* errors, yet there is not opportunity to disable TxError when there is no
|
||||
* data to send allowing disabling on last byte. When the slave sends the
|
||||
* only byte the NOAck causes a Tx Error. To disregard this as no real error,
|
||||
* when there is data in the Receive FIFO/register then the error was not
|
||||
* a device address write error, but a NOACK read error - to be ignored.
|
||||
* To work with or without FIFO's, the Rx Data interrupt is used to indicate
|
||||
* data is in the Rx register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void TxErrorHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* When Sending as a slave, Tx error signals end of msg. Not Addressed
|
||||
* As Slave will handle the callbacks. this is used to only flush
|
||||
* the Tx fifo. The addressed as slave bit is gone as soon as the bus
|
||||
* has been released such that the buffer pointers are used to determine
|
||||
* the direction of transfer (send or receive).
|
||||
*/
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
/*
|
||||
* Master Receiver finished reading message. Flush Tx fifo to
|
||||
* remove an 0xFF that was written to prevent bus throttling,
|
||||
* and disable all transmit and receive interrupts.
|
||||
*/
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_RX_INTERRUPTS);
|
||||
|
||||
/*
|
||||
* If operating in Master mode, call status handler to indicate
|
||||
* NOACK occurred.
|
||||
*/
|
||||
IntrStatus = XIic_ReadIisr(InstancePtr->BaseAddress);
|
||||
if ((IntrStatus & XIIC_INTR_AAS_MASK) == 0) {
|
||||
InstancePtr->StatusHandler(InstancePtr->
|
||||
StatusCallBackRef,
|
||||
XII_SLAVE_NO_ACK_EVENT);
|
||||
} else {
|
||||
/* Decrement the Tx Error since Tx Error interrupt
|
||||
* implies transmit complete while sending as Slave
|
||||
*/
|
||||
InstancePtr->Stats.TxErrors--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data in the receive register from either master or slave receive
|
||||
* When:slave, indicates master sent last byte, message completed.
|
||||
* When:master, indicates a master Receive with one byte received. When
|
||||
* a byte is in Rx reg then the Tx error indicates the Rx data was
|
||||
* recovered normally Tx errors are not enabled such that this should
|
||||
* not occur.
|
||||
*/
|
||||
IntrStatus = XIic_ReadIisr(InstancePtr->BaseAddress);
|
||||
if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
|
||||
/* Rx Reg/FIFO has data, Disable Tx error interrupts */
|
||||
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
return;
|
||||
}
|
||||
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Disable and clear Tx empty, <20> empty, Rx Full or Tx error interrupts.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
|
||||
|
||||
/* Clear MSMS as on Tx error when Rxing, the bus will be
|
||||
* stopped but MSMS bit is still set. Reset to proper state
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
CntlReg &= ~XIIC_CR_MSMS_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
|
||||
/*
|
||||
* Set FIFO occupancy depth = 1 so that the first byte will throttle
|
||||
* next receive msg.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Call the event callback.
|
||||
*/
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
|
||||
XII_SLAVE_NO_ACK_EVENT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is a stub function that is used for the default function for
|
||||
* events that are handled optionally only when the appropriate modules are
|
||||
* linked in. Function pointers are used to handle some events to allow
|
||||
* some events to be optionally handled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void StubFunction(XIic *InstancePtr)
|
||||
{
|
||||
(void )InstancePtr;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
/** @} */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,571 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_l.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and driver functions (or
|
||||
* macros) that can be used to access the device in normal and dynamic
|
||||
* controller mode. High-level driver functions are defined in xiic.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 05/07/02 First release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 04/04/06 Implemented Dynamic IIC core routines.
|
||||
* 1.03a rpm 09/08/06 Added include of xstatus.h for completeness
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.16a ktn 07/18/09 Updated the notes in XIIC_RESET macro to clearly indicate
|
||||
* that only the Interrupt Registers are reset.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIIC_RESET macro to mention
|
||||
* that the complete IIC core is Reset on giving a software
|
||||
* reset to the IIC core. Some previous versions of the
|
||||
* core only reset the Interrupt Logic/Registers, please
|
||||
* refer to the HW specification for further details.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access,
|
||||
* the register offsets are defined to be on 32 bit boundary.
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Some of the macros have been renamed to be consistent -
|
||||
* XIIC_GINTR_DISABLE is renamed as XIic_IntrGlobalDisable,
|
||||
* XIIC_GINTR_ENABLE is renamed as XIic_IntrGlobalEnable,
|
||||
* XIIC_IS_GINTR_ENABLED is renamed as
|
||||
* XIic_IsIntrGlobalEnabled,
|
||||
* XIIC_WRITE_IISR is renamed as XIic_WriteIisr,
|
||||
* XIIC_READ_IISR is renamed as XIic_ReadIisr,
|
||||
* XIIC_WRITE_IIER is renamed as XIic_WriteIier
|
||||
* The _m prefix in the name of the macros has been removed -
|
||||
* XIic_mClearIisr is now XIic_ClearIisr,
|
||||
* XIic_mSend7BitAddress is now XIic_Send7BitAddress,
|
||||
* XIic_mDynSend7BitAddress is now XIic_DynSend7BitAddress,
|
||||
* XIic_mDynSendStartStopAddress is now
|
||||
* XIic_DynSendStartStopAddress,
|
||||
* XIic_mDynSendStop is now XIic_DynSendStop.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototypes of XIic_Recv, XIic_Send,
|
||||
* XIic_DynRecv, XIic_DynSend and XIic_DynInit APIs.
|
||||
* 3.3 als 06/27/16 Added Low-level XIic_CheckIsBusBusy API.
|
||||
* 3.3 als 06/27/16 Added low-level XIic_WaitBusFree API.
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef XIIC_L_H /* prevent circular inclusions */
|
||||
#define XIIC_L_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
/** @name Register Map
|
||||
*
|
||||
* Register offsets for the XIic device.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_DGIER_OFFSET 0x1C /**< Global Interrupt Enable Register */
|
||||
#define XIIC_IISR_OFFSET 0x20 /**< Interrupt Status Register */
|
||||
#define XIIC_IIER_OFFSET 0x28 /**< Interrupt Enable Register */
|
||||
#define XIIC_RESETR_OFFSET 0x40 /**< Reset Register */
|
||||
#define XIIC_CR_REG_OFFSET 0x100 /**< Control Register */
|
||||
#define XIIC_SR_REG_OFFSET 0x104 /**< Status Register */
|
||||
#define XIIC_DTR_REG_OFFSET 0x108 /**< Data Tx Register */
|
||||
#define XIIC_DRR_REG_OFFSET 0x10C /**< Data Rx Register */
|
||||
#define XIIC_ADR_REG_OFFSET 0x110 /**< Address Register */
|
||||
#define XIIC_TFO_REG_OFFSET 0x114 /**< Tx FIFO Occupancy */
|
||||
#define XIIC_RFO_REG_OFFSET 0x118 /**< Rx FIFO Occupancy */
|
||||
#define XIIC_TBA_REG_OFFSET 0x11C /**< 10 Bit Address reg */
|
||||
#define XIIC_RFD_REG_OFFSET 0x120 /**< Rx FIFO Depth reg */
|
||||
#define XIIC_GPO_REG_OFFSET 0x124 /**< Output Register */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Device Global Interrupt Enable Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_GINTR_ENABLE_MASK 0x80000000 /**< Global Interrupt Enable Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Device Interrupt Status/Enable (INTR) Register Masks
|
||||
*
|
||||
* <b> Interrupt Status Register (IISR) </b>
|
||||
*
|
||||
* This register holds the interrupt status flags for the Spi device.
|
||||
*
|
||||
* <b> Interrupt Enable Register (IIER) </b>
|
||||
*
|
||||
* This register is used to enable interrupt sources for the IIC device.
|
||||
* Writing a '1' to a bit in this register enables the corresponding Interrupt.
|
||||
* Writing a '0' to a bit in this register disables the corresponding Interrupt.
|
||||
*
|
||||
* IISR/IIER registers have the same bit definitions and are only defined once.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_INTR_ARB_LOST_MASK 0x00000001 /**< 1 = Arbitration lost */
|
||||
#define XIIC_INTR_TX_ERROR_MASK 0x00000002 /**< 1 = Tx error/msg complete */
|
||||
#define XIIC_INTR_TX_EMPTY_MASK 0x00000004 /**< 1 = Tx FIFO/reg empty */
|
||||
#define XIIC_INTR_RX_FULL_MASK 0x00000008 /**< 1 = Rx FIFO/reg=OCY level */
|
||||
#define XIIC_INTR_BNB_MASK 0x00000010 /**< 1 = Bus not busy */
|
||||
#define XIIC_INTR_AAS_MASK 0x00000020 /**< 1 = When addr as slave */
|
||||
#define XIIC_INTR_NAAS_MASK 0x00000040 /**< 1 = Not addr as slave */
|
||||
#define XIIC_INTR_TX_HALF_MASK 0x00000080 /**< 1 = Tx FIFO half empty */
|
||||
|
||||
/**
|
||||
* All Tx interrupts commonly used.
|
||||
*/
|
||||
#define XIIC_TX_INTERRUPTS (XIIC_INTR_TX_ERROR_MASK | \
|
||||
XIIC_INTR_TX_EMPTY_MASK | \
|
||||
XIIC_INTR_TX_HALF_MASK)
|
||||
|
||||
/**
|
||||
* All interrupts commonly used
|
||||
*/
|
||||
#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
|
||||
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Reset Register mask
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_RESET_MASK 0x0000000A /**< RESET Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Control Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_CR_ENABLE_DEVICE_MASK 0x00000001 /**< Device enable = 1 */
|
||||
#define XIIC_CR_TX_FIFO_RESET_MASK 0x00000002 /**< Transmit FIFO reset=1 */
|
||||
#define XIIC_CR_MSMS_MASK 0x00000004 /**< Master starts Txing=1 */
|
||||
#define XIIC_CR_DIR_IS_TX_MASK 0x00000008 /**< Dir of Tx. Txing=1 */
|
||||
#define XIIC_CR_NO_ACK_MASK 0x00000010 /**< Tx Ack. NO ack = 1 */
|
||||
#define XIIC_CR_REPEATED_START_MASK 0x00000020 /**< Repeated start = 1 */
|
||||
#define XIIC_CR_GENERAL_CALL_MASK 0x00000040 /**< Gen Call enabled = 1 */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Status Register masks (SR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_SR_GEN_CALL_MASK 0x00000001 /**< 1 = A Master issued
|
||||
* a GC */
|
||||
#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x00000002 /**< 1 = When addressed as
|
||||
* slave */
|
||||
#define XIIC_SR_BUS_BUSY_MASK 0x00000004 /**< 1 = Bus is busy */
|
||||
#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x00000008 /**< 1 = Dir: Master <--
|
||||
* slave */
|
||||
#define XIIC_SR_TX_FIFO_FULL_MASK 0x00000010 /**< 1 = Tx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_FULL_MASK 0x00000020 /**< 1 = Rx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x00000040 /**< 1 = Rx FIFO empty */
|
||||
#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x00000080 /**< 1 = Tx FIFO empty */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Tx Register (DTR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_TX_DYN_START_MASK 0x00000100 /**< 1 = Set dynamic start */
|
||||
#define XIIC_TX_DYN_STOP_MASK 0x00000200 /**< 1 = Set dynamic stop */
|
||||
#define IIC_TX_FIFO_DEPTH 16 /**< Tx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Rx Register (DRR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define IIC_RX_FIFO_DEPTH 16 /**< Rx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
|
||||
#define XIIC_TX_ADDR_SENT 0x00
|
||||
#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02
|
||||
|
||||
|
||||
/**
|
||||
* The following constants are used to specify whether to do
|
||||
* Read or a Write operation on IIC bus.
|
||||
*/
|
||||
#define XIIC_READ_OPERATION 1 /**< Read operation on the IIC bus */
|
||||
#define XIIC_WRITE_OPERATION 0 /**< Write operation on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with the transmit FIFO fill function to
|
||||
* specify the role which the IIC device is acting as, a master or a slave.
|
||||
*/
|
||||
#define XIIC_MASTER_ROLE 1 /**< Master on the IIC bus */
|
||||
#define XIIC_SLAVE_ROLE 0 /**< Slave on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with Transmit Function (XIic_Send) to
|
||||
* specify whether to STOP after the current transfer of data or own the bus
|
||||
* with a Repeated start.
|
||||
*/
|
||||
#define XIIC_STOP 0x00 /**< Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
#define XIIC_REPEATED_START 0x01 /**< Donot Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define XIic_In32 Xil_In32
|
||||
#define XIic_Out32 Xil_Out32
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read from the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the device to
|
||||
* select the specific register.
|
||||
*
|
||||
* @return The value read from the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadReg(u32 BaseAddress, u32 RegOffset);
|
||||
*
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadReg(BaseAddress, RegOffset) \
|
||||
XIic_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write to the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the
|
||||
* device to select the specific register.
|
||||
* @param RegisterValue is the value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteReg(u32 BaseAddress, u32 RegOffset,
|
||||
* u32 RegisterValue);
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
XIic_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro disables all interrupts for the device by writing to the Global
|
||||
* interrupt enable register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalDisable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalDisable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, 0)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro writes to the global interrupt enable register to enable
|
||||
* interrupts from the device. This function does not enable individual
|
||||
* interrupts as the Interrupt Enable Register must be set appropriately.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalEnable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalEnable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function determines if interrupts are enabled at the global level by
|
||||
* reading the global interrupt register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the global interrupt is enabled.
|
||||
* - FALSE if global interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* int XIic_IsIntrGlobalEnabled(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IsIntrGlobalEnabled(BaseAddress) \
|
||||
(XIic_ReadReg((BaseAddress), XIIC_DGIER_OFFSET) == \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the Interrupt status register to the specified value.
|
||||
*
|
||||
* This register implements a toggle on write functionality. The interrupt is
|
||||
* cleared by writing to this register with the bits to be cleared set to a one
|
||||
* and all others to zero. Setting a bit which is zero within this register
|
||||
* causes an interrupt to be generated.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some status bits may be set and others cleared. It is the caller's
|
||||
* responsibility to get the value of the register prior to setting the value
|
||||
* to prevent an destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Status is the value to be written to the Interrupt
|
||||
* status register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIisr(u32 BaseAddress, u32 Status);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIisr(BaseAddress, Status) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IISR_OFFSET, (Status))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the contents of the Interrupt Status Register.
|
||||
* This register indicates the status of interrupt sources for the device.
|
||||
* The status is independent of whether interrupts are enabled such
|
||||
* that the status register may also be polled when interrupts are not enabled.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The value read from the Interrupt Status Register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIisr(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIisr(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IISR_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the contents of the Interrupt Enable Register.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some interrupt sources may be enabled and others disabled. It is the
|
||||
* caller's responsibility to get the value of the interrupt enable register
|
||||
* prior to setting the value to prevent a destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Enable is the value to be written to the Interrupt Enable
|
||||
* Register. Bit positions of 1 will be enabled. Bit positions of 0
|
||||
* will be disabled.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIier(u32 BaseAddress, u32 Enable);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIier(BaseAddress, Enable) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IIER_OFFSET, (Enable))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This function gets the Interrupt Enable Register contents.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The contents read from the Interrupt Enable Register.
|
||||
* Bit positions of 1 indicate that the corresponding interrupt
|
||||
* is enabled. Bit positions of 0 indicate that the corresponding
|
||||
* interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIier(u32 BaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIier(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IIER_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask is the bit mask of the interrupts to be cleared.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_ClearIisr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIisr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_Send7BitAddress(u32 BaseAddress, u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers for Dynamic
|
||||
* controller functionality.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSend7BitAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSend7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address, start and stop for a 7 bit address during both
|
||||
* write operations. It takes care of the details to format the address
|
||||
* correctly. This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStartStopAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStartStopAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | XIIC_TX_DYN_STOP_MASK | \
|
||||
LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends a stop condition on IIC bus for Dynamic logic.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param ByteCount is the number of Rx bytes received before the master.
|
||||
* doesn't respond with ACK.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStop(u32 BaseAddress, u32 ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStop(BaseAddress, ByteCount) \
|
||||
{ \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_STOP_MASK | ByteCount); \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_Send(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_DynRecv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, u8 ByteCount);
|
||||
|
||||
unsigned XIic_DynSend(UINTPTR BaseAddress, u16 Address, u8 *BufferPtr,
|
||||
u8 ByteCount, u8 Option);
|
||||
|
||||
int XIic_DynInit(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_WaitBusFree(UINTPTR BaseAddress);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,739 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_master.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains master functions for the XIic component. This file is necessary to
|
||||
* send or receive as a master on the IIC bus.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 03/27/02 Reparitioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for
|
||||
* further information
|
||||
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
|
||||
* SendBufferPtr in XIic_MasterRecv NULL
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This macro includes master code such that master operations, sending
|
||||
* and receiving data, may be used. This function hooks the master processing
|
||||
* to the driver such that events are handled properly and allows master
|
||||
* processing to be optional. It must be called before any functions which
|
||||
* are contained in this file are called, such as after the driver is
|
||||
* initialized.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIC_MASTER_INCLUDE \
|
||||
{ \
|
||||
XIic_RecvMasterFuncPtr = RecvMasterData; \
|
||||
XIic_SendMasterFuncPtr = SendMasterData; \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void SendSlaveAddr(XIic *InstancePtr);
|
||||
static void RecvMasterData(XIic *InstancePtr);
|
||||
static void SendMasterData(XIic *InstancePtr);
|
||||
static int IsBusBusy(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This function sends data as a master on the IIC bus. If the bus is busy, it
|
||||
* will indicate so and then enable an interrupt such that the status handler
|
||||
* will be called when the bus is no longer busy. The slave address which has
|
||||
* been set with the XIic_SetAddress() function is the address to which the
|
||||
* specific data is sent. Sending data on the bus performs a write operation.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
* @param TxMsgPtr points to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message transmission has been
|
||||
* initiated.
|
||||
* - XST_IIC_BUS_BUSY indicates the bus was in use and that
|
||||
* the BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the master processing has been included such that events
|
||||
* will be properly handled.
|
||||
*/
|
||||
XIIC_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus to not be busy, the function enables the bus not busy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it is already a master on the bus (repeated start), the direction
|
||||
* was set to Tx which is throttling bus. The control register needs to
|
||||
* be set before putting data into the FIFO.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
CntlReg &= ~XIIC_CR_NO_ACK_MASK;
|
||||
CntlReg |= (XIIC_CR_DIR_IS_TX_MASK |
|
||||
XIIC_CR_REPEATED_START_MASK);
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state.
|
||||
*/
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = TxMsgPtr;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Put the address into the FIFO to be sent and indicate that the
|
||||
* operation to be performed on the bus is a write operation,
|
||||
* a general call address is handled the same as a 7 bit address even
|
||||
* if 10 bit address is selected.
|
||||
* Set the transmit address state to indicate the address has been sent.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) &&
|
||||
(InstancePtr->AddrOfSlave != 0)) {
|
||||
XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
|
||||
} else {
|
||||
XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
}
|
||||
/*
|
||||
* Set the transmit address state to indicate the address has been sent
|
||||
* for communication with event driven processing.
|
||||
*/
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
|
||||
/*
|
||||
* Fill remaining available FIFO with message data.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* After filling fifo, if data yet to send > 1, enable Tx <20> empty
|
||||
* interrupt.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear any pending Tx empty, Tx Error and then enable them.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK |
|
||||
XIIC_INTR_TX_EMPTY_MASK);
|
||||
|
||||
/*
|
||||
* When repeated start not used, MSMS must be set after putting data
|
||||
* into transmit FIFO, start the transmitter.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
|
||||
CntlReg &= ~XIIC_CR_NO_ACK_MASK;
|
||||
CntlReg |= XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function receives data as a master from a slave device on the IIC bus.
|
||||
* If the bus is busy, it will indicate so and then enable an interrupt such
|
||||
* that the status handler will be called when the bus is no longer busy. The
|
||||
* slave address which has been set with the XIic_SetAddress() function is the
|
||||
* address from which data is received. Receiving data on the bus performs a
|
||||
* read operation.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the Iic instance to be worked on.
|
||||
* @param RxMsgPtr is a pointer to the data to be transmitted
|
||||
* @param ByteCount is the number of message bytes to be sent
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message reception processes has
|
||||
* been initiated.
|
||||
* - XST_IIC_BUS_BUSY indicates the bus was in use and that the
|
||||
* BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
* - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address
|
||||
* is set to the the general call address. This is not allowed
|
||||
* for Master receive mode.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The receive FIFO threshold is a zero based count such that 1 must be
|
||||
* subtracted from the desired count to get the correct value. When receiving
|
||||
* data it is also necessary to not receive the last byte with the prior bytes
|
||||
* because the acknowledge must be setup before the last byte is received.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u8 Temp;
|
||||
|
||||
/*
|
||||
* If the slave address is zero (general call) the master can't perform
|
||||
* receive operations, indicate an error.
|
||||
*/
|
||||
if (InstancePtr->AddrOfSlave == 0) {
|
||||
return XST_IIC_GENERAL_CALL_ADDRESS;
|
||||
}
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the master processing has been included such that events
|
||||
* will be properly handled.
|
||||
*/
|
||||
XIIC_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus to not be busy, the function enables the bus not busy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state for event driven processing.
|
||||
*/
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = RxMsgPtr;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait
|
||||
* until last address byte sent in case arbitration gets lost while
|
||||
* sending out address.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* If already a master on the bus, the direction was set by Rx Interrupt
|
||||
* routine to Tx which is throttling bus because during Rxing, Tx reg is
|
||||
* empty = throttle. CR needs setting before putting data or the address
|
||||
* written will go out as Tx instead of receive. Start Master Rx by
|
||||
* setting CR Bits MSMS to Master and msg direction.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
|
||||
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set receive FIFO occupancy depth which must be done prior to writing
|
||||
* the address in the FIFO because the transmitter will immediatedly
|
||||
* start when in repeated start mode followed by the receiver such that
|
||||
* the number of bytes to receive should be set 1st.
|
||||
*/
|
||||
if (ByteCount == 1) {
|
||||
Temp = 0;
|
||||
} else {
|
||||
if (ByteCount <= IIC_RX_FIFO_DEPTH) {
|
||||
Temp = ByteCount - 2;
|
||||
} else {
|
||||
Temp = IIC_RX_FIFO_DEPTH - 1;
|
||||
}
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
(u32) Temp);
|
||||
|
||||
if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
|
||||
/*
|
||||
* Send the 1st and 2nd byte of the 10 bit address of a write
|
||||
* operation, write because it's a 10 bit address.
|
||||
*/
|
||||
XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
|
||||
|
||||
/*
|
||||
* Set flag to indicate the next byte of the address needs to be
|
||||
* send, clear and enable Tx empty interrupt.
|
||||
*/
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_EMPTY_MASK);
|
||||
} else {
|
||||
/*
|
||||
* 7 bit slave address, send the address for a read operation
|
||||
* and set the state to indicate the address has been sent.
|
||||
*/
|
||||
XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
|
||||
XIIC_READ_OPERATION);
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tx error is enabled in case the address (7 or 10) has no device to
|
||||
* answer with Ack. When only one byte of data, must set NO ACK before
|
||||
* address goes out therefore Tx error must not be enabled as it will
|
||||
* go off immediately and the Rx full interrupt will be checked.
|
||||
* If full, then the one byte was received and the Tx error will be
|
||||
* disabled without sending an error callback msg.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* When repeated start not used, MSMS gets set after putting data
|
||||
* in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
|
||||
* msg direction.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
|
||||
CntlReg |= XIIC_CR_MSMS_MASK;
|
||||
XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This function checks to see if the IIC bus is busy. If so, it will enable
|
||||
* the bus not busy interrupt such that the driver is notified when the bus
|
||||
* is no longer busy.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - FALSE indicates the IIC bus is not busy.
|
||||
* - TRUE indicates the bus was in use and that the BusNotBusy
|
||||
* interrupt is enabled which will update the EventStatus when
|
||||
* the bus is no longer busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int IsBusBusy(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u32 StatusReg;
|
||||
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
StatusReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* If this device is already master of the bus as when using the
|
||||
* repeated start and the bus is busy setup to wait for it to not be
|
||||
* busy.
|
||||
*/
|
||||
if (((CntlReg & XIIC_CR_MSMS_MASK) == 0) && /* Not master */
|
||||
(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { /* Is busy */
|
||||
/*
|
||||
* The bus is busy, clear pending BNB interrupt in case
|
||||
* previously set and then enable BusNotBusy interrupt.
|
||||
*/
|
||||
InstancePtr->BNBOnly = TRUE;
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
InstancePtr->Stats.BusBusy++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function sends the proper byte of the address as well as generate the
|
||||
* proper address bit fields depending on the address byte required and the
|
||||
* direction of the data (write or read).
|
||||
*
|
||||
* A master receiving has the restriction that the direction must be switched
|
||||
* from write to read when the third address byte is transmitted.
|
||||
* For the last byte of the 10 bit address, repeated start must be set prior
|
||||
* to writing the address. If repeated start options is enabled, the
|
||||
* control register is written before the address is written to the Tx reg.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function does read/modify/write to the device control register. Calling
|
||||
* functions must ensure critical sections are used.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SendSlaveAddr(XIic *InstancePtr)
|
||||
{
|
||||
u32 CRreg;
|
||||
|
||||
/*
|
||||
* Set the control register for Master Receive, repeated start must be
|
||||
* set before writing the address, MSMS should be already set, don't
|
||||
* set here so if arbitration is lost or some other reason we don't
|
||||
* want MSMS set in case of error.
|
||||
*/
|
||||
CRreg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
|
||||
CRreg |= XIIC_CR_REPEATED_START_MASK;
|
||||
CRreg &= ~XIIC_CR_DIR_IS_TX_MASK;
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CRreg);
|
||||
|
||||
/*
|
||||
* Send the 1st byte of the 10 bit address as a read operation, enable
|
||||
* the receive interrupt to know when data is received, assuming that
|
||||
* the receive FIFO threshold has been previously set.
|
||||
*/
|
||||
XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
|
||||
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* When the IIC Tx FIFO/register goes empty, this routine is called by the
|
||||
* interrupt service routine to fill the transmit FIFO with data to be sent.
|
||||
*
|
||||
* This function also is called by the Tx <20> empty interrupt as the data handling
|
||||
* is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
|
||||
* register to indicate the available free FIFO bytes.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SendMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* The device is a master on the bus. If there is still more address
|
||||
* bytes to send when in master receive operation and the slave device
|
||||
* is 10 bit addressed.
|
||||
* This requires the lower 7 bits of address to be resent when the mode
|
||||
* switches to Read instead of write (while sending addresses).
|
||||
*/
|
||||
if (InstancePtr->TxAddrMode & XIIC_TX_ADDR_MSTR_RECV_MASK) {
|
||||
/*
|
||||
* Send the 1st byte of the slave address in the read operation
|
||||
* and change the state to indicate this has been done
|
||||
*/
|
||||
SendSlaveAddr(InstancePtr);
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* In between 1st and last byte of message, fill the FIFO with more data
|
||||
* to send, disable the 1/2 empty interrupt based upon data left to
|
||||
* send.
|
||||
*/
|
||||
else if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
|
||||
if (InstancePtr->SendByteCount < 2) {
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If there is only one byte left to send, processing differs between
|
||||
* repeated start and normal messages.
|
||||
*/
|
||||
else if (InstancePtr->SendByteCount == 1) {
|
||||
/*
|
||||
* When using repeated start, another interrupt is expected
|
||||
* after the last byte has been sent, so the message is not
|
||||
* done yet.
|
||||
*/
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* When not using repeated start, the stop condition must be
|
||||
* generated after the last byte is written. The bus is
|
||||
* throttled waiting for the last byte.
|
||||
*/
|
||||
else {
|
||||
/*
|
||||
* Set the stop condition before sending the last byte
|
||||
* of data so that the stop condition will be generated
|
||||
* immediately following the data another transmit
|
||||
* interrupt is not expected so the message is done.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg &= ~XIIC_CR_MSMS_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
|
||||
/*
|
||||
* Wait for bus to not be busy before declaring message
|
||||
* has been sent for the no repeated start operation.
|
||||
* The callback will be called from the BusNotBusy part
|
||||
* of the Interrupt handler to ensure that the message
|
||||
* is completely sent.
|
||||
* Disable the Tx interrupts and enable the BNB
|
||||
* interrupt.
|
||||
*/
|
||||
|
||||
InstancePtr->BNBOnly = FALSE;
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
XIic_EnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
|
||||
}
|
||||
} else {
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
|
||||
/*
|
||||
* The message being sent has completed. When using
|
||||
* repeated start with no more bytes to send repeated
|
||||
* start needs to be set in the control register so
|
||||
* that the bus will still be held by this master.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
/*
|
||||
* If the message that was being sent has finished,
|
||||
* disable all transmit interrupts and call the callback
|
||||
* that was setup to indicate the message was sent,
|
||||
* with 0 bytes remaining.
|
||||
*/
|
||||
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the receive register is full. The number
|
||||
* of bytes received to cause the interrupt is adjustable using the Receive FIFO
|
||||
* Depth register. The number of bytes in the register is read in the Receive
|
||||
* FIFO occupancy register. Both these registers are zero based values (0-15)
|
||||
* such that a value of zero indicates 1 byte.
|
||||
*
|
||||
* For a Master Receiver to properly signal the end of a message, the data must
|
||||
* be read in up to the message length - 1, where control register bits will be
|
||||
* set for bus controls to occur on reading of the last byte.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void RecvMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u8 LoopCnt;
|
||||
int BytesInFifo;
|
||||
int BytesToRead;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* Device is a master receiving, get the contents of the control
|
||||
* register and determine the number of bytes in fifo to be read out.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
BytesInFifo = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET) + 1;
|
||||
|
||||
/*
|
||||
* If data in FIFO holds all data to be retrieved - 1, set NOACK and
|
||||
* disable the Tx error.
|
||||
*/
|
||||
if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
|
||||
/*
|
||||
* Disable Tx error interrupt to prevent interrupt
|
||||
* as this device will cause it when it set NO ACK next.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* Write control reg with NO ACK allowing last byte to
|
||||
* have the No ack set to indicate to slave last byte read.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg | XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
/*
|
||||
* Read one byte to clear a place for the last byte to be read
|
||||
* which will set the NO ACK.
|
||||
*/
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If data in FIFO is all the data to be received then get the data
|
||||
* and also leave the device in a good state for the next transaction.
|
||||
*/
|
||||
else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
|
||||
/*
|
||||
* If repeated start option is off then the master should stop
|
||||
* using the bus, otherwise hold the bus, setting repeated start
|
||||
* stops the slave from transmitting data when the FIFO is read.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_REPEATED_START_OPTION) == 0) {
|
||||
CntlReg &= ~XIIC_CR_MSMS_MASK;
|
||||
} else {
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
/*
|
||||
* Read data from the FIFO then set zero based FIFO read depth
|
||||
* for a byte.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Disable Rx full interrupt and write the control reg with ACK
|
||||
* allowing next byte sent to be acknowledged automatically.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg & ~XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
/*
|
||||
* Send notification of msg Rx complete in RecvHandler callback.
|
||||
*/
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
|
||||
} else {
|
||||
/*
|
||||
* Fifo data not at n-1, read all but the last byte of data
|
||||
* from the slave, if more than a FIFO full yet to receive
|
||||
* read a FIFO full.
|
||||
*/
|
||||
BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
|
||||
if (BytesToRead > IIC_RX_FIFO_DEPTH) {
|
||||
BytesToRead = IIC_RX_FIFO_DEPTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in data from the FIFO.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,211 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_multi_master.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains multi-master functions for the XIic component. This file is
|
||||
* necessary if multiple masters are on the IIC bus such that arbitration can
|
||||
* be lost or the bus can be busy.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/27/02 Reparitioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void BusNotBusyHandler(XIic *InstancePtr);
|
||||
static void ArbitrationLostHandler(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This function includes multi-master code such that multi-master events are
|
||||
* handled properly. Multi-master events include a loss of arbitration and
|
||||
* the bus transitioning from busy to not busy. This function allows the
|
||||
* multi-master processing to be optional. This function must be called prior
|
||||
* to allowing any multi-master events to occur, such as after the driver is
|
||||
* initialized.
|
||||
*
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_MultiMasterInclude(void)
|
||||
{
|
||||
XIic_ArbLostFuncPtr = ArbitrationLostHandler;
|
||||
XIic_BusNotBusyFuncPtr = BusNotBusyHandler;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* The IIC bus busy signals when a master has control of the bus. Until the bus
|
||||
* is released, i.e. not busy, other devices must wait to use it.
|
||||
*
|
||||
* When this interrupt occurs, it signals that the previous master has released
|
||||
* the bus for another user.
|
||||
*
|
||||
* This interrupt is only enabled when the master Tx is waiting for the bus.
|
||||
*
|
||||
* This interrupt causes the following tasks:
|
||||
* - Disable Bus not busy interrupt
|
||||
* - Enable bus Ack
|
||||
* Should the slave receive have disabled acknowledgement, enable to allow
|
||||
* acknowledgment of the sending of our address to again be addressed as
|
||||
* slave
|
||||
* - Flush Rx FIFO
|
||||
* Should the slave receive have disabled acknowledgement, a few bytes may
|
||||
* be in FIFO if Rx full did not occur because of not enough byte in FIFO
|
||||
* to have caused an interrupt.
|
||||
* - Send status to user via status callback with the value:
|
||||
* XII_BUS_NOT_BUSY_EVENT
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void BusNotBusyHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* Should the slave receive have disabled acknowledgement,
|
||||
* enable to allow acknowledgment of the sending of our address to
|
||||
* again be addressed as slave.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg & ~XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
/*
|
||||
* Flush Tx FIFO by toggling TxFIFOResetBit. FIFO runs normally at 0
|
||||
* Do this in case needed to Tx FIFO with more than expected if what
|
||||
* was set to Tx was less than what the Master expected - read more
|
||||
* from this slave so FIFO had junk in it.
|
||||
*/
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Flush Rx FIFO should slave Rx had a problem, sent No ack but
|
||||
* still received a few bytes. Should the slave receive have disabled
|
||||
* acknowledgement, clear Rx FIFO.
|
||||
*/
|
||||
XIic_FlushRxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Send Application messaging status via callbacks. Disable either Tx or
|
||||
* Receive interrupt. Which callback depends on messaging direction.
|
||||
*/
|
||||
Status = XIic_ReadIier(InstancePtr->BaseAddress);
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
/*
|
||||
* Slave was sending data (master was reading), disable
|
||||
* all the transmit interrupts.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_TX_INTERRUPTS));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Slave was receiving data (master was writing) disable receive
|
||||
* interrupts.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_INTR_RX_FULL_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send Status in StatusHandler callback.
|
||||
*/
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
|
||||
XII_BUS_NOT_BUSY_EVENT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* When multiple IIC devices attempt to use the bus simultaneously, only
|
||||
* a single device will be able to keep control as a master. Those devices
|
||||
* that didn't retain control over the bus are said to have lost arbitration.
|
||||
* When arbitration is lost, this interrupt occurs sigaling the user that
|
||||
* the message did not get sent as expected.
|
||||
*
|
||||
* This function, at arbitration lost:
|
||||
* - Disables Tx empty, <20> empty and Tx error interrupts
|
||||
* - Clears any Tx empty, <20> empty Rx Full or Tx error interrupts
|
||||
* - Clears Arbitration lost interrupt,
|
||||
* - Flush Tx FIFO
|
||||
* - Call StatusHandler callback with the value: XII_ARB_LOST_EVENT
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void ArbitrationLostHandler(XIic *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Disable Tx empty and <20> empty and Tx error interrupts before clearing
|
||||
* them so they won't occur again.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_TX_INTERRUPTS);
|
||||
|
||||
/*
|
||||
* Clear any Tx empty, <20> empty Rx Full or Tx error interrupts.
|
||||
*/
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress, XIIC_TX_INTERRUPTS);
|
||||
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Update Status via StatusHandler callback.
|
||||
*/
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
|
||||
XII_ARB_LOST_EVENT);
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,150 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_options.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains options functions for the XIic component. This file is not required
|
||||
* unless the functions in this file are called.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the options for the IIC device driver. The options control
|
||||
* how the device behaves relative to the IIC bus. If an option applies to
|
||||
* how messages are sent or received on the IIC bus, it must be set prior to
|
||||
* calling functions which send or receive data.
|
||||
*
|
||||
* To set multiple options, the values must be ORed together. To not change
|
||||
* existing options, read/modify/write with the current options using
|
||||
* XIic_GetOptions().
|
||||
*
|
||||
* <b>USAGE EXAMPLE:</b>
|
||||
*
|
||||
* Read/modify/write to enable repeated start:
|
||||
* <pre>
|
||||
* u8 Options;
|
||||
* Options = XIic_GetOptions(&Iic);
|
||||
* XIic_SetOptions(&Iic, Options | XII_REPEATED_START_OPTION);
|
||||
* </pre>
|
||||
*
|
||||
* Disabling General Call:
|
||||
* <pre>
|
||||
* Options = XIic_GetOptions(&Iic);
|
||||
* XIic_SetOptions(&Iic, Options &= ~XII_GENERAL_CALL_OPTION);
|
||||
* </pre>
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param NewOptions are the options to be set. See xiic.h for a list of
|
||||
* the available options.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Sending or receiving messages with repeated start enabled, and then
|
||||
* disabling repeated start, will not take effect until another master
|
||||
* transaction is completed. i.e. After using repeated start, the bus will
|
||||
* continue to be throttled after repeated start is disabled until a master
|
||||
* transaction occurs allowing the IIC to release the bus.
|
||||
* <br><br>
|
||||
* Options enabled will have a 1 in its appropriate bit position.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetOptions(XIic *InstancePtr, u32 NewOptions)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Update the options in the instance and get the contents of the
|
||||
* control register such that the general call option can be modified.
|
||||
*/
|
||||
InstancePtr->Options = NewOptions;
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* The general call option is the only option that maps directly to
|
||||
* a hardware register feature.
|
||||
*/
|
||||
if (NewOptions & XII_GENERAL_CALL_OPTION) {
|
||||
CntlReg |= XIIC_CR_GENERAL_CALL_MASK;
|
||||
} else {
|
||||
CntlReg &= ~XIIC_CR_GENERAL_CALL_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the new control register value to the register.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the current options for the IIC device. Options control
|
||||
* the how the device behaves on the IIC bus. See SetOptions for more information
|
||||
* on options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return The options of the IIC device. See xiic.h for a list of
|
||||
* available options.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Options enabled will have a 1 in its appropriate bit position.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 XIic_GetOptions(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
return InstancePtr->Options;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,135 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2012 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_selftest.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains selftest functions for the XIic component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 03/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01c sv 05/09/05 Changed the data being written to the Address/Control
|
||||
* Register and removed the code for testing the
|
||||
* Receive Data Register.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.16a ktn 07/17/09 Updated the test to test only Interrupt Registers
|
||||
* as the software reset only resets the interrupt logic
|
||||
* and the Interrupt Registers are set to default values.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIic_SelfTest() API and
|
||||
* XIIC_RESET macro to mention that the complete IIC core
|
||||
* is Reset on giving a software reset to the IIC core.
|
||||
* Some previous versions of the core only reset the
|
||||
* Interrupt Logic/Registers, please refer to the HW
|
||||
* specification for further details.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Runs a limited self-test on the driver/device. This test does a read/write
|
||||
* test of the Interrupt Registers There is no loopback capabilities for the
|
||||
* device such that this test does not send or receive data.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if no errors are found
|
||||
* - XST_FAILURE if errors are found
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_SelfTest(XIic *InstancePtr)
|
||||
{
|
||||
int Status = XST_SUCCESS;
|
||||
int GlobalIntrStatus;
|
||||
u32 IntrEnableStatus;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Store the Global Interrupt Register and the Interrupt Enable Register
|
||||
* contents.
|
||||
*/
|
||||
GlobalIntrStatus = XIic_IsIntrGlobalEnabled(InstancePtr->BaseAddress);
|
||||
IntrEnableStatus = XIic_ReadIier(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Reset the device so it's in a known state and the default state of
|
||||
* the interrupt registers can be tested.
|
||||
*/
|
||||
XIic_Reset(InstancePtr);
|
||||
|
||||
if (XIic_IsIntrGlobalEnabled(InstancePtr->BaseAddress)!= 0) {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
if (XIic_ReadIier(InstancePtr->BaseAddress)!= 0) {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test Read/Write to the Interrupt Enable register.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
|
||||
if (XIic_ReadIier(InstancePtr->BaseAddress)!= XIIC_TX_RX_INTERRUPTS) {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset device to remove the affects of the previous test.
|
||||
*/
|
||||
XIic_Reset(InstancePtr);
|
||||
|
||||
/*
|
||||
* Restore the Global Interrupt Register and the Interrupt Enable
|
||||
* Register contents.
|
||||
*/
|
||||
if (GlobalIntrStatus == TRUE) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
}
|
||||
XIic_WriteIier(InstancePtr->BaseAddress, IntrEnableStatus);
|
||||
|
||||
return Status;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,140 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2005 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_sinit.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* The implementation of the Xiic component's static initialization functionality.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.02a jvb 10/13/05 release
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xparameters.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the unique device ID. The table
|
||||
* IicConfigTable contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId is the unique device ID to look for
|
||||
*
|
||||
* @return A pointer to the configuration data of the device,
|
||||
* or NULL if no match is found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XIic_Config *XIic_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XIic_Config *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XIIC_NUM_INSTANCES; Index++) {
|
||||
if (XIic_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XIic_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initializes a specific XIic instance. The initialization entails:
|
||||
*
|
||||
* - Check the device has an entry in the configuration table.
|
||||
* - Initialize the driver to allow access to the device registers and
|
||||
* initialize other subcomponents necessary for the operation of the device.
|
||||
* - Default options to:
|
||||
* - 7-bit slave addressing
|
||||
* - Send messages as a slave device
|
||||
* - Repeated start off
|
||||
* - General call recognition disabled
|
||||
* - Clear messageing and error statistics
|
||||
*
|
||||
* The XIic_Start() function must be called after this function before the device
|
||||
* is ready to send and receive data on the IIC bus.
|
||||
*
|
||||
* Before XIic_Start() is called, the interrupt control must connect the ISR
|
||||
* routine to the interrupt handler. This is done by the user, and not
|
||||
* XIic_Start() to allow the user to use an interrupt controller of their choice.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param DeviceId is the unique id of the device controlled by this XIic
|
||||
* instance. Passing in a device id associates the generic XIic
|
||||
* instance to a specific device, as chosen by the caller or
|
||||
* application developer.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS when successful
|
||||
* - XST_DEVICE_NOT_FOUND indicates the given device id isn't found
|
||||
* - XST_DEVICE_IS_STARTED indicates the device is started
|
||||
* (i.e. interrupts enabled and messaging is possible).
|
||||
* Must stop before re-initialization is allowed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_Initialize(XIic *InstancePtr, u16 DeviceId)
|
||||
{
|
||||
XIic_Config *ConfigPtr; /* Pointer to configuration data */
|
||||
|
||||
/*
|
||||
* Asserts test the validity of selected input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XIic_LookupConfig(DeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return XIic_CfgInitialize(InstancePtr, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,599 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_slave.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains slave functions for the XIic component. This file is necessary when
|
||||
* slave operations, sending and receiving data as a slave on the IIC bus,
|
||||
* are desired.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.15a ktn 03/18/09 Minor changes to comply to Doxygen
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Removed the macro XIic_mEnterCriticalRegion and used
|
||||
* XIic_IntrGlobalDisable int its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion and used
|
||||
* XIic_IntrGlobalEnable in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* 2.03a rkv 01/25/11 Updated in NAAS interrupt handler to support data
|
||||
* received less than FIFO size prior to NAAS interrupt.
|
||||
* Fixed for CR590212.
|
||||
* 2.04a sdm 07/22/11 Added IsSlaveSetAckOff flag to the instance structure.
|
||||
* The IsSlaveSetAckOff is set when the Slave has set the
|
||||
* Ack Off in the RecvSlaveData function and is cleared in the
|
||||
* NotAddrAsSlaveHandler when the master has released the
|
||||
* bus. This flag is to be used by slave applications for
|
||||
* recovering when it has gone out of sync with the master.
|
||||
* CR 615004.
|
||||
* 3.1 adk 01/08/15 When configured as a slave return the actual number of
|
||||
* bytes have been received/sent by the Master
|
||||
* to the user callback (CR: 828504).
|
||||
* 3.7 rna 10/06/20 Flush the RxFIFO in NAAS handler only when the FIFO is not
|
||||
* empty and the controller is still in NAAS state.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void AddrAsSlaveHandler(XIic *InstancePtr);
|
||||
static void NotAddrAsSlaveHandler(XIic *InstancePtr);
|
||||
static void RecvSlaveData(XIic *InstancePtr);
|
||||
static void SendSlaveData(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function includes slave code such that slave events will be processed.
|
||||
* It is necessary to allow slave code to be optional to reduce the size of
|
||||
* the driver. This function may be called at any time but must be prior to
|
||||
* being selected as a slave on the IIC bus. This function may be called prior
|
||||
* to the Cfg_Initialize() function and must be called before any functions in
|
||||
* this file are called.
|
||||
*
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_SlaveInclude(void)
|
||||
{
|
||||
XIic_AddrAsSlaveFuncPtr = AddrAsSlaveHandler;
|
||||
XIic_NotAddrAsSlaveFuncPtr = NotAddrAsSlaveHandler;
|
||||
XIic_RecvSlaveFuncPtr = RecvSlaveData;
|
||||
XIic_SendSlaveFuncPtr = SendSlaveData;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data as a slave on the IIC bus and should not be called
|
||||
* until an event has occurred that indicates the device has been selected by
|
||||
* a master attempting read from the slave (XII_MASTER_READ_EVENT).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param TxMsgPtr is a pointer to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message transmission has been
|
||||
* initiated.
|
||||
* - XST_IIC_NOT_SLAVE indicates the device has not been
|
||||
* selected to be a slave on the IIC bus such that data
|
||||
* cannot be sent.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_SlaveSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 Status;
|
||||
|
||||
/*
|
||||
* If the device is not a slave on the IIC bus then indicate an error
|
||||
* because data cannot be sent on the bus.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
if ((Status & XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
|
||||
return XST_IIC_NOT_SLAVE;
|
||||
}
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Save message state and invalidate the receive buffer pointer to
|
||||
* indicate the direction of transfer is sending.
|
||||
*/
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = TxMsgPtr;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Start sending the specified data and then interrupt processing will
|
||||
* complete it.
|
||||
*/
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_SLAVE_ROLE);
|
||||
|
||||
/* Clear any pending Tx empty, Tx Error and interrupt then enable them.
|
||||
* The Tx error interrupt indicates when the message is complete.
|
||||
* If data remaining to be sent, clear and enable Tx <20> empty interrupt.
|
||||
*/
|
||||
IntrStatus = (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK);
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
IntrStatus |= XIIC_INTR_TX_HALF_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupts in the status and then enable them and then
|
||||
* exit the critical region.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, IntrStatus);
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data as a slave on the IIC bus and should not be called
|
||||
* until an event has occurred that indicates the device has been selected by
|
||||
* a master attempting read from the slave (XII_MASTER_READ_EVENT).
|
||||
*
|
||||
* If more data is received than specified a No Acknowledge will be sent to
|
||||
* signal the Master to stop sending data. Any received data is read to prevent
|
||||
* the slave device from throttling the bus.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the Iic instance to be worked on.
|
||||
* @param RxMsgPtr is a pointer to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message transmission has been
|
||||
* initiated.
|
||||
* - XST_IIC_NOT_SLAVE indicates the device has not been selected
|
||||
* to be a slave on the IIC bus such that data cannot be received.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The master signals the message completion differently depending on the
|
||||
* repeated start options.
|
||||
*
|
||||
* When the master is not using repeated start:
|
||||
* - Not Addressed As Slave NAAS interrupt signals the master has sent a stop
|
||||
* condition and is no longer sending data. This doesn't imply that the master
|
||||
* will not send a No Ack. It covers when the master fails to send No
|
||||
* Acknowledge before releasing the bus.
|
||||
* - Tx Error interrupt signals end of message.
|
||||
*
|
||||
* When the master is using repeated start:
|
||||
* - the Tx Error interrupt signals the master finished sending the msg.
|
||||
* - NAAS interrupt will not signal when message is complete as the
|
||||
* master may want to write or read another message with this device.
|
||||
*
|
||||
* To prevent throttling, the slave must contine to read discard the data
|
||||
* when the receive buffer is full. When unexpected bytes are received, No Ack
|
||||
* must be set and the Rx buffer continually read until either NAAS
|
||||
* or Bus Not Busy BND interrupt signals the master is no longer
|
||||
* interacting with this slave. At this point the Ack is set to ON allowing
|
||||
* this device to acknowlefge the an address sent to it for the next
|
||||
* slave message.
|
||||
*
|
||||
* The slave will always receive 1 byte before the bus is throttled causing a
|
||||
* receive pending interrupt before this routine is executed. After one byte
|
||||
* the bus will throttle. The depth is set to the proper amount immediately
|
||||
* allowing the master to send more bytes and then to again throttle, but at the
|
||||
* proper fifo depth. The interrupt is a level. Clearing and enabling will cause
|
||||
* the Rx interrupt to pend at the correct level.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_SlaveRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 Status;
|
||||
|
||||
/*
|
||||
* If the device is not a slave on the IIC bus then indicate an error
|
||||
* because data cannot be received on the bus.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
if ((Status & XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
|
||||
return XST_IIC_NOT_SLAVE;
|
||||
}
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Save message state and invalidate the send buffer pointer to indicate
|
||||
* the direction of transfer is receive.
|
||||
*/
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = RxMsgPtr;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Set receive FIFO occupancy depth so the Rx interrupt will occur
|
||||
* when all bytes received or if more bytes than will fit in FIFO,
|
||||
* set to max depth.
|
||||
*/
|
||||
if (ByteCount > IIC_RX_FIFO_DEPTH) {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
IIC_RX_FIFO_DEPTH - 1);
|
||||
} else {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
ByteCount - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear and enable receive full interrupt except when the bytes to
|
||||
* receive is only 1, don't clear interrupt as it is the only one your
|
||||
* going to get.
|
||||
*/
|
||||
if (ByteCount > 1) {
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
}
|
||||
|
||||
XIic_EnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the IIC device is Addressed As a Slave (AAS).
|
||||
* This occurs when another device on the bus, a master, has addressed this
|
||||
* device to receive a message.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void AddrAsSlaveHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
int CallValue;
|
||||
|
||||
/*
|
||||
* Disable AAS interrupt to clear the interrupt condition since this is
|
||||
* interrupt does not go away and enable the not addressed as a slave
|
||||
* interrupt to tell when the master stops data transfer.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_INTR_AAS_MASK);
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_NAAS_MASK);
|
||||
|
||||
/*
|
||||
* Determine how the slave is being addressed and call the handler to
|
||||
* notify the user of the event.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* Determine if the master is trying to perform a read or write
|
||||
* operation.
|
||||
*/
|
||||
if (Status & XIIC_SR_MSTR_RDING_SLAVE_MASK) {
|
||||
CallValue = XII_MASTER_READ_EVENT;
|
||||
} else {
|
||||
CallValue = XII_MASTER_WRITE_EVENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* If being addressed with general call also indicate to handler.
|
||||
*/
|
||||
if (Status & XIIC_SR_GEN_CALL_MASK) {
|
||||
CallValue |= XII_GENERAL_CALL_EVENT;
|
||||
}
|
||||
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef, CallValue);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the IIC device receives Not Addressed As Slave
|
||||
* (NAAS) interrupt which indicates that the master has released the bus implying
|
||||
* a data transfer is complete.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void NotAddrAsSlaveHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 CntlReg;
|
||||
u8 BytesToRead;
|
||||
u8 LoopCnt;
|
||||
u32 TxFifoOcy;
|
||||
|
||||
/*
|
||||
* Disable NAAS so that the condition will not continue to interrupt
|
||||
* and enable the addressed as slave interrupt to know when a master
|
||||
* selects a slave on the bus.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_INTR_NAAS_MASK);
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_AAS_MASK);
|
||||
|
||||
/*
|
||||
* In the slave transmitter case pass the actual number of
|
||||
* bytes being recievd by the master to the user callback.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
TxFifoOcy = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_TFO_REG_OFFSET);
|
||||
if (!(Status & XIIC_SR_TX_FIFO_EMPTY_MASK)) {
|
||||
InstancePtr->SendByteCount = InstancePtr->Stats.SendBytes -
|
||||
(TxFifoOcy+1) ;
|
||||
} else {
|
||||
InstancePtr->SendByteCount = InstancePtr->Stats.SendBytes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flush Tx FIFO by toggling TxFIFOResetBit. FIFO runs normally at 0
|
||||
* Do this in case needed to Tx FIFO with more than expected if what
|
||||
* was set to Tx was less than what the Master expected - read more
|
||||
* from this slave so FIFO had junk in it.
|
||||
*/
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* NAAS interrupt was asserted but received data in receive FIFO is
|
||||
* less than Rc_FIFO_PIRQ to assert an receive full interrupt,in this
|
||||
* condition as data received is valid we have to read data before FIFO
|
||||
* flush.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
if (!(Status & XIIC_SR_RX_FIFO_EMPTY_MASK)) {
|
||||
BytesToRead = (XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET)) + 1;
|
||||
if (InstancePtr->RecvByteCount > BytesToRead) {
|
||||
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
} else if (!(Status & XIIC_SR_ADDR_AS_SLAVE_MASK)) {
|
||||
/*
|
||||
* Flush Rx FIFO should slave Rx had a problem, sent No ack but
|
||||
* still received a few bytes. Should the slave receive have disabled
|
||||
* acknowledgement, clear Rx FIFO.
|
||||
*/
|
||||
XIic_FlushRxFifo(InstancePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set FIFO occupancy depth = 1 so that the first byte will throttle
|
||||
* next receive msg.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Should the slave receive have disabled acknowledgement,
|
||||
* enable to allow acknowledgment for receipt of our address to
|
||||
* again be used as a slave.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg & ~XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
InstancePtr->IsSlaveSetAckOff = FALSE;
|
||||
|
||||
/*
|
||||
* Which callback depends on messaging direction, the buffer pointer NOT
|
||||
* being used indicates the direction of data transfer.
|
||||
*/
|
||||
Status = XIic_ReadIier(InstancePtr->BaseAddress);
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
/*
|
||||
* Slave was sending data so disable all transmit interrupts and
|
||||
* call the callback handler to indicate the transfer is
|
||||
* complete.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_TX_INTERRUPTS));
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
|
||||
InstancePtr->SendByteCount);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Slave was receiving data so disable receive full interrupt
|
||||
* and call the callback handler to notify the transfer is
|
||||
* complete.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_INTR_RX_FULL_MASK));
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
|
||||
InstancePtr->RecvByteCount);
|
||||
}
|
||||
InstancePtr->RecvByteCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function handles data received from the IIC bus as a slave.
|
||||
*
|
||||
* When the slave expects more than the master has to send, the slave will stall
|
||||
* waiting for data.
|
||||
*
|
||||
* When more data is received than data expected a Nack is done to signal master
|
||||
* to stop sending data. The excess data is discarded to prevent bus throttling.
|
||||
*
|
||||
* The buffer may be full and the master continues to send data if the master
|
||||
* and slave have different message lengths. This condition is handled by sending
|
||||
* No Ack to the master and reading Rx data until the master stops sending data
|
||||
* to prevent but throttling from locking up the bus. To ever receive as a slave
|
||||
* again, must know when to renable bus ACKs. NAAS is used to detect when the
|
||||
* master is finished sending messages for any mode.
|
||||
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void RecvSlaveData(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u8 BytesToRead;
|
||||
u8 LoopCnt;
|
||||
u8 Temp;
|
||||
|
||||
/*
|
||||
* When receive buffer has no room for the receive data discard it.
|
||||
*/
|
||||
if (InstancePtr->RecvByteCount == 0) {
|
||||
/*
|
||||
* Set acknowledge OFF to signal master to stop sending data.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg |= XIIC_CR_NO_ACK_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
/*
|
||||
* Set a Flag to indicate that the Slave has set the ACK Off.
|
||||
*/
|
||||
InstancePtr->IsSlaveSetAckOff = TRUE;
|
||||
|
||||
|
||||
/*
|
||||
* Clear excess received data to prevent bus throttling and set
|
||||
* receive FIFO occupancy to throttle at the 1st byte received.
|
||||
*/
|
||||
XIic_FlushRxFifo(InstancePtr);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Use occupancy count to determine how many bytes to read from the
|
||||
* FIFO, count is zero based so add 1, read that number of bytes from
|
||||
* the FIFO.
|
||||
*/
|
||||
BytesToRead = (XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET)) + 1;
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set receive FIFO depth for the number of bytes to be received such
|
||||
* that a receive interrupt will occur, the count is 0 based, the
|
||||
* last byte of the message has to be received separately to ack the
|
||||
* message.
|
||||
*/
|
||||
if (InstancePtr->RecvByteCount > IIC_RX_FIFO_DEPTH) {
|
||||
Temp = IIC_RX_FIFO_DEPTH - 1;
|
||||
} else {
|
||||
if (InstancePtr->RecvByteCount == 0) {
|
||||
Temp = 0;
|
||||
} else {
|
||||
Temp = InstancePtr->RecvByteCount - 1;
|
||||
}
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, (u32) Temp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data on the IIC bus as a slave.
|
||||
*
|
||||
* When message data has been sent, but the master keeps reading data, the FIFO
|
||||
* is filled to prevent bus throttling. There is no way to notify master of this
|
||||
* condition. While sending data as a slave a transmit error indicates the
|
||||
* master has completed the data transfer.
|
||||
*
|
||||
* NAAS interrupt signals when repeated start occurred and the msg is finished
|
||||
* and BNB signals when the master sent a stop.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SendSlaveData(XIic *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* When message has been sent, but master keeps reading data, must put a
|
||||
* byte in the FIFO or bus will throttle. There is no way to notify
|
||||
* master of this condition.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount == 0) {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_DTR_REG_OFFSET, 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the data by filling the transmit FIFO.
|
||||
*/
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_SLAVE_ROLE);
|
||||
/*
|
||||
* When the amount of data remaining to send is less than the half mark
|
||||
* of the FIFO making the use of <20> empty interrupt unnecessary,
|
||||
* disable it. Is this a problem that it's checking against 1 rather
|
||||
* than half?
|
||||
*/
|
||||
if (InstancePtr->SendByteCount < 1) {
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_stats.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains statistics functions for the XIic component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* XIic_ClearStats function is updated as the
|
||||
* macro XIIC_CLEAR_STATS has been removed.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Gets a copy of the statistics for an IIC device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param StatsPtr is a pointer to a XIicStats structure which will get a
|
||||
* copy of current statistics.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_GetStats(XIic *InstancePtr, XIicStats * StatsPtr)
|
||||
{
|
||||
u8 NumBytes;
|
||||
u8 *SrcPtr;
|
||||
u8 *DestPtr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(StatsPtr != NULL);
|
||||
|
||||
/*
|
||||
* Setup pointers to copy the stats structure
|
||||
*/
|
||||
SrcPtr = (u8 *) &InstancePtr->Stats;
|
||||
DestPtr = (u8 *) StatsPtr;
|
||||
|
||||
/*
|
||||
* Copy the current statistics to the structure passed in
|
||||
*/
|
||||
for (NumBytes = 0; NumBytes < sizeof(XIicStats); NumBytes++) {
|
||||
*DestPtr++ = *SrcPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Clears the statistics for the IIC device by zeroing all counts.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_ClearStats(XIic *InstancePtr)
|
||||
{
|
||||
u8 NumBytes;
|
||||
u8 *DestPtr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
DestPtr = (u8 *)&InstancePtr->Stats;
|
||||
for (NumBytes = 0; NumBytes < sizeof(XIicStats); NumBytes++) {
|
||||
*DestPtr++ = 0;
|
||||
}
|
||||
|
||||
}
|
||||
/** @} */
|
||||
@@ -84,6 +84,10 @@ XIntc_Config XIntc_ConfigTable[] =
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
},
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
},
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
|
||||
@@ -29,6 +29,14 @@ XUartLite_Config XUartLite_ConfigTable[] =
|
||||
XPAR_UARTLITE_0_USE_PARITY,
|
||||
XPAR_UARTLITE_0_ODD_PARITY,
|
||||
XPAR_UARTLITE_0_DATA_BITS
|
||||
},
|
||||
{
|
||||
XPAR_UARTLITE_1_DEVICE_ID,
|
||||
XPAR_UARTLITE_1_BASEADDR,
|
||||
XPAR_UARTLITE_1_BAUDRATE,
|
||||
XPAR_UARTLITE_1_USE_PARITY,
|
||||
XPAR_UARTLITE_1_ODD_PARITY,
|
||||
XPAR_UARTLITE_1_DATA_BITS
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ BEGIN OS
|
||||
PARAMETER OS_NAME = freertos10_xilinx
|
||||
PARAMETER OS_VER = 1.12
|
||||
PARAMETER PROC_INSTANCE = microblaze_0
|
||||
PARAMETER stdin = axi_uartlite_0
|
||||
PARAMETER stdout = axi_uartlite_0
|
||||
PARAMETER stdin = mdm_1
|
||||
PARAMETER stdout = mdm_1
|
||||
PARAMETER total_heap_size = 2097152
|
||||
END
|
||||
|
||||
@@ -139,6 +139,18 @@ BEGIN DRIVER
|
||||
PARAMETER HW_INSTANCE = qspi_flash
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = iic
|
||||
PARAMETER DRIVER_VER = 3.9
|
||||
PARAMETER HW_INSTANCE = axi_iic_0
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = uartlite
|
||||
PARAMETER DRIVER_VER = 3.7
|
||||
PARAMETER HW_INSTANCE = mdm_1
|
||||
END
|
||||
|
||||
|
||||
BEGIN LIBRARY
|
||||
PARAMETER LIBRARY_NAME = lwip211
|
||||
|
||||
@@ -0,0 +1,589 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* XIic is the driver for an IIC master or slave device.
|
||||
*
|
||||
* In order to reduce the memory requirements of the driver the driver is
|
||||
* partitioned such that there are optional parts of the driver.
|
||||
* Slave, master, and multimaster features are optional such that all these files
|
||||
* are not required at the same time.
|
||||
* In order to use the slave and multimaster features of the driver, the user
|
||||
* must call functions (XIic_SlaveInclude and XIic_MultiMasterInclude)
|
||||
* to dynamically include the code. These functions may be called at any time.
|
||||
*
|
||||
* Two sets of higher level API's are available in the XIic driver that can
|
||||
* be used for Transmission/Reception in Master mode :
|
||||
* - XIic_MasterSend()/ XIic_MasterRecv() which is used in normal mode.
|
||||
* - XIic_DynMasterSend()/ XIic_DynMasterRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* Similarly two sets of lower level API's are available in XIic driver that
|
||||
* can be used for Transmission/Reception in Master mode:
|
||||
* - XIic_Send()/ XIic_Recv() which is used in normal mode
|
||||
* - XIic_DynSend()/ XIic_DynRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* The user should use a single set of APIs as per his requirement and
|
||||
* should not intermix them.
|
||||
*
|
||||
* All the driver APIs can be used for read, write and combined mode of
|
||||
* operations on the IIC bus.
|
||||
*
|
||||
* In the normal mode IIC support both 7-bit and 10-bit addressing, and in
|
||||
* the dynamic mode support only 7-bit addressing.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XIic_Config structure is used by the driver to configure itself. This
|
||||
* configuration structure is typically created by the tool-chain based on HW
|
||||
* build properties.
|
||||
*
|
||||
* To support multiple runtime loading and initialization strategies employed
|
||||
* by various operating systems, the driver instance can be initialized in one
|
||||
* of the following ways:
|
||||
*
|
||||
* - XIic_Initialize() - The driver looks up its own
|
||||
* configuration structure created by the tool-chain based on an ID provided
|
||||
* by the tool-chain.
|
||||
*
|
||||
* - XIic_CfgInitialize() - The driver uses a configuration structure provided
|
||||
* by the caller. If running in a system with address translation, the
|
||||
* provided virtual memory base address replaces the physical address present
|
||||
* in the configuration structure.
|
||||
*
|
||||
* <b>General Purpose Output</b>
|
||||
* The IIC hardware provides a General Purpose Output Register that allows the
|
||||
* user to connect general purpose outputs to devices, such as a write protect,
|
||||
* for an EEPROM. This register is parameterizable in the hardware such that
|
||||
* there could be zero bits in this register and in this case it will cause
|
||||
* a bus error if read or written.
|
||||
*
|
||||
* <b>Bus Throttling</b>
|
||||
*
|
||||
* The IIC hardware provides bus throttling which allows either the device, as
|
||||
* either a master or a slave, to stop the clock on the IIC bus. This feature
|
||||
* allows the software to perform the appropriate processing for each interrupt
|
||||
* without an unreasonable response restriction. With this design, it is
|
||||
* important for the user to understand the implications of bus throttling.
|
||||
*
|
||||
* <b>Repeated Start</b>
|
||||
*
|
||||
* An application can send multiple messages, as a master, to a slave device
|
||||
* and re-acquire the IIC bus each time a message is sent. The repeated start
|
||||
* option allows the application to send multiple messages without re-acquiring
|
||||
* the IIC bus for each message. The transactions involving repeated start
|
||||
* are also called combined transfers if there is Read and Write in the
|
||||
* same transaction.
|
||||
*
|
||||
* The repeated start feature works with all the API's in XIic driver.
|
||||
*
|
||||
* The Repeated Start feature also could cause the application to lock up, or
|
||||
* monopolize the IIC bus, should repeated start option be enabled and sequences
|
||||
* of messages never end(periodic data collection).
|
||||
* Also when repeated start is not disable before the last master message is
|
||||
* sent or received, will leave the bus captive to the master, but unused.
|
||||
*
|
||||
* <b>Addressing</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built for 7 or 10
|
||||
* bit addresses. The driver provides the ability to control which address
|
||||
* size is sent in messages as a master to a slave device. The address size
|
||||
* which the hardware responds to as a slave is parameterized as 7 or 10 bits
|
||||
* but fixed by the hardware build.
|
||||
*
|
||||
* Addresses are represented as hex values with no adjustment for the data
|
||||
* direction bit as the software manages address bit placement. This is
|
||||
* especially important as the bit placement is not handled the same depending
|
||||
* on which options are used such as repeated start and 7 vs 10 bit addressing.
|
||||
*
|
||||
* <b>Data Rates</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built to support
|
||||
* data rates from DC to 400KBit. The frequency of the interrupts which
|
||||
* occur is proportional to the data rate.
|
||||
*
|
||||
* <b>Polled Mode Operation</b>
|
||||
*
|
||||
* This driver does not provide a polled mode of operation primarily because
|
||||
* polled mode which is non-blocking is difficult with the amount of
|
||||
* interaction with the hardware that is necessary.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The device has many interrupts which allow IIC data transactions as well
|
||||
* as bus status processing to occur.
|
||||
*
|
||||
* The interrupts are divided into two types, data and status. Data interrupts
|
||||
* indicate data has been received or transmitted while the status interrupts
|
||||
* indicate the status of the IIC bus. Some of the interrupts, such as Not
|
||||
* Addressed As Slave and Bus Not Busy, are only used when these specific
|
||||
* events must be recognized as opposed to being enabled at all times.
|
||||
*
|
||||
* Many of the interrupts are not a single event in that they are continuously
|
||||
* present such that they must be disabled after recognition or when undesired.
|
||||
* Some of these interrupts, which are data related, may be acknowledged by the
|
||||
* software by reading or writing data to the appropriate register, or must
|
||||
* be disabled. The following interrupts can be continuous rather than single
|
||||
* events.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Bus Not Busy
|
||||
* - Addressed As Slave
|
||||
* - Not Addressed As Slave
|
||||
*
|
||||
* The following interrupts are not passed directly to the application through the
|
||||
* status callback. These are only used internally for the driver processing
|
||||
* and may result in the receive and send handlers being called to indicate
|
||||
* completion of an operation. The following interrupts are data related
|
||||
* rather than status.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Slave Transmit Complete
|
||||
*
|
||||
* <b>Interrupt To Event Mapping</b>
|
||||
*
|
||||
* The following table provides a mapping of the interrupts to the events which
|
||||
* are passed to the status handler and the intended role (master or slave) for
|
||||
* the event. Some interrupts can cause multiple events which are combined
|
||||
* together into a single status event such as XII_MASTER_WRITE_EVENT and
|
||||
* XII_GENERAL_CALL_EVENT
|
||||
* <pre>
|
||||
* Interrupt Event(s) Role
|
||||
*
|
||||
* Arbitration Lost Interrupt XII_ARB_LOST_EVENT Master
|
||||
* Transmit Error XII_SLAVE_NO_ACK_EVENT Master
|
||||
* IIC Bus Not Busy XII_BUS_NOT_BUSY_EVENT Master
|
||||
* Addressed As Slave XII_MASTER_READ_EVENT, Slave
|
||||
* XII_MASTER_WRITE_EVENT, Slave
|
||||
* XII_GENERAL_CALL_EVENT Slave
|
||||
* </pre>
|
||||
* <b>Not Addressed As Slave Interrupt</b>
|
||||
*
|
||||
* The Not Addressed As Slave interrupt is not passed directly to the
|
||||
* application through the status callback. It is used to determine the end of
|
||||
* a message being received by a slave when there was no stop condition
|
||||
* (repeated start). It will cause the receive handler to be called to
|
||||
* indicate completion of the operation.
|
||||
*
|
||||
* <b>RTOS Independence</b>
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works
|
||||
* with physical addresses only. Any needs for dynamic memory management,
|
||||
* threads or thread mutual exclusion, virtual memory, or cache control must
|
||||
* be satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.01d sv 05/09/05 Changed the data being written to the Address/Control
|
||||
* Register and removed the code for testing the
|
||||
* Receive Data Register in XIic_SelfTest function of
|
||||
* xiic_selftest.c source file
|
||||
* 1.02a jvb 12/14/05 I separated dependency on the static config table and
|
||||
* xparameters.h from the driver initialization by moving
|
||||
* _Initialize and _LookupConfig to _sinit.c. I also added
|
||||
* the new _CfgInitialize routine.
|
||||
* 1.02a mta 03/09/06 Added a new function XIic_IsIicBusy() which returns
|
||||
* whether IIC Bus is Busy or Free.
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 07/17/06 Added files to support Dynamic IIC controller in High
|
||||
* level driver. Added xiic_dyn_master.c. Added support
|
||||
* for IIC Dynamic controller in Low level driver in xiic_l.c
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.13b ecm 11/29/07 added BB polling loops to the DynSend and DynRecv
|
||||
* routines to handle the race condition with BNB in IISR.
|
||||
* 1.14a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
|
||||
* file
|
||||
* 1.14a ecm 11/13/08 changed BB polling loops in DynRecv to handle race
|
||||
* condition, CR491889. DynSend was correct from v1.13.b
|
||||
* 1.15a ktn 02/17/09 Fixed XIic_GetAddress() to return correct device address.
|
||||
* 1.16a ktn 07/17/09 Updated the XIic_SelfTest() to test only Interrupt
|
||||
* Registers.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.,
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Removed the XIIC_CLEAR_STATS macro, XIic_ClearStats API
|
||||
* should be used in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name see the xiic_i.h and xiic_l.h file for further
|
||||
* information (Example XIic_mClearIntr is now
|
||||
* XIic_ClearIntr).
|
||||
* Some of the macros have been renamed to be consistent,
|
||||
* see the xiic_l.h file for further information
|
||||
* (Example XIIC_WRITE_IIER is renamed as XIic_WriteIier).
|
||||
* The driver has been updated to use the HAL APIs/macros
|
||||
* (Example XASSERT_NONVOID is now Xil_AssertNonvoid)
|
||||
* 2.01a ktn 04/09/10 Updated TxErrorhandler in xiic_intr.c to be called for
|
||||
* Master Transmitter case based on Addressed As Slave (AAS)
|
||||
* bit rather than MSMS bit(CR 540199).
|
||||
* 2.02a sdm 10/08/10 Updated to disable the device at the end of the transfer,
|
||||
* using Addressed As Slave (AAS) bit when addressed as
|
||||
* slave in XIic_Send for CR565373.
|
||||
* 2.03a rkv 01/25/11 Updated in NAAS interrupt handler to support data
|
||||
* received less than FIFO size prior to NAAS interrupt.
|
||||
* Fixed for CR590212.
|
||||
* 2.04a sdm 07/22/11 Added IsSlaveSetAckOff flag to the instance structure.
|
||||
* This flag is set when the Slave has set the Ack Off in the
|
||||
* RecvSlaveData function (xiic_slave.c) and
|
||||
* is cleared in the NotAddrAsSlaveHandler (xiic_slave.c)
|
||||
* when the master has released the bus. This flag is
|
||||
* to be used by slave applications for recovering when it
|
||||
* has gone out of sync with the master for CR 615004.
|
||||
* Removed a compiler warning in XIic_Send (xiic_l.c)
|
||||
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
|
||||
* SendBufferPtr in XIic_MasterRecv to NULL in xiic_master.c
|
||||
* 2.06a bss 02/14/13 Modified TxErrorHandler in xiic_intr.c to fix CR #686483
|
||||
* Modified xiic_eeprom_example.c to fix CR# 683509.
|
||||
* Modified bitwise OR to logical OR in
|
||||
* XIic_InterruptHandler API in xiic_intr.c.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
* 2.08a adk 29/07/13 In Low level driver In repeated start condition the
|
||||
* Direction of Tx bit must be disabled in recv condition
|
||||
* It Fixes the CR:685759 Changes are done in the file
|
||||
* xiic_l.c in the function XIic_Recv.
|
||||
* 3.0 adk 19/12/13 Updated as per the New Tcl API's
|
||||
* 3.1 adk 01/08/15 When configured as a slave return the actual number of
|
||||
* bytes have been received/sent by the Master
|
||||
* to the user callback (CR: 828504). Changes are made in the
|
||||
* file xiic_slave.c.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XIic_CfgInitialize API.
|
||||
* 3.2 sd 18/02/16 In Low level driver in repeated start condition
|
||||
* NACK for last byte is added. Changes are done in
|
||||
* XIic_Recv for CR# 862303
|
||||
* 3.3 sk 06/17/16 Added bus busy checks for slave send/recv and master
|
||||
* send/recv.
|
||||
* 3.3 als 06/27/16 XIic_IsIicBusy now a wrapper for XIic_CheckIsBusBusy.
|
||||
* 3.4 ms 01/23/17 Added xil_printf statement in main function for all
|
||||
* examples to ensure that "Successfully ran" and "Failed"
|
||||
* strings are available in all examples. This is a fix
|
||||
* for CR-965028.
|
||||
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
|
||||
* generation.
|
||||
* ms 04/05/17 Modified Comment lines in functions of iic
|
||||
* examples to recognize it as documentation block
|
||||
* for doxygen generation.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XIIC_H /* prevent circular inclusions */
|
||||
#define XIIC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* The following options may be specified or retrieved for the device and
|
||||
* enable/disable additional features of the IIC bus. Each of the options
|
||||
* are bit fields such that more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XII_GENERAL_CALL_OPTION The general call option allows an IIC slave to
|
||||
* recognized the general call address. The status
|
||||
* handler is called as usual indicating the device
|
||||
* has been addressed as a slave with a general
|
||||
* call. It is the application's responsibility to
|
||||
* perform any special processing for the general
|
||||
* call.
|
||||
*
|
||||
* XII_REPEATED_START_OPTION The repeated start option allows multiple
|
||||
* messages to be sent/received on the IIC bus
|
||||
* without rearbitrating for the bus. The messages
|
||||
* are sent as a series of messages such that the
|
||||
* option must be enabled before the 1st message of
|
||||
* the series, to prevent an stop condition from
|
||||
* being generated on the bus, and disabled before
|
||||
* the last message of the series, to allow the
|
||||
* stop condition to be generated.
|
||||
*
|
||||
* XII_SEND_10_BIT_OPTION The send 10 bit option allows 10 bit addresses
|
||||
* to be sent on the bus when the device is a
|
||||
* master. The device can be configured to respond
|
||||
* as to 7 bit addresses even though it may be
|
||||
* communicating with other devices that support 10
|
||||
* bit addresses. When this option is not enabled,
|
||||
* only 7 bit addresses are sent on the bus.
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
#define XII_GENERAL_CALL_OPTION 0x00000001
|
||||
#define XII_REPEATED_START_OPTION 0x00000002
|
||||
#define XII_SEND_10_BIT_OPTION 0x00000004
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Status events
|
||||
*
|
||||
* The following status events occur during IIC bus processing and are passed
|
||||
* to the status callback. Each event is only valid during the appropriate
|
||||
* processing of the IIC bus. Each of these events are bit fields such that
|
||||
* more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
#define XII_BUS_NOT_BUSY_EVENT 0x00000001 /**< Bus transitioned to not busy */
|
||||
#define XII_ARB_LOST_EVENT 0x00000002 /**< Arbitration was lost */
|
||||
#define XII_SLAVE_NO_ACK_EVENT 0x00000004 /**< Slave did not ACK (had error) */
|
||||
#define XII_MASTER_READ_EVENT 0x00000008 /**< Master reading from slave */
|
||||
#define XII_MASTER_WRITE_EVENT 0x00000010 /**< Master writing to slave */
|
||||
#define XII_GENERAL_CALL_EVENT 0x00000020 /**< General call to all slaves */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/*
|
||||
* The following address types are used when setting and getting the addresses
|
||||
* of the driver. These are mutually exclusive such that only one or the other
|
||||
* may be specified.
|
||||
*/
|
||||
#define XII_ADDR_TO_SEND_TYPE 1 /**< Bus address of slave device */
|
||||
#define XII_ADDR_TO_RESPOND_TYPE 2 /**< This device's bus address as slave */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< Does device have 10 bit address decoding */
|
||||
u8 GpOutWidth; /**< Number of bits in general purpose output */
|
||||
} XIic_Config;
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of sent and received data of the IIC driver. The application
|
||||
* using this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handlers are called in an interrupt context such
|
||||
* that minimal processing should be performed. The handler data type is
|
||||
* utilized for both send and receive handlers.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param ByteCount indicates the number of bytes remaining to be sent or
|
||||
* received. A value of zero indicates that the requested number
|
||||
* of bytes were sent or received.
|
||||
*
|
||||
******************************************************************************/
|
||||
typedef void (*XIic_Handler) (void *CallBackRef, int ByteCount);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of status events of the IIC driver. The application using
|
||||
* this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handler is called in an interrupt context such
|
||||
* that minimal processing should be performed.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param StatusEvent indicates one or more status events that occurred.
|
||||
* See the definition of the status events above.
|
||||
*
|
||||
********************************************************************************/
|
||||
typedef void (*XIic_StatusHandler) (void *CallBackRef, int StatusEvent);
|
||||
|
||||
/**
|
||||
* XIic statistics
|
||||
*/
|
||||
typedef struct {
|
||||
u8 ArbitrationLost;/**< Number of times arbitration was lost */
|
||||
u8 RepeatedStarts; /**< Number of repeated starts */
|
||||
u8 BusBusy; /**< Number of times bus busy status returned */
|
||||
u8 RecvBytes; /**< Number of bytes received */
|
||||
u8 RecvInterrupts; /**< Number of receive interrupts */
|
||||
u8 SendBytes; /**< Number of transmit bytes received */
|
||||
u8 SendInterrupts; /**< Number of transmit interrupts */
|
||||
u8 TxErrors; /**< Number of transmit errors (no ack) */
|
||||
u8 IicInterrupts; /**< Number of IIC (device) interrupts */
|
||||
} XIicStats;
|
||||
|
||||
/**
|
||||
* The XIic driver instance data. The user is required to allocate a
|
||||
* variable of this type for every IIC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XIicStats Stats; /**< Statistics */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< TRUE when 10 bit addressing in design */
|
||||
int IsReady; /**< Device is initialized and ready */
|
||||
int IsStarted; /**< Device has been started */
|
||||
int AddrOfSlave; /**< Slave Address writing to */
|
||||
|
||||
u32 Options; /**< Current operating options */
|
||||
u8 *SendBufferPtr; /**< Buffer to send (state) */
|
||||
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
|
||||
u8 TxAddrMode; /**< State of Tx Address transmission */
|
||||
int SendByteCount; /**< Number of data bytes in buffer (state) */
|
||||
int RecvByteCount; /**< Number of empty bytes in buffer (state) */
|
||||
|
||||
u32 BNBOnly; /**< TRUE when BNB interrupt needs to */
|
||||
/**< call callback */
|
||||
u8 GpOutWidth; /**< General purpose output width */
|
||||
|
||||
XIic_StatusHandler StatusHandler; /**< Status Handler */
|
||||
void *StatusCallBackRef; /**< Callback reference for status handler */
|
||||
XIic_Handler RecvHandler; /**< Receive Handler */
|
||||
void *RecvCallBackRef; /**< Callback reference for Recv handler */
|
||||
XIic_Handler SendHandler; /**< Send Handler */
|
||||
void *SendCallBackRef; /**< Callback reference for send handler */
|
||||
int IsDynamic; /**< TRUE when Dynamic control is used */
|
||||
int IsSlaveSetAckOff; /**< TRUE when Slave has set the ACK Off */
|
||||
|
||||
} XIic;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a function which tells whether the I2C bus is busy or free.
|
||||
*
|
||||
* @param InstancePtr points to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the bus is busy.
|
||||
* - FALSE if the bus is NOT busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static inline u32 XIic_IsIicBusy(XIic *InstancePtr)
|
||||
{
|
||||
return XIic_CheckIsBusBusy(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization functions in xiic_sinit.c
|
||||
*/
|
||||
int XIic_Initialize(XIic *InstancePtr, u16 DeviceId);
|
||||
XIic_Config *XIic_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions in xiic.c
|
||||
*/
|
||||
int XIic_CfgInitialize(XIic *InstancePtr, XIic_Config *Config,
|
||||
UINTPTR EffectiveAddr);
|
||||
|
||||
int XIic_Start(XIic *InstancePtr);
|
||||
int XIic_Stop(XIic *InstancePtr);
|
||||
|
||||
void XIic_Reset(XIic *InstancePtr);
|
||||
|
||||
int XIic_SetAddress(XIic *InstancePtr, int AddressType, int Address);
|
||||
u16 XIic_GetAddress(XIic *InstancePtr, int AddressType);
|
||||
|
||||
int XIic_SetGpOutput(XIic *InstancePtr, u8 OutputValue);
|
||||
int XIic_GetGpOutput(XIic *InstancePtr, u8 *OutputValuePtr);
|
||||
|
||||
u32 XIic_IsSlave(XIic *InstancePtr);
|
||||
|
||||
void XIic_SetRecvHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetSendHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetStatusHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_StatusHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xiic_intr.c
|
||||
*/
|
||||
void XIic_InterruptHandler(void *InstancePtr);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in normal mode in xiic_master.c
|
||||
*/
|
||||
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in dynamic mode in xiic_master.c
|
||||
*/
|
||||
int XIic_DynMasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, u8 ByteCount);
|
||||
int XIic_DynMasterSend(XIic *InstancePtr, u8 *TxMsgPtr, u8 ByteCount);
|
||||
|
||||
/*
|
||||
* Dynamic IIC Core Initialization.
|
||||
*/
|
||||
int XIic_DynamicInitialize(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Slave send and receive functions in xiic_slave.c
|
||||
*/
|
||||
void XIic_SlaveInclude(void);
|
||||
int XIic_SlaveRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_SlaveSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Statistics functions in xiic_stats.c
|
||||
*/
|
||||
void XIic_GetStats(XIic *InstancePtr, XIicStats *StatsPtr);
|
||||
void XIic_ClearStats(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Self test functions in xiic_selftest.c
|
||||
*/
|
||||
int XIic_SelfTest(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Bus busy Function in xiic.c
|
||||
*/
|
||||
u32 XIic_IsIicBusy(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Options functions in xiic_options.c
|
||||
*/
|
||||
void XIic_SetOptions(XIic *InstancePtr, u32 Options);
|
||||
u32 XIic_GetOptions(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Multi-master functions in xiic_multi_master.c
|
||||
*/
|
||||
void XIic_MultiMasterInclude(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,369 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_i.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains internal identifiers, which are those shared
|
||||
* between XIic components. The identifiers in this file are not intended for
|
||||
* use external to the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Removed the macro XIIC_CLEAR_STATS, user has to
|
||||
* use the the XIic_ClearStats API in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Removed the _m prefix from all the macros
|
||||
* XIic_mSend10BitAddrByte1 is now XIic_Send10BitAddrByte1
|
||||
* XIic_mSend10BitAddrByte2 is now XIic_Send10BitAddrByte2
|
||||
* XIic_mSend7BitAddr is now XIic_Send7BitAddr
|
||||
* XIic_mDisableIntr is now XIic_DisableIntr
|
||||
* XIic_mEnableIntr is now XIic_EnableIntr
|
||||
* XIic_mClearIntr is now XIic_ClearIntr
|
||||
* XIic_mClearEnableIntr is now XIic_ClearEnableIntr
|
||||
* XIic_mFlushRxFifo is now XIic_FlushRxFifo
|
||||
* XIic_mFlushTxFifo is now XIic_FlushTxFifo
|
||||
* XIic_mReadRecvByte is now XIic_ReadRecvByte
|
||||
* XIic_mWriteSendByte is now XIic_WriteSendByte
|
||||
* XIic_mSetControlRegister is now XIic_SetControlRegister
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings when
|
||||
* compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIIC_I_H /* prevent circular inclusions */
|
||||
#define XIIC_I_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the first byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* address = 1111_0xxD xx = address MSBits
|
||||
* D = Tx direction = 0 = write
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send10BitAddrByte1(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte1(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)((SlaveAddress) >> 7); \
|
||||
LocalAddr = (LocalAddr & 0xF6) | 0xF0 | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the second byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature: void XIic_Send10BitAddrByte2(u16 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte2(SlaveAddress) \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32)(SlaveAddress)); \
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send7BitAddr(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddr(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro disables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_DisableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DisableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) & ~(InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro enables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_EnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_EnableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) | (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears and enables the specified interrupt in the Interrupt
|
||||
* status and enable registers. It is non-destructive in that the registers are
|
||||
* read and only the interrupt specified is modified.
|
||||
* Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be cleared and enabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearEnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearEnableIntr(BaseAddress, InterruptMask) \
|
||||
{ \
|
||||
XIic_WriteIisr(BaseAddress, \
|
||||
(XIic_ReadIisr(BaseAddress) & (InterruptMask))); \
|
||||
\
|
||||
XIic_WriteIier(BaseAddress, \
|
||||
(XIic_ReadIier(BaseAddress) | (InterruptMask))); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the receive FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushRxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushRxFifo(InstancePtr) \
|
||||
{ \
|
||||
int LoopCnt; \
|
||||
u8 BytesToRead = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_RFO_REG_OFFSET) + 1; \
|
||||
for(LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) \
|
||||
{ \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_DRR_REG_OFFSET); \
|
||||
} \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the transmit FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushTxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushTxFifo(InstancePtr); \
|
||||
{ \
|
||||
u32 CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_CR_REG_OFFSET); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg | XIIC_CR_TX_FIFO_RESET_MASK); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro reads the next available received byte from the receive FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ReadRecvByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadRecvByte(InstancePtr) \
|
||||
{ \
|
||||
*InstancePtr->RecvBufferPtr++ = \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, XIIC_DRR_REG_OFFSET); \
|
||||
InstancePtr->RecvByteCount--; \
|
||||
InstancePtr->Stats.RecvBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro writes the next byte to be sent to the transmit FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_WriteSendByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteSendByte(InstancePtr) \
|
||||
{ \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
*InstancePtr->SendBufferPtr++); \
|
||||
InstancePtr->SendByteCount--; \
|
||||
InstancePtr->Stats.SendBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sets up the control register for a master receive operation.
|
||||
* A write is necessary if a 10 bit operation is being performed.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
* @param ControlRegister contains the contents of the IIC device control
|
||||
* register
|
||||
* @param ByteCount contains the number of bytes to be received for the
|
||||
* master receive operation
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_SetControlRegister(XIic *InstancePtr,
|
||||
* u8 ControlRegister,
|
||||
* int ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_SetControlRegister(InstancePtr, ControlRegister, ByteCount) \
|
||||
{ \
|
||||
(ControlRegister) &= ~(XIIC_CR_NO_ACK_MASK | XIIC_CR_DIR_IS_TX_MASK); \
|
||||
if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) { \
|
||||
(ControlRegister) |= XIIC_CR_DIR_IS_TX_MASK; \
|
||||
} else { \
|
||||
if ((ByteCount) == 1) \
|
||||
{ \
|
||||
(ControlRegister) |= XIIC_CR_NO_ACK_MASK; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
extern XIic_Config XIic_ConfigTable[];
|
||||
|
||||
/* The following variables are shared across files of the driver and
|
||||
* are function pointers that are necessary to break dependencies allowing
|
||||
* optional parts of the driver to be used without condition compilation
|
||||
*/
|
||||
extern void (*XIic_AddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_NotAddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_ArbLostFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_BusNotBusyFuncPtr) (XIic *InstancePtr);
|
||||
|
||||
void XIic_TransmitFifoFill(XIic *InstancePtr, int Role);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,571 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_l.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and driver functions (or
|
||||
* macros) that can be used to access the device in normal and dynamic
|
||||
* controller mode. High-level driver functions are defined in xiic.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 05/07/02 First release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 04/04/06 Implemented Dynamic IIC core routines.
|
||||
* 1.03a rpm 09/08/06 Added include of xstatus.h for completeness
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.16a ktn 07/18/09 Updated the notes in XIIC_RESET macro to clearly indicate
|
||||
* that only the Interrupt Registers are reset.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIIC_RESET macro to mention
|
||||
* that the complete IIC core is Reset on giving a software
|
||||
* reset to the IIC core. Some previous versions of the
|
||||
* core only reset the Interrupt Logic/Registers, please
|
||||
* refer to the HW specification for further details.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access,
|
||||
* the register offsets are defined to be on 32 bit boundary.
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Some of the macros have been renamed to be consistent -
|
||||
* XIIC_GINTR_DISABLE is renamed as XIic_IntrGlobalDisable,
|
||||
* XIIC_GINTR_ENABLE is renamed as XIic_IntrGlobalEnable,
|
||||
* XIIC_IS_GINTR_ENABLED is renamed as
|
||||
* XIic_IsIntrGlobalEnabled,
|
||||
* XIIC_WRITE_IISR is renamed as XIic_WriteIisr,
|
||||
* XIIC_READ_IISR is renamed as XIic_ReadIisr,
|
||||
* XIIC_WRITE_IIER is renamed as XIic_WriteIier
|
||||
* The _m prefix in the name of the macros has been removed -
|
||||
* XIic_mClearIisr is now XIic_ClearIisr,
|
||||
* XIic_mSend7BitAddress is now XIic_Send7BitAddress,
|
||||
* XIic_mDynSend7BitAddress is now XIic_DynSend7BitAddress,
|
||||
* XIic_mDynSendStartStopAddress is now
|
||||
* XIic_DynSendStartStopAddress,
|
||||
* XIic_mDynSendStop is now XIic_DynSendStop.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototypes of XIic_Recv, XIic_Send,
|
||||
* XIic_DynRecv, XIic_DynSend and XIic_DynInit APIs.
|
||||
* 3.3 als 06/27/16 Added Low-level XIic_CheckIsBusBusy API.
|
||||
* 3.3 als 06/27/16 Added low-level XIic_WaitBusFree API.
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef XIIC_L_H /* prevent circular inclusions */
|
||||
#define XIIC_L_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
/** @name Register Map
|
||||
*
|
||||
* Register offsets for the XIic device.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_DGIER_OFFSET 0x1C /**< Global Interrupt Enable Register */
|
||||
#define XIIC_IISR_OFFSET 0x20 /**< Interrupt Status Register */
|
||||
#define XIIC_IIER_OFFSET 0x28 /**< Interrupt Enable Register */
|
||||
#define XIIC_RESETR_OFFSET 0x40 /**< Reset Register */
|
||||
#define XIIC_CR_REG_OFFSET 0x100 /**< Control Register */
|
||||
#define XIIC_SR_REG_OFFSET 0x104 /**< Status Register */
|
||||
#define XIIC_DTR_REG_OFFSET 0x108 /**< Data Tx Register */
|
||||
#define XIIC_DRR_REG_OFFSET 0x10C /**< Data Rx Register */
|
||||
#define XIIC_ADR_REG_OFFSET 0x110 /**< Address Register */
|
||||
#define XIIC_TFO_REG_OFFSET 0x114 /**< Tx FIFO Occupancy */
|
||||
#define XIIC_RFO_REG_OFFSET 0x118 /**< Rx FIFO Occupancy */
|
||||
#define XIIC_TBA_REG_OFFSET 0x11C /**< 10 Bit Address reg */
|
||||
#define XIIC_RFD_REG_OFFSET 0x120 /**< Rx FIFO Depth reg */
|
||||
#define XIIC_GPO_REG_OFFSET 0x124 /**< Output Register */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Device Global Interrupt Enable Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_GINTR_ENABLE_MASK 0x80000000 /**< Global Interrupt Enable Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Device Interrupt Status/Enable (INTR) Register Masks
|
||||
*
|
||||
* <b> Interrupt Status Register (IISR) </b>
|
||||
*
|
||||
* This register holds the interrupt status flags for the Spi device.
|
||||
*
|
||||
* <b> Interrupt Enable Register (IIER) </b>
|
||||
*
|
||||
* This register is used to enable interrupt sources for the IIC device.
|
||||
* Writing a '1' to a bit in this register enables the corresponding Interrupt.
|
||||
* Writing a '0' to a bit in this register disables the corresponding Interrupt.
|
||||
*
|
||||
* IISR/IIER registers have the same bit definitions and are only defined once.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_INTR_ARB_LOST_MASK 0x00000001 /**< 1 = Arbitration lost */
|
||||
#define XIIC_INTR_TX_ERROR_MASK 0x00000002 /**< 1 = Tx error/msg complete */
|
||||
#define XIIC_INTR_TX_EMPTY_MASK 0x00000004 /**< 1 = Tx FIFO/reg empty */
|
||||
#define XIIC_INTR_RX_FULL_MASK 0x00000008 /**< 1 = Rx FIFO/reg=OCY level */
|
||||
#define XIIC_INTR_BNB_MASK 0x00000010 /**< 1 = Bus not busy */
|
||||
#define XIIC_INTR_AAS_MASK 0x00000020 /**< 1 = When addr as slave */
|
||||
#define XIIC_INTR_NAAS_MASK 0x00000040 /**< 1 = Not addr as slave */
|
||||
#define XIIC_INTR_TX_HALF_MASK 0x00000080 /**< 1 = Tx FIFO half empty */
|
||||
|
||||
/**
|
||||
* All Tx interrupts commonly used.
|
||||
*/
|
||||
#define XIIC_TX_INTERRUPTS (XIIC_INTR_TX_ERROR_MASK | \
|
||||
XIIC_INTR_TX_EMPTY_MASK | \
|
||||
XIIC_INTR_TX_HALF_MASK)
|
||||
|
||||
/**
|
||||
* All interrupts commonly used
|
||||
*/
|
||||
#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
|
||||
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Reset Register mask
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_RESET_MASK 0x0000000A /**< RESET Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Control Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_CR_ENABLE_DEVICE_MASK 0x00000001 /**< Device enable = 1 */
|
||||
#define XIIC_CR_TX_FIFO_RESET_MASK 0x00000002 /**< Transmit FIFO reset=1 */
|
||||
#define XIIC_CR_MSMS_MASK 0x00000004 /**< Master starts Txing=1 */
|
||||
#define XIIC_CR_DIR_IS_TX_MASK 0x00000008 /**< Dir of Tx. Txing=1 */
|
||||
#define XIIC_CR_NO_ACK_MASK 0x00000010 /**< Tx Ack. NO ack = 1 */
|
||||
#define XIIC_CR_REPEATED_START_MASK 0x00000020 /**< Repeated start = 1 */
|
||||
#define XIIC_CR_GENERAL_CALL_MASK 0x00000040 /**< Gen Call enabled = 1 */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Status Register masks (SR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_SR_GEN_CALL_MASK 0x00000001 /**< 1 = A Master issued
|
||||
* a GC */
|
||||
#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x00000002 /**< 1 = When addressed as
|
||||
* slave */
|
||||
#define XIIC_SR_BUS_BUSY_MASK 0x00000004 /**< 1 = Bus is busy */
|
||||
#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x00000008 /**< 1 = Dir: Master <--
|
||||
* slave */
|
||||
#define XIIC_SR_TX_FIFO_FULL_MASK 0x00000010 /**< 1 = Tx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_FULL_MASK 0x00000020 /**< 1 = Rx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x00000040 /**< 1 = Rx FIFO empty */
|
||||
#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x00000080 /**< 1 = Tx FIFO empty */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Tx Register (DTR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_TX_DYN_START_MASK 0x00000100 /**< 1 = Set dynamic start */
|
||||
#define XIIC_TX_DYN_STOP_MASK 0x00000200 /**< 1 = Set dynamic stop */
|
||||
#define IIC_TX_FIFO_DEPTH 16 /**< Tx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Rx Register (DRR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define IIC_RX_FIFO_DEPTH 16 /**< Rx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
|
||||
#define XIIC_TX_ADDR_SENT 0x00
|
||||
#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02
|
||||
|
||||
|
||||
/**
|
||||
* The following constants are used to specify whether to do
|
||||
* Read or a Write operation on IIC bus.
|
||||
*/
|
||||
#define XIIC_READ_OPERATION 1 /**< Read operation on the IIC bus */
|
||||
#define XIIC_WRITE_OPERATION 0 /**< Write operation on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with the transmit FIFO fill function to
|
||||
* specify the role which the IIC device is acting as, a master or a slave.
|
||||
*/
|
||||
#define XIIC_MASTER_ROLE 1 /**< Master on the IIC bus */
|
||||
#define XIIC_SLAVE_ROLE 0 /**< Slave on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with Transmit Function (XIic_Send) to
|
||||
* specify whether to STOP after the current transfer of data or own the bus
|
||||
* with a Repeated start.
|
||||
*/
|
||||
#define XIIC_STOP 0x00 /**< Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
#define XIIC_REPEATED_START 0x01 /**< Donot Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define XIic_In32 Xil_In32
|
||||
#define XIic_Out32 Xil_Out32
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read from the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the device to
|
||||
* select the specific register.
|
||||
*
|
||||
* @return The value read from the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadReg(u32 BaseAddress, u32 RegOffset);
|
||||
*
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadReg(BaseAddress, RegOffset) \
|
||||
XIic_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write to the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the
|
||||
* device to select the specific register.
|
||||
* @param RegisterValue is the value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteReg(u32 BaseAddress, u32 RegOffset,
|
||||
* u32 RegisterValue);
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
XIic_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro disables all interrupts for the device by writing to the Global
|
||||
* interrupt enable register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalDisable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalDisable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, 0)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro writes to the global interrupt enable register to enable
|
||||
* interrupts from the device. This function does not enable individual
|
||||
* interrupts as the Interrupt Enable Register must be set appropriately.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalEnable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalEnable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function determines if interrupts are enabled at the global level by
|
||||
* reading the global interrupt register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the global interrupt is enabled.
|
||||
* - FALSE if global interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* int XIic_IsIntrGlobalEnabled(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IsIntrGlobalEnabled(BaseAddress) \
|
||||
(XIic_ReadReg((BaseAddress), XIIC_DGIER_OFFSET) == \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the Interrupt status register to the specified value.
|
||||
*
|
||||
* This register implements a toggle on write functionality. The interrupt is
|
||||
* cleared by writing to this register with the bits to be cleared set to a one
|
||||
* and all others to zero. Setting a bit which is zero within this register
|
||||
* causes an interrupt to be generated.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some status bits may be set and others cleared. It is the caller's
|
||||
* responsibility to get the value of the register prior to setting the value
|
||||
* to prevent an destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Status is the value to be written to the Interrupt
|
||||
* status register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIisr(u32 BaseAddress, u32 Status);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIisr(BaseAddress, Status) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IISR_OFFSET, (Status))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the contents of the Interrupt Status Register.
|
||||
* This register indicates the status of interrupt sources for the device.
|
||||
* The status is independent of whether interrupts are enabled such
|
||||
* that the status register may also be polled when interrupts are not enabled.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The value read from the Interrupt Status Register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIisr(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIisr(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IISR_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the contents of the Interrupt Enable Register.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some interrupt sources may be enabled and others disabled. It is the
|
||||
* caller's responsibility to get the value of the interrupt enable register
|
||||
* prior to setting the value to prevent a destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Enable is the value to be written to the Interrupt Enable
|
||||
* Register. Bit positions of 1 will be enabled. Bit positions of 0
|
||||
* will be disabled.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIier(u32 BaseAddress, u32 Enable);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIier(BaseAddress, Enable) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IIER_OFFSET, (Enable))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This function gets the Interrupt Enable Register contents.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The contents read from the Interrupt Enable Register.
|
||||
* Bit positions of 1 indicate that the corresponding interrupt
|
||||
* is enabled. Bit positions of 0 indicate that the corresponding
|
||||
* interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIier(u32 BaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIier(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IIER_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask is the bit mask of the interrupts to be cleared.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_ClearIisr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIisr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_Send7BitAddress(u32 BaseAddress, u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers for Dynamic
|
||||
* controller functionality.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSend7BitAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSend7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address, start and stop for a 7 bit address during both
|
||||
* write operations. It takes care of the details to format the address
|
||||
* correctly. This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStartStopAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStartStopAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | XIIC_TX_DYN_STOP_MASK | \
|
||||
LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends a stop condition on IIC bus for Dynamic logic.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param ByteCount is the number of Rx bytes received before the master.
|
||||
* doesn't respond with ACK.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStop(u32 BaseAddress, u32 ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStop(BaseAddress, ByteCount) \
|
||||
{ \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_STOP_MASK | ByteCount); \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_Send(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_DynRecv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, u8 ByteCount);
|
||||
|
||||
unsigned XIic_DynSend(UINTPTR BaseAddress, u16 Address, u8 *BufferPtr,
|
||||
u8 ByteCount, u8 Option);
|
||||
|
||||
int XIic_DynInit(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_WaitBusFree(UINTPTR BaseAddress);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -2,14 +2,14 @@
|
||||
#define XPARAMETERS_H /* by using protection macros */
|
||||
|
||||
/* Definitions for bus frequencies */
|
||||
#define XPAR_CPU_M_AXI_DP_FREQ_HZ 150000000
|
||||
#define XPAR_CPU_M_AXI_DP_FREQ_HZ 125000000
|
||||
/******************************************************************/
|
||||
|
||||
/* Canonical definitions for bus frequencies */
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_CPU_CORE_CLOCK_FREQ_HZ 150000000
|
||||
#define XPAR_MICROBLAZE_CORE_CLOCK_FREQ_HZ 150000000
|
||||
#define XPAR_CPU_CORE_CLOCK_FREQ_HZ 125000000
|
||||
#define XPAR_MICROBLAZE_CORE_CLOCK_FREQ_HZ 125000000
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#define XPAR_MICROBLAZE_0_ENDIANNESS 1
|
||||
#define XPAR_MICROBLAZE_0_FAULT_TOLERANT 0
|
||||
#define XPAR_MICROBLAZE_0_FPU_EXCEPTION 1
|
||||
#define XPAR_MICROBLAZE_0_FREQ 150000000
|
||||
#define XPAR_MICROBLAZE_0_FREQ 125000000
|
||||
#define XPAR_MICROBLAZE_0_FSL_EXCEPTION 0
|
||||
#define XPAR_MICROBLAZE_0_FSL_LINKS 0
|
||||
#define XPAR_MICROBLAZE_0_IADDR_SIZE 32
|
||||
@@ -288,7 +288,7 @@
|
||||
#define XPAR_MICROBLAZE_ENDIANNESS 1
|
||||
#define XPAR_MICROBLAZE_FAULT_TOLERANT 0
|
||||
#define XPAR_MICROBLAZE_FPU_EXCEPTION 1
|
||||
#define XPAR_MICROBLAZE_FREQ 150000000
|
||||
#define XPAR_MICROBLAZE_FREQ 125000000
|
||||
#define XPAR_MICROBLAZE_FSL_EXCEPTION 0
|
||||
#define XPAR_MICROBLAZE_FSL_LINKS 0
|
||||
#define XPAR_MICROBLAZE_IADDR_SIZE 32
|
||||
@@ -913,7 +913,30 @@
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13
|
||||
/* Definitions for driver IIC */
|
||||
#define XPAR_XIIC_NUM_INSTANCES 1
|
||||
|
||||
/* Definitions for peripheral AXI_IIC_0 */
|
||||
#define XPAR_AXI_IIC_0_DEVICE_ID 0
|
||||
#define XPAR_AXI_IIC_0_BASEADDR 0x40110000
|
||||
#define XPAR_AXI_IIC_0_HIGHADDR 0x4011FFFF
|
||||
#define XPAR_AXI_IIC_0_TEN_BIT_ADR 0
|
||||
#define XPAR_AXI_IIC_0_GPO_WIDTH 1
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
/* Canonical definitions for peripheral AXI_IIC_0 */
|
||||
#define XPAR_IIC_0_DEVICE_ID XPAR_AXI_IIC_0_DEVICE_ID
|
||||
#define XPAR_IIC_0_BASEADDR 0x40110000
|
||||
#define XPAR_IIC_0_HIGHADDR 0x4011FFFF
|
||||
#define XPAR_IIC_0_TEN_BIT_ADR 0
|
||||
#define XPAR_IIC_0_GPO_WIDTH 1
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_INTC_MAX_NUM_INTR_INPUTS 14
|
||||
#define XPAR_XINTC_HAS_IPR 1
|
||||
#define XPAR_XINTC_HAS_SIE 1
|
||||
#define XPAR_XINTC_HAS_CIE 1
|
||||
@@ -925,10 +948,10 @@
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_DEVICE_ID 0
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_BASEADDR 0x40010000
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_HIGHADDR 0x4001FFFF
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_KIND_OF_INTR 0xFFFFFBC9
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_KIND_OF_INTR 0xFFFFDBC9
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_HAS_FAST 1
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_IVAR_RESET_VALUE 0x0000000000000010
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_NUM_INTR_INPUTS 13
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_NUM_INTR_INPUTS 14
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_NUM_SW_INTR 0
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_ADDR_WIDTH 32
|
||||
|
||||
@@ -965,6 +988,8 @@
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_QSPI_FLASH_IP2INTC_IRPT_INTR 11U
|
||||
#define XPAR_SYSTEM_PPS_MASK 0X001000U
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_SYSTEM_PPS_INTR 12U
|
||||
#define XPAR_AXI_IIC_0_IIC2INTC_IRPT_MASK 0X002000U
|
||||
#define XPAR_MICROBLAZE_0_AXI_INTC_AXI_IIC_0_IIC2INTC_IRPT_INTR 13U
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -972,10 +997,10 @@
|
||||
#define XPAR_INTC_0_DEVICE_ID XPAR_MICROBLAZE_0_AXI_INTC_DEVICE_ID
|
||||
#define XPAR_INTC_0_BASEADDR 0x40010000U
|
||||
#define XPAR_INTC_0_HIGHADDR 0x4001FFFFU
|
||||
#define XPAR_INTC_0_KIND_OF_INTR 0xFFFFFBC9U
|
||||
#define XPAR_INTC_0_KIND_OF_INTR 0xFFFFDBC9U
|
||||
#define XPAR_INTC_0_HAS_FAST 1U
|
||||
#define XPAR_INTC_0_IVAR_RESET_VALUE 0x0000000000000010U
|
||||
#define XPAR_INTC_0_NUM_INTR_INPUTS 13U
|
||||
#define XPAR_INTC_0_NUM_INTR_INPUTS 14U
|
||||
#define XPAR_INTC_0_NUM_SW_INTR 0U
|
||||
#define XPAR_INTC_0_ADDR_WIDTH 32U
|
||||
#define XPAR_INTC_0_INTC_TYPE 0U
|
||||
@@ -990,6 +1015,7 @@
|
||||
#define XPAR_INTC_0_SPI_1_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_QUAD_SPI_1_IP2INTC_IRPT_INTR
|
||||
#define XPAR_INTC_0_LLFIFO_0_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_FIFO_MM_S_0_INTERRUPT_INTR
|
||||
#define XPAR_INTC_0_SPI_2_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_QSPI_FLASH_IP2INTC_IRPT_INTR
|
||||
#define XPAR_INTC_0_IIC_0_VEC_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_IIC_0_IIC2INTC_IRPT_INTR
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -1165,7 +1191,7 @@
|
||||
#define XPAR_AXI_TIMER_0_DEVICE_ID 0U
|
||||
#define XPAR_AXI_TIMER_0_BASEADDR 0x40030000U
|
||||
#define XPAR_AXI_TIMER_0_HIGHADDR 0x4003FFFFU
|
||||
#define XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ 150000000U
|
||||
#define XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ 125000000U
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
@@ -1179,7 +1205,7 @@
|
||||
/******************************************************************/
|
||||
|
||||
/* Definitions for driver UARTLITE */
|
||||
#define XPAR_XUARTLITE_NUM_INSTANCES 1U
|
||||
#define XPAR_XUARTLITE_NUM_INSTANCES 2U
|
||||
|
||||
/* Definitions for peripheral AXI_UARTLITE_0 */
|
||||
#define XPAR_AXI_UARTLITE_0_DEVICE_ID 0U
|
||||
@@ -1200,5 +1226,25 @@
|
||||
#define XPAR_UARTLITE_0_DATA_BITS 8U
|
||||
|
||||
|
||||
|
||||
/* Definitions for peripheral MDM_1 */
|
||||
#define XPAR_MDM_1_DEVICE_ID 1U
|
||||
#define XPAR_MDM_1_BASEADDR 0x41400000U
|
||||
#define XPAR_MDM_1_HIGHADDR 0x41400FFFU
|
||||
#define XPAR_MDM_1_BAUDRATE 0U
|
||||
#define XPAR_MDM_1_USE_PARITY 0U
|
||||
#define XPAR_MDM_1_ODD_PARITY 0U
|
||||
#define XPAR_MDM_1_DATA_BITS 0U
|
||||
|
||||
/* Canonical definitions for peripheral MDM_1 */
|
||||
#define XPAR_UARTLITE_1_DEVICE_ID 1U
|
||||
#define XPAR_UARTLITE_1_BASEADDR 0x41400000U
|
||||
#define XPAR_UARTLITE_1_HIGHADDR 0x41400FFFU
|
||||
#define XPAR_UARTLITE_1_BAUDRATE 0U
|
||||
#define XPAR_UARTLITE_1_USE_PARITY 0U
|
||||
#define XPAR_UARTLITE_1_ODD_PARITY 0U
|
||||
#define XPAR_UARTLITE_1_DATA_BITS 0U
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
#endif /* end of protection macro */
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,39 @@
|
||||
DRIVER_LIB_VERSION = 1.0
|
||||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
|
||||
CC_FLAGS = $(COMPILER_FLAGS)
|
||||
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
|
||||
|
||||
RELEASEDIR=../../../lib/
|
||||
INCLUDEDIR=../../../include/
|
||||
INCLUDES=-I./. -I$(INCLUDEDIR)
|
||||
|
||||
SRCFILES:=$(wildcard *.c)
|
||||
|
||||
OBJECTS = $(addprefix $(RELEASEDIR), $(addsuffix .o, $(basename $(wildcard *.c))))
|
||||
|
||||
libs: $(OBJECTS)
|
||||
|
||||
DEPFILES := $(SRCFILES:%.c=$(RELEASEDIR)%.d)
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
|
||||
include $(wildcard ../../../../dep.mk)
|
||||
|
||||
$(RELEASEDIR)%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) $(DEPENDENCY_FLAGS) $< -o $@
|
||||
|
||||
.PHONY: include
|
||||
include: $(addprefix $(INCLUDEDIR),$(wildcard *.h))
|
||||
|
||||
$(INCLUDEDIR)%.h: %.h
|
||||
$(CP) $< $@
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
||||
rm -rf $(DEPFILES)
|
||||
@@ -0,0 +1,722 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains required functions for the XIic component. See xiic.h for more
|
||||
* information on the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01c rmm 05/14/03 Fixed diab compiler warnings relating to asserts.
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.02a jvb 12/13/05 Added CfgInitialize(), and made CfgInitialize() take
|
||||
* a pointer to a config structure instead of a device id.
|
||||
* Moved Initialize() into xiic_sinit.c, and have
|
||||
* Initialize() call CfgInitialize() after it retrieved the
|
||||
* config structure using the device id. Removed include of
|
||||
* xparameters.h along with any dependencies on xparameters.h
|
||||
* and the _g.c config table.
|
||||
* 1.02a mta 03/09/06 Added a new function XIic_IsIicBusy() which returns
|
||||
* whether IIC Bus is Busy or Free.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.15a ktn 02/17/09 Fixed XIic_GetAddress() to return correct device address.
|
||||
* 1.16a ktn 07/18/09 Updated the notes in XIic_Reset function to clearly
|
||||
* indicate that only the Interrupt Registers are reset.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIic_SelfTest() API to mention
|
||||
* that the complete IIC core is Reset on giving a software
|
||||
* reset to the IIC core. This issue is fixed in the latest
|
||||
* version of the IIC core (some previous versions of the
|
||||
* core only reset the Interrupt Logic/Registers), please
|
||||
* see the Hw specification for further information.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name see the xiic_i.h and xiic_l.h file for further
|
||||
* information (Example XIic_mClearIntr is now
|
||||
* XIic_ClearIntr).
|
||||
* Some of the macros have been renamed to be consistent,
|
||||
* see the xiic_l.h file for further information
|
||||
* (Example XIIC_WRITE_IIER is renamed as XIic_WriteIier).
|
||||
* The driver has been updated to use the HAL APIs/macros.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* Changes done if files xiic.c and xiic_i.h. CR:705001.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XIic_CfgInitialize API.
|
||||
* 3.3 als 06/27/16 XIic_IsIicBusy now static inline in xiic.h.
|
||||
* 3.8 rna 11/30/20 Corrected the order of Assert in XIic_SetRecvHandler.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void XIic_StubStatusHandler(void *CallBackRef, int ErrorCode);
|
||||
|
||||
static void XIic_StubHandler(void *CallBackRef, int ByteCount);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initializes a specific XIic instance. The initialization entails:
|
||||
*
|
||||
* - Initialize the driver to allow access to the device registers and
|
||||
* initialize other subcomponents necessary for the operation of the device.
|
||||
* - Default options to:
|
||||
* - 7-bit slave addressing
|
||||
* - Send messages as a slave device
|
||||
* - Repeated start off
|
||||
* - General call recognition disabled
|
||||
* - Clear messageing and error statistics
|
||||
*
|
||||
* The XIic_Start() function must be called after this function before the device
|
||||
* is ready to send and receive data on the IIC bus.
|
||||
*
|
||||
* Before XIic_Start() is called, the interrupt control must connect the ISR
|
||||
* routine to the interrupt handler. This is done by the user, and not
|
||||
* XIic_Start() to allow the user to use an interrupt controller of their choice.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param Config is a reference to a structure containing information
|
||||
* about a specific IIC device. This function can initialize
|
||||
* multiple instance objects with the use of multiple calls giving
|
||||
* different Config information on each call.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory
|
||||
* address space. The caller is responsible for keeping the
|
||||
* address mapping from EffectiveAddr to the device physical base
|
||||
* address unchanged once this function is invoked. Unexpected
|
||||
* errors may occur if the address mapping changes after this
|
||||
* function is called. If address translation is not used, use
|
||||
* Config->BaseAddress for this parameters, passing the physical
|
||||
* address instead.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS when successful
|
||||
* - XST_DEVICE_IS_STARTED indicates the device is started
|
||||
* (i.e. interrupts enabled and messaging is possible). Must stop
|
||||
* before re-initialization is allowed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_CfgInitialize(XIic *InstancePtr, XIic_Config * Config,
|
||||
UINTPTR EffectiveAddr)
|
||||
{
|
||||
/*
|
||||
* Asserts test the validity of selected input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
InstancePtr->IsReady = 0;
|
||||
|
||||
/*
|
||||
* If the device is started, disallow the initialize and return a Status
|
||||
* indicating it is started. This allows the user to stop the device
|
||||
* and reinitialize, but prevents a user from inadvertently
|
||||
* initializing.
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set default values and configuration data, including setting the
|
||||
* callback handlers to stubs so the system will not crash should the
|
||||
* application not assign its own callbacks.
|
||||
*/
|
||||
InstancePtr->IsStarted = 0;
|
||||
InstancePtr->BaseAddress = EffectiveAddr;
|
||||
InstancePtr->RecvHandler = XIic_StubHandler;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
InstancePtr->SendHandler = XIic_StubHandler;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
InstancePtr->StatusHandler = XIic_StubStatusHandler;
|
||||
InstancePtr->Has10BitAddr = Config->Has10BitAddr;
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
InstancePtr->Options = 0;
|
||||
InstancePtr->BNBOnly = FALSE;
|
||||
InstancePtr->GpOutWidth = Config->GpOutWidth;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
InstancePtr->IsSlaveSetAckOff = FALSE;
|
||||
|
||||
/*
|
||||
* Reset the device.
|
||||
*/
|
||||
XIic_Reset(InstancePtr);
|
||||
|
||||
XIic_ClearStats(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function starts the IIC device and driver by enabling the proper
|
||||
* interrupts such that data may be sent and received on the IIC bus.
|
||||
* This function must be called before the functions to send and receive data.
|
||||
*
|
||||
* Before XIic_Start() is called, the interrupt control must connect the ISR
|
||||
* routine to the interrupt handler. This is done by the user, and not
|
||||
* XIic_Start() to allow the user to use an interrupt controller of their choice.
|
||||
*
|
||||
* Start enables:
|
||||
* - IIC device
|
||||
* - Interrupts:
|
||||
* - Addressed as slave to allow messages from another master
|
||||
* - Arbitration Lost to detect Tx arbitration errors
|
||||
* - Global IIC interrupt
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return XST_SUCCESS always.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The device interrupt is connected to the interrupt controller, but no
|
||||
* "messaging" interrupts are enabled. Addressed as Slave is enabled to
|
||||
* reception of messages when this devices address is written to the bus.
|
||||
* The correct messaging interrupts are enabled when sending or receiving
|
||||
* via the IicSend() and IicRecv() functions. No action is required
|
||||
* by the user to control any IIC interrupts as the driver completely
|
||||
* manages all 8 interrupts. Start and Stop control the ability
|
||||
* to use the device. Stopping the device completely stops all device
|
||||
* interrupts from the processor.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_Start(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Mask off all interrupts, each is enabled when needed.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress, 0);
|
||||
|
||||
/*
|
||||
* Clear all interrupts by reading and rewriting exact value back.
|
||||
* Only those bits set will get written as 1 (writing 1 clears intr).
|
||||
*/
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress, 0xFFFFFFFF);
|
||||
|
||||
/*
|
||||
* Enable the device.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
XIIC_CR_ENABLE_DEVICE_MASK);
|
||||
/*
|
||||
* Set Rx FIFO Occupancy depth to throttle at
|
||||
* first byte(after reset = 0).
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Clear and enable the interrupts needed.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
|
||||
|
||||
InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
|
||||
/*
|
||||
* Enable the Global interrupt enable.
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function stops the IIC device and driver such that data is no longer
|
||||
* sent or received on the IIC bus. This function stops the device by
|
||||
* disabling interrupts. This function only disables interrupts within the
|
||||
* device such that the caller is responsible for disconnecting the interrupt
|
||||
* handler of the device from the interrupt source and disabling interrupts
|
||||
* at other levels.
|
||||
*
|
||||
* Due to bus throttling that could hold the bus between messages when using
|
||||
* repeated start option, stop will not occur when the device is actively
|
||||
* sending or receiving data from the IIC bus or the bus is being throttled
|
||||
* by this device, but instead return XST_IIC_BUS_BUSY.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates all IIC interrupts are disabled.
|
||||
* No messages can be received or transmitted until XIic_Start()
|
||||
* is called.
|
||||
* - XST_IIC_BUS_BUSY indicates this device is currently engaged
|
||||
* in message traffic and cannot be stopped.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_Stop(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 CntlReg;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Disable all interrupts globally.
|
||||
*/
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
if ((CntlReg & XIIC_CR_MSMS_MASK) ||
|
||||
(Status & XIIC_SR_ADDR_AS_SLAVE_MASK)) {
|
||||
/*
|
||||
* When this device is using the bus
|
||||
* - re-enable interrupts to finish current messaging
|
||||
* - return bus busy
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
InstancePtr->IsStarted = 0;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Resets the IIC device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The complete IIC core is Reset on giving a software reset to
|
||||
* the IIC core. Some previous versions of the core only reset
|
||||
* the Interrupt Logic/Registers, please refer to the HW specification
|
||||
* for further details about this.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_Reset(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RESETR_OFFSET,
|
||||
XIIC_RESET_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the bus addresses. The addresses include the device
|
||||
* address that the device responds to as a slave, or the slave address
|
||||
* to communicate with on the bus. The IIC device hardware is built to
|
||||
* allow either 7 or 10 bit slave addressing only at build time rather
|
||||
* than at run time. When this device is a master, slave addressing can
|
||||
* be selected at run time to match addressing modes for other bus devices.
|
||||
*
|
||||
* Addresses are represented as hex values with no adjustment for the data
|
||||
* direction bit as the software manages address bit placement.
|
||||
* Example: For a 7 address written to the device of 1010 011X where X is
|
||||
* the transfer direction (send/recv), the address parameter for this function
|
||||
* needs to be 01010011 or 0x53 where the correct bit alllignment will be
|
||||
* handled for 7 as well as 10 bit devices. This is especially important as
|
||||
* the bit placement is not handled the same depending on which options are
|
||||
* used such as repeated start.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param AddressType indicates which address is being modified, the
|
||||
* address which this device responds to on the IIC bus as a slave,
|
||||
* or the slave address to communicate with when this device is a
|
||||
* master. One of the following values must be contained in
|
||||
* this argument.
|
||||
* <pre>
|
||||
* XII_ADDR_TO_SEND_TYPE Slave being addressed by a this master
|
||||
* XII_ADDR_TO_RESPOND_TYPE Address to respond to as a slave device
|
||||
* </pre>
|
||||
*
|
||||
* @param Address contains the address to be set, 7 bit or 10 bit address.
|
||||
* A ten bit address must be within the range: 0 - 1023 and a 7 bit
|
||||
* address must be within the range 0 - 127.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS is returned if the address was successfully set.
|
||||
* - XST_IIC_NO_10_BIT_ADDRESSING indicates only 7 bit addressing
|
||||
* supported.
|
||||
* - XST_INVALID_PARAM indicates an invalid parameter was
|
||||
* specified.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Upper bits of 10-bit address is written only when current device is built
|
||||
* as a ten bit device.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_SetAddress(XIic *InstancePtr, int AddressType, int Address)
|
||||
{
|
||||
u32 SendAddr;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address < 1023);
|
||||
|
||||
/*
|
||||
* Set address to respond to for this device into address registers.
|
||||
*/
|
||||
if (AddressType == XII_ADDR_TO_RESPOND_TYPE) {
|
||||
/*
|
||||
* Address in upper 7 bits.
|
||||
*/
|
||||
SendAddr = ((Address & 0x007F) << 1);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_ADR_REG_OFFSET,
|
||||
SendAddr);
|
||||
|
||||
if (InstancePtr->Has10BitAddr == TRUE) {
|
||||
/*
|
||||
* Write upper 3 bits of addr to DTR only when 10 bit
|
||||
* option included in design i.e. register exists.
|
||||
*/
|
||||
SendAddr = ((Address & 0x0380) >> 7);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_TBA_REG_OFFSET, SendAddr);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store address of slave device being read from.
|
||||
*/
|
||||
if (AddressType == XII_ADDR_TO_SEND_TYPE) {
|
||||
InstancePtr->AddrOfSlave = Address;
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
return XST_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the addresses for the IIC device driver. The addresses
|
||||
* include the device address that the device responds to as a slave, or the
|
||||
* slave address to communicate with on the bus. The address returned has the
|
||||
* same format whether 7 or 10 bits.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param AddressType indicates which address, the address which this
|
||||
* responds to on the IIC bus as a slave, or the slave address to
|
||||
* communicate with when this device is a master. One of the
|
||||
* following values must be contained in this argument.
|
||||
* <pre>
|
||||
* XII_ADDR_TO_SEND_TYPE Slave being addressed as a master
|
||||
* XII_ADDR_TO_RESPOND_TYPE Slave address to respond to as a slave
|
||||
* </pre>
|
||||
* If neither of the two valid arguments are used, the function returns
|
||||
* the address of the slave device
|
||||
*
|
||||
* @return The address retrieved.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u16 XIic_GetAddress(XIic *InstancePtr, int AddressType)
|
||||
{
|
||||
u8 LowAddr;
|
||||
u16 HighAddr = 0;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Return this device's address.
|
||||
*/
|
||||
if (AddressType == XII_ADDR_TO_RESPOND_TYPE) {
|
||||
|
||||
LowAddr = (u8) XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_ADR_REG_OFFSET);
|
||||
|
||||
if (InstancePtr->Has10BitAddr == TRUE) {
|
||||
HighAddr = (u16) XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_TBA_REG_OFFSET);
|
||||
}
|
||||
return ((HighAddr << 8) | (u16) LowAddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise return address of slave device on the IIC bus.
|
||||
*/
|
||||
return InstancePtr->AddrOfSlave;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the contents of the General Purpose Output register
|
||||
* for the IIC device driver. Note that the number of bits in this register is
|
||||
* parameterizable in the hardware such that it may not exist. This function
|
||||
* checks to ensure that it does exist to prevent bus errors, but does not
|
||||
* ensure that the number of bits in the register are sufficient for the
|
||||
* value being written (won't cause a bus error).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param OutputValue contains the value to be written to the register.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the given data is written to the GPO register.
|
||||
* - XST_NO_FEATURE if the hardware is configured such that this
|
||||
* register does not contain any bits to read or write.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_SetGpOutput(XIic *InstancePtr, u8 OutputValue)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* If the general purpose output register is implemented by the hardware
|
||||
* then write the specified value to it, otherwise indicate an error.
|
||||
*/
|
||||
if (InstancePtr->GpOutWidth > 0) {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_GPO_REG_OFFSET,
|
||||
OutputValue);
|
||||
return XST_SUCCESS;
|
||||
} else {
|
||||
return XST_NO_FEATURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the contents of the General Purpose Output register
|
||||
* for the IIC device driver. Note that the number of bits in this register is
|
||||
* parameterizable in the hardware such that it may not exist. This function
|
||||
* checks to ensure that it does exist to prevent bus errors.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param OutputValuePtr contains the value which was read from the
|
||||
* register.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the given data is read from the GPO register.
|
||||
* - XST_NO_FEATURE if the hardware is configured such that this
|
||||
* register does not contain any bits to read or write.
|
||||
*
|
||||
* The OutputValuePtr is also an output as it contains the value read.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_GetGpOutput(XIic *InstancePtr, u8 *OutputValuePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(OutputValuePtr != NULL);
|
||||
|
||||
/*
|
||||
* If the general purpose output register is implemented by the hardware
|
||||
* then read the value from it, otherwise indicate an error.
|
||||
*/
|
||||
if (InstancePtr->GpOutWidth > 0) {
|
||||
*OutputValuePtr = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_GPO_REG_OFFSET);
|
||||
return XST_SUCCESS;
|
||||
} else {
|
||||
return XST_NO_FEATURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* A function to determine if the device is currently addressed as a slave.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the device is addressed as slave.
|
||||
* - FALSE if the device is NOT addressed as slave.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 XIic_IsSlave(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
if ((XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET) &
|
||||
XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the receive callback function, the receive handler, which the driver
|
||||
* calls when it finishes receiving data. The number of bytes used to signal
|
||||
* when the receive is complete is the number of bytes set in the XIic_Recv
|
||||
* function.
|
||||
*
|
||||
* The handler executes in an interrupt context such that it must minimize
|
||||
* the amount of processing performed such as transferring data to a thread
|
||||
* context.
|
||||
*
|
||||
* The number of bytes received is passed to the handler as an argument.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The handler is called within interrupt context .
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetRecvHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
|
||||
InstancePtr->RecvHandler = FuncPtr;
|
||||
InstancePtr->RecvCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the send callback function, the send handler, which the driver calls when
|
||||
* it receives confirmation of sent data. The handler executes in an interrupt
|
||||
* context such that it must minimize the amount of processing performed such
|
||||
* as transferring data to a thread context.
|
||||
*
|
||||
* @param InstancePtr the pointer to the XIic instance to be worked on.
|
||||
* @param CallBackRef the upper layer callback reference passed back when
|
||||
* the callback function is invoked.
|
||||
* @param FuncPtr the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The handler is called within interrupt context .
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetSendHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
|
||||
InstancePtr->SendHandler = FuncPtr;
|
||||
InstancePtr->SendCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the status callback function, the status handler, which the driver calls
|
||||
* when it encounters conditions which are not data related. The handler
|
||||
* executes in an interrupt context such that it must minimize the amount of
|
||||
* processing performed such as transferring data to a thread context. The
|
||||
* status events that can be returned are described in xiic.h.
|
||||
*
|
||||
* @param InstancePtr points to the XIic instance to be worked on.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note The handler is called within interrupt context .
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetStatusHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_StatusHandler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
|
||||
InstancePtr->StatusHandler = FuncPtr;
|
||||
InstancePtr->StatusCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a stub for the send and recv callbacks. The stub is here in case the
|
||||
* upper layers forget to set the handlers.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
* @param ByteCount is the number of bytes sent or received
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XIic_StubHandler(void *CallBackRef, int ByteCount)
|
||||
{
|
||||
(void) ByteCount;
|
||||
(void) CallBackRef;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a stub for the asynchronous error callback. The stub is here in case
|
||||
* the upper layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference.
|
||||
* @param ErrorCode is the Xilinx error code, indicating the cause of
|
||||
* the error.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XIic_StubStatusHandler(void *CallBackRef, int ErrorCode)
|
||||
{
|
||||
(void) ErrorCode;
|
||||
(void) CallBackRef;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,589 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* XIic is the driver for an IIC master or slave device.
|
||||
*
|
||||
* In order to reduce the memory requirements of the driver the driver is
|
||||
* partitioned such that there are optional parts of the driver.
|
||||
* Slave, master, and multimaster features are optional such that all these files
|
||||
* are not required at the same time.
|
||||
* In order to use the slave and multimaster features of the driver, the user
|
||||
* must call functions (XIic_SlaveInclude and XIic_MultiMasterInclude)
|
||||
* to dynamically include the code. These functions may be called at any time.
|
||||
*
|
||||
* Two sets of higher level API's are available in the XIic driver that can
|
||||
* be used for Transmission/Reception in Master mode :
|
||||
* - XIic_MasterSend()/ XIic_MasterRecv() which is used in normal mode.
|
||||
* - XIic_DynMasterSend()/ XIic_DynMasterRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* Similarly two sets of lower level API's are available in XIic driver that
|
||||
* can be used for Transmission/Reception in Master mode:
|
||||
* - XIic_Send()/ XIic_Recv() which is used in normal mode
|
||||
* - XIic_DynSend()/ XIic_DynRecv() which is used in Dynamic mode.
|
||||
*
|
||||
* The user should use a single set of APIs as per his requirement and
|
||||
* should not intermix them.
|
||||
*
|
||||
* All the driver APIs can be used for read, write and combined mode of
|
||||
* operations on the IIC bus.
|
||||
*
|
||||
* In the normal mode IIC support both 7-bit and 10-bit addressing, and in
|
||||
* the dynamic mode support only 7-bit addressing.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XIic_Config structure is used by the driver to configure itself. This
|
||||
* configuration structure is typically created by the tool-chain based on HW
|
||||
* build properties.
|
||||
*
|
||||
* To support multiple runtime loading and initialization strategies employed
|
||||
* by various operating systems, the driver instance can be initialized in one
|
||||
* of the following ways:
|
||||
*
|
||||
* - XIic_Initialize() - The driver looks up its own
|
||||
* configuration structure created by the tool-chain based on an ID provided
|
||||
* by the tool-chain.
|
||||
*
|
||||
* - XIic_CfgInitialize() - The driver uses a configuration structure provided
|
||||
* by the caller. If running in a system with address translation, the
|
||||
* provided virtual memory base address replaces the physical address present
|
||||
* in the configuration structure.
|
||||
*
|
||||
* <b>General Purpose Output</b>
|
||||
* The IIC hardware provides a General Purpose Output Register that allows the
|
||||
* user to connect general purpose outputs to devices, such as a write protect,
|
||||
* for an EEPROM. This register is parameterizable in the hardware such that
|
||||
* there could be zero bits in this register and in this case it will cause
|
||||
* a bus error if read or written.
|
||||
*
|
||||
* <b>Bus Throttling</b>
|
||||
*
|
||||
* The IIC hardware provides bus throttling which allows either the device, as
|
||||
* either a master or a slave, to stop the clock on the IIC bus. This feature
|
||||
* allows the software to perform the appropriate processing for each interrupt
|
||||
* without an unreasonable response restriction. With this design, it is
|
||||
* important for the user to understand the implications of bus throttling.
|
||||
*
|
||||
* <b>Repeated Start</b>
|
||||
*
|
||||
* An application can send multiple messages, as a master, to a slave device
|
||||
* and re-acquire the IIC bus each time a message is sent. The repeated start
|
||||
* option allows the application to send multiple messages without re-acquiring
|
||||
* the IIC bus for each message. The transactions involving repeated start
|
||||
* are also called combined transfers if there is Read and Write in the
|
||||
* same transaction.
|
||||
*
|
||||
* The repeated start feature works with all the API's in XIic driver.
|
||||
*
|
||||
* The Repeated Start feature also could cause the application to lock up, or
|
||||
* monopolize the IIC bus, should repeated start option be enabled and sequences
|
||||
* of messages never end(periodic data collection).
|
||||
* Also when repeated start is not disable before the last master message is
|
||||
* sent or received, will leave the bus captive to the master, but unused.
|
||||
*
|
||||
* <b>Addressing</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built for 7 or 10
|
||||
* bit addresses. The driver provides the ability to control which address
|
||||
* size is sent in messages as a master to a slave device. The address size
|
||||
* which the hardware responds to as a slave is parameterized as 7 or 10 bits
|
||||
* but fixed by the hardware build.
|
||||
*
|
||||
* Addresses are represented as hex values with no adjustment for the data
|
||||
* direction bit as the software manages address bit placement. This is
|
||||
* especially important as the bit placement is not handled the same depending
|
||||
* on which options are used such as repeated start and 7 vs 10 bit addressing.
|
||||
*
|
||||
* <b>Data Rates</b>
|
||||
*
|
||||
* The IIC hardware is parameterized such that it can be built to support
|
||||
* data rates from DC to 400KBit. The frequency of the interrupts which
|
||||
* occur is proportional to the data rate.
|
||||
*
|
||||
* <b>Polled Mode Operation</b>
|
||||
*
|
||||
* This driver does not provide a polled mode of operation primarily because
|
||||
* polled mode which is non-blocking is difficult with the amount of
|
||||
* interaction with the hardware that is necessary.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The device has many interrupts which allow IIC data transactions as well
|
||||
* as bus status processing to occur.
|
||||
*
|
||||
* The interrupts are divided into two types, data and status. Data interrupts
|
||||
* indicate data has been received or transmitted while the status interrupts
|
||||
* indicate the status of the IIC bus. Some of the interrupts, such as Not
|
||||
* Addressed As Slave and Bus Not Busy, are only used when these specific
|
||||
* events must be recognized as opposed to being enabled at all times.
|
||||
*
|
||||
* Many of the interrupts are not a single event in that they are continuously
|
||||
* present such that they must be disabled after recognition or when undesired.
|
||||
* Some of these interrupts, which are data related, may be acknowledged by the
|
||||
* software by reading or writing data to the appropriate register, or must
|
||||
* be disabled. The following interrupts can be continuous rather than single
|
||||
* events.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Bus Not Busy
|
||||
* - Addressed As Slave
|
||||
* - Not Addressed As Slave
|
||||
*
|
||||
* The following interrupts are not passed directly to the application through the
|
||||
* status callback. These are only used internally for the driver processing
|
||||
* and may result in the receive and send handlers being called to indicate
|
||||
* completion of an operation. The following interrupts are data related
|
||||
* rather than status.
|
||||
* - Data Transmit Register Empty/Transmit FIFO Empty
|
||||
* - Data Receive Register Full/Receive FIFO
|
||||
* - Transmit FIFO Half Empty
|
||||
* - Slave Transmit Complete
|
||||
*
|
||||
* <b>Interrupt To Event Mapping</b>
|
||||
*
|
||||
* The following table provides a mapping of the interrupts to the events which
|
||||
* are passed to the status handler and the intended role (master or slave) for
|
||||
* the event. Some interrupts can cause multiple events which are combined
|
||||
* together into a single status event such as XII_MASTER_WRITE_EVENT and
|
||||
* XII_GENERAL_CALL_EVENT
|
||||
* <pre>
|
||||
* Interrupt Event(s) Role
|
||||
*
|
||||
* Arbitration Lost Interrupt XII_ARB_LOST_EVENT Master
|
||||
* Transmit Error XII_SLAVE_NO_ACK_EVENT Master
|
||||
* IIC Bus Not Busy XII_BUS_NOT_BUSY_EVENT Master
|
||||
* Addressed As Slave XII_MASTER_READ_EVENT, Slave
|
||||
* XII_MASTER_WRITE_EVENT, Slave
|
||||
* XII_GENERAL_CALL_EVENT Slave
|
||||
* </pre>
|
||||
* <b>Not Addressed As Slave Interrupt</b>
|
||||
*
|
||||
* The Not Addressed As Slave interrupt is not passed directly to the
|
||||
* application through the status callback. It is used to determine the end of
|
||||
* a message being received by a slave when there was no stop condition
|
||||
* (repeated start). It will cause the receive handler to be called to
|
||||
* indicate completion of the operation.
|
||||
*
|
||||
* <b>RTOS Independence</b>
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works
|
||||
* with physical addresses only. Any needs for dynamic memory management,
|
||||
* threads or thread mutual exclusion, virtual memory, or cache control must
|
||||
* be satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.01d sv 05/09/05 Changed the data being written to the Address/Control
|
||||
* Register and removed the code for testing the
|
||||
* Receive Data Register in XIic_SelfTest function of
|
||||
* xiic_selftest.c source file
|
||||
* 1.02a jvb 12/14/05 I separated dependency on the static config table and
|
||||
* xparameters.h from the driver initialization by moving
|
||||
* _Initialize and _LookupConfig to _sinit.c. I also added
|
||||
* the new _CfgInitialize routine.
|
||||
* 1.02a mta 03/09/06 Added a new function XIic_IsIicBusy() which returns
|
||||
* whether IIC Bus is Busy or Free.
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 07/17/06 Added files to support Dynamic IIC controller in High
|
||||
* level driver. Added xiic_dyn_master.c. Added support
|
||||
* for IIC Dynamic controller in Low level driver in xiic_l.c
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.13b ecm 11/29/07 added BB polling loops to the DynSend and DynRecv
|
||||
* routines to handle the race condition with BNB in IISR.
|
||||
* 1.14a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
|
||||
* file
|
||||
* 1.14a ecm 11/13/08 changed BB polling loops in DynRecv to handle race
|
||||
* condition, CR491889. DynSend was correct from v1.13.b
|
||||
* 1.15a ktn 02/17/09 Fixed XIic_GetAddress() to return correct device address.
|
||||
* 1.16a ktn 07/17/09 Updated the XIic_SelfTest() to test only Interrupt
|
||||
* Registers.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.,
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Removed the XIIC_CLEAR_STATS macro, XIic_ClearStats API
|
||||
* should be used in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name see the xiic_i.h and xiic_l.h file for further
|
||||
* information (Example XIic_mClearIntr is now
|
||||
* XIic_ClearIntr).
|
||||
* Some of the macros have been renamed to be consistent,
|
||||
* see the xiic_l.h file for further information
|
||||
* (Example XIIC_WRITE_IIER is renamed as XIic_WriteIier).
|
||||
* The driver has been updated to use the HAL APIs/macros
|
||||
* (Example XASSERT_NONVOID is now Xil_AssertNonvoid)
|
||||
* 2.01a ktn 04/09/10 Updated TxErrorhandler in xiic_intr.c to be called for
|
||||
* Master Transmitter case based on Addressed As Slave (AAS)
|
||||
* bit rather than MSMS bit(CR 540199).
|
||||
* 2.02a sdm 10/08/10 Updated to disable the device at the end of the transfer,
|
||||
* using Addressed As Slave (AAS) bit when addressed as
|
||||
* slave in XIic_Send for CR565373.
|
||||
* 2.03a rkv 01/25/11 Updated in NAAS interrupt handler to support data
|
||||
* received less than FIFO size prior to NAAS interrupt.
|
||||
* Fixed for CR590212.
|
||||
* 2.04a sdm 07/22/11 Added IsSlaveSetAckOff flag to the instance structure.
|
||||
* This flag is set when the Slave has set the Ack Off in the
|
||||
* RecvSlaveData function (xiic_slave.c) and
|
||||
* is cleared in the NotAddrAsSlaveHandler (xiic_slave.c)
|
||||
* when the master has released the bus. This flag is
|
||||
* to be used by slave applications for recovering when it
|
||||
* has gone out of sync with the master for CR 615004.
|
||||
* Removed a compiler warning in XIic_Send (xiic_l.c)
|
||||
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
|
||||
* SendBufferPtr in XIic_MasterRecv to NULL in xiic_master.c
|
||||
* 2.06a bss 02/14/13 Modified TxErrorHandler in xiic_intr.c to fix CR #686483
|
||||
* Modified xiic_eeprom_example.c to fix CR# 683509.
|
||||
* Modified bitwise OR to logical OR in
|
||||
* XIic_InterruptHandler API in xiic_intr.c.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
* 2.08a adk 29/07/13 In Low level driver In repeated start condition the
|
||||
* Direction of Tx bit must be disabled in recv condition
|
||||
* It Fixes the CR:685759 Changes are done in the file
|
||||
* xiic_l.c in the function XIic_Recv.
|
||||
* 3.0 adk 19/12/13 Updated as per the New Tcl API's
|
||||
* 3.1 adk 01/08/15 When configured as a slave return the actual number of
|
||||
* bytes have been received/sent by the Master
|
||||
* to the user callback (CR: 828504). Changes are made in the
|
||||
* file xiic_slave.c.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XIic_CfgInitialize API.
|
||||
* 3.2 sd 18/02/16 In Low level driver in repeated start condition
|
||||
* NACK for last byte is added. Changes are done in
|
||||
* XIic_Recv for CR# 862303
|
||||
* 3.3 sk 06/17/16 Added bus busy checks for slave send/recv and master
|
||||
* send/recv.
|
||||
* 3.3 als 06/27/16 XIic_IsIicBusy now a wrapper for XIic_CheckIsBusBusy.
|
||||
* 3.4 ms 01/23/17 Added xil_printf statement in main function for all
|
||||
* examples to ensure that "Successfully ran" and "Failed"
|
||||
* strings are available in all examples. This is a fix
|
||||
* for CR-965028.
|
||||
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
|
||||
* generation.
|
||||
* ms 04/05/17 Modified Comment lines in functions of iic
|
||||
* examples to recognize it as documentation block
|
||||
* for doxygen generation.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XIIC_H /* prevent circular inclusions */
|
||||
#define XIIC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* The following options may be specified or retrieved for the device and
|
||||
* enable/disable additional features of the IIC bus. Each of the options
|
||||
* are bit fields such that more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XII_GENERAL_CALL_OPTION The general call option allows an IIC slave to
|
||||
* recognized the general call address. The status
|
||||
* handler is called as usual indicating the device
|
||||
* has been addressed as a slave with a general
|
||||
* call. It is the application's responsibility to
|
||||
* perform any special processing for the general
|
||||
* call.
|
||||
*
|
||||
* XII_REPEATED_START_OPTION The repeated start option allows multiple
|
||||
* messages to be sent/received on the IIC bus
|
||||
* without rearbitrating for the bus. The messages
|
||||
* are sent as a series of messages such that the
|
||||
* option must be enabled before the 1st message of
|
||||
* the series, to prevent an stop condition from
|
||||
* being generated on the bus, and disabled before
|
||||
* the last message of the series, to allow the
|
||||
* stop condition to be generated.
|
||||
*
|
||||
* XII_SEND_10_BIT_OPTION The send 10 bit option allows 10 bit addresses
|
||||
* to be sent on the bus when the device is a
|
||||
* master. The device can be configured to respond
|
||||
* as to 7 bit addresses even though it may be
|
||||
* communicating with other devices that support 10
|
||||
* bit addresses. When this option is not enabled,
|
||||
* only 7 bit addresses are sent on the bus.
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
#define XII_GENERAL_CALL_OPTION 0x00000001
|
||||
#define XII_REPEATED_START_OPTION 0x00000002
|
||||
#define XII_SEND_10_BIT_OPTION 0x00000004
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name Status events
|
||||
*
|
||||
* The following status events occur during IIC bus processing and are passed
|
||||
* to the status callback. Each event is only valid during the appropriate
|
||||
* processing of the IIC bus. Each of these events are bit fields such that
|
||||
* more than one may be specified.
|
||||
* @{
|
||||
*/
|
||||
#define XII_BUS_NOT_BUSY_EVENT 0x00000001 /**< Bus transitioned to not busy */
|
||||
#define XII_ARB_LOST_EVENT 0x00000002 /**< Arbitration was lost */
|
||||
#define XII_SLAVE_NO_ACK_EVENT 0x00000004 /**< Slave did not ACK (had error) */
|
||||
#define XII_MASTER_READ_EVENT 0x00000008 /**< Master reading from slave */
|
||||
#define XII_MASTER_WRITE_EVENT 0x00000010 /**< Master writing to slave */
|
||||
#define XII_GENERAL_CALL_EVENT 0x00000020 /**< General call to all slaves */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/*
|
||||
* The following address types are used when setting and getting the addresses
|
||||
* of the driver. These are mutually exclusive such that only one or the other
|
||||
* may be specified.
|
||||
*/
|
||||
#define XII_ADDR_TO_SEND_TYPE 1 /**< Bus address of slave device */
|
||||
#define XII_ADDR_TO_RESPOND_TYPE 2 /**< This device's bus address as slave */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< Does device have 10 bit address decoding */
|
||||
u8 GpOutWidth; /**< Number of bits in general purpose output */
|
||||
} XIic_Config;
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of sent and received data of the IIC driver. The application
|
||||
* using this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handlers are called in an interrupt context such
|
||||
* that minimal processing should be performed. The handler data type is
|
||||
* utilized for both send and receive handlers.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param ByteCount indicates the number of bytes remaining to be sent or
|
||||
* received. A value of zero indicates that the requested number
|
||||
* of bytes were sent or received.
|
||||
*
|
||||
******************************************************************************/
|
||||
typedef void (*XIic_Handler) (void *CallBackRef, int ByteCount);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This callback function data type is defined to handle the asynchronous
|
||||
* processing of status events of the IIC driver. The application using
|
||||
* this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handler is called in an interrupt context such
|
||||
* that minimal processing should be performed.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back
|
||||
* to the upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver component, so it is a void pointer.
|
||||
* @param StatusEvent indicates one or more status events that occurred.
|
||||
* See the definition of the status events above.
|
||||
*
|
||||
********************************************************************************/
|
||||
typedef void (*XIic_StatusHandler) (void *CallBackRef, int StatusEvent);
|
||||
|
||||
/**
|
||||
* XIic statistics
|
||||
*/
|
||||
typedef struct {
|
||||
u8 ArbitrationLost;/**< Number of times arbitration was lost */
|
||||
u8 RepeatedStarts; /**< Number of repeated starts */
|
||||
u8 BusBusy; /**< Number of times bus busy status returned */
|
||||
u8 RecvBytes; /**< Number of bytes received */
|
||||
u8 RecvInterrupts; /**< Number of receive interrupts */
|
||||
u8 SendBytes; /**< Number of transmit bytes received */
|
||||
u8 SendInterrupts; /**< Number of transmit interrupts */
|
||||
u8 TxErrors; /**< Number of transmit errors (no ack) */
|
||||
u8 IicInterrupts; /**< Number of IIC (device) interrupts */
|
||||
} XIicStats;
|
||||
|
||||
/**
|
||||
* The XIic driver instance data. The user is required to allocate a
|
||||
* variable of this type for every IIC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XIicStats Stats; /**< Statistics */
|
||||
UINTPTR BaseAddress; /**< Device base address */
|
||||
int Has10BitAddr; /**< TRUE when 10 bit addressing in design */
|
||||
int IsReady; /**< Device is initialized and ready */
|
||||
int IsStarted; /**< Device has been started */
|
||||
int AddrOfSlave; /**< Slave Address writing to */
|
||||
|
||||
u32 Options; /**< Current operating options */
|
||||
u8 *SendBufferPtr; /**< Buffer to send (state) */
|
||||
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
|
||||
u8 TxAddrMode; /**< State of Tx Address transmission */
|
||||
int SendByteCount; /**< Number of data bytes in buffer (state) */
|
||||
int RecvByteCount; /**< Number of empty bytes in buffer (state) */
|
||||
|
||||
u32 BNBOnly; /**< TRUE when BNB interrupt needs to */
|
||||
/**< call callback */
|
||||
u8 GpOutWidth; /**< General purpose output width */
|
||||
|
||||
XIic_StatusHandler StatusHandler; /**< Status Handler */
|
||||
void *StatusCallBackRef; /**< Callback reference for status handler */
|
||||
XIic_Handler RecvHandler; /**< Receive Handler */
|
||||
void *RecvCallBackRef; /**< Callback reference for Recv handler */
|
||||
XIic_Handler SendHandler; /**< Send Handler */
|
||||
void *SendCallBackRef; /**< Callback reference for send handler */
|
||||
int IsDynamic; /**< TRUE when Dynamic control is used */
|
||||
int IsSlaveSetAckOff; /**< TRUE when Slave has set the ACK Off */
|
||||
|
||||
} XIic;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This is a function which tells whether the I2C bus is busy or free.
|
||||
*
|
||||
* @param InstancePtr points to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the bus is busy.
|
||||
* - FALSE if the bus is NOT busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static inline u32 XIic_IsIicBusy(XIic *InstancePtr)
|
||||
{
|
||||
return XIic_CheckIsBusBusy(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization functions in xiic_sinit.c
|
||||
*/
|
||||
int XIic_Initialize(XIic *InstancePtr, u16 DeviceId);
|
||||
XIic_Config *XIic_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions in xiic.c
|
||||
*/
|
||||
int XIic_CfgInitialize(XIic *InstancePtr, XIic_Config *Config,
|
||||
UINTPTR EffectiveAddr);
|
||||
|
||||
int XIic_Start(XIic *InstancePtr);
|
||||
int XIic_Stop(XIic *InstancePtr);
|
||||
|
||||
void XIic_Reset(XIic *InstancePtr);
|
||||
|
||||
int XIic_SetAddress(XIic *InstancePtr, int AddressType, int Address);
|
||||
u16 XIic_GetAddress(XIic *InstancePtr, int AddressType);
|
||||
|
||||
int XIic_SetGpOutput(XIic *InstancePtr, u8 OutputValue);
|
||||
int XIic_GetGpOutput(XIic *InstancePtr, u8 *OutputValuePtr);
|
||||
|
||||
u32 XIic_IsSlave(XIic *InstancePtr);
|
||||
|
||||
void XIic_SetRecvHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetSendHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_Handler FuncPtr);
|
||||
void XIic_SetStatusHandler(XIic *InstancePtr, void *CallBackRef,
|
||||
XIic_StatusHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xiic_intr.c
|
||||
*/
|
||||
void XIic_InterruptHandler(void *InstancePtr);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in normal mode in xiic_master.c
|
||||
*/
|
||||
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Master send and receive functions in dynamic mode in xiic_master.c
|
||||
*/
|
||||
int XIic_DynMasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, u8 ByteCount);
|
||||
int XIic_DynMasterSend(XIic *InstancePtr, u8 *TxMsgPtr, u8 ByteCount);
|
||||
|
||||
/*
|
||||
* Dynamic IIC Core Initialization.
|
||||
*/
|
||||
int XIic_DynamicInitialize(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Slave send and receive functions in xiic_slave.c
|
||||
*/
|
||||
void XIic_SlaveInclude(void);
|
||||
int XIic_SlaveRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount);
|
||||
int XIic_SlaveSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount);
|
||||
|
||||
/*
|
||||
* Statistics functions in xiic_stats.c
|
||||
*/
|
||||
void XIic_GetStats(XIic *InstancePtr, XIicStats *StatsPtr);
|
||||
void XIic_ClearStats(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Self test functions in xiic_selftest.c
|
||||
*/
|
||||
int XIic_SelfTest(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Bus busy Function in xiic.c
|
||||
*/
|
||||
u32 XIic_IsIicBusy(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Options functions in xiic_options.c
|
||||
*/
|
||||
void XIic_SetOptions(XIic *InstancePtr, u32 Options);
|
||||
u32 XIic_GetOptions(XIic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Multi-master functions in xiic_multi_master.c
|
||||
*/
|
||||
void XIic_MultiMasterInclude(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,603 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2006 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_dyn_master.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains master functions for the XIic component in Dynamic controller mode.
|
||||
* This file is necessary to send or receive as a master on the IIC bus.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------------------
|
||||
* 1.03a mta 04/10/06 Created.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros. The macros
|
||||
* XIic_mDynSend7BitAddress and XIic_mDynSendStop have
|
||||
* been removed from this file as they were already
|
||||
* defined in a header file.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and Some of the macros have been renamed to be
|
||||
* consistent, see the xiic_l.h file for further information.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro includes dynamic master code such that dynamic master operations,
|
||||
* sending and receiving data, may be used. This function hooks the dynamic
|
||||
* master processing to the driver such that events are handled properly and
|
||||
* allows dynamic master processing to be optional. It must be called before any
|
||||
* functions which are contained in this file are called, such as after the
|
||||
* driver is initialized.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIC_DYN_MASTER_INCLUDE \
|
||||
{ \
|
||||
XIic_RecvMasterFuncPtr = DynRecvMasterData; \
|
||||
XIic_SendMasterFuncPtr = DynSendMasterData; \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void DynRecvMasterData(XIic *InstancePtr);
|
||||
static void DynSendMasterData(XIic *InstancePtr);
|
||||
static int IsBusBusy(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function sends data as a Dynamic master on the IIC bus. If the bus is
|
||||
* busy, it will indicate so and then enable an interrupt such that the status
|
||||
* handler will be called when the bus is no longer busy. The slave address is
|
||||
* sent by using XIic_DynSend7BitAddress().
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
* @param TxMsgPtr points to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_DynMasterSend(XIic *InstancePtr, u8 *TxMsgPtr, u8 ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the Dynamic master processing has been included such that
|
||||
* events will be properly handled.
|
||||
*/
|
||||
XIIC_DYN_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = TRUE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus not to be busy. The function enables the BusNotBusy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it is already a master on the bus (repeated start), the direction
|
||||
* was set to Tx which is throttling bus. The control register needs to
|
||||
* be set before putting data into the FIFO.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
CntlReg &= ~XIIC_CR_NO_ACK_MASK;
|
||||
CntlReg |= XIIC_CR_DIR_IS_TX_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state.
|
||||
*/
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = TxMsgPtr;
|
||||
|
||||
/*
|
||||
* Send the Seven Bit address. Only 7 bit addressing is supported in
|
||||
* Dynamic mode.
|
||||
*/
|
||||
XIic_DynSend7BitAddress(InstancePtr->BaseAddress,
|
||||
InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
|
||||
/*
|
||||
* Set the transmit address state to indicate the address has been sent
|
||||
* for communication with event driven processing.
|
||||
*/
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
|
||||
/*
|
||||
* Fill the Tx FIFO.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* After filling fifo, if data yet to send > 1, enable Tx <20> empty
|
||||
* interrupt.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear any pending Tx empty, Tx Error and then enable them.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK |
|
||||
XIIC_INTR_TX_EMPTY_MASK);
|
||||
|
||||
/*
|
||||
* Enable the Interrupts.
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* When the IIC Tx FIFO/register goes empty, this routine is called by the
|
||||
* interrupt service routine to fill the transmit FIFO with data to be sent.
|
||||
*
|
||||
* This function also is called by the Tx <20> empty interrupt as the data handling
|
||||
* is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
|
||||
* register to indicate the available free FIFO bytes.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DynSendMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* In between 1st and last byte of message, fill the FIFO with more data
|
||||
* to send, disable the 1/2 empty interrupt based upon data left to
|
||||
* send.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
|
||||
if (InstancePtr->SendByteCount < 2) {
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is only one byte left to send, processing differs between
|
||||
* repeated start and normal messages.
|
||||
*/
|
||||
else if (InstancePtr->SendByteCount == 1) {
|
||||
/*
|
||||
* When using repeated start, another interrupt is expected
|
||||
* after the last byte has been sent, so the message is not
|
||||
* done yet.
|
||||
*/
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
} else {
|
||||
XIic_DynSendStop(InstancePtr->BaseAddress,
|
||||
*InstancePtr->SendBufferPtr);
|
||||
|
||||
/*
|
||||
* Wait for bus to not be busy before declaring message
|
||||
* has been sent for the no repeated start operation.
|
||||
* The callback will be called from the BusNotBusy part
|
||||
* of the Interrupt handler to ensure that the message
|
||||
* is completely sent. Disable the Tx interrupts and
|
||||
* enable the BNB interrupt.
|
||||
*/
|
||||
InstancePtr->BNBOnly = FALSE;
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
XIic_EnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
}
|
||||
} else {
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
/*
|
||||
* The message being sent has completed. When using
|
||||
* repeated start with no more bytes to send repeated
|
||||
* start needs to be set in the control register so
|
||||
* that the bus will still be held by this master.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
/*
|
||||
* If the message that was being sent has finished,
|
||||
* disable all transmit interrupts and call the callback
|
||||
* that was setup to indicate the message was sent,
|
||||
* with 0 bytes remaining.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function receives data as a master from a slave device on the IIC bus.
|
||||
* If the bus is busy, it will indicate so and then enable an interrupt such
|
||||
* that the status handler will be called when the bus is no longer busy. The
|
||||
* slave address which has been set with the XIic_SetAddress() function is the
|
||||
* address from which data is received. Receiving data on the bus performs a
|
||||
* read operation.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the Iic instance to be worked on.
|
||||
* @param RxMsgPtr is a pointer to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return - XST_SUCCESS indicates the message reception processes has been
|
||||
* initiated.
|
||||
* - XST_IIC_BUS_BUSY indicates the bus was in use and that the
|
||||
* BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
* - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address is
|
||||
* set to the general call address. This is not allowed for Master
|
||||
* receive mode.
|
||||
*
|
||||
* @note The receive FIFO threshold is a zero based count such that 1
|
||||
* must be subtracted from the desired count to get the correct
|
||||
* value. When receiving data it is also necessary to not receive
|
||||
* the last byte with the prior bytes because the acknowledge must
|
||||
* be setup before the last byte is received.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_DynMasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, u8 ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u32 RxFifoOccy;
|
||||
|
||||
/*
|
||||
* If the slave address is zero (general call) the master can't perform
|
||||
* receive operations, indicate an error.
|
||||
*/
|
||||
if (InstancePtr->AddrOfSlave == 0) {
|
||||
return XST_IIC_GENERAL_CALL_ADDRESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the Interrupts.
|
||||
*/
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the master processing has been included such that events
|
||||
* will be properly handled.
|
||||
*/
|
||||
XIIC_DYN_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = TRUE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus to not be busy, the function enables the bus not busy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state for event driven processing.
|
||||
*/
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = RxMsgPtr;
|
||||
|
||||
/*
|
||||
* Clear and enable Rx full interrupt.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
/*
|
||||
* If already a master on the bus, the direction was set by Rx Interrupt
|
||||
* routine to Tx which is throttling bus because during Rxing, Tx reg is
|
||||
* empty = throttle. CR needs setting before putting data or the address
|
||||
* written will go out as Tx instead of receive. Start Master Rx by
|
||||
* setting CR Bits MSMS to Master and msg direction.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
/*
|
||||
* Set the Repeated Start bit in CR.
|
||||
*/
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
|
||||
|
||||
/*
|
||||
* Increment stats counts.
|
||||
*/
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set receive FIFO occupancy depth which must be done prior to writing
|
||||
* the address in the FIFO because the transmitter will immediately
|
||||
* start when in repeated start mode followed by the receiver such
|
||||
* that the number of bytes to receive should be set 1st.
|
||||
*/
|
||||
if (ByteCount == 1) {
|
||||
RxFifoOccy = 0;
|
||||
}
|
||||
else {
|
||||
if (ByteCount <= IIC_RX_FIFO_DEPTH) {
|
||||
RxFifoOccy = ByteCount - 2;
|
||||
} else {
|
||||
RxFifoOccy = IIC_RX_FIFO_DEPTH - 1;
|
||||
}
|
||||
}
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
RxFifoOccy);
|
||||
|
||||
/*
|
||||
* Send the Seven Bit address. Only 7 bit addressing is supported in
|
||||
* Dynamic mode and mark that the address has been sent.
|
||||
*/
|
||||
XIic_DynSend7BitAddress(InstancePtr->BaseAddress,
|
||||
InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
|
||||
/*
|
||||
* Send the bytecount to be received and set the stop bit.
|
||||
*/
|
||||
XIic_DynSendStop(InstancePtr->BaseAddress, ByteCount);
|
||||
|
||||
/*
|
||||
* Tx error is enabled in case the address has no device to answer
|
||||
* with Ack. When only one byte of data, must set NO ACK before address
|
||||
* goes out therefore Tx error must not be enabled as it will go off
|
||||
* immediately and the Rx full interrupt will be checked. If full, then
|
||||
* the one byte was received and the Tx error will be disabled without
|
||||
* sending an error callback msg.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* Enable the Interrupts.
|
||||
*/
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the receive register is full. The number
|
||||
* of bytes received to cause the interrupt is adjustable using the Receive FIFO
|
||||
* Depth register. The number of bytes in the register is read in the Receive
|
||||
* FIFO occupancy register. Both these registers are zero based values (0-15)
|
||||
* such that a value of zero indicates 1 byte.
|
||||
*
|
||||
* For a Master Receiver to properly signal the end of a message, the data must
|
||||
* be read in up to the message length - 1, where control register bits will be
|
||||
* set for bus controls to occur on reading of the last byte.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DynRecvMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u8 LoopCnt;
|
||||
u8 BytesInFifo;
|
||||
u8 BytesToRead;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* Device is a master receiving, get the contents of the control
|
||||
* register and determine the number of bytes in fifo to be read out.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
BytesInFifo = (u8) XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET) + 1;
|
||||
|
||||
/*
|
||||
* If data in FIFO holds all data to be retrieved - 1, set NOACK and
|
||||
* disable the Tx error.
|
||||
*/
|
||||
if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
|
||||
/*
|
||||
* Disable Tx error interrupt to prevent interrupt as this
|
||||
* device will cause it when it set NO ACK next.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* Read one byte to clear a place for the last byte to be read
|
||||
* which will set the NO ACK.
|
||||
*/
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If data in FIFO is all the data to be received then get the data and
|
||||
* also leave the device in a good state for the next transaction.
|
||||
*/
|
||||
else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from the FIFO then set zero based FIFO read depth
|
||||
* for a byte.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Disable Rx full interrupt and write the control reg with ACK
|
||||
* allowing next byte sent to be acknowledged automatically.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
/*
|
||||
* Send notification of msg Rx complete in RecvHandler callback.
|
||||
*/
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Fifo data not at n-1, read all but the last byte of data
|
||||
* from the slave, if more than a FIFO full yet to receive
|
||||
* read a FIFO full.
|
||||
*/
|
||||
BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
|
||||
if (BytesToRead > IIC_RX_FIFO_DEPTH) {
|
||||
BytesToRead = IIC_RX_FIFO_DEPTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in data from the FIFO.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function checks to see if the IIC bus is busy. If so, it will enable
|
||||
* the bus not busy interrupt such that the driver is notified when the bus
|
||||
* is no longer busy.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
*
|
||||
* @return FALSE if the IIC bus is not busy else TRUE.
|
||||
*
|
||||
* @note The BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int IsBusBusy(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u32 StatusReg;
|
||||
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
StatusReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* If this device is already master of the bus as when using the
|
||||
* repeated start and the bus is busy setup to wait for it to not
|
||||
* be busy.
|
||||
*/
|
||||
if (((CntlReg & XIIC_CR_MSMS_MASK) == 0) && /* Not master */
|
||||
(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { /* Is busy */
|
||||
/*
|
||||
* The bus is busy, clear pending BNB interrupt in case
|
||||
* previously set and then enable BusNotBusy interrupt.
|
||||
*/
|
||||
InstancePtr->BNBOnly = TRUE;
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
InstancePtr->Stats.BusBusy++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Initialize the IIC core for Dynamic Functionality.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
*
|
||||
* @return XST_SUCCESS if Successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_DynamicInitialize(XIic *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
Status = XIic_DynInit(InstancePtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version: 2022.2
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2025 Xilinx, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xiic.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XIic_Config XIic_ConfigTable[XPAR_XIIC_NUM_INSTANCES] =
|
||||
{
|
||||
{
|
||||
XPAR_AXI_IIC_0_DEVICE_ID,
|
||||
XPAR_AXI_IIC_0_BASEADDR,
|
||||
XPAR_AXI_IIC_0_TEN_BIT_ADR,
|
||||
XPAR_AXI_IIC_0_GPO_WIDTH
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_i.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains internal identifiers, which are those shared
|
||||
* between XIic components. The identifiers in this file are not intended for
|
||||
* use external to the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Removed the macro XIIC_CLEAR_STATS, user has to
|
||||
* use the the XIic_ClearStats API in its place.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Removed the _m prefix from all the macros
|
||||
* XIic_mSend10BitAddrByte1 is now XIic_Send10BitAddrByte1
|
||||
* XIic_mSend10BitAddrByte2 is now XIic_Send10BitAddrByte2
|
||||
* XIic_mSend7BitAddr is now XIic_Send7BitAddr
|
||||
* XIic_mDisableIntr is now XIic_DisableIntr
|
||||
* XIic_mEnableIntr is now XIic_EnableIntr
|
||||
* XIic_mClearIntr is now XIic_ClearIntr
|
||||
* XIic_mClearEnableIntr is now XIic_ClearEnableIntr
|
||||
* XIic_mFlushRxFifo is now XIic_FlushRxFifo
|
||||
* XIic_mFlushTxFifo is now XIic_FlushTxFifo
|
||||
* XIic_mReadRecvByte is now XIic_ReadRecvByte
|
||||
* XIic_mWriteSendByte is now XIic_WriteSendByte
|
||||
* XIic_mSetControlRegister is now XIic_SetControlRegister
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings when
|
||||
* compiling with the -Wextra -Wall flags.
|
||||
* Changes done in files xiic.c and xiic_i.h. CR:705001
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIIC_I_H /* prevent circular inclusions */
|
||||
#define XIIC_I_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the first byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* address = 1111_0xxD xx = address MSBits
|
||||
* D = Tx direction = 0 = write
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send10BitAddrByte1(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte1(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)((SlaveAddress) >> 7); \
|
||||
LocalAddr = (LocalAddr & 0xF6) | 0xF0 | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the second byte of the address for a 10 bit address during
|
||||
* both read and write operations. It takes care of the details to format the
|
||||
* address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature: void XIic_Send10BitAddrByte2(u16 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send10BitAddrByte2(SlaveAddress) \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32)(SlaveAddress)); \
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
*
|
||||
* @param SlaveAddress contains the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_Send7BitAddr(u16 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddr(SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
(u32) LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro disables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_DisableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DisableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) & ~(InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro enables the specified interrupts in the Interrupt enable
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupts specified is changed.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_EnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_EnableIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIier((BaseAddress), \
|
||||
XIic_ReadIier(BaseAddress) | (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be disabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIntr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro clears and enables the specified interrupt in the Interrupt
|
||||
* status and enable registers. It is non-destructive in that the registers are
|
||||
* read and only the interrupt specified is modified.
|
||||
* Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask contains the interrupts to be cleared and enabled
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ClearEnableIntr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearEnableIntr(BaseAddress, InterruptMask) \
|
||||
{ \
|
||||
XIic_WriteIisr(BaseAddress, \
|
||||
(XIic_ReadIisr(BaseAddress) & (InterruptMask))); \
|
||||
\
|
||||
XIic_WriteIier(BaseAddress, \
|
||||
(XIic_ReadIier(BaseAddress) | (InterruptMask))); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the receive FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushRxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushRxFifo(InstancePtr) \
|
||||
{ \
|
||||
int LoopCnt; \
|
||||
u8 BytesToRead = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_RFO_REG_OFFSET) + 1; \
|
||||
for(LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) \
|
||||
{ \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_DRR_REG_OFFSET); \
|
||||
} \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro flushes the transmit FIFO such that all bytes contained within it
|
||||
* are discarded.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance containing the FIFO
|
||||
* to be flushed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_FlushTxFifo(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_FlushTxFifo(InstancePtr); \
|
||||
{ \
|
||||
u32 CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, \
|
||||
XIIC_CR_REG_OFFSET); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg | XIIC_CR_TX_FIFO_RESET_MASK); \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, \
|
||||
CntlReg); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro reads the next available received byte from the receive FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_ReadRecvByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadRecvByte(InstancePtr) \
|
||||
{ \
|
||||
*InstancePtr->RecvBufferPtr++ = \
|
||||
XIic_ReadReg(InstancePtr->BaseAddress, XIIC_DRR_REG_OFFSET); \
|
||||
InstancePtr->RecvByteCount--; \
|
||||
InstancePtr->Stats.RecvBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro writes the next byte to be sent to the transmit FIFO
|
||||
* and updates all the data structures to reflect it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_WriteSendByte(XIic *InstancePtr);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteSendByte(InstancePtr) \
|
||||
{ \
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
*InstancePtr->SendBufferPtr++); \
|
||||
InstancePtr->SendByteCount--; \
|
||||
InstancePtr->Stats.SendBytes++; \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This macro sets up the control register for a master receive operation.
|
||||
* A write is necessary if a 10 bit operation is being performed.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the IIC instance to be operated on.
|
||||
* @param ControlRegister contains the contents of the IIC device control
|
||||
* register
|
||||
* @param ByteCount contains the number of bytes to be received for the
|
||||
* master receive operation
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Signature:
|
||||
* void XIic_SetControlRegister(XIic *InstancePtr,
|
||||
* u8 ControlRegister,
|
||||
* int ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_SetControlRegister(InstancePtr, ControlRegister, ByteCount) \
|
||||
{ \
|
||||
(ControlRegister) &= ~(XIIC_CR_NO_ACK_MASK | XIIC_CR_DIR_IS_TX_MASK); \
|
||||
if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) { \
|
||||
(ControlRegister) |= XIIC_CR_DIR_IS_TX_MASK; \
|
||||
} else { \
|
||||
if ((ByteCount) == 1) \
|
||||
{ \
|
||||
(ControlRegister) |= XIIC_CR_NO_ACK_MASK; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
extern XIic_Config XIic_ConfigTable[];
|
||||
|
||||
/* The following variables are shared across files of the driver and
|
||||
* are function pointers that are necessary to break dependencies allowing
|
||||
* optional parts of the driver to be used without condition compilation
|
||||
*/
|
||||
extern void (*XIic_AddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_NotAddrAsSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendSlaveFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_RecvMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_SendMasterFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_ArbLostFuncPtr) (XIic *InstancePtr);
|
||||
extern void (*XIic_BusNotBusyFuncPtr) (XIic *InstancePtr);
|
||||
|
||||
void XIic_TransmitFifoFill(XIic *InstancePtr, int Role);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,431 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2006 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_intr.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains interrupt functions of the XIic driver. This file is required
|
||||
* for the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.01a rfp 10/19/01 release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01c rmm 05/14/03 Fixed diab compiler warnings relating to asserts.
|
||||
* 1.03a ecm 06/22/06 Added a call to the status handler in the TxErrorHandler
|
||||
* even if the Rx buffer pointer is not set. This fix is as
|
||||
* a result of a Sony use model which did not set the Rx
|
||||
* pointer while in Master mode so it checks if MSMS == 1.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and Some of the macros have been renamed to be
|
||||
* consistent, see the xiic_l.h file for further information.
|
||||
* 2.01a ktn 04/09/10 Updated TxErrorhandler to be called for Master Transmitter
|
||||
* case based on Addressed As Slave (AAS) bit rather than
|
||||
* MSMS bit(CR 540199).
|
||||
* 2.06a bss 02/14/13 Modified TxErrorHandler in xiic_intr.c to fix CR #686483
|
||||
* Modified bitwise OR to logical OR in
|
||||
* XIic_InterruptHandler API.
|
||||
* 2.07a adk 18/04/13 Updated the code to avoid unused variable warnings
|
||||
* when compiling with the -Wextra -Wall flags.
|
||||
* In the file xiic.c and xiic_i.h. CR:705001
|
||||
* 3.9 gm 08/02/22 Modified handling of XIIC_INTR_RX_FULL_MASK in xiic_intr.c
|
||||
* to fix CR #1119930 handling RX FULL interrupt before
|
||||
* TX error interrupt and clearing TX error interrupt while
|
||||
* handling RX FULL interrupt when receive byte count is one,
|
||||
* because here the TX error interrupt indicate NACK, not
|
||||
* actually TX error.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions ******************/
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void StubFunction(XIic *InstancePtr);
|
||||
static void TxErrorHandler(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/* The following function pointers are used to help allow finer partitioning
|
||||
* of the driver such that some parts of it are optional. These pointers are
|
||||
* setup by functions in the optional parts of the driver.
|
||||
*/
|
||||
void (*XIic_AddrAsSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_NotAddrAsSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_RecvSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_SendSlaveFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_RecvMasterFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_SendMasterFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_ArbLostFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
void (*XIic_BusNotBusyFuncPtr) (XIic *InstancePtr) = StubFunction;
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the interrupt handler for the XIic driver. This function
|
||||
* should be connected to the interrupt system.
|
||||
*
|
||||
* Only one interrupt source is handled for each interrupt allowing
|
||||
* higher priority system interrupts quicker response time.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The XIIC_INTR_ARB_LOST_MASK and XIIC_INTR_TX_ERROR_MASK interrupts must have
|
||||
* higher priority than the other device interrupts so that the IIC device does
|
||||
* not get into a potentially confused state. The remaining interrupts may be
|
||||
* rearranged with no harm.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_InterruptHandler(void *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 IntrStatus;
|
||||
u32 IntrPending;
|
||||
u32 IntrEnable;
|
||||
XIic *IicPtr = NULL;
|
||||
u32 Clear = 0;
|
||||
|
||||
/*
|
||||
* Verify that each of the inputs are valid.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Convert the non-typed pointer to an IIC instance pointer
|
||||
*/
|
||||
IicPtr = (XIic *) InstancePtr;
|
||||
|
||||
/*
|
||||
* Get the interrupt Status.
|
||||
*/
|
||||
IntrPending = XIic_ReadIisr(IicPtr->BaseAddress);
|
||||
IntrEnable = XIic_ReadIier(IicPtr->BaseAddress);
|
||||
IntrStatus = IntrPending & IntrEnable;
|
||||
|
||||
/*
|
||||
* Do not processes a devices interrupts if the device has no
|
||||
* interrupts pending or the global interrupts have been disabled.
|
||||
*/
|
||||
if ((IntrStatus == 0) ||
|
||||
(XIic_IsIntrGlobalEnabled(IicPtr->BaseAddress) == FALSE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update interrupt stats and get the contents of the status register.
|
||||
*/
|
||||
IicPtr->Stats.IicInterrupts++;
|
||||
Status = XIic_ReadReg(IicPtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* Service requesting interrupt.
|
||||
*/
|
||||
if (IntrStatus & XIIC_INTR_ARB_LOST_MASK) {
|
||||
/* Bus Arbritration Lost */
|
||||
|
||||
IicPtr->Stats.ArbitrationLost++;
|
||||
XIic_ArbLostFuncPtr(IicPtr);
|
||||
|
||||
Clear = XIIC_INTR_ARB_LOST_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
|
||||
/* Receive register/FIFO is full */
|
||||
|
||||
if((IicPtr->RecvByteCount == 1) && (IntrStatus & XIIC_INTR_TX_ERROR_MASK)) {
|
||||
XIic_WriteIisr(IicPtr->BaseAddress, XIIC_INTR_TX_ERROR_MASK);
|
||||
}
|
||||
|
||||
IicPtr->Stats.RecvInterrupts++;
|
||||
|
||||
if (Status & XIIC_SR_ADDR_AS_SLAVE_MASK) {
|
||||
XIic_RecvSlaveFuncPtr(IicPtr);
|
||||
} else {
|
||||
XIic_RecvMasterFuncPtr(IicPtr);
|
||||
}
|
||||
|
||||
Clear = XIIC_INTR_RX_FULL_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_TX_ERROR_MASK) {
|
||||
/* Transmit errors (no acknowledge) received */
|
||||
IicPtr->Stats.TxErrors++;
|
||||
TxErrorHandler(IicPtr);
|
||||
|
||||
Clear = XIIC_INTR_TX_ERROR_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_NAAS_MASK) {
|
||||
/* Not Addressed As Slave */
|
||||
|
||||
XIic_NotAddrAsSlaveFuncPtr(IicPtr);
|
||||
Clear = XIIC_INTR_NAAS_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_AAS_MASK) {
|
||||
/* Addressed As Slave */
|
||||
|
||||
XIic_AddrAsSlaveFuncPtr(IicPtr);
|
||||
Clear = XIIC_INTR_AAS_MASK;
|
||||
} else if (IntrStatus & XIIC_INTR_BNB_MASK) {
|
||||
/* IIC bus has transitioned to not busy */
|
||||
|
||||
/* Check if send callback needs to run */
|
||||
if (IicPtr->BNBOnly == TRUE) {
|
||||
XIic_BusNotBusyFuncPtr(IicPtr);
|
||||
IicPtr->BNBOnly = FALSE;
|
||||
} else {
|
||||
IicPtr->SendHandler(IicPtr->SendCallBackRef, 0);
|
||||
}
|
||||
|
||||
Clear = XIIC_INTR_BNB_MASK;
|
||||
|
||||
/* The bus is not busy, disable BusNotBusy interrupt */
|
||||
XIic_DisableIntr(IicPtr->BaseAddress, XIIC_INTR_BNB_MASK);
|
||||
|
||||
} else if ((IntrStatus & XIIC_INTR_TX_EMPTY_MASK) ||
|
||||
(IntrStatus & XIIC_INTR_TX_HALF_MASK)) {
|
||||
/* Transmit register/FIFO is empty or <20> empty */
|
||||
IicPtr->Stats.SendInterrupts++;
|
||||
|
||||
if (Status & XIIC_SR_ADDR_AS_SLAVE_MASK) {
|
||||
XIic_SendSlaveFuncPtr(IicPtr);
|
||||
} else {
|
||||
XIic_SendMasterFuncPtr(IicPtr);
|
||||
}
|
||||
|
||||
IntrStatus = XIic_ReadIisr(IicPtr->BaseAddress);
|
||||
Clear = IntrStatus & (XIIC_INTR_TX_EMPTY_MASK |
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear Interrupts.
|
||||
*/
|
||||
XIic_WriteIisr(IicPtr->BaseAddress, Clear);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function fills the FIFO using the occupancy register to determine the
|
||||
* available space to be filled. When the repeated start option is on, the last
|
||||
* byte is withheld to allow the control register to be properly set on the last
|
||||
* byte.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @param Role indicates the role of this IIC device, a slave or a master,
|
||||
* on the IIC bus (XIIC_SLAVE_ROLE or XIIC_MASTER_ROLE).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_TransmitFifoFill(XIic *InstancePtr, int Role)
|
||||
{
|
||||
u8 AvailBytes;
|
||||
int LoopCnt;
|
||||
int NumBytesToSend;
|
||||
|
||||
/*
|
||||
* Determine number of bytes to write to FIFO. Number of bytes that
|
||||
* can be put into the FIFO is (FIFO depth) - (current occupancy + 1)
|
||||
* When more room in FIFO than msg bytes put all of message in the FIFO.
|
||||
*/
|
||||
AvailBytes = IIC_TX_FIFO_DEPTH -
|
||||
(u8) (XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_TFO_REG_OFFSET) + 1);
|
||||
|
||||
if (InstancePtr->SendByteCount > AvailBytes) {
|
||||
NumBytesToSend = AvailBytes;
|
||||
} else {
|
||||
/*
|
||||
* More space in FIFO than bytes in message.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_REPEATED_START_OPTION) ||
|
||||
(Role == XIIC_SLAVE_ROLE)) {
|
||||
NumBytesToSend = InstancePtr->SendByteCount;
|
||||
} else {
|
||||
NumBytesToSend = InstancePtr->SendByteCount - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill FIFO with amount determined above.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < NumBytesToSend; LoopCnt++) {
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This interrupt occurs four different ways: Two as master and two as slave.
|
||||
* Master:
|
||||
* <pre>
|
||||
* (1) Transmitter (IMPLIES AN ERROR)
|
||||
* The slave receiver did not acknowledge properly.
|
||||
* (2) Receiver (Implies Tx complete)
|
||||
* Interrupt caused by setting TxAck high in the IIC to indicate to the
|
||||
* the last byte has been transmitted.
|
||||
* </pre>
|
||||
*
|
||||
* Slave:
|
||||
* <pre>
|
||||
* (3) Transmitter (Implies Tx complete)
|
||||
* Interrupt caused by master device indicating last byte of the message
|
||||
* has been transmitted.
|
||||
* (4) Receiver (IMPLIES AN ERROR)
|
||||
* Interrupt caused by setting TxAck high in the IIC to indicate Rx
|
||||
* IIC had a problem - set by this device and condition already known
|
||||
* and interrupt is not enabled.
|
||||
* </pre>
|
||||
*
|
||||
* This interrupt is enabled during Master send and receive and disabled
|
||||
* when this device knows it is going to send a negative acknowledge (Ack = No).
|
||||
*
|
||||
* Signals user of Tx error via status callback sending: XII_TX_ERROR_EVENT
|
||||
*
|
||||
* When MasterRecv has no message to send and only receives one byte of data
|
||||
* from the salve device, the TxError must be enabled to catch addressing
|
||||
* errors, yet there is not opportunity to disable TxError when there is no
|
||||
* data to send allowing disabling on last byte. When the slave sends the
|
||||
* only byte the NOAck causes a Tx Error. To disregard this as no real error,
|
||||
* when there is data in the Receive FIFO/register then the error was not
|
||||
* a device address write error, but a NOACK read error - to be ignored.
|
||||
* To work with or without FIFO's, the Rx Data interrupt is used to indicate
|
||||
* data is in the Rx register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void TxErrorHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* When Sending as a slave, Tx error signals end of msg. Not Addressed
|
||||
* As Slave will handle the callbacks. this is used to only flush
|
||||
* the Tx fifo. The addressed as slave bit is gone as soon as the bus
|
||||
* has been released such that the buffer pointers are used to determine
|
||||
* the direction of transfer (send or receive).
|
||||
*/
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
/*
|
||||
* Master Receiver finished reading message. Flush Tx fifo to
|
||||
* remove an 0xFF that was written to prevent bus throttling,
|
||||
* and disable all transmit and receive interrupts.
|
||||
*/
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_RX_INTERRUPTS);
|
||||
|
||||
/*
|
||||
* If operating in Master mode, call status handler to indicate
|
||||
* NOACK occurred.
|
||||
*/
|
||||
IntrStatus = XIic_ReadIisr(InstancePtr->BaseAddress);
|
||||
if ((IntrStatus & XIIC_INTR_AAS_MASK) == 0) {
|
||||
InstancePtr->StatusHandler(InstancePtr->
|
||||
StatusCallBackRef,
|
||||
XII_SLAVE_NO_ACK_EVENT);
|
||||
} else {
|
||||
/* Decrement the Tx Error since Tx Error interrupt
|
||||
* implies transmit complete while sending as Slave
|
||||
*/
|
||||
InstancePtr->Stats.TxErrors--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data in the receive register from either master or slave receive
|
||||
* When:slave, indicates master sent last byte, message completed.
|
||||
* When:master, indicates a master Receive with one byte received. When
|
||||
* a byte is in Rx reg then the Tx error indicates the Rx data was
|
||||
* recovered normally Tx errors are not enabled such that this should
|
||||
* not occur.
|
||||
*/
|
||||
IntrStatus = XIic_ReadIisr(InstancePtr->BaseAddress);
|
||||
if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
|
||||
/* Rx Reg/FIFO has data, Disable Tx error interrupts */
|
||||
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
return;
|
||||
}
|
||||
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Disable and clear Tx empty, <20> empty, Rx Full or Tx error interrupts.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
|
||||
|
||||
/* Clear MSMS as on Tx error when Rxing, the bus will be
|
||||
* stopped but MSMS bit is still set. Reset to proper state
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
CntlReg &= ~XIIC_CR_MSMS_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
|
||||
/*
|
||||
* Set FIFO occupancy depth = 1 so that the first byte will throttle
|
||||
* next receive msg.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Call the event callback.
|
||||
*/
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
|
||||
XII_SLAVE_NO_ACK_EVENT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is a stub function that is used for the default function for
|
||||
* events that are handled optionally only when the appropriate modules are
|
||||
* linked in. Function pointers are used to handle some events to allow
|
||||
* some events to be optionally handled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void StubFunction(XIic *InstancePtr)
|
||||
{
|
||||
(void )InstancePtr;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
/** @} */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,571 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_l.h
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and driver functions (or
|
||||
* macros) that can be used to access the device in normal and dynamic
|
||||
* controller mode. High-level driver functions are defined in xiic.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 05/07/02 First release
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01d jhl 10/08/03 Added general purpose output feature
|
||||
* 1.02a mta 03/09/06 Implemented Repeated Start in the Low Level Driver.
|
||||
* 1.03a mta 04/04/06 Implemented Dynamic IIC core routines.
|
||||
* 1.03a rpm 09/08/06 Added include of xstatus.h for completeness
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.16a ktn 07/18/09 Updated the notes in XIIC_RESET macro to clearly indicate
|
||||
* that only the Interrupt Registers are reset.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIIC_RESET macro to mention
|
||||
* that the complete IIC core is Reset on giving a software
|
||||
* reset to the IIC core. Some previous versions of the
|
||||
* core only reset the Interrupt Logic/Registers, please
|
||||
* refer to the HW specification for further details.
|
||||
* 2.00a sdm 10/22/09 Converted all register accesses to 32 bit access,
|
||||
* the register offsets are defined to be on 32 bit boundary.
|
||||
* Removed the macro XIIC_RESET, XIic_Reset API should be
|
||||
* used in its place.
|
||||
* Some of the macros have been renamed to be consistent -
|
||||
* XIIC_GINTR_DISABLE is renamed as XIic_IntrGlobalDisable,
|
||||
* XIIC_GINTR_ENABLE is renamed as XIic_IntrGlobalEnable,
|
||||
* XIIC_IS_GINTR_ENABLED is renamed as
|
||||
* XIic_IsIntrGlobalEnabled,
|
||||
* XIIC_WRITE_IISR is renamed as XIic_WriteIisr,
|
||||
* XIIC_READ_IISR is renamed as XIic_ReadIisr,
|
||||
* XIIC_WRITE_IIER is renamed as XIic_WriteIier
|
||||
* The _m prefix in the name of the macros has been removed -
|
||||
* XIic_mClearIisr is now XIic_ClearIisr,
|
||||
* XIic_mSend7BitAddress is now XIic_Send7BitAddress,
|
||||
* XIic_mDynSend7BitAddress is now XIic_DynSend7BitAddress,
|
||||
* XIic_mDynSendStartStopAddress is now
|
||||
* XIic_DynSendStartStopAddress,
|
||||
* XIic_mDynSendStop is now XIic_DynSendStop.
|
||||
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototypes of XIic_Recv, XIic_Send,
|
||||
* XIic_DynRecv, XIic_DynSend and XIic_DynInit APIs.
|
||||
* 3.3 als 06/27/16 Added Low-level XIic_CheckIsBusBusy API.
|
||||
* 3.3 als 06/27/16 Added low-level XIic_WaitBusFree API.
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef XIIC_L_H /* prevent circular inclusions */
|
||||
#define XIIC_L_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
/** @name Register Map
|
||||
*
|
||||
* Register offsets for the XIic device.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_DGIER_OFFSET 0x1C /**< Global Interrupt Enable Register */
|
||||
#define XIIC_IISR_OFFSET 0x20 /**< Interrupt Status Register */
|
||||
#define XIIC_IIER_OFFSET 0x28 /**< Interrupt Enable Register */
|
||||
#define XIIC_RESETR_OFFSET 0x40 /**< Reset Register */
|
||||
#define XIIC_CR_REG_OFFSET 0x100 /**< Control Register */
|
||||
#define XIIC_SR_REG_OFFSET 0x104 /**< Status Register */
|
||||
#define XIIC_DTR_REG_OFFSET 0x108 /**< Data Tx Register */
|
||||
#define XIIC_DRR_REG_OFFSET 0x10C /**< Data Rx Register */
|
||||
#define XIIC_ADR_REG_OFFSET 0x110 /**< Address Register */
|
||||
#define XIIC_TFO_REG_OFFSET 0x114 /**< Tx FIFO Occupancy */
|
||||
#define XIIC_RFO_REG_OFFSET 0x118 /**< Rx FIFO Occupancy */
|
||||
#define XIIC_TBA_REG_OFFSET 0x11C /**< 10 Bit Address reg */
|
||||
#define XIIC_RFD_REG_OFFSET 0x120 /**< Rx FIFO Depth reg */
|
||||
#define XIIC_GPO_REG_OFFSET 0x124 /**< Output Register */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Device Global Interrupt Enable Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_GINTR_ENABLE_MASK 0x80000000 /**< Global Interrupt Enable Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Device Interrupt Status/Enable (INTR) Register Masks
|
||||
*
|
||||
* <b> Interrupt Status Register (IISR) </b>
|
||||
*
|
||||
* This register holds the interrupt status flags for the Spi device.
|
||||
*
|
||||
* <b> Interrupt Enable Register (IIER) </b>
|
||||
*
|
||||
* This register is used to enable interrupt sources for the IIC device.
|
||||
* Writing a '1' to a bit in this register enables the corresponding Interrupt.
|
||||
* Writing a '0' to a bit in this register disables the corresponding Interrupt.
|
||||
*
|
||||
* IISR/IIER registers have the same bit definitions and are only defined once.
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_INTR_ARB_LOST_MASK 0x00000001 /**< 1 = Arbitration lost */
|
||||
#define XIIC_INTR_TX_ERROR_MASK 0x00000002 /**< 1 = Tx error/msg complete */
|
||||
#define XIIC_INTR_TX_EMPTY_MASK 0x00000004 /**< 1 = Tx FIFO/reg empty */
|
||||
#define XIIC_INTR_RX_FULL_MASK 0x00000008 /**< 1 = Rx FIFO/reg=OCY level */
|
||||
#define XIIC_INTR_BNB_MASK 0x00000010 /**< 1 = Bus not busy */
|
||||
#define XIIC_INTR_AAS_MASK 0x00000020 /**< 1 = When addr as slave */
|
||||
#define XIIC_INTR_NAAS_MASK 0x00000040 /**< 1 = Not addr as slave */
|
||||
#define XIIC_INTR_TX_HALF_MASK 0x00000080 /**< 1 = Tx FIFO half empty */
|
||||
|
||||
/**
|
||||
* All Tx interrupts commonly used.
|
||||
*/
|
||||
#define XIIC_TX_INTERRUPTS (XIIC_INTR_TX_ERROR_MASK | \
|
||||
XIIC_INTR_TX_EMPTY_MASK | \
|
||||
XIIC_INTR_TX_HALF_MASK)
|
||||
|
||||
/**
|
||||
* All interrupts commonly used
|
||||
*/
|
||||
#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
|
||||
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Reset Register mask
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_RESET_MASK 0x0000000A /**< RESET Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Control Register masks (CR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_CR_ENABLE_DEVICE_MASK 0x00000001 /**< Device enable = 1 */
|
||||
#define XIIC_CR_TX_FIFO_RESET_MASK 0x00000002 /**< Transmit FIFO reset=1 */
|
||||
#define XIIC_CR_MSMS_MASK 0x00000004 /**< Master starts Txing=1 */
|
||||
#define XIIC_CR_DIR_IS_TX_MASK 0x00000008 /**< Dir of Tx. Txing=1 */
|
||||
#define XIIC_CR_NO_ACK_MASK 0x00000010 /**< Tx Ack. NO ack = 1 */
|
||||
#define XIIC_CR_REPEATED_START_MASK 0x00000020 /**< Repeated start = 1 */
|
||||
#define XIIC_CR_GENERAL_CALL_MASK 0x00000040 /**< Gen Call enabled = 1 */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Status Register masks (SR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_SR_GEN_CALL_MASK 0x00000001 /**< 1 = A Master issued
|
||||
* a GC */
|
||||
#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x00000002 /**< 1 = When addressed as
|
||||
* slave */
|
||||
#define XIIC_SR_BUS_BUSY_MASK 0x00000004 /**< 1 = Bus is busy */
|
||||
#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x00000008 /**< 1 = Dir: Master <--
|
||||
* slave */
|
||||
#define XIIC_SR_TX_FIFO_FULL_MASK 0x00000010 /**< 1 = Tx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_FULL_MASK 0x00000020 /**< 1 = Rx FIFO full */
|
||||
#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x00000040 /**< 1 = Rx FIFO empty */
|
||||
#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x00000080 /**< 1 = Tx FIFO empty */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Tx Register (DTR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define XIIC_TX_DYN_START_MASK 0x00000100 /**< 1 = Set dynamic start */
|
||||
#define XIIC_TX_DYN_STOP_MASK 0x00000200 /**< 1 = Set dynamic stop */
|
||||
#define IIC_TX_FIFO_DEPTH 16 /**< Tx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @name Data Rx Register (DRR) mask(s)
|
||||
* @{
|
||||
*/
|
||||
#define IIC_RX_FIFO_DEPTH 16 /**< Rx fifo capacity */
|
||||
/* @} */
|
||||
|
||||
|
||||
#define XIIC_TX_ADDR_SENT 0x00
|
||||
#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02
|
||||
|
||||
|
||||
/**
|
||||
* The following constants are used to specify whether to do
|
||||
* Read or a Write operation on IIC bus.
|
||||
*/
|
||||
#define XIIC_READ_OPERATION 1 /**< Read operation on the IIC bus */
|
||||
#define XIIC_WRITE_OPERATION 0 /**< Write operation on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with the transmit FIFO fill function to
|
||||
* specify the role which the IIC device is acting as, a master or a slave.
|
||||
*/
|
||||
#define XIIC_MASTER_ROLE 1 /**< Master on the IIC bus */
|
||||
#define XIIC_SLAVE_ROLE 0 /**< Slave on the IIC bus */
|
||||
|
||||
/**
|
||||
* The following constants are used with Transmit Function (XIic_Send) to
|
||||
* specify whether to STOP after the current transfer of data or own the bus
|
||||
* with a Repeated start.
|
||||
*/
|
||||
#define XIIC_STOP 0x00 /**< Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
#define XIIC_REPEATED_START 0x01 /**< Donot Send a stop on the IIC bus after
|
||||
* the current data transfer */
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define XIic_In32 Xil_In32
|
||||
#define XIic_Out32 Xil_Out32
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read from the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the device to
|
||||
* select the specific register.
|
||||
*
|
||||
* @return The value read from the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadReg(u32 BaseAddress, u32 RegOffset);
|
||||
*
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadReg(BaseAddress, RegOffset) \
|
||||
XIic_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write to the specified IIC device register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the offset from the 1st register of the
|
||||
* device to select the specific register.
|
||||
* @param RegisterValue is the value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteReg(u32 BaseAddress, u32 RegOffset,
|
||||
* u32 RegisterValue);
|
||||
* This macro does not do any checking to ensure that the
|
||||
* register exists if the register may be excluded due to
|
||||
* parameterization, such as the GPO Register.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
XIic_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro disables all interrupts for the device by writing to the Global
|
||||
* interrupt enable register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalDisable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalDisable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, 0)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro writes to the global interrupt enable register to enable
|
||||
* interrupts from the device. This function does not enable individual
|
||||
* interrupts as the Interrupt Enable Register must be set appropriately.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_IntrGlobalEnable(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IntrGlobalEnable(BaseAddress) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function determines if interrupts are enabled at the global level by
|
||||
* reading the global interrupt register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the global interrupt is enabled.
|
||||
* - FALSE if global interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* int XIic_IsIntrGlobalEnabled(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_IsIntrGlobalEnabled(BaseAddress) \
|
||||
(XIic_ReadReg((BaseAddress), XIIC_DGIER_OFFSET) == \
|
||||
XIIC_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the Interrupt status register to the specified value.
|
||||
*
|
||||
* This register implements a toggle on write functionality. The interrupt is
|
||||
* cleared by writing to this register with the bits to be cleared set to a one
|
||||
* and all others to zero. Setting a bit which is zero within this register
|
||||
* causes an interrupt to be generated.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some status bits may be set and others cleared. It is the caller's
|
||||
* responsibility to get the value of the register prior to setting the value
|
||||
* to prevent an destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Status is the value to be written to the Interrupt
|
||||
* status register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIisr(u32 BaseAddress, u32 Status);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIisr(BaseAddress, Status) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IISR_OFFSET, (Status))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the contents of the Interrupt Status Register.
|
||||
* This register indicates the status of interrupt sources for the device.
|
||||
* The status is independent of whether interrupts are enabled such
|
||||
* that the status register may also be polled when interrupts are not enabled.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The value read from the Interrupt Status Register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIisr(u32 BaseAddress);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIisr(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IISR_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the contents of the Interrupt Enable Register.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some interrupt sources may be enabled and others disabled. It is the
|
||||
* caller's responsibility to get the value of the interrupt enable register
|
||||
* prior to setting the value to prevent a destructive behavior.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param Enable is the value to be written to the Interrupt Enable
|
||||
* Register. Bit positions of 1 will be enabled. Bit positions of 0
|
||||
* will be disabled.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_WriteIier(u32 BaseAddress, u32 Enable);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_WriteIier(BaseAddress, Enable) \
|
||||
XIic_WriteReg((BaseAddress), XIIC_IIER_OFFSET, (Enable))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This function gets the Interrupt Enable Register contents.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
*
|
||||
* @return The contents read from the Interrupt Enable Register.
|
||||
* Bit positions of 1 indicate that the corresponding interrupt
|
||||
* is enabled. Bit positions of 0 indicate that the corresponding
|
||||
* interrupt is disabled.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIic_ReadIier(u32 BaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ReadIier(BaseAddress) \
|
||||
XIic_ReadReg((BaseAddress), XIIC_IIER_OFFSET)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro clears the specified interrupt in the Interrupt status
|
||||
* register. It is non-destructive in that the register is read and only the
|
||||
* interrupt specified is cleared. Clearing an interrupt acknowledges it.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC device.
|
||||
* @param InterruptMask is the bit mask of the interrupts to be cleared.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_ClearIisr(u32 BaseAddress, u32 InterruptMask);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_ClearIisr(BaseAddress, InterruptMask) \
|
||||
XIic_WriteIisr((BaseAddress), \
|
||||
XIic_ReadIisr(BaseAddress) & (InterruptMask))
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_Send7BitAddress(u32 BaseAddress, u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address for a 7 bit address during both read and write
|
||||
* operations. It takes care of the details to format the address correctly.
|
||||
* This macro is designed to be called internally to the drivers for Dynamic
|
||||
* controller functionality.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSend7BitAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress, u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSend7BitAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends the address, start and stop for a 7 bit address during both
|
||||
* write operations. It takes care of the details to format the address
|
||||
* correctly. This macro is designed to be called internally to the drivers.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param SlaveAddress is the address of the slave to send to.
|
||||
* @param Operation indicates XIIC_WRITE_OPERATION.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStartStopAddress(u32 BaseAddress,
|
||||
* u8 SlaveAddress,
|
||||
* u8 Operation);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStartStopAddress(BaseAddress, SlaveAddress, Operation) \
|
||||
{ \
|
||||
u8 LocalAddr = (u8)(SlaveAddress << 1); \
|
||||
LocalAddr = (LocalAddr & 0xFE) | (Operation); \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_START_MASK | XIIC_TX_DYN_STOP_MASK | \
|
||||
LocalAddr); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sends a stop condition on IIC bus for Dynamic logic.
|
||||
*
|
||||
* @param BaseAddress is the base address of the IIC Device.
|
||||
* @param ByteCount is the number of Rx bytes received before the master.
|
||||
* doesn't respond with ACK.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIic_DynSendStop(u32 BaseAddress, u32 ByteCount);
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIic_DynSendStop(BaseAddress, ByteCount) \
|
||||
{ \
|
||||
XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \
|
||||
XIIC_TX_DYN_STOP_MASK | ByteCount); \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_Send(UINTPTR BaseAddress, u8 Address,
|
||||
u8 *BufferPtr, unsigned ByteCount, u8 Option);
|
||||
|
||||
unsigned XIic_DynRecv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, u8 ByteCount);
|
||||
|
||||
unsigned XIic_DynSend(UINTPTR BaseAddress, u16 Address, u8 *BufferPtr,
|
||||
u8 ByteCount, u8 Option);
|
||||
|
||||
int XIic_DynInit(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress);
|
||||
|
||||
u32 XIic_WaitBusFree(UINTPTR BaseAddress);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
@@ -0,0 +1,739 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_master.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains master functions for the XIic component. This file is necessary to
|
||||
* send or receive as a master on the IIC bus.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 03/27/02 Reparitioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Removed the macro XIic_mEnterCriticalRegion,
|
||||
* XIic_IntrGlobalDisable should be used in its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion,
|
||||
* XIic_IntrGlobalEnable should be used in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for
|
||||
* further information
|
||||
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
|
||||
* SendBufferPtr in XIic_MasterRecv NULL
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This macro includes master code such that master operations, sending
|
||||
* and receiving data, may be used. This function hooks the master processing
|
||||
* to the driver such that events are handled properly and allows master
|
||||
* processing to be optional. It must be called before any functions which
|
||||
* are contained in this file are called, such as after the driver is
|
||||
* initialized.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIC_MASTER_INCLUDE \
|
||||
{ \
|
||||
XIic_RecvMasterFuncPtr = RecvMasterData; \
|
||||
XIic_SendMasterFuncPtr = SendMasterData; \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void SendSlaveAddr(XIic *InstancePtr);
|
||||
static void RecvMasterData(XIic *InstancePtr);
|
||||
static void SendMasterData(XIic *InstancePtr);
|
||||
static int IsBusBusy(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This function sends data as a master on the IIC bus. If the bus is busy, it
|
||||
* will indicate so and then enable an interrupt such that the status handler
|
||||
* will be called when the bus is no longer busy. The slave address which has
|
||||
* been set with the XIic_SetAddress() function is the address to which the
|
||||
* specific data is sent. Sending data on the bus performs a write operation.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
* @param TxMsgPtr points to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message transmission has been
|
||||
* initiated.
|
||||
* - XST_IIC_BUS_BUSY indicates the bus was in use and that
|
||||
* the BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the master processing has been included such that events
|
||||
* will be properly handled.
|
||||
*/
|
||||
XIIC_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus to not be busy, the function enables the bus not busy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it is already a master on the bus (repeated start), the direction
|
||||
* was set to Tx which is throttling bus. The control register needs to
|
||||
* be set before putting data into the FIFO.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
CntlReg &= ~XIIC_CR_NO_ACK_MASK;
|
||||
CntlReg |= (XIIC_CR_DIR_IS_TX_MASK |
|
||||
XIIC_CR_REPEATED_START_MASK);
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state.
|
||||
*/
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = TxMsgPtr;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Put the address into the FIFO to be sent and indicate that the
|
||||
* operation to be performed on the bus is a write operation,
|
||||
* a general call address is handled the same as a 7 bit address even
|
||||
* if 10 bit address is selected.
|
||||
* Set the transmit address state to indicate the address has been sent.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) &&
|
||||
(InstancePtr->AddrOfSlave != 0)) {
|
||||
XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
|
||||
} else {
|
||||
XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
}
|
||||
/*
|
||||
* Set the transmit address state to indicate the address has been sent
|
||||
* for communication with event driven processing.
|
||||
*/
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
|
||||
/*
|
||||
* Fill remaining available FIFO with message data.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* After filling fifo, if data yet to send > 1, enable Tx <20> empty
|
||||
* interrupt.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear any pending Tx empty, Tx Error and then enable them.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK |
|
||||
XIIC_INTR_TX_EMPTY_MASK);
|
||||
|
||||
/*
|
||||
* When repeated start not used, MSMS must be set after putting data
|
||||
* into transmit FIFO, start the transmitter.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
|
||||
CntlReg &= ~XIIC_CR_NO_ACK_MASK;
|
||||
CntlReg |= XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function receives data as a master from a slave device on the IIC bus.
|
||||
* If the bus is busy, it will indicate so and then enable an interrupt such
|
||||
* that the status handler will be called when the bus is no longer busy. The
|
||||
* slave address which has been set with the XIic_SetAddress() function is the
|
||||
* address from which data is received. Receiving data on the bus performs a
|
||||
* read operation.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the Iic instance to be worked on.
|
||||
* @param RxMsgPtr is a pointer to the data to be transmitted
|
||||
* @param ByteCount is the number of message bytes to be sent
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message reception processes has
|
||||
* been initiated.
|
||||
* - XST_IIC_BUS_BUSY indicates the bus was in use and that the
|
||||
* BusNotBusy interrupt is enabled which will update the
|
||||
* EventStatus when the bus is no longer busy.
|
||||
* - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address
|
||||
* is set to the the general call address. This is not allowed
|
||||
* for Master receive mode.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The receive FIFO threshold is a zero based count such that 1 must be
|
||||
* subtracted from the desired count to get the correct value. When receiving
|
||||
* data it is also necessary to not receive the last byte with the prior bytes
|
||||
* because the acknowledge must be setup before the last byte is received.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u8 Temp;
|
||||
|
||||
/*
|
||||
* If the slave address is zero (general call) the master can't perform
|
||||
* receive operations, indicate an error.
|
||||
*/
|
||||
if (InstancePtr->AddrOfSlave == 0) {
|
||||
return XST_IIC_GENERAL_CALL_ADDRESS;
|
||||
}
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Ensure that the master processing has been included such that events
|
||||
* will be properly handled.
|
||||
*/
|
||||
XIIC_MASTER_INCLUDE;
|
||||
InstancePtr->IsDynamic = FALSE;
|
||||
|
||||
/*
|
||||
* If the busy is busy, then exit the critical region and wait for the
|
||||
* bus to not be busy, the function enables the bus not busy interrupt.
|
||||
*/
|
||||
if (IsBusBusy(InstancePtr)) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_IIC_BUS_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save message state for event driven processing.
|
||||
*/
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = RxMsgPtr;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait
|
||||
* until last address byte sent in case arbitration gets lost while
|
||||
* sending out address.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* If already a master on the bus, the direction was set by Rx Interrupt
|
||||
* routine to Tx which is throttling bus because during Rxing, Tx reg is
|
||||
* empty = throttle. CR needs setting before putting data or the address
|
||||
* written will go out as Tx instead of receive. Start Master Rx by
|
||||
* setting CR Bits MSMS to Master and msg direction.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
|
||||
if (CntlReg & XIIC_CR_MSMS_MASK) {
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
|
||||
|
||||
InstancePtr->Stats.RepeatedStarts++;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set receive FIFO occupancy depth which must be done prior to writing
|
||||
* the address in the FIFO because the transmitter will immediatedly
|
||||
* start when in repeated start mode followed by the receiver such that
|
||||
* the number of bytes to receive should be set 1st.
|
||||
*/
|
||||
if (ByteCount == 1) {
|
||||
Temp = 0;
|
||||
} else {
|
||||
if (ByteCount <= IIC_RX_FIFO_DEPTH) {
|
||||
Temp = ByteCount - 2;
|
||||
} else {
|
||||
Temp = IIC_RX_FIFO_DEPTH - 1;
|
||||
}
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
(u32) Temp);
|
||||
|
||||
if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
|
||||
/*
|
||||
* Send the 1st and 2nd byte of the 10 bit address of a write
|
||||
* operation, write because it's a 10 bit address.
|
||||
*/
|
||||
XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
|
||||
XIIC_WRITE_OPERATION);
|
||||
XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
|
||||
|
||||
/*
|
||||
* Set flag to indicate the next byte of the address needs to be
|
||||
* send, clear and enable Tx empty interrupt.
|
||||
*/
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_EMPTY_MASK);
|
||||
} else {
|
||||
/*
|
||||
* 7 bit slave address, send the address for a read operation
|
||||
* and set the state to indicate the address has been sent.
|
||||
*/
|
||||
XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
|
||||
XIIC_READ_OPERATION);
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tx error is enabled in case the address (7 or 10) has no device to
|
||||
* answer with Ack. When only one byte of data, must set NO ACK before
|
||||
* address goes out therefore Tx error must not be enabled as it will
|
||||
* go off immediately and the Rx full interrupt will be checked.
|
||||
* If full, then the one byte was received and the Tx error will be
|
||||
* disabled without sending an error callback msg.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* When repeated start not used, MSMS gets set after putting data
|
||||
* in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
|
||||
* msg direction.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
|
||||
CntlReg |= XIIC_CR_MSMS_MASK;
|
||||
XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
}
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This function checks to see if the IIC bus is busy. If so, it will enable
|
||||
* the bus not busy interrupt such that the driver is notified when the bus
|
||||
* is no longer busy.
|
||||
*
|
||||
* @param InstancePtr points to the Iic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - FALSE indicates the IIC bus is not busy.
|
||||
* - TRUE indicates the bus was in use and that the BusNotBusy
|
||||
* interrupt is enabled which will update the EventStatus when
|
||||
* the bus is no longer busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int IsBusBusy(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u32 StatusReg;
|
||||
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
StatusReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* If this device is already master of the bus as when using the
|
||||
* repeated start and the bus is busy setup to wait for it to not be
|
||||
* busy.
|
||||
*/
|
||||
if (((CntlReg & XIIC_CR_MSMS_MASK) == 0) && /* Not master */
|
||||
(StatusReg & XIIC_SR_BUS_BUSY_MASK)) { /* Is busy */
|
||||
/*
|
||||
* The bus is busy, clear pending BNB interrupt in case
|
||||
* previously set and then enable BusNotBusy interrupt.
|
||||
*/
|
||||
InstancePtr->BNBOnly = TRUE;
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
InstancePtr->Stats.BusBusy++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function sends the proper byte of the address as well as generate the
|
||||
* proper address bit fields depending on the address byte required and the
|
||||
* direction of the data (write or read).
|
||||
*
|
||||
* A master receiving has the restriction that the direction must be switched
|
||||
* from write to read when the third address byte is transmitted.
|
||||
* For the last byte of the 10 bit address, repeated start must be set prior
|
||||
* to writing the address. If repeated start options is enabled, the
|
||||
* control register is written before the address is written to the Tx reg.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function does read/modify/write to the device control register. Calling
|
||||
* functions must ensure critical sections are used.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SendSlaveAddr(XIic *InstancePtr)
|
||||
{
|
||||
u32 CRreg;
|
||||
|
||||
/*
|
||||
* Set the control register for Master Receive, repeated start must be
|
||||
* set before writing the address, MSMS should be already set, don't
|
||||
* set here so if arbitration is lost or some other reason we don't
|
||||
* want MSMS set in case of error.
|
||||
*/
|
||||
CRreg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
|
||||
CRreg |= XIIC_CR_REPEATED_START_MASK;
|
||||
CRreg &= ~XIIC_CR_DIR_IS_TX_MASK;
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CRreg);
|
||||
|
||||
/*
|
||||
* Send the 1st byte of the 10 bit address as a read operation, enable
|
||||
* the receive interrupt to know when data is received, assuming that
|
||||
* the receive FIFO threshold has been previously set.
|
||||
*/
|
||||
XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
|
||||
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* When the IIC Tx FIFO/register goes empty, this routine is called by the
|
||||
* interrupt service routine to fill the transmit FIFO with data to be sent.
|
||||
*
|
||||
* This function also is called by the Tx <20> empty interrupt as the data handling
|
||||
* is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
|
||||
* register to indicate the available free FIFO bytes.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SendMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* The device is a master on the bus. If there is still more address
|
||||
* bytes to send when in master receive operation and the slave device
|
||||
* is 10 bit addressed.
|
||||
* This requires the lower 7 bits of address to be resent when the mode
|
||||
* switches to Read instead of write (while sending addresses).
|
||||
*/
|
||||
if (InstancePtr->TxAddrMode & XIIC_TX_ADDR_MSTR_RECV_MASK) {
|
||||
/*
|
||||
* Send the 1st byte of the slave address in the read operation
|
||||
* and change the state to indicate this has been done
|
||||
*/
|
||||
SendSlaveAddr(InstancePtr);
|
||||
InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* In between 1st and last byte of message, fill the FIFO with more data
|
||||
* to send, disable the 1/2 empty interrupt based upon data left to
|
||||
* send.
|
||||
*/
|
||||
else if (InstancePtr->SendByteCount > 1) {
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
|
||||
|
||||
if (InstancePtr->SendByteCount < 2) {
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If there is only one byte left to send, processing differs between
|
||||
* repeated start and normal messages.
|
||||
*/
|
||||
else if (InstancePtr->SendByteCount == 1) {
|
||||
/*
|
||||
* When using repeated start, another interrupt is expected
|
||||
* after the last byte has been sent, so the message is not
|
||||
* done yet.
|
||||
*/
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* When not using repeated start, the stop condition must be
|
||||
* generated after the last byte is written. The bus is
|
||||
* throttled waiting for the last byte.
|
||||
*/
|
||||
else {
|
||||
/*
|
||||
* Set the stop condition before sending the last byte
|
||||
* of data so that the stop condition will be generated
|
||||
* immediately following the data another transmit
|
||||
* interrupt is not expected so the message is done.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg &= ~XIIC_CR_MSMS_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
XIic_WriteSendByte(InstancePtr);
|
||||
|
||||
/*
|
||||
* Wait for bus to not be busy before declaring message
|
||||
* has been sent for the no repeated start operation.
|
||||
* The callback will be called from the BusNotBusy part
|
||||
* of the Interrupt handler to ensure that the message
|
||||
* is completely sent.
|
||||
* Disable the Tx interrupts and enable the BNB
|
||||
* interrupt.
|
||||
*/
|
||||
|
||||
InstancePtr->BNBOnly = FALSE;
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
XIic_EnableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_BNB_MASK);
|
||||
|
||||
}
|
||||
} else {
|
||||
if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
|
||||
|
||||
/*
|
||||
* The message being sent has completed. When using
|
||||
* repeated start with no more bytes to send repeated
|
||||
* start needs to be set in the control register so
|
||||
* that the bus will still be held by this master.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
/*
|
||||
* If the message that was being sent has finished,
|
||||
* disable all transmit interrupts and call the callback
|
||||
* that was setup to indicate the message was sent,
|
||||
* with 0 bytes remaining.
|
||||
*/
|
||||
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_TX_INTERRUPTS);
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the receive register is full. The number
|
||||
* of bytes received to cause the interrupt is adjustable using the Receive FIFO
|
||||
* Depth register. The number of bytes in the register is read in the Receive
|
||||
* FIFO occupancy register. Both these registers are zero based values (0-15)
|
||||
* such that a value of zero indicates 1 byte.
|
||||
*
|
||||
* For a Master Receiver to properly signal the end of a message, the data must
|
||||
* be read in up to the message length - 1, where control register bits will be
|
||||
* set for bus controls to occur on reading of the last byte.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void RecvMasterData(XIic *InstancePtr)
|
||||
{
|
||||
u8 LoopCnt;
|
||||
int BytesInFifo;
|
||||
int BytesToRead;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* Device is a master receiving, get the contents of the control
|
||||
* register and determine the number of bytes in fifo to be read out.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
BytesInFifo = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET) + 1;
|
||||
|
||||
/*
|
||||
* If data in FIFO holds all data to be retrieved - 1, set NOACK and
|
||||
* disable the Tx error.
|
||||
*/
|
||||
if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
|
||||
/*
|
||||
* Disable Tx error interrupt to prevent interrupt
|
||||
* as this device will cause it when it set NO ACK next.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_ERROR_MASK);
|
||||
|
||||
/*
|
||||
* Write control reg with NO ACK allowing last byte to
|
||||
* have the No ack set to indicate to slave last byte read.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg | XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
/*
|
||||
* Read one byte to clear a place for the last byte to be read
|
||||
* which will set the NO ACK.
|
||||
*/
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If data in FIFO is all the data to be received then get the data
|
||||
* and also leave the device in a good state for the next transaction.
|
||||
*/
|
||||
else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
|
||||
/*
|
||||
* If repeated start option is off then the master should stop
|
||||
* using the bus, otherwise hold the bus, setting repeated start
|
||||
* stops the slave from transmitting data when the FIFO is read.
|
||||
*/
|
||||
if ((InstancePtr->Options & XII_REPEATED_START_OPTION) == 0) {
|
||||
CntlReg &= ~XIIC_CR_MSMS_MASK;
|
||||
} else {
|
||||
CntlReg |= XIIC_CR_REPEATED_START_MASK;
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
/*
|
||||
* Read data from the FIFO then set zero based FIFO read depth
|
||||
* for a byte.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Disable Rx full interrupt and write the control reg with ACK
|
||||
* allowing next byte sent to be acknowledged automatically.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg & ~XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
/*
|
||||
* Send notification of msg Rx complete in RecvHandler callback.
|
||||
*/
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
|
||||
} else {
|
||||
/*
|
||||
* Fifo data not at n-1, read all but the last byte of data
|
||||
* from the slave, if more than a FIFO full yet to receive
|
||||
* read a FIFO full.
|
||||
*/
|
||||
BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
|
||||
if (BytesToRead > IIC_RX_FIFO_DEPTH) {
|
||||
BytesToRead = IIC_RX_FIFO_DEPTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in data from the FIFO.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,211 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_multi_master.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains multi-master functions for the XIic component. This file is
|
||||
* necessary if multiple masters are on the IIC bus such that arbitration can
|
||||
* be lost or the bus can be busy.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/27/02 Reparitioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void BusNotBusyHandler(XIic *InstancePtr);
|
||||
static void ArbitrationLostHandler(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This function includes multi-master code such that multi-master events are
|
||||
* handled properly. Multi-master events include a loss of arbitration and
|
||||
* the bus transitioning from busy to not busy. This function allows the
|
||||
* multi-master processing to be optional. This function must be called prior
|
||||
* to allowing any multi-master events to occur, such as after the driver is
|
||||
* initialized.
|
||||
*
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_MultiMasterInclude(void)
|
||||
{
|
||||
XIic_ArbLostFuncPtr = ArbitrationLostHandler;
|
||||
XIic_BusNotBusyFuncPtr = BusNotBusyHandler;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* The IIC bus busy signals when a master has control of the bus. Until the bus
|
||||
* is released, i.e. not busy, other devices must wait to use it.
|
||||
*
|
||||
* When this interrupt occurs, it signals that the previous master has released
|
||||
* the bus for another user.
|
||||
*
|
||||
* This interrupt is only enabled when the master Tx is waiting for the bus.
|
||||
*
|
||||
* This interrupt causes the following tasks:
|
||||
* - Disable Bus not busy interrupt
|
||||
* - Enable bus Ack
|
||||
* Should the slave receive have disabled acknowledgement, enable to allow
|
||||
* acknowledgment of the sending of our address to again be addressed as
|
||||
* slave
|
||||
* - Flush Rx FIFO
|
||||
* Should the slave receive have disabled acknowledgement, a few bytes may
|
||||
* be in FIFO if Rx full did not occur because of not enough byte in FIFO
|
||||
* to have caused an interrupt.
|
||||
* - Send status to user via status callback with the value:
|
||||
* XII_BUS_NOT_BUSY_EVENT
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void BusNotBusyHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 CntlReg;
|
||||
|
||||
/*
|
||||
* Should the slave receive have disabled acknowledgement,
|
||||
* enable to allow acknowledgment of the sending of our address to
|
||||
* again be addressed as slave.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg & ~XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
/*
|
||||
* Flush Tx FIFO by toggling TxFIFOResetBit. FIFO runs normally at 0
|
||||
* Do this in case needed to Tx FIFO with more than expected if what
|
||||
* was set to Tx was less than what the Master expected - read more
|
||||
* from this slave so FIFO had junk in it.
|
||||
*/
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Flush Rx FIFO should slave Rx had a problem, sent No ack but
|
||||
* still received a few bytes. Should the slave receive have disabled
|
||||
* acknowledgement, clear Rx FIFO.
|
||||
*/
|
||||
XIic_FlushRxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Send Application messaging status via callbacks. Disable either Tx or
|
||||
* Receive interrupt. Which callback depends on messaging direction.
|
||||
*/
|
||||
Status = XIic_ReadIier(InstancePtr->BaseAddress);
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
/*
|
||||
* Slave was sending data (master was reading), disable
|
||||
* all the transmit interrupts.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_TX_INTERRUPTS));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Slave was receiving data (master was writing) disable receive
|
||||
* interrupts.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_INTR_RX_FULL_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send Status in StatusHandler callback.
|
||||
*/
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
|
||||
XII_BUS_NOT_BUSY_EVENT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* When multiple IIC devices attempt to use the bus simultaneously, only
|
||||
* a single device will be able to keep control as a master. Those devices
|
||||
* that didn't retain control over the bus are said to have lost arbitration.
|
||||
* When arbitration is lost, this interrupt occurs sigaling the user that
|
||||
* the message did not get sent as expected.
|
||||
*
|
||||
* This function, at arbitration lost:
|
||||
* - Disables Tx empty, <20> empty and Tx error interrupts
|
||||
* - Clears any Tx empty, <20> empty Rx Full or Tx error interrupts
|
||||
* - Clears Arbitration lost interrupt,
|
||||
* - Flush Tx FIFO
|
||||
* - Call StatusHandler callback with the value: XII_ARB_LOST_EVENT
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void ArbitrationLostHandler(XIic *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Disable Tx empty and <20> empty and Tx error interrupts before clearing
|
||||
* them so they won't occur again.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_TX_INTERRUPTS);
|
||||
|
||||
/*
|
||||
* Clear any Tx empty, <20> empty Rx Full or Tx error interrupts.
|
||||
*/
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress, XIIC_TX_INTERRUPTS);
|
||||
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* Update Status via StatusHandler callback.
|
||||
*/
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
|
||||
XII_ARB_LOST_EVENT);
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,150 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_options.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains options functions for the XIic component. This file is not required
|
||||
* unless the functions in this file are called.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the options for the IIC device driver. The options control
|
||||
* how the device behaves relative to the IIC bus. If an option applies to
|
||||
* how messages are sent or received on the IIC bus, it must be set prior to
|
||||
* calling functions which send or receive data.
|
||||
*
|
||||
* To set multiple options, the values must be ORed together. To not change
|
||||
* existing options, read/modify/write with the current options using
|
||||
* XIic_GetOptions().
|
||||
*
|
||||
* <b>USAGE EXAMPLE:</b>
|
||||
*
|
||||
* Read/modify/write to enable repeated start:
|
||||
* <pre>
|
||||
* u8 Options;
|
||||
* Options = XIic_GetOptions(&Iic);
|
||||
* XIic_SetOptions(&Iic, Options | XII_REPEATED_START_OPTION);
|
||||
* </pre>
|
||||
*
|
||||
* Disabling General Call:
|
||||
* <pre>
|
||||
* Options = XIic_GetOptions(&Iic);
|
||||
* XIic_SetOptions(&Iic, Options &= ~XII_GENERAL_CALL_OPTION);
|
||||
* </pre>
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param NewOptions are the options to be set. See xiic.h for a list of
|
||||
* the available options.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Sending or receiving messages with repeated start enabled, and then
|
||||
* disabling repeated start, will not take effect until another master
|
||||
* transaction is completed. i.e. After using repeated start, the bus will
|
||||
* continue to be throttled after repeated start is disabled until a master
|
||||
* transaction occurs allowing the IIC to release the bus.
|
||||
* <br><br>
|
||||
* Options enabled will have a 1 in its appropriate bit position.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_SetOptions(XIic *InstancePtr, u32 NewOptions)
|
||||
{
|
||||
u32 CntlReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Update the options in the instance and get the contents of the
|
||||
* control register such that the general call option can be modified.
|
||||
*/
|
||||
InstancePtr->Options = NewOptions;
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* The general call option is the only option that maps directly to
|
||||
* a hardware register feature.
|
||||
*/
|
||||
if (NewOptions & XII_GENERAL_CALL_OPTION) {
|
||||
CntlReg |= XIIC_CR_GENERAL_CALL_MASK;
|
||||
} else {
|
||||
CntlReg &= ~XIIC_CR_GENERAL_CALL_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the new control register value to the register.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CntlReg);
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the current options for the IIC device. Options control
|
||||
* the how the device behaves on the IIC bus. See SetOptions for more information
|
||||
* on options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return The options of the IIC device. See xiic.h for a list of
|
||||
* available options.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Options enabled will have a 1 in its appropriate bit position.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 XIic_GetOptions(XIic *InstancePtr)
|
||||
{
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
return InstancePtr->Options;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,135 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2012 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_selftest.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains selftest functions for the XIic component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 03/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.01c sv 05/09/05 Changed the data being written to the Address/Control
|
||||
* Register and removed the code for testing the
|
||||
* Receive Data Register.
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.16a ktn 07/17/09 Updated the test to test only Interrupt Registers
|
||||
* as the software reset only resets the interrupt logic
|
||||
* and the Interrupt Registers are set to default values.
|
||||
* 1.16a ktn 10/16/09 Updated the notes in the XIic_SelfTest() API and
|
||||
* XIIC_RESET macro to mention that the complete IIC core
|
||||
* is Reset on giving a software reset to the IIC core.
|
||||
* Some previous versions of the core only reset the
|
||||
* Interrupt Logic/Registers, please refer to the HW
|
||||
* specification for further details.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Runs a limited self-test on the driver/device. This test does a read/write
|
||||
* test of the Interrupt Registers There is no loopback capabilities for the
|
||||
* device such that this test does not send or receive data.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if no errors are found
|
||||
* - XST_FAILURE if errors are found
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_SelfTest(XIic *InstancePtr)
|
||||
{
|
||||
int Status = XST_SUCCESS;
|
||||
int GlobalIntrStatus;
|
||||
u32 IntrEnableStatus;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Store the Global Interrupt Register and the Interrupt Enable Register
|
||||
* contents.
|
||||
*/
|
||||
GlobalIntrStatus = XIic_IsIntrGlobalEnabled(InstancePtr->BaseAddress);
|
||||
IntrEnableStatus = XIic_ReadIier(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Reset the device so it's in a known state and the default state of
|
||||
* the interrupt registers can be tested.
|
||||
*/
|
||||
XIic_Reset(InstancePtr);
|
||||
|
||||
if (XIic_IsIntrGlobalEnabled(InstancePtr->BaseAddress)!= 0) {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
if (XIic_ReadIier(InstancePtr->BaseAddress)!= 0) {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test Read/Write to the Interrupt Enable register.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
|
||||
if (XIic_ReadIier(InstancePtr->BaseAddress)!= XIIC_TX_RX_INTERRUPTS) {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset device to remove the affects of the previous test.
|
||||
*/
|
||||
XIic_Reset(InstancePtr);
|
||||
|
||||
/*
|
||||
* Restore the Global Interrupt Register and the Interrupt Enable
|
||||
* Register contents.
|
||||
*/
|
||||
if (GlobalIntrStatus == TRUE) {
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
}
|
||||
XIic_WriteIier(InstancePtr->BaseAddress, IntrEnableStatus);
|
||||
|
||||
return Status;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,140 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2005 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_sinit.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* The implementation of the Xiic component's static initialization functionality.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.02a jvb 10/13/05 release
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xparameters.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the unique device ID. The table
|
||||
* IicConfigTable contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId is the unique device ID to look for
|
||||
*
|
||||
* @return A pointer to the configuration data of the device,
|
||||
* or NULL if no match is found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XIic_Config *XIic_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XIic_Config *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XIIC_NUM_INSTANCES; Index++) {
|
||||
if (XIic_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XIic_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initializes a specific XIic instance. The initialization entails:
|
||||
*
|
||||
* - Check the device has an entry in the configuration table.
|
||||
* - Initialize the driver to allow access to the device registers and
|
||||
* initialize other subcomponents necessary for the operation of the device.
|
||||
* - Default options to:
|
||||
* - 7-bit slave addressing
|
||||
* - Send messages as a slave device
|
||||
* - Repeated start off
|
||||
* - General call recognition disabled
|
||||
* - Clear messageing and error statistics
|
||||
*
|
||||
* The XIic_Start() function must be called after this function before the device
|
||||
* is ready to send and receive data on the IIC bus.
|
||||
*
|
||||
* Before XIic_Start() is called, the interrupt control must connect the ISR
|
||||
* routine to the interrupt handler. This is done by the user, and not
|
||||
* XIic_Start() to allow the user to use an interrupt controller of their choice.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param DeviceId is the unique id of the device controlled by this XIic
|
||||
* instance. Passing in a device id associates the generic XIic
|
||||
* instance to a specific device, as chosen by the caller or
|
||||
* application developer.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS when successful
|
||||
* - XST_DEVICE_NOT_FOUND indicates the given device id isn't found
|
||||
* - XST_DEVICE_IS_STARTED indicates the device is started
|
||||
* (i.e. interrupts enabled and messaging is possible).
|
||||
* Must stop before re-initialization is allowed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIic_Initialize(XIic *InstancePtr, u16 DeviceId)
|
||||
{
|
||||
XIic_Config *ConfigPtr; /* Pointer to configuration data */
|
||||
|
||||
/*
|
||||
* Asserts test the validity of selected input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XIic_LookupConfig(DeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return XIic_CfgInitialize(InstancePtr, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,599 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_slave.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains slave functions for the XIic component. This file is necessary when
|
||||
* slave operations, sending and receiving data as a slave on the IIC bus,
|
||||
* are desired.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 1.15a ktn 03/18/09 Minor changes to comply to Doxygen
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* Removed the macro XIic_mEnterCriticalRegion and used
|
||||
* XIic_IntrGlobalDisable int its place.
|
||||
* Removed the macro XIic_mExitCriticalRegion and used
|
||||
* XIic_IntrGlobalEnable in its place.
|
||||
* Some of the macros have been renamed to remove _m from
|
||||
* the name and some of the macros have been renamed to be
|
||||
* consistent, see the xiic_i.h and xiic_l.h files for further
|
||||
* information
|
||||
* 2.03a rkv 01/25/11 Updated in NAAS interrupt handler to support data
|
||||
* received less than FIFO size prior to NAAS interrupt.
|
||||
* Fixed for CR590212.
|
||||
* 2.04a sdm 07/22/11 Added IsSlaveSetAckOff flag to the instance structure.
|
||||
* The IsSlaveSetAckOff is set when the Slave has set the
|
||||
* Ack Off in the RecvSlaveData function and is cleared in the
|
||||
* NotAddrAsSlaveHandler when the master has released the
|
||||
* bus. This flag is to be used by slave applications for
|
||||
* recovering when it has gone out of sync with the master.
|
||||
* CR 615004.
|
||||
* 3.1 adk 01/08/15 When configured as a slave return the actual number of
|
||||
* bytes have been received/sent by the Master
|
||||
* to the user callback (CR: 828504).
|
||||
* 3.7 rna 10/06/20 Flush the RxFIFO in NAAS handler only when the FIFO is not
|
||||
* empty and the controller is still in NAAS state.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
static void AddrAsSlaveHandler(XIic *InstancePtr);
|
||||
static void NotAddrAsSlaveHandler(XIic *InstancePtr);
|
||||
static void RecvSlaveData(XIic *InstancePtr);
|
||||
static void SendSlaveData(XIic *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function includes slave code such that slave events will be processed.
|
||||
* It is necessary to allow slave code to be optional to reduce the size of
|
||||
* the driver. This function may be called at any time but must be prior to
|
||||
* being selected as a slave on the IIC bus. This function may be called prior
|
||||
* to the Cfg_Initialize() function and must be called before any functions in
|
||||
* this file are called.
|
||||
*
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIic_SlaveInclude(void)
|
||||
{
|
||||
XIic_AddrAsSlaveFuncPtr = AddrAsSlaveHandler;
|
||||
XIic_NotAddrAsSlaveFuncPtr = NotAddrAsSlaveHandler;
|
||||
XIic_RecvSlaveFuncPtr = RecvSlaveData;
|
||||
XIic_SendSlaveFuncPtr = SendSlaveData;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data as a slave on the IIC bus and should not be called
|
||||
* until an event has occurred that indicates the device has been selected by
|
||||
* a master attempting read from the slave (XII_MASTER_READ_EVENT).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param TxMsgPtr is a pointer to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message transmission has been
|
||||
* initiated.
|
||||
* - XST_IIC_NOT_SLAVE indicates the device has not been
|
||||
* selected to be a slave on the IIC bus such that data
|
||||
* cannot be sent.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_SlaveSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 Status;
|
||||
|
||||
/*
|
||||
* If the device is not a slave on the IIC bus then indicate an error
|
||||
* because data cannot be sent on the bus.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
if ((Status & XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
|
||||
return XST_IIC_NOT_SLAVE;
|
||||
}
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Save message state and invalidate the receive buffer pointer to
|
||||
* indicate the direction of transfer is sending.
|
||||
*/
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = TxMsgPtr;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Start sending the specified data and then interrupt processing will
|
||||
* complete it.
|
||||
*/
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_SLAVE_ROLE);
|
||||
|
||||
/* Clear any pending Tx empty, Tx Error and interrupt then enable them.
|
||||
* The Tx error interrupt indicates when the message is complete.
|
||||
* If data remaining to be sent, clear and enable Tx <20> empty interrupt.
|
||||
*/
|
||||
IntrStatus = (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK);
|
||||
if (InstancePtr->SendByteCount > 1) {
|
||||
IntrStatus |= XIIC_INTR_TX_HALF_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupts in the status and then enable them and then
|
||||
* exit the critical region.
|
||||
*/
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, IntrStatus);
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data as a slave on the IIC bus and should not be called
|
||||
* until an event has occurred that indicates the device has been selected by
|
||||
* a master attempting read from the slave (XII_MASTER_READ_EVENT).
|
||||
*
|
||||
* If more data is received than specified a No Acknowledge will be sent to
|
||||
* signal the Master to stop sending data. Any received data is read to prevent
|
||||
* the slave device from throttling the bus.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the Iic instance to be worked on.
|
||||
* @param RxMsgPtr is a pointer to the data to be transmitted.
|
||||
* @param ByteCount is the number of message bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS indicates the message transmission has been
|
||||
* initiated.
|
||||
* - XST_IIC_NOT_SLAVE indicates the device has not been selected
|
||||
* to be a slave on the IIC bus such that data cannot be received.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The master signals the message completion differently depending on the
|
||||
* repeated start options.
|
||||
*
|
||||
* When the master is not using repeated start:
|
||||
* - Not Addressed As Slave NAAS interrupt signals the master has sent a stop
|
||||
* condition and is no longer sending data. This doesn't imply that the master
|
||||
* will not send a No Ack. It covers when the master fails to send No
|
||||
* Acknowledge before releasing the bus.
|
||||
* - Tx Error interrupt signals end of message.
|
||||
*
|
||||
* When the master is using repeated start:
|
||||
* - the Tx Error interrupt signals the master finished sending the msg.
|
||||
* - NAAS interrupt will not signal when message is complete as the
|
||||
* master may want to write or read another message with this device.
|
||||
*
|
||||
* To prevent throttling, the slave must contine to read discard the data
|
||||
* when the receive buffer is full. When unexpected bytes are received, No Ack
|
||||
* must be set and the Rx buffer continually read until either NAAS
|
||||
* or Bus Not Busy BND interrupt signals the master is no longer
|
||||
* interacting with this slave. At this point the Ack is set to ON allowing
|
||||
* this device to acknowlefge the an address sent to it for the next
|
||||
* slave message.
|
||||
*
|
||||
* The slave will always receive 1 byte before the bus is throttled causing a
|
||||
* receive pending interrupt before this routine is executed. After one byte
|
||||
* the bus will throttle. The depth is set to the proper amount immediately
|
||||
* allowing the master to send more bytes and then to again throttle, but at the
|
||||
* proper fifo depth. The interrupt is a level. Clearing and enabling will cause
|
||||
* the Rx interrupt to pend at the correct level.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIic_SlaveRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
|
||||
{
|
||||
u32 Status;
|
||||
|
||||
/*
|
||||
* If the device is not a slave on the IIC bus then indicate an error
|
||||
* because data cannot be received on the bus.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
if ((Status & XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
|
||||
return XST_IIC_NOT_SLAVE;
|
||||
}
|
||||
|
||||
XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Save message state and invalidate the send buffer pointer to indicate
|
||||
* the direction of transfer is receive.
|
||||
*/
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = RxMsgPtr;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
|
||||
/*
|
||||
* Set receive FIFO occupancy depth so the Rx interrupt will occur
|
||||
* when all bytes received or if more bytes than will fit in FIFO,
|
||||
* set to max depth.
|
||||
*/
|
||||
if (ByteCount > IIC_RX_FIFO_DEPTH) {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
IIC_RX_FIFO_DEPTH - 1);
|
||||
} else {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
|
||||
ByteCount - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear and enable receive full interrupt except when the bytes to
|
||||
* receive is only 1, don't clear interrupt as it is the only one your
|
||||
* going to get.
|
||||
*/
|
||||
if (ByteCount > 1) {
|
||||
XIic_ClearIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_RX_FULL_MASK);
|
||||
}
|
||||
|
||||
XIic_EnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
|
||||
|
||||
XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the IIC device is Addressed As a Slave (AAS).
|
||||
* This occurs when another device on the bus, a master, has addressed this
|
||||
* device to receive a message.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void AddrAsSlaveHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
int CallValue;
|
||||
|
||||
/*
|
||||
* Disable AAS interrupt to clear the interrupt condition since this is
|
||||
* interrupt does not go away and enable the not addressed as a slave
|
||||
* interrupt to tell when the master stops data transfer.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_INTR_AAS_MASK);
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_NAAS_MASK);
|
||||
|
||||
/*
|
||||
* Determine how the slave is being addressed and call the handler to
|
||||
* notify the user of the event.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
/*
|
||||
* Determine if the master is trying to perform a read or write
|
||||
* operation.
|
||||
*/
|
||||
if (Status & XIIC_SR_MSTR_RDING_SLAVE_MASK) {
|
||||
CallValue = XII_MASTER_READ_EVENT;
|
||||
} else {
|
||||
CallValue = XII_MASTER_WRITE_EVENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* If being addressed with general call also indicate to handler.
|
||||
*/
|
||||
if (Status & XIIC_SR_GEN_CALL_MASK) {
|
||||
CallValue |= XII_GENERAL_CALL_EVENT;
|
||||
}
|
||||
|
||||
InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef, CallValue);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called when the IIC device receives Not Addressed As Slave
|
||||
* (NAAS) interrupt which indicates that the master has released the bus implying
|
||||
* a data transfer is complete.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void NotAddrAsSlaveHandler(XIic *InstancePtr)
|
||||
{
|
||||
u32 Status;
|
||||
u32 CntlReg;
|
||||
u8 BytesToRead;
|
||||
u8 LoopCnt;
|
||||
u32 TxFifoOcy;
|
||||
|
||||
/*
|
||||
* Disable NAAS so that the condition will not continue to interrupt
|
||||
* and enable the addressed as slave interrupt to know when a master
|
||||
* selects a slave on the bus.
|
||||
*/
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress, XIIC_INTR_NAAS_MASK);
|
||||
XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_AAS_MASK);
|
||||
|
||||
/*
|
||||
* In the slave transmitter case pass the actual number of
|
||||
* bytes being recievd by the master to the user callback.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
TxFifoOcy = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_TFO_REG_OFFSET);
|
||||
if (!(Status & XIIC_SR_TX_FIFO_EMPTY_MASK)) {
|
||||
InstancePtr->SendByteCount = InstancePtr->Stats.SendBytes -
|
||||
(TxFifoOcy+1) ;
|
||||
} else {
|
||||
InstancePtr->SendByteCount = InstancePtr->Stats.SendBytes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flush Tx FIFO by toggling TxFIFOResetBit. FIFO runs normally at 0
|
||||
* Do this in case needed to Tx FIFO with more than expected if what
|
||||
* was set to Tx was less than what the Master expected - read more
|
||||
* from this slave so FIFO had junk in it.
|
||||
*/
|
||||
XIic_FlushTxFifo(InstancePtr);
|
||||
|
||||
/*
|
||||
* NAAS interrupt was asserted but received data in receive FIFO is
|
||||
* less than Rc_FIFO_PIRQ to assert an receive full interrupt,in this
|
||||
* condition as data received is valid we have to read data before FIFO
|
||||
* flush.
|
||||
*/
|
||||
Status = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
|
||||
|
||||
if (!(Status & XIIC_SR_RX_FIFO_EMPTY_MASK)) {
|
||||
BytesToRead = (XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET)) + 1;
|
||||
if (InstancePtr->RecvByteCount > BytesToRead) {
|
||||
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
} else if (!(Status & XIIC_SR_ADDR_AS_SLAVE_MASK)) {
|
||||
/*
|
||||
* Flush Rx FIFO should slave Rx had a problem, sent No ack but
|
||||
* still received a few bytes. Should the slave receive have disabled
|
||||
* acknowledgement, clear Rx FIFO.
|
||||
*/
|
||||
XIic_FlushRxFifo(InstancePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set FIFO occupancy depth = 1 so that the first byte will throttle
|
||||
* next receive msg.
|
||||
*/
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Should the slave receive have disabled acknowledgement,
|
||||
* enable to allow acknowledgment for receipt of our address to
|
||||
* again be used as a slave.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
(CntlReg & ~XIIC_CR_NO_ACK_MASK));
|
||||
|
||||
InstancePtr->IsSlaveSetAckOff = FALSE;
|
||||
|
||||
/*
|
||||
* Which callback depends on messaging direction, the buffer pointer NOT
|
||||
* being used indicates the direction of data transfer.
|
||||
*/
|
||||
Status = XIic_ReadIier(InstancePtr->BaseAddress);
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
/*
|
||||
* Slave was sending data so disable all transmit interrupts and
|
||||
* call the callback handler to indicate the transfer is
|
||||
* complete.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_TX_INTERRUPTS));
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
|
||||
InstancePtr->SendByteCount);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Slave was receiving data so disable receive full interrupt
|
||||
* and call the callback handler to notify the transfer is
|
||||
* complete.
|
||||
*/
|
||||
XIic_WriteIier(InstancePtr->BaseAddress,
|
||||
(Status & ~XIIC_INTR_RX_FULL_MASK));
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
|
||||
InstancePtr->RecvByteCount);
|
||||
}
|
||||
InstancePtr->RecvByteCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function handles data received from the IIC bus as a slave.
|
||||
*
|
||||
* When the slave expects more than the master has to send, the slave will stall
|
||||
* waiting for data.
|
||||
*
|
||||
* When more data is received than data expected a Nack is done to signal master
|
||||
* to stop sending data. The excess data is discarded to prevent bus throttling.
|
||||
*
|
||||
* The buffer may be full and the master continues to send data if the master
|
||||
* and slave have different message lengths. This condition is handled by sending
|
||||
* No Ack to the master and reading Rx data until the master stops sending data
|
||||
* to prevent but throttling from locking up the bus. To ever receive as a slave
|
||||
* again, must know when to renable bus ACKs. NAAS is used to detect when the
|
||||
* master is finished sending messages for any mode.
|
||||
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void RecvSlaveData(XIic *InstancePtr)
|
||||
{
|
||||
u32 CntlReg;
|
||||
u8 BytesToRead;
|
||||
u8 LoopCnt;
|
||||
u8 Temp;
|
||||
|
||||
/*
|
||||
* When receive buffer has no room for the receive data discard it.
|
||||
*/
|
||||
if (InstancePtr->RecvByteCount == 0) {
|
||||
/*
|
||||
* Set acknowledge OFF to signal master to stop sending data.
|
||||
*/
|
||||
CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_CR_REG_OFFSET);
|
||||
CntlReg |= XIIC_CR_NO_ACK_MASK;
|
||||
XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
|
||||
CntlReg);
|
||||
|
||||
/*
|
||||
* Set a Flag to indicate that the Slave has set the ACK Off.
|
||||
*/
|
||||
InstancePtr->IsSlaveSetAckOff = TRUE;
|
||||
|
||||
|
||||
/*
|
||||
* Clear excess received data to prevent bus throttling and set
|
||||
* receive FIFO occupancy to throttle at the 1st byte received.
|
||||
*/
|
||||
XIic_FlushRxFifo(InstancePtr);
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Use occupancy count to determine how many bytes to read from the
|
||||
* FIFO, count is zero based so add 1, read that number of bytes from
|
||||
* the FIFO.
|
||||
*/
|
||||
BytesToRead = (XIic_ReadReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFO_REG_OFFSET)) + 1;
|
||||
for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
|
||||
XIic_ReadRecvByte(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set receive FIFO depth for the number of bytes to be received such
|
||||
* that a receive interrupt will occur, the count is 0 based, the
|
||||
* last byte of the message has to be received separately to ack the
|
||||
* message.
|
||||
*/
|
||||
if (InstancePtr->RecvByteCount > IIC_RX_FIFO_DEPTH) {
|
||||
Temp = IIC_RX_FIFO_DEPTH - 1;
|
||||
} else {
|
||||
if (InstancePtr->RecvByteCount == 0) {
|
||||
Temp = 0;
|
||||
} else {
|
||||
Temp = InstancePtr->RecvByteCount - 1;
|
||||
}
|
||||
}
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_RFD_REG_OFFSET, (u32) Temp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data on the IIC bus as a slave.
|
||||
*
|
||||
* When message data has been sent, but the master keeps reading data, the FIFO
|
||||
* is filled to prevent bus throttling. There is no way to notify master of this
|
||||
* condition. While sending data as a slave a transmit error indicates the
|
||||
* master has completed the data transfer.
|
||||
*
|
||||
* NAAS interrupt signals when repeated start occurred and the msg is finished
|
||||
* and BNB signals when the master sent a stop.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SendSlaveData(XIic *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* When message has been sent, but master keeps reading data, must put a
|
||||
* byte in the FIFO or bus will throttle. There is no way to notify
|
||||
* master of this condition.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount == 0) {
|
||||
XIic_WriteReg(InstancePtr->BaseAddress,
|
||||
XIIC_DTR_REG_OFFSET, 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the data by filling the transmit FIFO.
|
||||
*/
|
||||
XIic_TransmitFifoFill(InstancePtr, XIIC_SLAVE_ROLE);
|
||||
/*
|
||||
* When the amount of data remaining to send is less than the half mark
|
||||
* of the FIFO making the use of <20> empty interrupt unnecessary,
|
||||
* disable it. Is this a problem that it's checking against 1 rather
|
||||
* than half?
|
||||
*/
|
||||
if (InstancePtr->SendByteCount < 1) {
|
||||
XIic_DisableIntr(InstancePtr->BaseAddress,
|
||||
XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/** @} */
|
||||
@@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xiic_stats.c
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* Contains statistics functions for the XIic component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- ------- -----------------------------------------------
|
||||
* 1.01b jhl 3/26/02 repartioned the driver
|
||||
* 1.01c ecm 12/05/02 new rev
|
||||
* 1.13a wgr 03/22/07 Converted to new coding style.
|
||||
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
|
||||
* Updated to use the HAL APIs/macros.
|
||||
* XIic_ClearStats function is updated as the
|
||||
* macro XIIC_CLEAR_STATS has been removed.
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files *******************************/
|
||||
|
||||
#include "xiic.h"
|
||||
#include "xiic_i.h"
|
||||
|
||||
/************************** Constant Definitions ***************************/
|
||||
|
||||
/**************************** Type Definitions *****************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *******************/
|
||||
|
||||
/************************** Function Prototypes ****************************/
|
||||
|
||||
/************************** Variable Definitions **************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Gets a copy of the statistics for an IIC device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
* @param StatsPtr is a pointer to a XIicStats structure which will get a
|
||||
* copy of current statistics.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_GetStats(XIic *InstancePtr, XIicStats * StatsPtr)
|
||||
{
|
||||
u8 NumBytes;
|
||||
u8 *SrcPtr;
|
||||
u8 *DestPtr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(StatsPtr != NULL);
|
||||
|
||||
/*
|
||||
* Setup pointers to copy the stats structure
|
||||
*/
|
||||
SrcPtr = (u8 *) &InstancePtr->Stats;
|
||||
DestPtr = (u8 *) StatsPtr;
|
||||
|
||||
/*
|
||||
* Copy the current statistics to the structure passed in
|
||||
*/
|
||||
for (NumBytes = 0; NumBytes < sizeof(XIicStats); NumBytes++) {
|
||||
*DestPtr++ = *SrcPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Clears the statistics for the IIC device by zeroing all counts.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIic instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIic_ClearStats(XIic *InstancePtr)
|
||||
{
|
||||
u8 NumBytes;
|
||||
u8 *DestPtr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
DestPtr = (u8 *)&InstancePtr->Stats;
|
||||
for (NumBytes = 0; NumBytes < sizeof(XIicStats); NumBytes++) {
|
||||
*DestPtr++ = 0;
|
||||
}
|
||||
|
||||
}
|
||||
/** @} */
|
||||
@@ -84,6 +84,10 @@ XIntc_Config XIntc_ConfigTable[] =
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
},
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
},
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
|
||||
@@ -29,6 +29,14 @@ XUartLite_Config XUartLite_ConfigTable[] =
|
||||
XPAR_UARTLITE_0_USE_PARITY,
|
||||
XPAR_UARTLITE_0_ODD_PARITY,
|
||||
XPAR_UARTLITE_0_DATA_BITS
|
||||
},
|
||||
{
|
||||
XPAR_UARTLITE_1_DEVICE_ID,
|
||||
XPAR_UARTLITE_1_BASEADDR,
|
||||
XPAR_UARTLITE_1_BAUDRATE,
|
||||
XPAR_UARTLITE_1_USE_PARITY,
|
||||
XPAR_UARTLITE_1_ODD_PARITY,
|
||||
XPAR_UARTLITE_1_DATA_BITS
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -138,4 +138,16 @@ BEGIN DRIVER
|
||||
PARAMETER HW_INSTANCE = system_management_wiz_0
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = iic
|
||||
PARAMETER DRIVER_VER = 3.9
|
||||
PARAMETER HW_INSTANCE = axi_iic_0
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = uartlite
|
||||
PARAMETER DRIVER_VER = 3.7
|
||||
PARAMETER HW_INSTANCE = mdm_1
|
||||
END
|
||||
|
||||
|
||||
|
||||
@@ -138,4 +138,16 @@ BEGIN DRIVER
|
||||
PARAMETER HW_INSTANCE = system_management_wiz_0
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = iic
|
||||
PARAMETER DRIVER_VER = 3.9
|
||||
PARAMETER HW_INSTANCE = axi_iic_0
|
||||
END
|
||||
|
||||
BEGIN DRIVER
|
||||
PARAMETER DRIVER_NAME = uartlite
|
||||
PARAMETER DRIVER_VER = 3.7
|
||||
PARAMETER HW_INSTANCE = mdm_1
|
||||
END
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user