├── sim
├── run_icarus.bat
├── viewWave.bat
├── build_icarus.bat
├── filelist.icarus
├── myWave.sav
└── gtkwave.ini
├── progFiles
└── 2008_12_17
│ ├── aardvark_sw
│ ├── run_i2cSlaveTest.bat
│ ├── aardvark.dll
│ ├── i2cSlaveTest.exe
│ └── readWriteTest.xml
│ ├── download.bat
│ ├── i2cSlaveTopAltera.rbf
│ └── i2cSlaveTopAltera.rbf.b2d.bin
├── syn
└── Altera
│ ├── download.bat
│ ├── i2cSlaveTopAltera.cof
│ ├── i2cSlaveTopAltera.qpf
│ ├── i2cSlaveTopAltera.qsf
│ ├── i2cSlaveAlteraTop.sdc
│ ├── i2cSlaveTopAltera.v
│ └── pll_48MHz.v
├── doc
├── i2cSlave_FSM.pdf
├── Philips_I2C_spec.pdf
├── i2cSlave_IPCore_Specification.pdf
└── src
│ └── i2cSlave_IPCore_Specification.sxw
├── model
├── i2c_master_specs.pdf
├── i2c_master_defines.v
├── wb_master_model.v
├── i2c_master_top.v
├── i2c_master_byte_ctrl.v
└── i2c_master_bit_ctrl.v
├── sw
├── aardvark_c
│ ├── aardvark.dll
│ ├── README.txt
│ ├── Makefile
│ ├── i2cSlaveTest.c
│ ├── aardvark.h
│ └── aardvark.c
└── aardvark_xml
│ └── readWriteTest.xml
├── Aldec
└── design0
│ ├── fsm.set
│ ├── design0.adf
│ └── src
│ └── serialInterface.asf
├── rtl
├── timescale.v
├── i2cSlave_define.v
├── i2cSlaveTop.v
├── registerInterface.v
├── i2cSlave.v
└── serialInterface.v
└── bench
├── i2cSlaveTB_defines.v
├── testCase0.v
├── testHarness.v
└── multiByteReadWrite.v
/sim/run_icarus.bat:
--------------------------------------------------------------------------------
1 | vvp testHarness
2 |
3 |
--------------------------------------------------------------------------------
/sim/viewWave.bat:
--------------------------------------------------------------------------------
1 | gtkwave wave.vcd myWave.sav
2 |
--------------------------------------------------------------------------------
/sim/build_icarus.bat:
--------------------------------------------------------------------------------
1 | iverilog -o testHarness -cfilelist.icarus
2 |
3 | pause
4 |
5 |
--------------------------------------------------------------------------------
/progFiles/2008_12_17/aardvark_sw/run_i2cSlaveTest.bat:
--------------------------------------------------------------------------------
1 | i2cSlaveTest.exe 0
2 | pause
3 |
4 |
--------------------------------------------------------------------------------
/syn/Altera/download.bat:
--------------------------------------------------------------------------------
1 | fpgaConfig -i i2cSlaveTopAltera.rbf -r -w -l -a 0
2 | pause
3 |
4 |
--------------------------------------------------------------------------------
/doc/i2cSlave_FSM.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/doc/i2cSlave_FSM.pdf
--------------------------------------------------------------------------------
/doc/Philips_I2C_spec.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/doc/Philips_I2C_spec.pdf
--------------------------------------------------------------------------------
/progFiles/2008_12_17/download.bat:
--------------------------------------------------------------------------------
1 | fpgaConfig -i i2cSlaveTopAltera.rbf -r -w -l -a 0
2 | pause
3 |
4 |
--------------------------------------------------------------------------------
/model/i2c_master_specs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/model/i2c_master_specs.pdf
--------------------------------------------------------------------------------
/sw/aardvark_c/aardvark.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/sw/aardvark_c/aardvark.dll
--------------------------------------------------------------------------------
/doc/i2cSlave_IPCore_Specification.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/doc/i2cSlave_IPCore_Specification.pdf
--------------------------------------------------------------------------------
/doc/src/i2cSlave_IPCore_Specification.sxw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/doc/src/i2cSlave_IPCore_Specification.sxw
--------------------------------------------------------------------------------
/progFiles/2008_12_17/i2cSlaveTopAltera.rbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/progFiles/2008_12_17/i2cSlaveTopAltera.rbf
--------------------------------------------------------------------------------
/Aldec/design0/fsm.set:
--------------------------------------------------------------------------------
1 | FSMSET_CUTHEADER=1
2 | FSMSET_GENCOMMENTS=1
3 | FSMSET_USEDEFINE=1
4 | FSMSET_OMITGENNULL=0
5 | FSMSET_ENABLEPARSING=1
6 |
--------------------------------------------------------------------------------
/progFiles/2008_12_17/aardvark_sw/aardvark.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/progFiles/2008_12_17/aardvark_sw/aardvark.dll
--------------------------------------------------------------------------------
/progFiles/2008_12_17/aardvark_sw/i2cSlaveTest.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/progFiles/2008_12_17/aardvark_sw/i2cSlaveTest.exe
--------------------------------------------------------------------------------
/progFiles/2008_12_17/i2cSlaveTopAltera.rbf.b2d.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freecores/i2cslave/HEAD/progFiles/2008_12_17/i2cSlaveTopAltera.rbf.b2d.bin
--------------------------------------------------------------------------------
/rtl/timescale.v:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | // timescale.v
3 | //////////////////////////////////////////////////////////////////////
4 | `timescale 1ns / 1ps
5 |
6 |
--------------------------------------------------------------------------------
/sw/aardvark_c/README.txt:
--------------------------------------------------------------------------------
1 |
2 | Windows gcc-mingw32:
3 | 1) Install GCC MinGW32.
4 | The latest version can be downloaded from the MinGW website:
5 | http://www.mingw.org/
6 | 2) Install MSYS
7 | The latest version can be downloaded from the MinGW website:
8 | http://www.mingw.org/
9 | 3) Type 'make' at the MSYS command line
10 | 4) _output/PROGRAM
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sim/filelist.icarus:
--------------------------------------------------------------------------------
1 | ../rtl/serialInterface.v
2 | ../rtl/registerInterface.v
3 | ../rtl/i2cSlave.v
4 | ../model/i2c_master_bit_ctrl.v
5 | ../model/i2c_master_byte_ctrl.v
6 | ../model/i2c_master_top.v
7 | ../model/wb_master_model.v
8 | ../bench/multiByteReadWrite.v
9 | ../bench/testHarness.v
10 | ../bench/testCase0.v
11 |
12 | +incdir+../rtl
13 | +incdir+../bench
14 | +incdir+../model
15 | +define+SIM_COMPILE
16 |
17 |
--------------------------------------------------------------------------------
/bench/i2cSlaveTB_defines.v:
--------------------------------------------------------------------------------
1 | // ---------------------------- i2cSlaveTB_defines.v -----------------
2 | `define SEND_START 1'b1
3 | `define SEND_STOP 1'b1
4 | `define NULL 1'b0
5 | `define ACK 1'b0
6 | `define NACK 1'b1
7 |
8 | `define DEV_I2C_ADDR 8'hcc
9 |
10 | `define PRER_LO_REG 3'b000
11 | `define PRER_HI_REG 3'b001
12 | `define CTR_REG 3'b010
13 | `define RXR_REG 3'b011
14 | `define TXR_REG 3'b011
15 | `define CR_REG 3'b100
16 | `define SR_REG 3'b100
17 |
18 |
--------------------------------------------------------------------------------
/sw/aardvark_xml/readWriteTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 00 89 ab cd ef
5 | 00
6 |
7 | 04
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/syn/Altera/i2cSlaveTopAltera.cof:
--------------------------------------------------------------------------------
1 |
2 |
3 | NONE
4 | i2cSlaveTopAltera.rbf
5 | 1
6 | 1
7 | 0
8 |
9 | 1
10 |
11 | i2cSlaveTopAltera.sof
12 |
13 |
14 | 4
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Aldec/design0/design0.adf:
--------------------------------------------------------------------------------
1 | [Project]
2 | Current Flow=Generic
3 | VCS=0
4 | version=1
5 | Current Config=compile
6 |
7 | [Configurations]
8 | compile=design0
9 |
10 | [Library]
11 | design0=.\design0.LIB
12 |
13 | [$LibMap$]
14 | design0=.
15 |
16 | [Settings]
17 | FLOW_TYPE=HDL
18 | LANGUAGE=VHDL
19 |
20 | [Files]
21 | /serialInterface.asf=-1
22 |
23 | [Files.Data]
24 | .\src\serialInterface.asf=State Diagram
25 |
26 | [file_out:/serialInterface.asf]
27 | /\compile\serialInterface.v=-1
28 |
29 |
--------------------------------------------------------------------------------
/progFiles/2008_12_17/aardvark_sw/readWriteTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 00 89 ab cd ef
5 | 00
6 |
7 | 04
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sim/myWave.sav:
--------------------------------------------------------------------------------
1 | *-27.236394 43400000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
2 | @28
3 | testHarness.u_i2cSlave.scl
4 | testHarness.u_i2cSlave.sda
5 | @22
6 | testHarness.u_i2cSlave.myReg0[7:0]
7 | testHarness.u_i2cSlave.myReg1[7:0]
8 | testHarness.u_i2cSlave.myReg2[7:0]
9 | testHarness.u_i2cSlave.myReg3[7:0]
10 | testHarness.u_i2cSlave.myReg4[7:0]
11 | testHarness.u_i2cSlave.myReg5[7:0]
12 | testHarness.u_i2cSlave.myReg6[7:0]
13 | testHarness.u_i2cSlave.myReg7[7:0]
14 |
--------------------------------------------------------------------------------
/sim/gtkwave.ini:
--------------------------------------------------------------------------------
1 | #
2 | # sample rc file
3 | #
4 | hier_max_level 1
5 | force_toolbars 0
6 |
7 | dynamic_resizing 1
8 | hpane_pack 1
9 | use_vcd 0
10 | #initial_window_x 700
11 | #initial_window_y 400
12 | use_maxtime_display 0
13 |
14 | enable_vcd_autosave 0
15 | use_roundcaps 1
16 |
17 | use_nonprop_fonts yes
18 | enable_horiz_grid yes
19 | use_big_fonts no
20 | constant_marker_update yes
21 | show_grid yes
22 | show_base_symbols no
23 | use_roundcaps yes
24 |
25 | atomic_vectors yes
26 | vcd_explicit_zero_subscripts no
27 |
28 | #
29 | # color additions
30 | #
31 | color_back 000000
32 | color_grid 202070
33 | color_high 00ff00
34 | color_low 008000
35 | color_trans 00c000
36 | color_mid c0c000
37 |
38 | color_value ffffff
39 | color_vbox 00ff00
40 | color_vtrans 00c000
41 |
42 | color_x 00ff00
43 | color_xfill 004000
44 |
45 | color_umark ff8080
46 | color_mark ffff80
47 |
48 | color_time ffffff
49 | color_timeb 000000
50 |
51 |
--------------------------------------------------------------------------------
/syn/Altera/i2cSlaveTopAltera.qpf:
--------------------------------------------------------------------------------
1 | # Copyright (C) 1991-2007 Altera Corporation
2 | # Your use of Altera Corporation's design tools, logic functions
3 | # and other software and tools, and its AMPP partner logic
4 | # functions, and any output files from any of the foregoing
5 | # (including device programming or simulation files), and any
6 | # associated documentation or information are expressly subject
7 | # to the terms and conditions of the Altera Program License
8 | # Subscription Agreement, Altera MegaCore Function License
9 | # Agreement, or other applicable license agreement, including,
10 | # without limitation, that your use is for the sole purpose of
11 | # programming logic devices manufactured by Altera and sold by
12 | # Altera or its authorized distributors. Please refer to the
13 | # applicable agreement for further details.
14 |
15 |
16 |
17 | QUARTUS_VERSION = "7.2"
18 | DATE = "20:22:13 December 16, 2008"
19 |
20 |
21 | # Revisions
22 |
23 | PROJECT_REVISION = "i2cSlaveTopAltera"
24 |
--------------------------------------------------------------------------------
/bench/testCase0.v:
--------------------------------------------------------------------------------
1 | // ---------------------------------- testcase0.v ----------------------------
2 | `include "timescale.v"
3 | `include "i2cSlave_define.v"
4 | `include "i2cSlaveTB_defines.v"
5 |
6 | module testCase0();
7 |
8 | reg ack;
9 | reg [7:0] data;
10 | reg [15:0] dataWord;
11 | reg [7:0] dataRead;
12 | reg [7:0] dataWrite;
13 | integer i;
14 | integer j;
15 |
16 | initial
17 | begin
18 | $write("\n\n");
19 | testHarness.reset;
20 | #1000;
21 |
22 | // set i2c master clock scale reg PRER = (48MHz / (5 * 400KHz) ) - 1
23 | $write("Testing register read/write\n");
24 | testHarness.u_wb_master_model.wb_write(1, `PRER_LO_REG , 8'h17);
25 | testHarness.u_wb_master_model.wb_write(1, `PRER_HI_REG , 8'h00);
26 | testHarness.u_wb_master_model.wb_cmp(1, `PRER_LO_REG , 8'h17);
27 |
28 | // enable i2c master
29 | testHarness.u_wb_master_model.wb_write(1, `CTR_REG , 8'h80);
30 |
31 | multiByteReadWrite.write({`I2C_ADDRESS, 1'b0}, 8'h00, 32'h89abcdef, `SEND_STOP);
32 | multiByteReadWrite.read({`I2C_ADDRESS, 1'b0}, 8'h00, 32'h89abcdef, dataWord, `NULL);
33 | multiByteReadWrite.read({`I2C_ADDRESS, 1'b0}, 8'h04, 32'h12345678, dataWord, `NULL);
34 |
35 | $write("Finished all tests\n");
36 | $stop;
37 |
38 | end
39 |
40 | endmodule
41 |
42 |
--------------------------------------------------------------------------------
/bench/testHarness.v:
--------------------------------------------------------------------------------
1 | // -------------------------- testHarness.v -----------------------
2 | `include "timescale.v"
3 |
4 | module testHarness ();
5 |
6 | reg rst;
7 | reg clk;
8 | reg i2cHostClk;
9 | wire sda;
10 | wire scl;
11 | wire sdaOutEn;
12 | wire sdaOut;
13 | wire sdaIn;
14 | wire [2:0] adr;
15 | wire [7:0] masterDout;
16 | wire [7:0] masterDin;
17 | wire we;
18 | wire stb;
19 | wire cyc;
20 | wire ack;
21 | wire scl_pad_i;
22 | wire scl_pad_o;
23 | wire scl_padoen_o;
24 | wire sda_pad_i;
25 | wire sda_pad_o;
26 | wire sda_padoen_o;
27 |
28 | initial begin
29 | $dumpfile("wave.vcd");
30 | $dumpvars(0, testHarness);
31 | end
32 |
33 |
34 | i2cSlave u_i2cSlave(
35 | .clk(clk),
36 | .rst(rst),
37 | .sda(sda),
38 | .scl(scl),
39 | .myReg0(),
40 | .myReg1(),
41 | .myReg2(),
42 | .myReg3(),
43 | .myReg4(8'h12),
44 | .myReg5(8'h34),
45 | .myReg6(8'h56),
46 | .myReg7(8'h78)
47 | );
48 |
49 | i2c_master_top #(.ARST_LVL(1'b1)) u_i2c_master_top (
50 | .wb_clk_i(clk),
51 | .wb_rst_i(rst),
52 | .arst_i(rst),
53 | .wb_adr_i(adr),
54 | .wb_dat_i(masterDout),
55 | .wb_dat_o(masterDin),
56 | .wb_we_i(we),
57 | .wb_stb_i(stb),
58 | .wb_cyc_i(cyc),
59 | .wb_ack_o(ack),
60 | .wb_inta_o(),
61 | .scl_pad_i(scl_pad_i),
62 | .scl_pad_o(scl_pad_o),
63 | .scl_padoen_o(scl_padoen_o),
64 | .sda_pad_i(sda_pad_i),
65 | .sda_pad_o(sda_pad_o),
66 | .sda_padoen_o(sda_padoen_o)
67 | );
68 |
69 | wb_master_model #(.dwidth(8), .awidth(3)) u_wb_master_model (
70 | .clk(clk),
71 | .rst(rst),
72 | .adr(adr),
73 | .din(masterDin),
74 | .dout(masterDout),
75 | .cyc(cyc),
76 | .stb(stb),
77 | .we(we),
78 | .sel(),
79 | .ack(ack),
80 | .err(1'b0),
81 | .rty(1'b0)
82 | );
83 |
84 | assign sda = (sda_padoen_o == 1'b0) ? sda_pad_o : 1'bz;
85 | assign sda_pad_i = sda;
86 | pullup(sda);
87 |
88 | assign scl = (scl_padoen_o == 1'b0) ? scl_pad_o : 1'bz;
89 | assign scl_pad_i = scl;
90 | pullup(scl);
91 |
92 |
93 | // ****************************** Clock section ******************************
94 | //approx 48MHz clock
95 | `define CLK_HALF_PERIOD 10
96 | always begin
97 | #`CLK_HALF_PERIOD clk <= 1'b0;
98 | #`CLK_HALF_PERIOD clk <= 1'b1;
99 | end
100 |
101 |
102 | // ****************************** reset ******************************
103 | task reset;
104 | begin
105 | rst <= 1'b1;
106 | @(posedge clk);
107 | @(posedge clk);
108 | @(posedge clk);
109 | @(posedge clk);
110 | @(posedge clk);
111 | @(posedge clk);
112 | rst <= 1'b0;
113 | @(posedge clk);
114 | @(posedge clk);
115 | @(posedge clk);
116 | end
117 | endtask
118 |
119 | endmodule
120 |
--------------------------------------------------------------------------------
/rtl/i2cSlave_define.v:
--------------------------------------------------------------------------------
1 | // ----------------------- i2cSlave_define.v --------------------
2 |
3 | // stream states
4 | `define STREAM_IDLE 2'b00
5 | `define STREAM_READ 2'b01
6 | `define STREAM_WRITE_ADDR 2'b10
7 | `define STREAM_WRITE_DATA 2'b11
8 |
9 | // start stop detection states
10 | `define NULL_DET 2'b00
11 | `define START_DET 2'b01
12 | `define STOP_DET 2'b10
13 |
14 | // i2c ack and nak
15 | `define I2C_NAK 1'b1
16 | `define I2C_ACK 1'b0
17 |
18 | // ----------------------------------------------------------------
19 | // ------------- modify constants below this line -----------------
20 | // ----------------------------------------------------------------
21 |
22 | // i2c device address
23 | `define I2C_ADDRESS 7'h3c
24 |
25 | // System clock frequency in MHz
26 | // If you are using a clock frequency below 24MHz, then the macro
27 | // for SDA_DEL_LEN will result in compile errors for i2cSlave.v
28 | // you will need to hand tweak the SDA_DEL_LEN constant definition
29 | `define CLK_FREQ 48
30 |
31 | // Debounce SCL and SDA over this many clock ticks
32 | // The rise time of SCL and SDA can be up to 1000nS (in standard mode)
33 | // so it is essential to debounce the inputs.
34 | // The spec requires 0.05V of hysteresis, but in practise
35 | // simply debouncing the inputs is sufficient
36 | // I2C spec requires suppresion of spikes of
37 | // maximum duration 50nS, so this debounce time should be greater than 50nS
38 | // Also increases data hold time and decreases data setup time
39 | // during an I2C read operation
40 | // 10 ticks = 208nS @ 48MHz
41 | `define DEB_I2C_LEN (10*`CLK_FREQ)/48
42 |
43 | // Delay SCL for use as internal sampling clock
44 | // Using delayed version of SCL to ensure that
45 | // SDA is stable when it is sampled.
46 | // Not entirely citical, as according to I2C spec
47 | // SDA should have a minimum of 100nS of set up time
48 | // with respect to SCL rising edge. But with the very slow edge
49 | // speeds used in I2C it is better to err on the side of caution.
50 | // This delay also has the effect of adding extra hold time to the data
51 | // with respect to SCL falling edge. I2C spec requires 0nS of data hold time.
52 | // 10 ticks = 208nS @ 48MHz
53 | `define SCL_DEL_LEN (10*`CLK_FREQ)/48
54 |
55 | // Delay SDA for use in start/stop detection
56 | // Use delayed SDA during start/stop detection to avoid
57 | // incorrect detection at SCL falling edge.
58 | // From I2C spec start/stop setup is 600nS with respect to SCL rising edge
59 | // and start/stop hold is 600nS wrt SCL falling edge.
60 | // So it is relatively easy to discriminate start/stop,
61 | // but data setup time is a minimum of 100nS with respect to SCL rising edge
62 | // and 0nS hold wrt to SCL falling edge.
63 | // So the tricky part is providing robust start/stop detection
64 | // in the presence of regular data transitions.
65 | // This delay time should be less than 100nS
66 | // 4 ticks = 83nS @ 48MHz
67 | `define SDA_DEL_LEN (4*`CLK_FREQ)/48
68 |
69 |
--------------------------------------------------------------------------------
/sw/aardvark_c/Makefile:
--------------------------------------------------------------------------------
1 | #==========================================================================
2 | # (c) 2003-2008 Total Phase, Inc.
3 | #--------------------------------------------------------------------------
4 | # Project : Aardvark Sample Code
5 | # File : Makefile
6 | #--------------------------------------------------------------------------
7 | # Redistribution and use of this file in source and binary forms, with
8 | # or without modification, are permitted.
9 | #
10 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
11 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
12 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
14 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
15 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
16 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
18 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
20 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 | # POSSIBILITY OF SUCH DAMAGE.
22 | #==========================================================================
23 |
24 | #==========================================================================
25 | # CONFIGURATION
26 | #==========================================================================
27 | OS=$(shell if [ -x /bin/uname ]; then /bin/uname; fi)
28 |
29 | ifeq ($(OS),Linux)
30 | SYSLIBS=-ldl
31 | endif
32 |
33 |
34 | #==========================================================================
35 | # CONSTANTS
36 | #==========================================================================
37 | OUTDIR=_output
38 | CC=gcc
39 | CFLAGS=-Wall -Werror
40 | LD=$(CC)
41 |
42 |
43 | #==========================================================================
44 | # TARGETS
45 | #==========================================================================
46 | TARGETS= i2cSlaveTest
47 |
48 | BINARIES=$(TARGETS:%=$(OUTDIR)/%)
49 |
50 | all : $(OUTDIR) $(BINARIES)
51 | @if [ -r aardvark.so ]; then cp -f aardvark.so $(OUTDIR); fi
52 | @if [ -r aardvark.dll ]; then cp -f aardvark.dll $(OUTDIR); fi
53 |
54 | $(BINARIES) : % : $(OUTDIR)/aardvark.o %.o
55 | @echo " Linking $@"
56 | @$(LD) -o $@ $^ $(SYSLIBS)
57 |
58 |
59 | #==========================================================================
60 | # RULES
61 | #==========================================================================
62 | $(OUTDIR)/%.o : %.c
63 | @echo "+++ Compiling $<"
64 | @$(CC) $(CFLAGS) -c -o $@ $<
65 |
66 | $(OUTDIR) :
67 | @echo "=== Making output directory."
68 | -@mkdir -p $(OUTDIR)
69 |
70 | clean:
71 | @echo "=== Cleaning output directory."
72 | @rm -fr $(OUTDIR)
73 | @rm -f MSVC/*.ncb MSVC/*.opt MSVC/*.plg
74 | @rm -f .bak* *~
75 |
--------------------------------------------------------------------------------
/model/i2c_master_defines.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// WISHBONE rev.B2 compliant I2C Master controller defines ////
4 | //// ////
5 | //// ////
6 | //// Author: Richard Herveille ////
7 | //// richard@asics.ws ////
8 | //// www.asics.ws ////
9 | //// ////
10 | //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
11 | //// ////
12 | /////////////////////////////////////////////////////////////////////
13 | //// ////
14 | //// Copyright (C) 2001 Richard Herveille ////
15 | //// richard@asics.ws ////
16 | //// ////
17 | //// This source file may be used and distributed without ////
18 | //// restriction provided that this copyright statement is not ////
19 | //// removed from the file and that any derivative work contains ////
20 | //// the original copyright notice and the associated disclaimer.////
21 | //// ////
22 | //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
23 | //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
24 | //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
25 | //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
26 | //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
27 | //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
28 | //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
29 | //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
30 | //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
31 | //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
32 | //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
33 | //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
34 | //// POSSIBILITY OF SUCH DAMAGE. ////
35 | //// ////
36 | /////////////////////////////////////////////////////////////////////
37 |
38 | // CVS Log
39 | //
40 | // $Id: i2c_master_defines.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
41 | //
42 | // $Date: 2008-11-08 13:15:10 $
43 | // $Revision: 1.1 $
44 | // $Author: sfielding $
45 | // $Locker: $
46 | // $State: Exp $
47 | //
48 | // Change History:
49 | // $Log: not supported by cvs2svn $
50 | // Revision 1.3 2001/11/05 11:59:25 rherveille
51 | // Fixed wb_ack_o generation bug.
52 | // Fixed bug in the byte_controller statemachine.
53 | // Added headers.
54 | //
55 |
56 |
57 | // I2C registers wishbone addresses
58 |
59 | // bitcontroller states
60 | `define I2C_CMD_NOP 4'b0000
61 | `define I2C_CMD_START 4'b0001
62 | `define I2C_CMD_STOP 4'b0010
63 | `define I2C_CMD_WRITE 4'b0100
64 | `define I2C_CMD_READ 4'b1000
65 |
--------------------------------------------------------------------------------
/rtl/i2cSlaveTop.v:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// i2cSlaveTop.v ////
4 | //// ////
5 | //// This file is part of the i2cSlave opencores effort.
6 | //// ////
7 | //// ////
8 | //// Module Description: ////
9 | //// You will need to modify this file to implement your
10 | //// interface.
11 | //// ////
12 | //// To Do: ////
13 | ////
14 | //// ////
15 | //// Author(s): ////
16 | //// - Steve Fielding, sfielding@base2designs.com ////
17 | //// ////
18 | //////////////////////////////////////////////////////////////////////
19 | //// ////
20 | //// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
21 | //// ////
22 | //// This source file may be used and distributed without ////
23 | //// restriction provided that this copyright statement is not ////
24 | //// removed from the file and that any derivative work contains ////
25 | //// the original copyright notice and the associated disclaimer. ////
26 | //// ////
27 | //// This source file is free software; you can redistribute it ////
28 | //// and/or modify it under the terms of the GNU Lesser General ////
29 | //// Public License as published by the Free Software Foundation; ////
30 | //// either version 2.1 of the License, or (at your option) any ////
31 | //// later version. ////
32 | //// ////
33 | //// This source is distributed in the hope that it will be ////
34 | //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
35 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
36 | //// PURPOSE. See the GNU Lesser General Public License for more ////
37 | //// details. ////
38 | //// ////
39 | //// You should have received a copy of the GNU Lesser General ////
40 | //// Public License along with this source; if not, download it ////
41 | //// from ////
42 | //// ////
43 | //////////////////////////////////////////////////////////////////////
44 | //
45 | `include "i2cSlave_define.v"
46 |
47 |
48 | module i2cSlaveTop (
49 | clk,
50 | rst,
51 | sda,
52 | scl,
53 | myReg0
54 | );
55 | input clk;
56 | input rst;
57 | inout sda;
58 | input scl;
59 | output [7:0] myReg0;
60 |
61 |
62 | i2cSlave u_i2cSlave(
63 | .clk(clk),
64 | .rst(rst),
65 | .sda(sda),
66 | .scl(scl),
67 | .myReg0(myReg0),
68 | .myReg1(),
69 | .myReg2(),
70 | .myReg3(),
71 | .myReg4(8'h12),
72 | .myReg5(8'h34),
73 | .myReg6(8'h56),
74 | .myReg7(8'h78)
75 |
76 | );
77 |
78 |
79 | endmodule
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/syn/Altera/i2cSlaveTopAltera.qsf:
--------------------------------------------------------------------------------
1 | # Copyright (C) 1991-2007 Altera Corporation
2 | # Your use of Altera Corporation's design tools, logic functions
3 | # and other software and tools, and its AMPP partner logic
4 | # functions, and any output files from any of the foregoing
5 | # (including device programming or simulation files), and any
6 | # associated documentation or information are expressly subject
7 | # to the terms and conditions of the Altera Program License
8 | # Subscription Agreement, Altera MegaCore Function License
9 | # Agreement, or other applicable license agreement, including,
10 | # without limitation, that your use is for the sole purpose of
11 | # programming logic devices manufactured by Altera and sold by
12 | # Altera or its authorized distributors. Please refer to the
13 | # applicable agreement for further details.
14 |
15 |
16 | # The default values for assignments are stored in the file
17 | # i2cSlaveTopAltera_assignment_defaults.qdf
18 | # If this file doesn't exist, and for assignments not listed, see file
19 | # assignment_defaults.qdf
20 |
21 | # Altera recommends that you do not modify this file. This
22 | # file is updated automatically by the Quartus II software
23 | # and any changes you make may be lost or overwritten.
24 |
25 |
26 | set_global_assignment -name FAMILY "Cyclone II"
27 | set_global_assignment -name DEVICE EP2C20Q240C8
28 | set_global_assignment -name TOP_LEVEL_ENTITY i2cSlaveTopAltera
29 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION "7.2 SP3"
30 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "20:22:13 DECEMBER 16, 2008"
31 | set_global_assignment -name LAST_QUARTUS_VERSION "7.2 SP3"
32 | set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_palace
33 | set_global_assignment -name USER_LIBRARIES ../../rtl/
34 | set_global_assignment -name VERILOG_FILE ../../rtl/timescale.v
35 | set_global_assignment -name VERILOG_FILE ../../rtl/i2cSlave.v
36 | set_global_assignment -name VERILOG_FILE ../../rtl/i2cSlave_define.v
37 | set_global_assignment -name VERILOG_FILE ../../rtl/i2cSlaveTop.v
38 | set_global_assignment -name VERILOG_FILE ../../rtl/registerInterface.v
39 | set_global_assignment -name VERILOG_FILE ../../rtl/serialInterface.v
40 | set_global_assignment -name VERILOG_FILE pll_48MHz.v
41 | set_global_assignment -name VERILOG_FILE i2cSlaveTopAltera.v
42 |
43 |
44 | set_global_assignment -name NUMBER_OF_PATHS_TO_REPORT 1000
45 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF
46 | set_global_assignment -name USE_TIMEQUEST_TIMING_ANALYZER ON
47 | set_global_assignment -name TIMEQUEST_DO_REPORT_TIMING ON
48 | set_global_assignment -name SDC_FILE i2cSlaveAlteraTop.sdc
49 |
50 | set_global_assignment -name RESERVE_PIN "AS INPUT TRI-STATED"
51 | set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"
52 | set_global_assignment -name CYCLONEII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
53 | set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
54 |
55 |
56 | set_location_assignment PIN_30 -to clk
57 | set_location_assignment PIN_46 -to LED
58 | set_location_assignment PIN_41 -to scl
59 | set_location_assignment PIN_42 -to sda
60 |
61 |
62 |
63 | set_instance_assignment -name PARTITION_HIERARCHY no_file_for_top_partition -to | -section_id Top
64 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
65 | set_global_assignment -name PARTITION_COLOR 2147039 -section_id Top
66 | set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
67 | set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
68 |
--------------------------------------------------------------------------------
/syn/Altera/i2cSlaveAlteraTop.sdc:
--------------------------------------------------------------------------------
1 | ## Generated SDC file "i2cSlaveAlteraTop.sdc"
2 |
3 | ## Copyright (C) 1991-2007 Altera Corporation
4 | ## Your use of Altera Corporation's design tools, logic functions
5 | ## and other software and tools, and its AMPP partner logic
6 | ## functions, and any output files from any of the foregoing
7 | ## (including device programming or simulation files), and any
8 | ## associated documentation or information are expressly subject
9 | ## to the terms and conditions of the Altera Program License
10 | ## Subscription Agreement, Altera MegaCore Function License
11 | ## Agreement, or other applicable license agreement, including,
12 | ## without limitation, that your use is for the sole purpose of
13 | ## programming logic devices manufactured by Altera and sold by
14 | ## Altera or its authorized distributors. Please refer to the
15 | ## applicable agreement for further details.
16 |
17 |
18 | ## VENDOR "Altera"
19 | ## PROGRAM "Quartus II"
20 | ## VERSION "Version 7.2 Build 203 02/05/2008 Service Pack 2 SJ Web Edition"
21 |
22 | ## DATE "Fri May 16 09:55:20 2008"
23 |
24 | ##
25 | ## DEVICE "EP2C20Q240C8"
26 | ##
27 |
28 |
29 | #**************************************************************
30 | # Time Information
31 | #**************************************************************
32 |
33 | set_time_format -unit ns -decimal_places 3
34 |
35 |
36 |
37 | #**************************************************************
38 | # Create Clock
39 | #**************************************************************
40 |
41 | create_clock -name {clk} -period 20.830 -waveform { 0.000 10.415 } [get_ports {clk}] -add
42 |
43 |
44 | #**************************************************************
45 | # Create Generated Clock
46 | #**************************************************************
47 |
48 | derive_pll_clocks -use_tan_name
49 |
50 |
51 | #**************************************************************
52 | # Set Clock Latency
53 | #**************************************************************
54 |
55 |
56 |
57 | #**************************************************************
58 | # Set Clock Uncertainty
59 | #**************************************************************
60 |
61 |
62 |
63 | #**************************************************************
64 | # Set Input Delay
65 | #**************************************************************
66 |
67 |
68 |
69 | #**************************************************************
70 | # Set Output Delay
71 | #**************************************************************
72 |
73 |
74 |
75 | #**************************************************************
76 | # Set Clock Groups
77 | #**************************************************************
78 |
79 |
80 |
81 | #**************************************************************
82 | # Set False Path
83 | #**************************************************************
84 |
85 |
86 |
87 | #**************************************************************
88 | # Set Multicycle Path
89 | #**************************************************************
90 |
91 |
92 |
93 | #**************************************************************
94 | # Set Maximum Delay
95 | #**************************************************************
96 |
97 |
98 |
99 | #**************************************************************
100 | # Set Minimum Delay
101 | #**************************************************************
102 |
103 |
104 |
105 | #**************************************************************
106 | # Set Input Transition
107 | #**************************************************************
108 |
109 |
110 |
111 | #**************************************************************
112 | # Set Load
113 | #**************************************************************
114 |
115 |
--------------------------------------------------------------------------------
/syn/Altera/i2cSlaveTopAltera.v:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// i2cSlaveTopAltera.v ////
4 | //// ////
5 | //// This file is part of the i2cSlave opencores effort.
6 | //// ////
7 | //// ////
8 | //// Module Description: ////
9 | //// You will need to modify this file to implement your
10 | //// interface.
11 | //// ////
12 | //// To Do: ////
13 | ////
14 | //// ////
15 | //// Author(s): ////
16 | //// - Steve Fielding, sfielding@base2designs.com ////
17 | //// ////
18 | //////////////////////////////////////////////////////////////////////
19 | //// ////
20 | //// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
21 | //// ////
22 | //// This source file may be used and distributed without ////
23 | //// restriction provided that this copyright statement is not ////
24 | //// removed from the file and that any derivative work contains ////
25 | //// the original copyright notice and the associated disclaimer. ////
26 | //// ////
27 | //// This source file is free software; you can redistribute it ////
28 | //// and/or modify it under the terms of the GNU Lesser General ////
29 | //// Public License as published by the Free Software Foundation; ////
30 | //// either version 2.1 of the License, or (at your option) any ////
31 | //// later version. ////
32 | //// ////
33 | //// This source is distributed in the hope that it will be ////
34 | //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
35 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
36 | //// PURPOSE. See the GNU Lesser General Public License for more ////
37 | //// details. ////
38 | //// ////
39 | //// You should have received a copy of the GNU Lesser General ////
40 | //// Public License along with this source; if not, download it ////
41 | //// from ////
42 | //// ////
43 | //////////////////////////////////////////////////////////////////////
44 | //
45 | `include "i2cSlave_define.v"
46 |
47 |
48 | module i2cSlaveTopAltera (
49 | clk,
50 | sda,
51 | scl,
52 | LED
53 | );
54 | input clk;
55 | inout sda;
56 | input scl;
57 | output LED;
58 |
59 | //local wires and regs
60 | reg [1:0] rstReg;
61 | wire rst;
62 | wire pll_locked;
63 | wire [7:0] myReg0;
64 |
65 | assign LED = myReg0[0];
66 |
67 | i2cSlave u_i2cSlave(
68 | .clk(clk),
69 | .rst(rst),
70 | .sda(sda),
71 | .scl(scl),
72 | .myReg0(myReg0),
73 | .myReg1(),
74 | .myReg2(),
75 | .myReg3(),
76 | .myReg4(8'h12),
77 | .myReg5(8'h34),
78 | .myReg6(8'h56),
79 | .myReg7(8'h78)
80 |
81 | );
82 |
83 | pll_48MHz pll_48MHz_inst (
84 | .inclk0 ( clk ),
85 | .locked( pll_locked)
86 | );
87 |
88 | //generate sync reset from pll lock signal
89 | always @(posedge clk) begin
90 | rstReg[1:0] <= {rstReg[0], ~pll_locked};
91 | end
92 | assign rst = rstReg[1];
93 |
94 | endmodule
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/rtl/registerInterface.v:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// registerInterface.v ////
4 | //// ////
5 | //// This file is part of the i2cSlave opencores effort.
6 | //// ////
7 | //// ////
8 | //// Module Description: ////
9 | //// You will need to modify this file to implement your
10 | //// interface.
11 | //// Add your control and status bytes/bits to module inputs and outputs,
12 | //// and also to the I2C read and write process blocks
13 | //// ////
14 | //// To Do: ////
15 | ////
16 | //// ////
17 | //// Author(s): ////
18 | //// - Steve Fielding, sfielding@base2designs.com ////
19 | //// ////
20 | //////////////////////////////////////////////////////////////////////
21 | //// ////
22 | //// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
23 | //// ////
24 | //// This source file may be used and distributed without ////
25 | //// restriction provided that this copyright statement is not ////
26 | //// removed from the file and that any derivative work contains ////
27 | //// the original copyright notice and the associated disclaimer. ////
28 | //// ////
29 | //// This source file is free software; you can redistribute it ////
30 | //// and/or modify it under the terms of the GNU Lesser General ////
31 | //// Public License as published by the Free Software Foundation; ////
32 | //// either version 2.1 of the License, or (at your option) any ////
33 | //// later version. ////
34 | //// ////
35 | //// This source is distributed in the hope that it will be ////
36 | //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
37 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
38 | //// PURPOSE. See the GNU Lesser General Public License for more ////
39 | //// details. ////
40 | //// ////
41 | //// You should have received a copy of the GNU Lesser General ////
42 | //// Public License along with this source; if not, download it ////
43 | //// from ////
44 | //// ////
45 | //////////////////////////////////////////////////////////////////////
46 | //
47 | `include "i2cSlave_define.v"
48 |
49 |
50 | module registerInterface (
51 | clk,
52 | addr,
53 | dataIn,
54 | writeEn,
55 | dataOut,
56 | myReg0,
57 | myReg1,
58 | myReg2,
59 | myReg3,
60 | myReg4,
61 | myReg5,
62 | myReg6,
63 | myReg7
64 |
65 | );
66 | input clk;
67 | input [7:0] addr;
68 | input [7:0] dataIn;
69 | input writeEn;
70 | output [7:0] dataOut;
71 | output [7:0] myReg0;
72 | output [7:0] myReg1;
73 | output [7:0] myReg2;
74 | output [7:0] myReg3;
75 | input [7:0] myReg4;
76 | input [7:0] myReg5;
77 | input [7:0] myReg6;
78 | input [7:0] myReg7;
79 |
80 | reg [7:0] dataOut;
81 | reg [7:0] myReg0;
82 | reg [7:0] myReg1;
83 | reg [7:0] myReg2;
84 | reg [7:0] myReg3;
85 |
86 | // --- I2C Read
87 | always @(posedge clk) begin
88 | case (addr)
89 | 8'h00: dataOut <= myReg0;
90 | 8'h01: dataOut <= myReg1;
91 | 8'h02: dataOut <= myReg2;
92 | 8'h03: dataOut <= myReg3;
93 | 8'h04: dataOut <= myReg4;
94 | 8'h05: dataOut <= myReg5;
95 | 8'h06: dataOut <= myReg6;
96 | 8'h07: dataOut <= myReg7;
97 | default: dataOut <= 8'h00;
98 | endcase
99 | end
100 |
101 | // --- I2C Write
102 | always @(posedge clk) begin
103 | if (writeEn == 1'b1) begin
104 | case (addr)
105 | 8'h00: myReg0 <= dataIn;
106 | 8'h01: myReg1 <= dataIn;
107 | 8'h02: myReg2 <= dataIn;
108 | 8'h03: myReg3 <= dataIn;
109 | endcase
110 | end
111 | end
112 |
113 | endmodule
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/sw/aardvark_c/i2cSlaveTest.c:
--------------------------------------------------------------------------------
1 | /*=========================================================================
2 | |
3 | |--------------------------------------------------------------------------
4 | |
5 | | File : i2cSlaveTest.c
6 | |--------------------------------------------------------------------------
7 | |
8 | |--------------------------------------------------------------------------
9 | ========================================================================*/
10 |
11 | //=========================================================================
12 | // INCLUDES
13 | //=========================================================================
14 | #include
15 | #include
16 | #include
17 |
18 | #include "aardvark.h"
19 |
20 | #ifdef _MSC_VER
21 | #define fileno _fileno
22 | #endif
23 |
24 |
25 | //=========================================================================
26 | // CONSTANTS
27 | //=========================================================================
28 | #define I2C_BITRATE 400 // kHz
29 |
30 |
31 | //=========================================================================
32 | // STATIC FUNCTIONS
33 | //=========================================================================
34 | static int testRegs (Aardvark handle, unsigned char LEDstate)
35 | {
36 | int res, i, count;
37 | unsigned char data_out[16];
38 | unsigned char data_in[16];
39 | unsigned char expected_data [] = {LEDstate, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78};
40 |
41 |
42 | // Set address reg = 0
43 | data_out[0] = 0x00;
44 | res = aa_i2c_write(handle, 0x3c, AA_I2C_NO_FLAGS, 1, data_out);
45 | if (res < 0) return res;
46 |
47 | if (res == 0) {
48 | printf("error: slave device 0x38 not found\n");
49 | return -1;
50 | }
51 |
52 | // Write to registers 0 through 3
53 | data_out[0] = 0x00;
54 | data_out[1] = LEDstate;
55 | data_out[2] = 0xab;
56 | data_out[3] = 0xcd;
57 | data_out[4] = 0xef;
58 | res = aa_i2c_write(handle, 0x3c, AA_I2C_NO_FLAGS, 5, data_out);
59 | if (res < 0) return res;
60 |
61 |
62 |
63 | // Set address reg = 0
64 | data_out[0] = 0x00;
65 | res = aa_i2c_write(handle, 0x3c, AA_I2C_NO_FLAGS, 1, data_out);
66 | if (res < 0) return res;
67 | if (res == 0) {
68 | printf("error: slave device 0x38 not found\n");
69 | return -1;
70 | }
71 | //read 8 bytes
72 | count = aa_i2c_read(handle, 0x3c, AA_I2C_NO_FLAGS, 8, data_in);
73 | if (count < 0) {
74 | printf("error: %s\n", aa_status_string(count));
75 | return -1;
76 | }
77 | if (count == 0) {
78 | printf("error: no bytes read\n");
79 | printf(" are you sure you have the right slave address?\n");
80 | return -1;
81 | }
82 | else if (count != 8) {
83 | printf("error: read %d bytes (expected 8)\n", count);
84 | return -1;
85 | }
86 | // Dump the data to the screen
87 | //printf("\nData read from device:");
88 | for (i = 0; i < count; ++i) {
89 | //printf("Reg[0x%02x] = 0x%02x\n", i, data_in[i]);
90 | if (expected_data[i] != data_in[i]) {
91 | printf("Reg[0x%02x] expected 0x%02x got 0x%02x\n", i, expected_data[i], data_in[i]);
92 | return -1;
93 | }
94 | }
95 | //printf("\n");
96 |
97 | return 0;
98 | }
99 |
100 |
101 | //=========================================================================
102 | // MAIN PROGRAM
103 | //=========================================================================
104 | int main (int argc, char *argv[]) {
105 | Aardvark handle;
106 | int port = 0;
107 | int bitrate = 100;
108 | int res = 0;
109 | //FILE *logfile = 0;
110 | int i;
111 | unsigned char LEDstate;
112 |
113 | if (argc < 2) {
114 | printf("usage: i2cSlaveTest PORT\n");
115 | return 1;
116 | }
117 |
118 | port = atoi(argv[1]);
119 |
120 | // Open the device
121 | handle = aa_open(port);
122 | if (handle <= 0) {
123 | printf("Unable to open Aardvark device on port %d\n", port);
124 | printf("Error code = %d\n", handle);
125 | return 1;
126 | }
127 |
128 | // Enable logging
129 | //logfile = fopen("log.txt", "at");
130 | //if (logfile != 0) {
131 | // aa_log(handle, 3, fileno(logfile));
132 | //}
133 |
134 | // Ensure that the I2C subsystem is enabled
135 | aa_configure(handle, AA_CONFIG_SPI_I2C);
136 |
137 | // Enable the I2C bus pullup resistors (2.2k resistors).
138 | // This command is only effective on v2.0 hardware or greater.
139 | // The pullup resistors on the v1.02 hardware are enabled by default.
140 | aa_i2c_pullup(handle, AA_I2C_PULLUP_NONE);
141 |
142 | // Power the board using the Aardvark adapter's power supply.
143 | // This command is only effective on v2.0 hardware or greater.
144 | // The power pins on the v1.02 hardware are not enabled by default.
145 | aa_target_power(handle, AA_TARGET_POWER_NONE);
146 |
147 | // Set the bitrate
148 | bitrate = aa_i2c_bitrate(handle, I2C_BITRATE);
149 | printf("Bitrate set to %d kHz\n", bitrate);
150 |
151 | i = 0;
152 | LEDstate = 0x89;
153 | do {
154 | i++;
155 | res = testRegs(handle, LEDstate);
156 | if (i % 100 == 0) {
157 | if (LEDstate == 0x89) LEDstate = 0x88; else LEDstate = 0x89;
158 | printf("Test loop: %d\n", i);
159 | fflush(stdout);
160 | }
161 | } while (i <= 100000 && res >= 0);
162 | if (res < 0)
163 | printf("error: %s\n", aa_status_string(res));
164 | else
165 | printf("All tests passed\n");
166 |
167 | // Close the device and exit
168 | aa_close(handle);
169 |
170 | // Close the logging file
171 | //fclose(logfile);
172 |
173 | return 0;
174 | }
175 |
--------------------------------------------------------------------------------
/model/wb_master_model.v:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// wb_master_model.v ////
4 | //// ////
5 | //// This file is part of the SPI IP core project ////
6 | //// http://www.opencores.org/projects/spi/ ////
7 | //// ////
8 | //// Author(s): ////
9 | //// - Simon Srot (simons@opencores.org) ////
10 | //// ////
11 | //// Based on: ////
12 | //// - i2c/bench/verilog/wb_master_model.v ////
13 | //// Copyright (C) 2001 Richard Herveille ////
14 | //// ////
15 | //// All additional information is avaliable in the Readme.txt ////
16 | //// file. ////
17 | //// ////
18 | //////////////////////////////////////////////////////////////////////
19 | //// ////
20 | //// Copyright (C) 2002 Authors ////
21 | //// ////
22 | //// This source file may be used and distributed without ////
23 | //// restriction provided that this copyright statement is not ////
24 | //// removed from the file and that any derivative work contains ////
25 | //// the original copyright notice and the associated disclaimer. ////
26 | //// ////
27 | //// This source file is free software; you can redistribute it ////
28 | //// and/or modify it under the terms of the GNU Lesser General ////
29 | //// Public License as published by the Free Software Foundation; ////
30 | //// either version 2.1 of the License, or (at your option) any ////
31 | //// later version. ////
32 | //// ////
33 | //// This source is distributed in the hope that it will be ////
34 | //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
35 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
36 | //// PURPOSE. See the GNU Lesser General Public License for more ////
37 | //// details. ////
38 | //// ////
39 | //// You should have received a copy of the GNU Lesser General ////
40 | //// Public License along with this source; if not, download it ////
41 | //// from http://www.opencores.org/lgpl.shtml ////
42 | //// ////
43 | //////////////////////////////////////////////////////////////////////
44 |
45 | `include "timescale.v"
46 |
47 | module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty);
48 |
49 | parameter dwidth = 32;
50 | parameter awidth = 32;
51 |
52 | input clk, rst;
53 | output [awidth -1:0] adr;
54 | input [dwidth -1:0] din;
55 | output [dwidth -1:0] dout;
56 | output cyc, stb;
57 | output we;
58 | output [dwidth/8 -1:0] sel;
59 | input ack, err, rty;
60 |
61 | // Internal signals
62 | reg [awidth -1:0] adr;
63 | reg [dwidth -1:0] dout;
64 | reg cyc, stb;
65 | reg we;
66 | reg [dwidth/8 -1:0] sel;
67 |
68 | reg [dwidth -1:0] q;
69 |
70 | // Memory Logic
71 | initial
72 | begin
73 | adr = {awidth{1'bx}};
74 | dout = {dwidth{1'bx}};
75 | cyc = 1'b0;
76 | stb = 1'bx;
77 | we = 1'hx;
78 | sel = {dwidth/8{1'bx}};
79 | #1;
80 | end
81 |
82 | // Wishbone write cycle
83 | task wb_write;
84 | input delay;
85 | integer delay;
86 |
87 | input [awidth -1:0] a;
88 | input [dwidth -1:0] d;
89 |
90 | begin
91 |
92 | // wait initial delay
93 | repeat(delay) @(posedge clk);
94 |
95 | // assert wishbone signal
96 | #1;
97 | adr = a;
98 | dout = d;
99 | cyc = 1'b1;
100 | stb = 1'b1;
101 | we = 1'b1;
102 | sel = {dwidth/8{1'b1}};
103 | @(posedge clk);
104 |
105 | // wait for acknowledge from slave
106 | while(~ack) @(posedge clk);
107 |
108 | // negate wishbone signals
109 | #1;
110 | cyc = 1'b0;
111 | stb = 1'bx;
112 | adr = {awidth{1'bx}};
113 | dout = {dwidth{1'bx}};
114 | we = 1'hx;
115 | sel = {dwidth/8{1'bx}};
116 |
117 | end
118 | endtask
119 |
120 | // Wishbone read cycle
121 | task wb_read;
122 | input delay;
123 | integer delay;
124 |
125 | input [awidth -1:0] a;
126 | output [dwidth -1:0] d;
127 |
128 | begin
129 |
130 | // wait initial delay
131 | repeat(delay) @(posedge clk);
132 |
133 | // assert wishbone signals
134 | #1;
135 | adr = a;
136 | dout = {dwidth{1'bx}};
137 | cyc = 1'b1;
138 | stb = 1'b1;
139 | we = 1'b0;
140 | sel = {dwidth/8{1'b1}};
141 | @(posedge clk);
142 |
143 | // wait for acknowledge from slave
144 | while(~ack) @(posedge clk);
145 |
146 | // negate wishbone signals
147 | #1;
148 | cyc = 1'b0;
149 | stb = 1'bx;
150 | adr = {awidth{1'bx}};
151 | dout = {dwidth{1'bx}};
152 | we = 1'hx;
153 | sel = {dwidth/8{1'bx}};
154 | d = din;
155 |
156 | end
157 | endtask
158 |
159 | // Wishbone compare cycle (read data from location and compare with expected data)
160 | task wb_cmp;
161 | input delay;
162 | integer delay;
163 |
164 | input [awidth -1:0] a;
165 | input [dwidth -1:0] d_exp;
166 |
167 | begin
168 | wb_read (delay, a, q);
169 |
170 | if (d_exp !== q)
171 | $display("Data compare error. Received %h, expected %h at time %t", q, d_exp, $time);
172 | end
173 | endtask
174 |
175 | endmodule
176 |
177 |
--------------------------------------------------------------------------------
/bench/multiByteReadWrite.v:
--------------------------------------------------------------------------------
1 | // ------------------ multiByteReadWrite.v ----------------------
2 | `include "timescale.v"
3 | `include "i2cSlaveTB_defines.v"
4 |
5 |
6 | module multiByteReadWrite();
7 | reg ack;
8 | reg [31:0] readData;
9 | reg [7:0] dataByteRead;
10 | //reg [7:0] dataMSB;
11 |
12 | // ------------------ write ----------------------
13 | task write;
14 | input [7:0] i2cAddr;
15 | input [7:0] regAddr;
16 | input [31:0] data;
17 | input stop;
18 |
19 | begin
20 | $write("I2C Write: At [0x%0x] = 0x%0x\n", regAddr, data);
21 |
22 | //i2c address
23 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, i2cAddr);
24 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h90); //STA, WR
25 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
26 | while (dataByteRead[1] == 1'b1) //while trans in progress
27 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
28 | //$write("I2C device address sent, SR = 0x%x\n", dataByteRead );
29 |
30 | //slave reg address
31 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, regAddr);
32 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR
33 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
34 | while (dataByteRead[1] == 1'b1) //while trans in progress
35 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
36 | //$write("Slave reg address sent, SR = 0x%x\n", dataByteRead );
37 |
38 | //data[31:24]
39 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[31:24]);
40 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR
41 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
42 | while (dataByteRead[1] == 1'b1) //while trans in progress
43 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
44 | //$write("Data[31:24] sent, SR = 0x%x\n", dataByteRead );
45 |
46 | //data[23:16]
47 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[23:16]);
48 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR
49 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
50 | while (dataByteRead[1] == 1'b1) //while trans in progress
51 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
52 | //$write("Data[23:16] sent, SR = 0x%x\n", dataByteRead );
53 |
54 | //data[15:8]
55 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[15:8]);
56 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR
57 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
58 | while (dataByteRead[1] == 1'b1) //while trans in progress
59 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
60 | //$write("Data[15:8] sent, SR = 0x%x\n", dataByteRead );
61 |
62 | //data[7:0]
63 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[7:0]);
64 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , {1'b0, stop, 6'b010000}); //STO?, WR
65 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
66 | while (dataByteRead[1] == 1'b1) //while trans in progress
67 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
68 | //$write("Data[7:0] sent, SR = 0x%x\n", dataByteRead );
69 |
70 | end
71 | endtask
72 |
73 | // ------------------ read ----------------------
74 | task read;
75 | input [7:0] i2cAddr;
76 | input [7:0] regAddr;
77 | input [31:0] expectedData;
78 | output [31:0] data;
79 | input stop;
80 |
81 | begin
82 |
83 | //i2c address
84 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, i2cAddr); //write
85 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h90); //STA, WR
86 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
87 | while (dataByteRead[1] == 1'b1) //while trans in progress
88 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
89 | //$write("I2C device address sent, SR = 0x%x\n", dataByteRead );
90 | #5000;
91 |
92 | //slave reg address
93 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, regAddr);
94 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , {1'b0, stop, 6'b010000}); //STO?, WR
95 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
96 | while (dataByteRead[1] == 1'b1) //while trans in progress
97 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
98 | //$write("Slave reg address sent, SR = 0x%x\n", dataByteRead );
99 | #5000;
100 |
101 | //i2c address
102 | testHarness.u_wb_master_model.wb_write(1, `TXR_REG, {i2cAddr[7:1], 1'b1}); //read
103 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h90); //STA, WR
104 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
105 | while (dataByteRead[1] == 1'b1) //while trans in progress
106 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
107 | //$write("I2C device address sent, SR = 0x%x\n", dataByteRead );
108 |
109 | //data[31:24]
110 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h20); //RD, ACK
111 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
112 | while (dataByteRead[1] == 1'b1) //while trans in progress
113 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
114 | //$write("Data[31:24] rxed, SR = 0x%x\n", dataByteRead );
115 | testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[31:24]);
116 |
117 | //data[23:16]
118 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h20); //RD, ACK
119 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
120 | while (dataByteRead[1] == 1'b1) //while trans in progress
121 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
122 | //$write("Data[23:16] rxed, SR = 0x%x\n", dataByteRead );
123 | testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[23:16]);
124 |
125 | //data[15:8]
126 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h20); //RD, ACK
127 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
128 | while (dataByteRead[1] == 1'b1) //while trans in progress
129 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
130 | //$write("Data[15:8] rxed, SR = 0x%x\n", dataByteRead );
131 | testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[15:8]);
132 |
133 | //data[7:0]
134 | testHarness.u_wb_master_model.wb_write(1, `CR_REG , {1'b0, 1'b0, 6'b101000}); //STO, RD, NAK
135 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
136 | while (dataByteRead[1] == 1'b1) //while trans in progress
137 | testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead);
138 | //$write("Data[7:0] rxed, SR = 0x%x\n", dataByteRead );
139 | testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[7:0]);
140 |
141 | data = readData;
142 | if (data != expectedData) begin
143 | $write("***** I2C Read ERROR: At 0x%0x. Expected 0x%0x, got 0x%0x\n", regAddr, expectedData, data);
144 | $stop;
145 | end
146 | else
147 | $write("I2C Read: At [0x%0x] = 0x%0x\n", regAddr, data);
148 | end
149 | endtask
150 |
151 | endmodule
152 |
153 |
--------------------------------------------------------------------------------
/rtl/i2cSlave.v:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// i2cSlave.v ////
4 | //// ////
5 | //// This file is part of the i2cSlave opencores effort.
6 | //// ////
7 | //// ////
8 | //// Module Description: ////
9 | //// You will need to modify this file to implement your
10 | //// interface.
11 | //// ////
12 | //// To Do: ////
13 | ////
14 | //// ////
15 | //// Author(s): ////
16 | //// - Steve Fielding, sfielding@base2designs.com ////
17 | //// ////
18 | //////////////////////////////////////////////////////////////////////
19 | //// ////
20 | //// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
21 | //// ////
22 | //// This source file may be used and distributed without ////
23 | //// restriction provided that this copyright statement is not ////
24 | //// removed from the file and that any derivative work contains ////
25 | //// the original copyright notice and the associated disclaimer. ////
26 | //// ////
27 | //// This source file is free software; you can redistribute it ////
28 | //// and/or modify it under the terms of the GNU Lesser General ////
29 | //// Public License as published by the Free Software Foundation; ////
30 | //// either version 2.1 of the License, or (at your option) any ////
31 | //// later version. ////
32 | //// ////
33 | //// This source is distributed in the hope that it will be ////
34 | //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
35 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
36 | //// PURPOSE. See the GNU Lesser General Public License for more ////
37 | //// details. ////
38 | //// ////
39 | //// You should have received a copy of the GNU Lesser General ////
40 | //// Public License along with this source; if not, download it ////
41 | //// from ////
42 | //// ////
43 | //////////////////////////////////////////////////////////////////////
44 | //
45 | `include "i2cSlave_define.v"
46 |
47 |
48 | module i2cSlave (
49 | clk,
50 | rst,
51 | sda,
52 | scl,
53 | myReg0,
54 | myReg1,
55 | myReg2,
56 | myReg3,
57 | myReg4,
58 | myReg5,
59 | myReg6,
60 | myReg7
61 | );
62 |
63 | input clk;
64 | input rst;
65 | inout sda;
66 | input scl;
67 | output [7:0] myReg0;
68 | output [7:0] myReg1;
69 | output [7:0] myReg2;
70 | output [7:0] myReg3;
71 | input [7:0] myReg4;
72 | input [7:0] myReg5;
73 | input [7:0] myReg6;
74 | input [7:0] myReg7;
75 |
76 |
77 | // local wires and regs
78 | reg sdaDeb;
79 | reg sclDeb;
80 | reg [`DEB_I2C_LEN-1:0] sdaPipe;
81 | reg [`DEB_I2C_LEN-1:0] sclPipe;
82 |
83 | reg [`SCL_DEL_LEN-1:0] sclDelayed;
84 | reg [`SDA_DEL_LEN-1:0] sdaDelayed;
85 | reg [1:0] startStopDetState;
86 | wire clearStartStopDet;
87 | wire sdaOut;
88 | wire sdaIn;
89 | wire [7:0] regAddr;
90 | wire [7:0] dataToRegIF;
91 | wire writeEn;
92 | wire [7:0] dataFromRegIF;
93 | reg [1:0] rstPipe;
94 | wire rstSyncToClk;
95 | reg startEdgeDet;
96 |
97 | assign sda = (sdaOut == 1'b0) ? 1'b0 : 1'bz;
98 | assign sdaIn = sda;
99 |
100 | // sync rst rsing edge to clk
101 | always @(posedge clk) begin
102 | if (rst == 1'b1)
103 | rstPipe <= 2'b11;
104 | else
105 | rstPipe <= {rstPipe[0], 1'b0};
106 | end
107 |
108 | assign rstSyncToClk = rstPipe[1];
109 |
110 | // debounce sda and scl
111 | always @(posedge clk) begin
112 | if (rstSyncToClk == 1'b1) begin
113 | sdaPipe <= {`DEB_I2C_LEN{1'b1}};
114 | sdaDeb <= 1'b1;
115 | sclPipe <= {`DEB_I2C_LEN{1'b1}};
116 | sclDeb <= 1'b1;
117 | end
118 | else begin
119 | sdaPipe <= {sdaPipe[`DEB_I2C_LEN-2:0], sdaIn};
120 | sclPipe <= {sclPipe[`DEB_I2C_LEN-2:0], scl};
121 | if (&sclPipe[`DEB_I2C_LEN-1:1] == 1'b1)
122 | sclDeb <= 1'b1;
123 | else if (|sclPipe[`DEB_I2C_LEN-1:1] == 1'b0)
124 | sclDeb <= 1'b0;
125 | if (&sdaPipe[`DEB_I2C_LEN-1:1] == 1'b1)
126 | sdaDeb <= 1'b1;
127 | else if (|sdaPipe[`DEB_I2C_LEN-1:1] == 1'b0)
128 | sdaDeb <= 1'b0;
129 | end
130 | end
131 |
132 |
133 | // delay scl and sda
134 | // sclDelayed is used as a delayed sampling clock
135 | // sdaDelayed is only used for start stop detection
136 | // Because sda hold time from scl falling is 0nS
137 | // sda must be delayed with respect to scl to avoid incorrect
138 | // detection of start/stop at scl falling edge.
139 | always @(posedge clk) begin
140 | if (rstSyncToClk == 1'b1) begin
141 | sclDelayed <= {`SCL_DEL_LEN{1'b1}};
142 | sdaDelayed <= {`SDA_DEL_LEN{1'b1}};
143 | end
144 | else begin
145 | sclDelayed <= {sclDelayed[`SCL_DEL_LEN-2:0], sclDeb};
146 | sdaDelayed <= {sdaDelayed[`SDA_DEL_LEN-2:0], sdaDeb};
147 | end
148 | end
149 |
150 | // start stop detection
151 | always @(posedge clk) begin
152 | if (rstSyncToClk == 1'b1) begin
153 | startStopDetState <= `NULL_DET;
154 | startEdgeDet <= 1'b0;
155 | end
156 | else begin
157 | if (sclDeb == 1'b1 && sdaDelayed[`SDA_DEL_LEN-2] == 1'b0 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b1)
158 | startEdgeDet <= 1'b1;
159 | else
160 | startEdgeDet <= 1'b0;
161 | if (clearStartStopDet == 1'b1)
162 | startStopDetState <= `NULL_DET;
163 | else if (sclDeb == 1'b1) begin
164 | if (sdaDelayed[`SDA_DEL_LEN-2] == 1'b1 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b0)
165 | startStopDetState <= `STOP_DET;
166 | else if (sdaDelayed[`SDA_DEL_LEN-2] == 1'b0 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b1)
167 | startStopDetState <= `START_DET;
168 | end
169 | end
170 | end
171 |
172 |
173 | registerInterface u_registerInterface(
174 | .clk(clk),
175 | .addr(regAddr),
176 | .dataIn(dataToRegIF),
177 | .writeEn(writeEn),
178 | .dataOut(dataFromRegIF),
179 | .myReg0(myReg0),
180 | .myReg1(myReg1),
181 | .myReg2(myReg2),
182 | .myReg3(myReg3),
183 | .myReg4(myReg4),
184 | .myReg5(myReg5),
185 | .myReg6(myReg6),
186 | .myReg7(myReg7)
187 | );
188 |
189 | serialInterface u_serialInterface (
190 | .clk(clk),
191 | .rst(rstSyncToClk | startEdgeDet),
192 | .dataIn(dataFromRegIF),
193 | .dataOut(dataToRegIF),
194 | .writeEn(writeEn),
195 | .regAddr(regAddr),
196 | .scl(sclDelayed[`SCL_DEL_LEN-1]),
197 | .sdaIn(sdaDeb),
198 | .sdaOut(sdaOut),
199 | .startStopDetState(startStopDetState),
200 | .clearStartStopDet(clearStartStopDet)
201 | );
202 |
203 |
204 | endmodule
205 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/model/i2c_master_top.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// WISHBONE revB.2 compliant I2C Master controller Top-level ////
4 | //// ////
5 | //// ////
6 | //// Author: Richard Herveille ////
7 | //// richard@asics.ws ////
8 | //// www.asics.ws ////
9 | //// ////
10 | //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
11 | //// ////
12 | /////////////////////////////////////////////////////////////////////
13 | //// ////
14 | //// Copyright (C) 2001 Richard Herveille ////
15 | //// richard@asics.ws ////
16 | //// ////
17 | //// This source file may be used and distributed without ////
18 | //// restriction provided that this copyright statement is not ////
19 | //// removed from the file and that any derivative work contains ////
20 | //// the original copyright notice and the associated disclaimer.////
21 | //// ////
22 | //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
23 | //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
24 | //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
25 | //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
26 | //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
27 | //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
28 | //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
29 | //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
30 | //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
31 | //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
32 | //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
33 | //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
34 | //// POSSIBILITY OF SUCH DAMAGE. ////
35 | //// ////
36 | /////////////////////////////////////////////////////////////////////
37 |
38 | // CVS Log
39 | //
40 | // $Id: i2c_master_top.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
41 | //
42 | // $Date: 2008-11-08 13:15:10 $
43 | // $Revision: 1.1 $
44 | // $Author: sfielding $
45 | // $Locker: $
46 | // $State: Exp $
47 | //
48 | // Change History:
49 | // $Log: not supported by cvs2svn $
50 | // Revision 1.11 2005/02/27 09:26:24 rherveille
51 | // Fixed register overwrite issue.
52 | // Removed full_case pragma, replaced it by a default statement.
53 | //
54 | // Revision 1.10 2003/09/01 10:34:38 rherveille
55 | // Fix a blocking vs. non-blocking error in the wb_dat output mux.
56 | //
57 | // Revision 1.9 2003/01/09 16:44:45 rherveille
58 | // Fixed a bug in the Command Register declaration.
59 | //
60 | // Revision 1.8 2002/12/26 16:05:12 rherveille
61 | // Small code simplifications
62 | //
63 | // Revision 1.7 2002/12/26 15:02:32 rherveille
64 | // Core is now a Multimaster I2C controller
65 | //
66 | // Revision 1.6 2002/11/30 22:24:40 rherveille
67 | // Cleaned up code
68 | //
69 | // Revision 1.5 2001/11/10 10:52:55 rherveille
70 | // Changed PRER reset value from 0x0000 to 0xffff, conform specs.
71 | //
72 |
73 | // synopsys translate_off
74 | `include "timescale.v"
75 | // synopsys translate_on
76 |
77 | `include "i2c_master_defines.v"
78 |
79 | module i2c_master_top(
80 | wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
81 | wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
82 | scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
83 |
84 | // parameters
85 | parameter ARST_LVL = 1'b0; // asynchronous reset level
86 |
87 | //
88 | // inputs & outputs
89 | //
90 |
91 | // wishbone signals
92 | input wb_clk_i; // master clock input
93 | input wb_rst_i; // synchronous active high reset
94 | input arst_i; // asynchronous reset
95 | input [2:0] wb_adr_i; // lower address bits
96 | input [7:0] wb_dat_i; // databus input
97 | output [7:0] wb_dat_o; // databus output
98 | input wb_we_i; // write enable input
99 | input wb_stb_i; // stobe/core select signal
100 | input wb_cyc_i; // valid bus cycle input
101 | output wb_ack_o; // bus cycle acknowledge output
102 | output wb_inta_o; // interrupt request signal output
103 |
104 | reg [7:0] wb_dat_o;
105 | reg wb_ack_o;
106 | reg wb_inta_o;
107 |
108 | // I2C signals
109 | // i2c clock line
110 | input scl_pad_i; // SCL-line input
111 | output scl_pad_o; // SCL-line output (always 1'b0)
112 | output scl_padoen_o; // SCL-line output enable (active low)
113 |
114 | // i2c data line
115 | input sda_pad_i; // SDA-line input
116 | output sda_pad_o; // SDA-line output (always 1'b0)
117 | output sda_padoen_o; // SDA-line output enable (active low)
118 |
119 |
120 | //
121 | // variable declarations
122 | //
123 |
124 | // registers
125 | reg [15:0] prer; // clock prescale register
126 | reg [ 7:0] ctr; // control register
127 | reg [ 7:0] txr; // transmit register
128 | wire [ 7:0] rxr; // receive register
129 | reg [ 7:0] cr; // command register
130 | wire [ 7:0] sr; // status register
131 |
132 | // done signal: command completed, clear command register
133 | wire done;
134 |
135 | // core enable signal
136 | wire core_en;
137 | wire ien;
138 |
139 | // status register signals
140 | wire irxack;
141 | reg rxack; // received aknowledge from slave
142 | reg tip; // transfer in progress
143 | reg irq_flag; // interrupt pending flag
144 | wire i2c_busy; // bus busy (start signal detected)
145 | wire i2c_al; // i2c bus arbitration lost
146 | reg al; // status register arbitration lost bit
147 |
148 | //
149 | // module body
150 | //
151 |
152 | // generate internal reset
153 | wire rst_i = arst_i ^ ARST_LVL;
154 |
155 | // generate wishbone signals
156 | wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i;
157 |
158 | // generate acknowledge output signal
159 | always @(posedge wb_clk_i)
160 | wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
161 |
162 | // assign DAT_O
163 | always @(posedge wb_clk_i)
164 | begin
165 | case (wb_adr_i) // synopsis parallel_case
166 | 3'b000: wb_dat_o <= #1 prer[ 7:0];
167 | 3'b001: wb_dat_o <= #1 prer[15:8];
168 | 3'b010: wb_dat_o <= #1 ctr;
169 | 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
170 | 3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
171 | 3'b101: wb_dat_o <= #1 txr;
172 | 3'b110: wb_dat_o <= #1 cr;
173 | 3'b111: wb_dat_o <= #1 0; // reserved
174 | endcase
175 | end
176 |
177 | // generate registers
178 | always @(posedge wb_clk_i or negedge rst_i)
179 | if (!rst_i)
180 | begin
181 | prer <= #1 16'hffff;
182 | ctr <= #1 8'h0;
183 | txr <= #1 8'h0;
184 | end
185 | else if (wb_rst_i)
186 | begin
187 | prer <= #1 16'hffff;
188 | ctr <= #1 8'h0;
189 | txr <= #1 8'h0;
190 | end
191 | else
192 | if (wb_wacc)
193 | case (wb_adr_i) // synopsis parallel_case
194 | 3'b000 : prer [ 7:0] <= #1 wb_dat_i;
195 | 3'b001 : prer [15:8] <= #1 wb_dat_i;
196 | 3'b010 : ctr <= #1 wb_dat_i;
197 | 3'b011 : txr <= #1 wb_dat_i;
198 | default: ;
199 | endcase
200 |
201 | // generate command register (special case)
202 | always @(posedge wb_clk_i or negedge rst_i)
203 | if (~rst_i)
204 | cr <= #1 8'h0;
205 | else if (wb_rst_i)
206 | cr <= #1 8'h0;
207 | else if (wb_wacc)
208 | begin
209 | if (core_en & (wb_adr_i == 3'b100) )
210 | cr <= #1 wb_dat_i;
211 | end
212 | else
213 | begin
214 | if (done | i2c_al)
215 | cr[7:4] <= #1 4'h0; // clear command bits when done
216 | // or when aribitration lost
217 | cr[2:1] <= #1 2'b0; // reserved bits
218 | cr[0] <= #1 2'b0; // clear IRQ_ACK bit
219 | end
220 |
221 |
222 | // decode command register
223 | wire sta = cr[7];
224 | wire sto = cr[6];
225 | wire rd = cr[5];
226 | wire wr = cr[4];
227 | wire ack = cr[3];
228 | wire iack = cr[0];
229 |
230 | // decode control register
231 | assign core_en = ctr[7];
232 | assign ien = ctr[6];
233 |
234 | // hookup byte controller block
235 | i2c_master_byte_ctrl byte_controller (
236 | .clk ( wb_clk_i ),
237 | .rst ( wb_rst_i ),
238 | .nReset ( rst_i ),
239 | .ena ( core_en ),
240 | .clk_cnt ( prer ),
241 | .start ( sta ),
242 | .stop ( sto ),
243 | .read ( rd ),
244 | .write ( wr ),
245 | .ack_in ( ack ),
246 | .din ( txr ),
247 | .cmd_ack ( done ),
248 | .ack_out ( irxack ),
249 | .dout ( rxr ),
250 | .i2c_busy ( i2c_busy ),
251 | .i2c_al ( i2c_al ),
252 | .scl_i ( scl_pad_i ),
253 | .scl_o ( scl_pad_o ),
254 | .scl_oen ( scl_padoen_o ),
255 | .sda_i ( sda_pad_i ),
256 | .sda_o ( sda_pad_o ),
257 | .sda_oen ( sda_padoen_o )
258 | );
259 |
260 | // status register block + interrupt request signal
261 | always @(posedge wb_clk_i or negedge rst_i)
262 | if (!rst_i)
263 | begin
264 | al <= #1 1'b0;
265 | rxack <= #1 1'b0;
266 | tip <= #1 1'b0;
267 | irq_flag <= #1 1'b0;
268 | end
269 | else if (wb_rst_i)
270 | begin
271 | al <= #1 1'b0;
272 | rxack <= #1 1'b0;
273 | tip <= #1 1'b0;
274 | irq_flag <= #1 1'b0;
275 | end
276 | else
277 | begin
278 | al <= #1 i2c_al | (al & ~sta);
279 | rxack <= #1 irxack;
280 | tip <= #1 (rd | wr);
281 | irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
282 | end
283 |
284 | // generate interrupt request signals
285 | always @(posedge wb_clk_i or negedge rst_i)
286 | if (!rst_i)
287 | wb_inta_o <= #1 1'b0;
288 | else if (wb_rst_i)
289 | wb_inta_o <= #1 1'b0;
290 | else
291 | wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
292 |
293 | // assign status register bits
294 | assign sr[7] = rxack;
295 | assign sr[6] = i2c_busy;
296 | assign sr[5] = al;
297 | assign sr[4:2] = 3'h0; // reserved
298 | assign sr[1] = tip;
299 | assign sr[0] = irq_flag;
300 |
301 | endmodule
302 |
--------------------------------------------------------------------------------
/model/i2c_master_byte_ctrl.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// WISHBONE rev.B2 compliant I2C Master byte-controller ////
4 | //// ////
5 | //// ////
6 | //// Author: Richard Herveille ////
7 | //// richard@asics.ws ////
8 | //// www.asics.ws ////
9 | //// ////
10 | //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
11 | //// ////
12 | /////////////////////////////////////////////////////////////////////
13 | //// ////
14 | //// Copyright (C) 2001 Richard Herveille ////
15 | //// richard@asics.ws ////
16 | //// ////
17 | //// This source file may be used and distributed without ////
18 | //// restriction provided that this copyright statement is not ////
19 | //// removed from the file and that any derivative work contains ////
20 | //// the original copyright notice and the associated disclaimer.////
21 | //// ////
22 | //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
23 | //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
24 | //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
25 | //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
26 | //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
27 | //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
28 | //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
29 | //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
30 | //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
31 | //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
32 | //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
33 | //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
34 | //// POSSIBILITY OF SUCH DAMAGE. ////
35 | //// ////
36 | /////////////////////////////////////////////////////////////////////
37 |
38 | // CVS Log
39 | //
40 | // $Id: i2c_master_byte_ctrl.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
41 | //
42 | // $Date: 2008-11-08 13:15:10 $
43 | // $Revision: 1.1 $
44 | // $Author: sfielding $
45 | // $Locker: $
46 | // $State: Exp $
47 | //
48 | // Change History:
49 | // $Log: not supported by cvs2svn $
50 | // Revision 1.7 2004/02/18 11:40:46 rherveille
51 | // Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
52 | //
53 | // Revision 1.6 2003/08/09 07:01:33 rherveille
54 | // Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
55 | // Fixed a potential bug in the byte controller's host-acknowledge generation.
56 | //
57 | // Revision 1.5 2002/12/26 15:02:32 rherveille
58 | // Core is now a Multimaster I2C controller
59 | //
60 | // Revision 1.4 2002/11/30 22:24:40 rherveille
61 | // Cleaned up code
62 | //
63 | // Revision 1.3 2001/11/05 11:59:25 rherveille
64 | // Fixed wb_ack_o generation bug.
65 | // Fixed bug in the byte_controller statemachine.
66 | // Added headers.
67 | //
68 |
69 | // synopsys translate_off
70 | `include "timescale.v"
71 | // synopsys translate_on
72 |
73 | `include "i2c_master_defines.v"
74 |
75 | module i2c_master_byte_ctrl (
76 | clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
77 | cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
78 |
79 | //
80 | // inputs & outputs
81 | //
82 | input clk; // master clock
83 | input rst; // synchronous active high reset
84 | input nReset; // asynchronous active low reset
85 | input ena; // core enable signal
86 |
87 | input [15:0] clk_cnt; // 4x SCL
88 |
89 | // control inputs
90 | input start;
91 | input stop;
92 | input read;
93 | input write;
94 | input ack_in;
95 | input [7:0] din;
96 |
97 | // status outputs
98 | output cmd_ack;
99 | reg cmd_ack;
100 | output ack_out;
101 | reg ack_out;
102 | output i2c_busy;
103 | output i2c_al;
104 | output [7:0] dout;
105 |
106 | // I2C signals
107 | input scl_i;
108 | output scl_o;
109 | output scl_oen;
110 | input sda_i;
111 | output sda_o;
112 | output sda_oen;
113 |
114 |
115 | //
116 | // Variable declarations
117 | //
118 |
119 | // statemachine
120 | parameter [4:0] ST_IDLE = 5'b0_0000;
121 | parameter [4:0] ST_START = 5'b0_0001;
122 | parameter [4:0] ST_READ = 5'b0_0010;
123 | parameter [4:0] ST_WRITE = 5'b0_0100;
124 | parameter [4:0] ST_ACK = 5'b0_1000;
125 | parameter [4:0] ST_STOP = 5'b1_0000;
126 |
127 | // signals for bit_controller
128 | reg [3:0] core_cmd;
129 | reg core_txd;
130 | wire core_ack, core_rxd;
131 |
132 | // signals for shift register
133 | reg [7:0] sr; //8bit shift register
134 | reg shift, ld;
135 |
136 | // signals for state machine
137 | wire go;
138 | reg [2:0] dcnt;
139 | wire cnt_done;
140 |
141 | //
142 | // Module body
143 | //
144 |
145 | // hookup bit_controller
146 | i2c_master_bit_ctrl bit_controller (
147 | .clk ( clk ),
148 | .rst ( rst ),
149 | .nReset ( nReset ),
150 | .ena ( ena ),
151 | .clk_cnt ( clk_cnt ),
152 | .cmd ( core_cmd ),
153 | .cmd_ack ( core_ack ),
154 | .busy ( i2c_busy ),
155 | .al ( i2c_al ),
156 | .din ( core_txd ),
157 | .dout ( core_rxd ),
158 | .scl_i ( scl_i ),
159 | .scl_o ( scl_o ),
160 | .scl_oen ( scl_oen ),
161 | .sda_i ( sda_i ),
162 | .sda_o ( sda_o ),
163 | .sda_oen ( sda_oen )
164 | );
165 |
166 | // generate go-signal
167 | assign go = (read | write | stop) & ~cmd_ack;
168 |
169 | // assign dout output to shift-register
170 | assign dout = sr;
171 |
172 | // generate shift register
173 | always @(posedge clk or negedge nReset)
174 | if (!nReset)
175 | sr <= #1 8'h0;
176 | else if (rst)
177 | sr <= #1 8'h0;
178 | else if (ld)
179 | sr <= #1 din;
180 | else if (shift)
181 | sr <= #1 {sr[6:0], core_rxd};
182 |
183 | // generate counter
184 | always @(posedge clk or negedge nReset)
185 | if (!nReset)
186 | dcnt <= #1 3'h0;
187 | else if (rst)
188 | dcnt <= #1 3'h0;
189 | else if (ld)
190 | dcnt <= #1 3'h7;
191 | else if (shift)
192 | dcnt <= #1 dcnt - 3'h1;
193 |
194 | assign cnt_done = ~(|dcnt);
195 |
196 | //
197 | // state machine
198 | //
199 | reg [4:0] c_state; // synopsis enum_state
200 |
201 | always @(posedge clk or negedge nReset)
202 | if (!nReset)
203 | begin
204 | core_cmd <= #1 `I2C_CMD_NOP;
205 | core_txd <= #1 1'b0;
206 | shift <= #1 1'b0;
207 | ld <= #1 1'b0;
208 | cmd_ack <= #1 1'b0;
209 | c_state <= #1 ST_IDLE;
210 | ack_out <= #1 1'b0;
211 | end
212 | else if (rst | i2c_al)
213 | begin
214 | core_cmd <= #1 `I2C_CMD_NOP;
215 | core_txd <= #1 1'b0;
216 | shift <= #1 1'b0;
217 | ld <= #1 1'b0;
218 | cmd_ack <= #1 1'b0;
219 | c_state <= #1 ST_IDLE;
220 | ack_out <= #1 1'b0;
221 | end
222 | else
223 | begin
224 | // initially reset all signals
225 | core_txd <= #1 sr[7];
226 | shift <= #1 1'b0;
227 | ld <= #1 1'b0;
228 | cmd_ack <= #1 1'b0;
229 |
230 | case (c_state) // synopsys full_case parallel_case
231 | ST_IDLE:
232 | if (go)
233 | begin
234 | if (start)
235 | begin
236 | c_state <= #1 ST_START;
237 | core_cmd <= #1 `I2C_CMD_START;
238 | end
239 | else if (read)
240 | begin
241 | c_state <= #1 ST_READ;
242 | core_cmd <= #1 `I2C_CMD_READ;
243 | end
244 | else if (write)
245 | begin
246 | c_state <= #1 ST_WRITE;
247 | core_cmd <= #1 `I2C_CMD_WRITE;
248 | end
249 | else // stop
250 | begin
251 | c_state <= #1 ST_STOP;
252 | core_cmd <= #1 `I2C_CMD_STOP;
253 | end
254 |
255 | ld <= #1 1'b1;
256 | end
257 |
258 | ST_START:
259 | if (core_ack)
260 | begin
261 | if (read)
262 | begin
263 | c_state <= #1 ST_READ;
264 | core_cmd <= #1 `I2C_CMD_READ;
265 | end
266 | else
267 | begin
268 | c_state <= #1 ST_WRITE;
269 | core_cmd <= #1 `I2C_CMD_WRITE;
270 | end
271 |
272 | ld <= #1 1'b1;
273 | end
274 |
275 | ST_WRITE:
276 | if (core_ack)
277 | if (cnt_done)
278 | begin
279 | c_state <= #1 ST_ACK;
280 | core_cmd <= #1 `I2C_CMD_READ;
281 | end
282 | else
283 | begin
284 | c_state <= #1 ST_WRITE; // stay in same state
285 | core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
286 | shift <= #1 1'b1;
287 | end
288 |
289 | ST_READ:
290 | if (core_ack)
291 | begin
292 | if (cnt_done)
293 | begin
294 | c_state <= #1 ST_ACK;
295 | core_cmd <= #1 `I2C_CMD_WRITE;
296 | end
297 | else
298 | begin
299 | c_state <= #1 ST_READ; // stay in same state
300 | core_cmd <= #1 `I2C_CMD_READ; // read next bit
301 | end
302 |
303 | shift <= #1 1'b1;
304 | core_txd <= #1 ack_in;
305 | end
306 |
307 | ST_ACK:
308 | if (core_ack)
309 | begin
310 | if (stop)
311 | begin
312 | c_state <= #1 ST_STOP;
313 | core_cmd <= #1 `I2C_CMD_STOP;
314 | end
315 | else
316 | begin
317 | c_state <= #1 ST_IDLE;
318 | core_cmd <= #1 `I2C_CMD_NOP;
319 |
320 | // generate command acknowledge signal
321 | cmd_ack <= #1 1'b1;
322 | end
323 |
324 | // assign ack_out output to bit_controller_rxd (contains last received bit)
325 | ack_out <= #1 core_rxd;
326 |
327 | core_txd <= #1 1'b1;
328 | end
329 | else
330 | core_txd <= #1 ack_in;
331 |
332 | ST_STOP:
333 | if (core_ack)
334 | begin
335 | c_state <= #1 ST_IDLE;
336 | core_cmd <= #1 `I2C_CMD_NOP;
337 |
338 | // generate command acknowledge signal
339 | cmd_ack <= #1 1'b1;
340 | end
341 |
342 | endcase
343 | end
344 | endmodule
345 |
--------------------------------------------------------------------------------
/rtl/serialInterface.v:
--------------------------------------------------------------------------------
1 |
2 | //////////////////////////////////////////////////////////////////////
3 | //// ////
4 | //// serialInterface.v ////
5 | //// ////
6 | //// This file is part of the i2cSlave opencores effort.
7 | //// ////
8 | //// ////
9 | //// Module Description: ////
10 | //// Perform all serial to parallel, and parallel
11 | //// to serial conversions. Perform device address matching
12 | //// Handle arbitrary length I2C reads terminated by NAK
13 | //// from host, and arbitrary length I2C writes terminated
14 | //// by STOP from host
15 | //// The second byte of a I2C write is always interpreted
16 | //// as a register address, and becomes the base register address
17 | //// for all read and write transactions.
18 | //// I2C WRITE: devAddr, regAddr, data[regAddr], data[regAddr+1], ..... data[regAddr+N]
19 | //// I2C READ: data[regAddr], data[regAddr+1], ..... data[regAddr+N]
20 | //// Note that when regAddR reaches 255 it will automatically wrap round to 0
21 | //// ////
22 | //// To Do: ////
23 | ////
24 | //// ////
25 | //// Author(s): ////
26 | //// - Steve Fielding, sfielding@base2designs.com ////
27 | //// ////
28 | //////////////////////////////////////////////////////////////////////
29 | //// ////
30 | //// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
31 | //// ////
32 | //// This source file may be used and distributed without ////
33 | //// restriction provided that this copyright statement is not ////
34 | //// removed from the file and that any derivative work contains ////
35 | //// the original copyright notice and the associated disclaimer. ////
36 | //// ////
37 | //// This source file is free software; you can redistribute it ////
38 | //// and/or modify it under the terms of the GNU Lesser General ////
39 | //// Public License as published by the Free Software Foundation; ////
40 | //// either version 2.1 of the License, or (at your option) any ////
41 | //// later version. ////
42 | //// ////
43 | //// This source is distributed in the hope that it will be ////
44 | //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
45 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
46 | //// PURPOSE. See the GNU Lesser General Public License for more ////
47 | //// details. ////
48 | //// ////
49 | //// You should have received a copy of the GNU Lesser General ////
50 | //// Public License along with this source; if not, download it ////
51 | //// from ////
52 | //// ////
53 | //////////////////////////////////////////////////////////////////////
54 | //
55 | `include "timescale.v"
56 | `include "i2cSlave_define.v"
57 |
58 | module serialInterface (clearStartStopDet, clk, dataIn, dataOut, regAddr, rst, scl, sdaIn, sdaOut, startStopDetState, writeEn);
59 | input clk;
60 | input [7:0]dataIn;
61 | input rst;
62 | input scl;
63 | input sdaIn;
64 | input [1:0]startStopDetState;
65 | output clearStartStopDet;
66 | output [7:0]dataOut;
67 | output [7:0]regAddr;
68 | output sdaOut;
69 | output writeEn;
70 |
71 | reg clearStartStopDet, next_clearStartStopDet;
72 | wire clk;
73 | wire [7:0]dataIn;
74 | reg [7:0]dataOut, next_dataOut;
75 | reg [7:0]regAddr, next_regAddr;
76 | wire rst;
77 | wire scl;
78 | wire sdaIn;
79 | reg sdaOut, next_sdaOut;
80 | wire [1:0]startStopDetState;
81 | reg writeEn, next_writeEn;
82 |
83 | // diagram signals declarations
84 | reg [2:0]bitCnt, next_bitCnt;
85 | reg [7:0]rxData, next_rxData;
86 | reg [1:0]streamSt, next_streamSt;
87 | reg [7:0]txData, next_txData;
88 |
89 | // BINARY ENCODED state machine: SISt
90 | // State codes definitions:
91 | `define START 4'b0000
92 | `define CHK_RD_WR 4'b0001
93 | `define READ_RD_LOOP 4'b0010
94 | `define READ_WT_HI 4'b0011
95 | `define READ_CHK_LOOP_FIN 4'b0100
96 | `define READ_WT_LO 4'b0101
97 | `define READ_WT_ACK 4'b0110
98 | `define WRITE_WT_LO 4'b0111
99 | `define WRITE_WT_HI 4'b1000
100 | `define WRITE_CHK_LOOP_FIN 4'b1001
101 | `define WRITE_LOOP_WT_LO 4'b1010
102 | `define WRITE_ST_LOOP 4'b1011
103 | `define WRITE_WT_LO2 4'b1100
104 | `define WRITE_WT_HI2 4'b1101
105 | `define WRITE_CLR_WR 4'b1110
106 | `define WRITE_CLR_ST_STOP 4'b1111
107 |
108 | reg [3:0]CurrState_SISt, NextState_SISt;
109 |
110 | // Diagram actions (continuous assignments allowed only: assign ...)
111 | // diagram ACTION
112 |
113 |
114 | // Machine: SISt
115 |
116 | // NextState logic (combinatorial)
117 | always @ (startStopDetState or streamSt or scl or txData or bitCnt or rxData or sdaIn or regAddr or dataIn or sdaOut or writeEn or dataOut or clearStartStopDet or CurrState_SISt)
118 | begin
119 | NextState_SISt <= CurrState_SISt;
120 | // Set default values for outputs and signals
121 | next_streamSt <= streamSt;
122 | next_txData <= txData;
123 | next_rxData <= rxData;
124 | next_sdaOut <= sdaOut;
125 | next_writeEn <= writeEn;
126 | next_dataOut <= dataOut;
127 | next_bitCnt <= bitCnt;
128 | next_clearStartStopDet <= clearStartStopDet;
129 | next_regAddr <= regAddr;
130 | case (CurrState_SISt) // synopsys parallel_case full_case
131 | `START:
132 | begin
133 | next_streamSt <= `STREAM_IDLE;
134 | next_txData <= 8'h00;
135 | next_rxData <= 8'h00;
136 | next_sdaOut <= 1'b1;
137 | next_writeEn <= 1'b0;
138 | next_dataOut <= 8'h00;
139 | next_bitCnt <= 3'b000;
140 | next_clearStartStopDet <= 1'b0;
141 | NextState_SISt <= `CHK_RD_WR;
142 | end
143 | `CHK_RD_WR:
144 | begin
145 | if (streamSt == `STREAM_READ)
146 | begin
147 | NextState_SISt <= `READ_RD_LOOP;
148 | next_txData <= dataIn;
149 | next_regAddr <= regAddr + 1'b1;
150 | next_bitCnt <= 3'b001;
151 | end
152 | else
153 | begin
154 | NextState_SISt <= `WRITE_WT_HI;
155 | next_rxData <= 8'h00;
156 | end
157 | end
158 | `READ_RD_LOOP:
159 | begin
160 | if (scl == 1'b0)
161 | begin
162 | NextState_SISt <= `READ_WT_HI;
163 | next_sdaOut <= txData [7];
164 | next_txData <= {txData [6:0], 1'b0};
165 | end
166 | end
167 | `READ_WT_HI:
168 | begin
169 | if (scl == 1'b1)
170 | begin
171 | NextState_SISt <= `READ_CHK_LOOP_FIN;
172 | end
173 | end
174 | `READ_CHK_LOOP_FIN:
175 | begin
176 | if (bitCnt == 3'b000)
177 | begin
178 | NextState_SISt <= `READ_WT_LO;
179 | end
180 | else
181 | begin
182 | NextState_SISt <= `READ_RD_LOOP;
183 | next_bitCnt <= bitCnt + 1'b1;
184 | end
185 | end
186 | `READ_WT_LO:
187 | begin
188 | if (scl == 1'b0)
189 | begin
190 | NextState_SISt <= `READ_WT_ACK;
191 | next_sdaOut <= 1'b1;
192 | end
193 | end
194 | `READ_WT_ACK:
195 | begin
196 | if (scl == 1'b1)
197 | begin
198 | NextState_SISt <= `CHK_RD_WR;
199 | if (sdaIn == `I2C_NAK)
200 | next_streamSt <= `STREAM_IDLE;
201 | end
202 | end
203 | `WRITE_WT_LO:
204 | begin
205 | if ((scl == 1'b0) && (startStopDetState == `STOP_DET ||
206 | (streamSt == `STREAM_IDLE && startStopDetState == `NULL_DET)))
207 | begin
208 | NextState_SISt <= `WRITE_CLR_ST_STOP;
209 | case (startStopDetState)
210 | `NULL_DET:
211 | next_bitCnt <= bitCnt + 1'b1;
212 | `START_DET: begin
213 | next_streamSt <= `STREAM_IDLE;
214 | next_rxData <= 8'h00;
215 | end
216 | default: ;
217 | endcase
218 | next_streamSt <= `STREAM_IDLE;
219 | next_clearStartStopDet <= 1'b1;
220 | end
221 | else if (scl == 1'b0)
222 | begin
223 | NextState_SISt <= `WRITE_ST_LOOP;
224 | case (startStopDetState)
225 | `NULL_DET:
226 | next_bitCnt <= bitCnt + 1'b1;
227 | `START_DET: begin
228 | next_streamSt <= `STREAM_IDLE;
229 | next_rxData <= 8'h00;
230 | end
231 | default: ;
232 | endcase
233 | end
234 | end
235 | `WRITE_WT_HI:
236 | begin
237 | if (scl == 1'b1)
238 | begin
239 | NextState_SISt <= `WRITE_WT_LO;
240 | next_rxData <= {rxData [6:0], sdaIn};
241 | next_bitCnt <= 3'b000;
242 | end
243 | end
244 | `WRITE_CHK_LOOP_FIN:
245 | begin
246 | if (bitCnt == 3'b111)
247 | begin
248 | NextState_SISt <= `WRITE_CLR_WR;
249 | next_sdaOut <= `I2C_ACK;
250 | case (streamSt)
251 | `STREAM_IDLE: begin
252 | if (rxData[7:1] == `I2C_ADDRESS &&
253 | startStopDetState == `START_DET) begin
254 | if (rxData[0] == 1'b1)
255 | next_streamSt <= `STREAM_READ;
256 | else
257 | next_streamSt <= `STREAM_WRITE_ADDR;
258 | end
259 | else
260 | next_sdaOut <= `I2C_NAK;
261 | end
262 | `STREAM_WRITE_ADDR: begin
263 | next_streamSt <= `STREAM_WRITE_DATA;
264 | next_regAddr <= rxData;
265 | end
266 | `STREAM_WRITE_DATA: begin
267 | next_dataOut <= rxData;
268 | next_writeEn <= 1'b1;
269 | end
270 | default:
271 | next_streamSt <= streamSt;
272 | endcase
273 | end
274 | else
275 | begin
276 | NextState_SISt <= `WRITE_ST_LOOP;
277 | next_bitCnt <= bitCnt + 1'b1;
278 | end
279 | end
280 | `WRITE_LOOP_WT_LO:
281 | begin
282 | if (scl == 1'b0)
283 | begin
284 | NextState_SISt <= `WRITE_CHK_LOOP_FIN;
285 | end
286 | end
287 | `WRITE_ST_LOOP:
288 | begin
289 | if (scl == 1'b1)
290 | begin
291 | NextState_SISt <= `WRITE_LOOP_WT_LO;
292 | next_rxData <= {rxData [6:0], sdaIn};
293 | end
294 | end
295 | `WRITE_WT_LO2:
296 | begin
297 | if (scl == 1'b0)
298 | begin
299 | NextState_SISt <= `CHK_RD_WR;
300 | next_sdaOut <= 1'b1;
301 | end
302 | end
303 | `WRITE_WT_HI2:
304 | begin
305 | next_clearStartStopDet <= 1'b0;
306 | if (scl == 1'b1)
307 | begin
308 | NextState_SISt <= `WRITE_WT_LO2;
309 | end
310 | end
311 | `WRITE_CLR_WR:
312 | begin
313 | if (writeEn == 1'b1)
314 | next_regAddr <= regAddr + 1'b1;
315 | next_writeEn <= 1'b0;
316 | next_clearStartStopDet <= 1'b1;
317 | NextState_SISt <= `WRITE_WT_HI2;
318 | end
319 | `WRITE_CLR_ST_STOP:
320 | begin
321 | next_clearStartStopDet <= 1'b0;
322 | NextState_SISt <= `CHK_RD_WR;
323 | end
324 | endcase
325 | end
326 |
327 | // Current State Logic (sequential)
328 | always @ (posedge clk)
329 | begin
330 | if (rst == 1'b1)
331 | CurrState_SISt <= `START;
332 | else
333 | CurrState_SISt <= NextState_SISt;
334 | end
335 |
336 | // Registered outputs logic
337 | always @ (posedge clk)
338 | begin
339 | if (rst == 1'b1)
340 | begin
341 | sdaOut <= 1'b1;
342 | writeEn <= 1'b0;
343 | dataOut <= 8'h00;
344 | clearStartStopDet <= 1'b0;
345 | // regAddr <= // Initialization in the reset state or default value required!!
346 | streamSt <= `STREAM_IDLE;
347 | txData <= 8'h00;
348 | rxData <= 8'h00;
349 | bitCnt <= 3'b000;
350 | end
351 | else
352 | begin
353 | sdaOut <= next_sdaOut;
354 | writeEn <= next_writeEn;
355 | dataOut <= next_dataOut;
356 | clearStartStopDet <= next_clearStartStopDet;
357 | regAddr <= next_regAddr;
358 | streamSt <= next_streamSt;
359 | txData <= next_txData;
360 | rxData <= next_rxData;
361 | bitCnt <= next_bitCnt;
362 | end
363 | end
364 |
365 | endmodule
--------------------------------------------------------------------------------
/syn/Altera/pll_48MHz.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %ALTPLL%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: altpll
5 |
6 | // ============================================================
7 | // File Name: pll_48MHz.v
8 | // Megafunction Name(s):
9 | // altpll
10 | //
11 | // Simulation Library Files(s):
12 | // altera_mf
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 7.2 Build 203 02/05/2008 SP 2 SJ Web Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 1991-2007 Altera Corporation
22 | //Your use of Altera Corporation's design tools, logic functions
23 | //and other software and tools, and its AMPP partner logic
24 | //functions, and any output files from any of the foregoing
25 | //(including device programming or simulation files), and any
26 | //associated documentation or information are expressly subject
27 | //to the terms and conditions of the Altera Program License
28 | //Subscription Agreement, Altera MegaCore Function License
29 | //Agreement, or other applicable license agreement, including,
30 | //without limitation, that your use is for the sole purpose of
31 | //programming logic devices manufactured by Altera and sold by
32 | //Altera or its authorized distributors. Please refer to the
33 | //applicable agreement for further details.
34 |
35 |
36 | // synopsys translate_off
37 | `timescale 1 ps / 1 ps
38 | // synopsys translate_on
39 | module pll_48MHz (
40 | inclk0,
41 | locked);
42 |
43 | input inclk0;
44 | output locked;
45 |
46 | wire sub_wire0;
47 | wire [0:0] sub_wire3 = 1'h0;
48 | wire locked = sub_wire0;
49 | wire sub_wire1 = inclk0;
50 | wire [1:0] sub_wire2 = {sub_wire3, sub_wire1};
51 |
52 | altpll altpll_component (
53 | .inclk (sub_wire2),
54 | .locked (sub_wire0),
55 | .activeclock (),
56 | .areset (1'b0),
57 | .clk (),
58 | .clkbad (),
59 | .clkena ({6{1'b1}}),
60 | .clkloss (),
61 | .clkswitch (1'b0),
62 | .configupdate (1'b0),
63 | .enable0 (),
64 | .enable1 (),
65 | .extclk (),
66 | .extclkena ({4{1'b1}}),
67 | .fbin (1'b1),
68 | .fbmimicbidir (),
69 | .fbout (),
70 | .pfdena (1'b1),
71 | .phasecounterselect ({4{1'b1}}),
72 | .phasedone (),
73 | .phasestep (1'b1),
74 | .phaseupdown (1'b1),
75 | .pllena (1'b1),
76 | .scanaclr (1'b0),
77 | .scanclk (1'b0),
78 | .scanclkena (1'b1),
79 | .scandata (1'b0),
80 | .scandataout (),
81 | .scandone (),
82 | .scanread (1'b0),
83 | .scanwrite (1'b0),
84 | .sclkout0 (),
85 | .sclkout1 (),
86 | .vcooverrange (),
87 | .vcounderrange ());
88 | defparam
89 | altpll_component.gate_lock_signal = "NO",
90 | altpll_component.inclk0_input_frequency = 20833,
91 | altpll_component.intended_device_family = "Cyclone II",
92 | altpll_component.invalid_lock_multiplier = 5,
93 | altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_48MHz",
94 | altpll_component.lpm_type = "altpll",
95 | altpll_component.operation_mode = "NO_COMPENSATION",
96 | altpll_component.port_activeclock = "PORT_UNUSED",
97 | altpll_component.port_areset = "PORT_UNUSED",
98 | altpll_component.port_clkbad0 = "PORT_UNUSED",
99 | altpll_component.port_clkbad1 = "PORT_UNUSED",
100 | altpll_component.port_clkloss = "PORT_UNUSED",
101 | altpll_component.port_clkswitch = "PORT_UNUSED",
102 | altpll_component.port_configupdate = "PORT_UNUSED",
103 | altpll_component.port_fbin = "PORT_UNUSED",
104 | altpll_component.port_inclk0 = "PORT_USED",
105 | altpll_component.port_inclk1 = "PORT_UNUSED",
106 | altpll_component.port_locked = "PORT_USED",
107 | altpll_component.port_pfdena = "PORT_UNUSED",
108 | altpll_component.port_phasecounterselect = "PORT_UNUSED",
109 | altpll_component.port_phasedone = "PORT_UNUSED",
110 | altpll_component.port_phasestep = "PORT_UNUSED",
111 | altpll_component.port_phaseupdown = "PORT_UNUSED",
112 | altpll_component.port_pllena = "PORT_UNUSED",
113 | altpll_component.port_scanaclr = "PORT_UNUSED",
114 | altpll_component.port_scanclk = "PORT_UNUSED",
115 | altpll_component.port_scanclkena = "PORT_UNUSED",
116 | altpll_component.port_scandata = "PORT_UNUSED",
117 | altpll_component.port_scandataout = "PORT_UNUSED",
118 | altpll_component.port_scandone = "PORT_UNUSED",
119 | altpll_component.port_scanread = "PORT_UNUSED",
120 | altpll_component.port_scanwrite = "PORT_UNUSED",
121 | altpll_component.port_clk0 = "PORT_UNUSED",
122 | altpll_component.port_clk1 = "PORT_UNUSED",
123 | altpll_component.port_clk2 = "PORT_UNUSED",
124 | altpll_component.port_clk3 = "PORT_UNUSED",
125 | altpll_component.port_clk4 = "PORT_UNUSED",
126 | altpll_component.port_clk5 = "PORT_UNUSED",
127 | altpll_component.port_clkena0 = "PORT_UNUSED",
128 | altpll_component.port_clkena1 = "PORT_UNUSED",
129 | altpll_component.port_clkena2 = "PORT_UNUSED",
130 | altpll_component.port_clkena3 = "PORT_UNUSED",
131 | altpll_component.port_clkena4 = "PORT_UNUSED",
132 | altpll_component.port_clkena5 = "PORT_UNUSED",
133 | altpll_component.port_extclk0 = "PORT_UNUSED",
134 | altpll_component.port_extclk1 = "PORT_UNUSED",
135 | altpll_component.port_extclk2 = "PORT_UNUSED",
136 | altpll_component.port_extclk3 = "PORT_UNUSED",
137 | altpll_component.valid_lock_multiplier = 1;
138 |
139 |
140 | endmodule
141 |
142 | // ============================================================
143 | // CNX file retrieval info
144 | // ============================================================
145 | // Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
146 | // Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
147 | // Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
148 | // Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
149 | // Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
150 | // Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
151 | // Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
152 | // Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
153 | // Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
154 | // Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
155 | // Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
156 | // Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "1"
157 | // Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
158 | // Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
159 | // Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
160 | // Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
161 | // Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
162 | // Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
163 | // Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
164 | // Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
165 | // Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
166 | // Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
167 | // Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
168 | // Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
169 | // Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "48.000"
170 | // Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
171 | // Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
172 | // Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
173 | // Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
174 | // Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
175 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
176 | // Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
177 | // Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
178 | // Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
179 | // Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
180 | // Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
181 | // Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0"
182 | // Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
183 | // Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
184 | // Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
185 | // Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
186 | // Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
187 | // Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
188 | // Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
189 | // Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
190 | // Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
191 | // Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
192 | // Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
193 | // Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
194 | // Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
195 | // Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
196 | // Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_48MHz.mif"
197 | // Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
198 | // Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
199 | // Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
200 | // Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
201 | // Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
202 | // Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
203 | // Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
204 | // Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
205 | // Retrieval info: PRIVATE: SPREAD_USE STRING "0"
206 | // Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
207 | // Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
208 | // Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
209 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
210 | // Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
211 | // Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
212 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
213 | // Retrieval info: CONSTANT: GATE_LOCK_SIGNAL STRING "NO"
214 | // Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20833"
215 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
216 | // Retrieval info: CONSTANT: INVALID_LOCK_MULTIPLIER NUMERIC "5"
217 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
218 | // Retrieval info: CONSTANT: OPERATION_MODE STRING "NO_COMPENSATION"
219 | // Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
220 | // Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
221 | // Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
222 | // Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
223 | // Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
224 | // Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
225 | // Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
226 | // Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
227 | // Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
228 | // Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
229 | // Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
230 | // Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
231 | // Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
232 | // Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
233 | // Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
234 | // Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
235 | // Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
236 | // Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
237 | // Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
238 | // Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
239 | // Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
240 | // Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
241 | // Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
242 | // Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
243 | // Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
244 | // Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_UNUSED"
245 | // Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
246 | // Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
247 | // Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
248 | // Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
249 | // Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
250 | // Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
251 | // Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
252 | // Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
253 | // Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
254 | // Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
255 | // Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
256 | // Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
257 | // Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
258 | // Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
259 | // Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
260 | // Retrieval info: CONSTANT: VALID_LOCK_MULTIPLIER NUMERIC "1"
261 | // Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
262 | // Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
263 | // Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
264 | // Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
265 | // Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
266 | // Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
267 | // Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
268 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz.v TRUE FALSE
269 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz.ppf TRUE FALSE
270 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz.inc FALSE FALSE
271 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz.cmp FALSE FALSE
272 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz.bsf FALSE FALSE
273 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz_inst.v TRUE FALSE
274 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz_bb.v FALSE FALSE
275 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz_waveforms.html TRUE FALSE
276 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll_48MHz_wave*.jpg FALSE FALSE
277 | // Retrieval info: LIB_FILE: altera_mf
278 | // Retrieval info: CBX_MODULE_PREFIX: ON
279 |
--------------------------------------------------------------------------------
/Aldec/design0/src/serialInterface.asf:
--------------------------------------------------------------------------------
1 | VERSION=1.15
2 | HEADER
3 | FILE="serialInterface.asf"
4 | FID=4788d213
5 | LANGUAGE=VERILOG
6 | ENTITY="serialInterface"
7 | FRAMES=ON
8 | FREEOID=1240
9 | "LIBRARIES=//////////////////////////////////////////////////////////////////////\n//// ////\n//// serialInterface.v ////\n//// ////\n//// This file is part of the i2cSlave opencores effort.\n//// ////\n//// ////\n//// Module Description: ////\n//// Perform all serial to parallel, and parallel\n//// to serial conversions. Perform device address matching\n//// Handle arbitrary length I2C reads terminated by NAK\n//// from host, and arbitrary length I2C writes terminated\n//// by STOP from host\n//// The second byte of a I2C write is always interpreted\n//// as a register address, and becomes the base register address\n//// for all read and write transactions.\n//// I2C WRITE: devAddr, regAddr, data[regAddr], data[regAddr+1], ..... data[regAddr+N]\n//// I2C READ: data[regAddr], data[regAddr+1], ..... data[regAddr+N]\n//// Note that when regAddR reaches 255 it will automatically wrap round to 0\n//// ////\n//// To Do: ////\n//// \n//// ////\n//// Author(s): ////\n//// - Steve Fielding, sfielding@base2designs.com ////\n//// ////\n//////////////////////////////////////////////////////////////////////\n//// ////\n//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////\n//// ////\n//// This source file may be used and distributed without ////\n//// restriction provided that this copyright statement is not ////\n//// removed from the file and that any derivative work contains ////\n//// the original copyright notice and the associated disclaimer. ////\n//// ////\n//// This source file is free software; you can redistribute it ////\n//// and/or modify it under the terms of the GNU Lesser General ////\n//// Public License as published by the Free Software Foundation; ////\n//// either version 2.1 of the License, or (at your option) any ////\n//// later version. ////\n//// ////\n//// This source is distributed in the hope that it will be ////\n//// useful, but WITHOUT ANY WARRANTY; without even the implied ////\n//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////\n//// PURPOSE. See the GNU Lesser General Public License for more ////\n//// details. ////\n//// ////\n//// You should have received a copy of the GNU Lesser General ////\n//// Public License along with this source; if not, download it ////\n//// from ////\n//// ////\n//////////////////////////////////////////////////////////////////////\n//\n`include \"timescale.v\"\n`include \"i2cSlave_define.v\"\n"
10 | END
11 | BUNDLES
12 | B T "Declarations" 0,0,255 0 0 1 255,255,255 0 2844 0 0000 1 "Arial" 0
13 | B T "Conditions" 0,0,0 0 0 0 255,255,255 0 2844 0 0110 1 "Arial" 0
14 | B F "States" 0,0,0 0 0 1 0,255,0 1 3527 1480 0000 1 "Arial" 0
15 | B T "Actions" 0,0,0 0 0 1 255,255,255 0 2844 0 0000 1 "Arial" 0
16 | B T "Labels" 0,0,0 0 0 0 255,255,255 0 2844 0 0000 1 "Arial" 0
17 | B L "Transitions" 0,0,0 0 0 1 0,0,0 1 3527 1480 0000 1 "Arial" 0
18 | B F "Ports" 0,0,0 0 0 1 0,255,255 1 3527 1480 0000 1 "Arial" 0
19 | B L "Errors" 255,0,0 0 3 1 255,255,255 1 3527 1480 0000 1 "Arial" 0
20 | B T "State Labels" 0,0,0 0 0 0 255,255,255 0 2844 0 0000 1 "Arial" 4
21 | B F "Current State" 255,255,0 0 0 1 255,255,0 1 3527 1480 0000 1 "Arial" 0
22 | B T "Comments" 157,157,157 0 0 1 255,255,255 0 3527 1480 0000 1 "Arial" 0
23 | B L "Info" 0,255,0 0 3 1 255,255,255 1 3527 1480 0000 1 "Arial" 0
24 | END
25 | INSTHEADER 1
26 | PAGE 25400,25400 215900,279400
27 | UPPERLEFT 0,0
28 | GRID=OFF
29 | GRIDSIZE 5000,5000 10000,10000
30 | END
31 | INSTHEADER 1093
32 | PAGE 25400,25400 215900,279400
33 | UPPERLEFT 0,0
34 | GRID=OFF
35 | GRIDSIZE 0,0 10000,10000
36 | END
37 | INSTHEADER 1102
38 | PAGE 25400,25400 215900,279400
39 | UPPERLEFT 0,0
40 | GRID=OFF
41 | GRIDSIZE 0,0 10000,10000
42 | END
43 | INSTHEADER 1163
44 | PAGE 25400,25400 215900,279400
45 | UPPERLEFT 0,0
46 | GRID=OFF
47 | GRIDSIZE 0,0 10000,10000
48 | END
49 | OBJECTS
50 | L 7 6 0 TEXT "Labels" | 31673,209974 1 0 0 "SISt"
51 | F 6 0 512 72 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,212603
52 | A 5 0 1 TEXT "Actions" | 30400,266783 1 0 0 "-- diagram ACTION"
53 | G 1 0 0 TEXT 0,0,0 0 0 0 255,255,255 0 3527 1480 0000 1 "Arial" 0 | 110650,276400 1 0 0 "Module: serialInterface"
54 | I 1088 0 130 Builtin Signal | 170556,231962 "" ""
55 | A 1089 100 4 TEXT "Actions" | 164916,210687 1 0 0 "streamSt <= `STREAM_IDLE;\ntxData <= 8'h00;\nrxData <= 8'h00;\nsdaOut <= 1'b1;\nwriteEn <= 1'b0;\ndataOut <= 8'h00;\nbitCnt <= 3'b000;\nclearStartStopDet <= 1'b0;"
56 | L 1090 1091 0 TEXT "State Labels" | 113022,167010 1 0 0 "CHK_RD_WR\n/1/"
57 | S 1091 6 4096 ELLIPSE "States" | 113022,167010 6500 6500
58 | L 1092 1093 0 TEXT "State Labels" | 145788,131922 1 0 0 "READ"
59 | S 1093 6 8196 ELLIPSE 0,0,0 0 0 1 0,255,255 1 | 145788,131922 6500 6500
60 | H 1094 1093 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,276400
61 | I 1097 1094 0 Builtin Entry | 45436,264408
62 | I 1098 1094 0 Builtin Exit | 66804,75108
63 | L 1101 1102 0 TEXT "State Labels" | 82836,130374 1 0 0 "WRITE"
64 | S 1102 6 12292 ELLIPSE 0,0,0 0 0 1 0,255,255 1 | 82836,130374 6500 6500
65 | H 1103 1102 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,276400
66 | I 1106 1103 0 Builtin Entry | 45436,269052
67 | W 1111 6 1 1091 1093 BEZIER "Transitions" | 117575,162372 124283,155471 134905,143802 141613,136901
68 | W 1112 6 2 1091 1102 BEZIER "Transitions" | 108455,162386 102521,154775 92600,143235 86666,135624
69 | C 1113 1111 0 TEXT "Conditions" | 124761,159657 1 0 0 "streamSt == `STREAM_READ"
70 | L 1114 1115 0 TEXT "State Labels" | 60132,233832 1 0 0 "RD_LOOP\n/2/"
71 | S 1115 1094 16384 ELLIPSE "States" | 60132,233832 6500 6500
72 | W 1116 1094 0 1097 1115 BEZIER "Transitions" | 49435,264408 51757,258345 54648,245572 56970,239509
73 | L 1117 1118 0 TEXT "State Labels" | 62196,202356 1 0 0 "WT_HI\n/3/"
74 | S 1118 1094 20480 ELLIPSE "States" | 62196,202356 6500 6500
75 | W 1119 1094 0 1115 1118 BEZIER "Transitions" | 60334,227358 60656,222198 61220,213982 61542,208822
76 | C 1120 1119 0 TEXT "Conditions" | 61814,227496 1 0 0 "scl == 1'b0"
77 | L 1121 1122 0 TEXT "State Labels" | 63833,168493 1 0 0 "CHK_LOOP_FIN\n/4/"
78 | S 1122 1094 24576 ELLIPSE "States" | 63833,168493 6500 6500
79 | W 1123 1094 0 1118 1122 BEZIER "Transitions" | 62616,195885 62873,192095 63548,178990 63552,174971
80 | C 1124 1123 0 TEXT "Conditions" | 65004,194763 1 0 0 "scl == 1'b1"
81 | A 1125 1116 16 TEXT "Actions" | 46574,259544 1 0 0 "txData <= dataIn;\nregAddr <= regAddr + 1'b1;\nbitCnt <= 3'b001;"
82 | L 1127 1128 0 TEXT "State Labels" | 64515,139815 1 0 0 "WT_LO\n/5/"
83 | S 1128 1094 28672 ELLIPSE "States" | 64515,139815 6500 6500
84 | W 1133 1094 1 1122 1128 BEZIER "Transitions" | 63734,162016 63671,157426 63956,150868 63893,146278
85 | C 1135 1133 0 TEXT "Conditions" | 67448,161363 1 0 0 "bitCnt == 3'b000"
86 | W 1136 1094 2 1122 1115 BEZIER "Transitions" | 70264,169432 80793,170973 95664,170699 106435,174896\
87 | 117206,179094 120169,183293 119563,193014 118958,202736\
88 | 113857,211534 106441,217176 99026,222818 76882,233683\
89 | 66172,236233
90 | L 1137 1138 0 TEXT "State Labels" | 65790,108960 1 0 0 "WT_ACK\n/6/"
91 | S 1138 1094 32768 ELLIPSE "States" | 65790,108960 6500 6500
92 | W 1139 1094 0 1128 1138 BEZIER "Transitions" | 64641,133339 64223,128449 65212,119705 65696,115446
93 | A 1141 1136 16 TEXT "Actions" | 99952,191787 1 0 0 "bitCnt <= bitCnt + 1'b1;"
94 | A 1143 1119 16 TEXT "Actions" | 42458,221543 1 0 0 "sdaOut <= txData [7];\ntxData <= {txData [6:0], 1'b0};"
95 | C 1144 1139 0 TEXT "Conditions" | 66481,131783 1 0 0 "scl == 1'b0"
96 | W 1147 1094 0 1138 1098 BEZIER "Transitions" | 65848,102499 65911,97591 66741,82032 66804,77124
97 | C 1148 1147 0 TEXT "Conditions" | 67234,101707 1 0 0 "scl == 1'b1"
98 | A 1149 1147 16 TEXT "Actions" | 61593,95455 1 0 0 "if (sdaIn == `I2C_NAK)\n streamSt <= `STREAM_IDLE;"
99 | A 1150 1139 16 TEXT "Actions" | 63113,125918 1 0 0 "sdaOut <= 1'b1;"
100 | L 71 72 0 TEXT "Labels" | 201700,272800 1 0 0 "clk"
101 | I 72 0 3 Builtin InPort | 195700,272800 "" ""
102 | L 73 74 0 TEXT "Labels" | 201700,267632 1 0 0 "rst"
103 | I 74 0 2 Builtin InPort | 195700,267632 "" ""
104 | L 1152 1153 0 TEXT "State Labels" | 50328,243636 1 0 0 "WT_HI\n/8/"
105 | S 1153 1103 45056 ELLIPSE "States" | 50328,243636 6500 6500
106 | W 1154 1103 0 1106 1153 BEZIER "Transitions" | 45436,266988 46403,261957 48180,255054 49147,250023
107 | L 1156 1157 0 TEXT "State Labels" | 53682,211902 1 0 0 "WT_LO\n/7/"
108 | S 1157 1103 40960 ELLIPSE "States" | 53682,211902 6500 6500
109 | W 1158 1103 0 1153 1157 BEZIER "Transitions" | 50941,237173 51263,234013 52778,221621 52602,218309
110 | C 1160 1158 0 TEXT "Conditions" | 52521,236757 1 0 0 "scl == 1'b1"
111 | L 1162 1163 0 TEXT "State Labels" | 54198,183780 1 0 0 "J1"
112 | S 1163 1103 36868 ELLIPSE 0,0,0 0 0 1 255,0,0 1 | 54136,183976 3858 3858
113 | W 1164 1103 0 1157 1163 BEZIER "Transitions" | 53938,205422 54389,199424 52869,194235 53483,187777
114 | C 1165 1164 0 TEXT "Conditions" | 36280,204549 1 0 0 "scl == 1'b0"
115 | H 1166 1163 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,276400
116 | I 1169 1166 0 Builtin Entry | 96520,182880
117 | I 1170 1166 0 Builtin Exit | 144780,121920
118 | W 1171 1166 0 1169 1170 BEZIER "Transitions" | 100503,182880 105961,175176 136367,129625 141825,121920
119 | C 1174 1173 0 TEXT "Conditions" | 38599,178519 1 0 0 "startStopDetState == `STOP_DET || \n(streamSt == `STREAM_IDLE && startStopDetState == `NULL_DET)"
120 | A 1175 1158 16 TEXT "Actions" | 50457,231381 1 0 0 "rxData <= {rxData [6:0], sdaIn};\nbitCnt <= 3'b000;"
121 | L 1176 1177 0 TEXT "State Labels" | 153270,180426 1 0 0 "ST_LOOP\n/11/"
122 | S 1177 1103 57344 ELLIPSE "States" | 153270,180426 6500 6500
123 | W 1178 1103 2 1163 1177 BEZIER "Transitions" | 57992,183868 81212,183352 123565,181370 146785,180854
124 | L 1179 1180 0 TEXT "State Labels" | 155592,146628 1 0 0 "LOOP_WT_LO\n/10/"
125 | S 1180 1103 53248 ELLIPSE "States" | 155592,146628 6500 6500
126 | L 1181 1182 0 TEXT "State Labels" | 157656,119022 1 0 0 "CHK_LOOP_FIN\n/9/"
127 | S 1182 1103 49152 ELLIPSE "States" | 157656,119022 6500 6500
128 | W 1183 1103 0 1177 1180 BEZIER "Transitions" | 153480,173948 154060,169433 154616,157853 155339,153110
129 | W 1173 1103 1 1163 1227 BEZIER "Transitions" | 53628,180156 50790,158613 43756,133955 42667,107411
130 | L 99 100 0 TEXT "State Labels" | 112176,193512 1 0 0 "START\n/0/"
131 | S 100 6 0 ELLIPSE "States" | 112176,193512 6500 6500
132 | C 1184 1183 0 TEXT "Conditions" | 155746,173950 1 0 0 "scl == 1'b1"
133 | A 1185 1183 16 TEXT "Actions" | 132915,164958 1 0 0 "rxData <= {rxData [6:0], sdaIn};"
134 | W 1186 1103 0 1180 1182 BEZIER "Transitions" | 155830,140145 156152,136275 156699,129381 156919,125472
135 | C 1187 1186 0 TEXT "Conditions" | 157807,138966 1 0 0 "scl == 1'b0"
136 | L 1188 1189 0 TEXT "State Labels" | 140079,63027 1 0 0 "WT_HI2\n/13/"
137 | S 1189 1103 65536 ELLIPSE "States" | 140079,63027 6500 6500
138 | W 1190 1103 1 1182 1222 BEZIER "Transitions" | 158063,112542 158373,105705 114008,67631 99616,51225
139 | C 1191 1190 0 TEXT "Conditions" | 154327,105370 1 0 0 "bitCnt == 3'b111"
140 | W 1192 1103 2 1182 1177 BEZIER "Transitions" | 164050,120187 172177,122186 187713,125537 192034,132825\
141 | 196356,140113 197388,165269 194840,174814 192293,184360\
142 | 181069,197390 175554,198486 170040,199583 161883,190407\
143 | 156465,186086
144 | A 1194 1192 16 TEXT "Actions" | 177909,132825 1 0 0 "bitCnt <= bitCnt + 1'b1;"
145 | A 1195 1190 16 TEXT "Actions" | 75201,159471 1 0 0 "sdaOut <= `I2C_ACK;\ncase (streamSt)\n `STREAM_IDLE: begin\n if (rxData[7:1] == `I2C_ADDRESS && \n startStopDetState == `START_DET) begin\n if (rxData[0] == 1'b1)\n streamSt <= `STREAM_READ;\n else\n streamSt <= `STREAM_WRITE_ADDR;\n end\n else\n sdaOut <= `I2C_NAK;\n end\n `STREAM_WRITE_ADDR: begin\n streamSt <= `STREAM_WRITE_DATA;\n regAddr <= rxData;\n end\n `STREAM_WRITE_DATA: begin\n dataOut <= rxData;\n writeEn <= 1'b1;\n end\n default:\n streamSt <= streamSt; \nendcase"
146 | L 1196 1197 0 TEXT "State Labels" | 191305,78543 1 0 0 "WT_LO2\n/12/"
147 | S 1197 1103 61440 ELLIPSE "States" | 191305,78543 6500 6500
148 | W 1198 1103 0 1189 1197 BEZIER "Transitions" | 146335,64787 154139,63625 179557,72674 185403,75822
149 | C 1199 1198 0 TEXT "Conditions" | 155872,71869 1 0 0 "scl == 1'b1"
150 | W 1211 6 0 1102 1091 BEZIER "Transitions" | 76391,131214 68980,132010 55006,133664 50535,137890\
151 | 46064,142116 43001,157429 45206,164043 47411,170658\
152 | 59294,181807 66276,184103 73258,186400 89307,184440\
153 | 95064,182296 100821,180153 105473,175392 108964,172085
154 | W 1210 6 0 1093 1091 BEZIER "Transitions" | 152177,133113 160752,135501 176220,139177 178823,144934\
155 | 181427,150691 174688,168944 167277,174211 159867,179478\
156 | 136958,182297 130006,181531 123055,180765 119021,175394\
157 | 116571,172454
158 | I 1209 0 130 Builtin Signal | 170935,221379 "" ""
159 | L 1208 1209 0 TEXT "Labels" | 173935,221379 1 0 0 "rxData[7:0]"
160 | I 1207 0 130 Builtin Signal | 170682,226692 "" ""
161 | L 1206 1207 0 TEXT "Labels" | 173682,226692 1 0 0 "txData[7:0]"
162 | I 387 6 0 Builtin Reset | 49555,202550
163 | W 388 6 0 387 100 BEZIER "Transitions" | 49555,202550 64193,201024 91216,196545 105854,195019
164 | C 389 388 0 TEXT "Conditions" | 63836,205024 1 0 0 "rst == 1'b1"
165 | W 1201 1103 0 1197 1228 BEZIER "Transitions" | 192418,72141 193381,63146 199794,43721 197819,33702
166 | C 1202 1201 0 TEXT "Conditions" | 186842,58803 1 0 0 "scl == 1'b0"
167 | A 1203 1173 16 TEXT "Actions" | 31827,161251 1 0 0 "streamSt <= `STREAM_IDLE;\nclearStartStopDet <= 1'b1;"
168 | A 1205 1154 16 TEXT "Actions" | 46743,263198 1 0 0 "rxData <= 8'h00;"
169 | L 1212 1213 0 TEXT "Labels" | 173176,236812 1 0 0 "bitCnt[2:0]"
170 | I 1213 0 130 Builtin Signal | 170176,236812 "" ""
171 | L 1215 1216 0 TEXT "Labels" | 82738,249858 1 0 0 "clearStartStopDet"
172 | I 1216 0 2 Builtin OutPort | 76738,249858 "" ""
173 | A 1218 1164 16 TEXT "Actions" | 61717,219098 1 0 0 "case (startStopDetState)\n `NULL_DET:\n bitCnt <= bitCnt + 1'b1;\n `START_DET: begin\n streamSt <= `STREAM_IDLE;\n rxData <= 8'h00;\n end\n default: ;\nendcase"
174 | A 1219 1201 16 TEXT "Actions" | 186936,64587 1 0 0 "sdaOut <= 1'b1;"
175 | L 1221 1222 0 TEXT "State Labels" | 97155,45210 1 0 0 "CLR_WR\n/14/"
176 | S 1222 1103 69632 ELLIPSE "States" | 97155,45210 6500 6500
177 | A 1223 1222 4 TEXT "Actions" | 51543,60237 1 0 0 "if (writeEn == 1'b1)\n regAddr <= regAddr + 1'b1;\nwriteEn <= 1'b0;\nclearStartStopDet <= 1'b1;"
178 | W 1224 1103 0 1222 1189 BEZIER "Transitions" | 103397,43398 108943,43589 118129,42724 122750,44891\
179 | 127372,47058 132685,53538 136382,57681
180 | A 1225 1189 4 TEXT "Actions" | 138593,50693 1 0 0 "clearStartStopDet <= 1'b0;"
181 | L 1226 1227 0 TEXT "State Labels" | 44784,101266 1 0 0 "CLR_ST_STOP\n/15/"
182 | S 1227 1103 73728 ELLIPSE "States" | 44784,101266 6500 6500
183 | I 1228 1103 0 Builtin Exit | 194898,33702
184 | W 1229 1103 0 1227 1228 BEZIER "Transitions" | 43558,94885 41209,84027 36973,63356 36338,55800\
185 | 35703,48244 37863,39734 41355,37226 44847,34718\
186 | 56659,33194 75867,32940 95076,32686 159465,33448\
187 | 191977,33702
188 | A 1230 1227 4 TEXT "Actions" | 30606,92250 1 0 0 "clearStartStopDet <= 1'b0;"
189 | W 1239 6 0 100 1091 BEZIER "Transitions" | 112488,187021 112665,183009 112810,177405 112987,173393
190 | I 479 0 130 Builtin InPort | 123454,253473 "" ""
191 | L 478 477 0 TEXT "Labels" | 127232,248761 1 0 0 "dataOut[7:0]"
192 | I 477 0 130 Builtin OutPort | 121232,248761 "" ""
193 | L 476 475 0 TEXT "Labels" | 127470,243915 1 0 0 "writeEn"
194 | I 475 0 2 Builtin OutPort | 121470,243915 "" ""
195 | L 472 471 0 TEXT "Labels" | 126974,258272 1 0 0 "regAddr[7:0]"
196 | I 471 0 130 Builtin OutPort | 120974,258272 "" ""
197 | L 480 479 0 TEXT "Labels" | 129454,253473 1 0 0 "dataIn[7:0]"
198 | I 499 0 2 Builtin InPort | 79523,242127 "" ""
199 | L 498 499 0 TEXT "Labels" | 85523,242127 1 0 0 "scl"
200 | I 497 0 130 Builtin InPort | 78578,254745 "" ""
201 | L 496 497 0 TEXT "Labels" | 84578,254745 1 0 0 "startStopDetState[1:0]"
202 | I 1065 0 2 Builtin InPort | 79622,237762 "" ""
203 | L 1064 1065 0 TEXT "Labels" | 85622,237762 1 0 0 "sdaIn"
204 | L 1083 1084 0 TEXT "Labels" | 83208,232994 1 0 0 "sdaOut"
205 | I 1084 0 2 Builtin OutPort | 77208,232994 "" ""
206 | L 1087 1088 0 TEXT "Labels" | 173556,231962 1 0 0 "streamSt[1:0]"
207 | END
208 |
--------------------------------------------------------------------------------
/model/i2c_master_bit_ctrl.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////
2 | //// ////
3 | //// WISHBONE rev.B2 compliant I2C Master bit-controller ////
4 | //// ////
5 | //// ////
6 | //// Author: Richard Herveille ////
7 | //// richard@asics.ws ////
8 | //// www.asics.ws ////
9 | //// ////
10 | //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
11 | //// ////
12 | /////////////////////////////////////////////////////////////////////
13 | //// ////
14 | //// Copyright (C) 2001 Richard Herveille ////
15 | //// richard@asics.ws ////
16 | //// ////
17 | //// This source file may be used and distributed without ////
18 | //// restriction provided that this copyright statement is not ////
19 | //// removed from the file and that any derivative work contains ////
20 | //// the original copyright notice and the associated disclaimer.////
21 | //// ////
22 | //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
23 | //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
24 | //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
25 | //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
26 | //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
27 | //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
28 | //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
29 | //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
30 | //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
31 | //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
32 | //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
33 | //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
34 | //// POSSIBILITY OF SUCH DAMAGE. ////
35 | //// ////
36 | /////////////////////////////////////////////////////////////////////
37 |
38 | // CVS Log
39 | //
40 | // $Id: i2c_master_bit_ctrl.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
41 | //
42 | // $Date: 2008-11-08 13:15:10 $
43 | // $Revision: 1.1 $
44 | // $Author: sfielding $
45 | // $Locker: $
46 | // $State: Exp $
47 | //
48 | // Change History:
49 | // $Log: not supported by cvs2svn $
50 | // Revision 1.12 2006/09/04 09:08:13 rherveille
51 | // fixed short scl high pulse after clock stretch
52 | // fixed slave model not returning correct '(n)ack' signal
53 | //
54 | // Revision 1.11 2004/05/07 11:02:26 rherveille
55 | // Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
56 | //
57 | // Revision 1.10 2003/08/09 07:01:33 rherveille
58 | // Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
59 | // Fixed a potential bug in the byte controller's host-acknowledge generation.
60 | //
61 | // Revision 1.9 2003/03/10 14:26:37 rherveille
62 | // Fixed cmd_ack generation item (no bug).
63 | //
64 | // Revision 1.8 2003/02/05 00:06:10 rherveille
65 | // Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
66 | //
67 | // Revision 1.7 2002/12/26 16:05:12 rherveille
68 | // Small code simplifications
69 | //
70 | // Revision 1.6 2002/12/26 15:02:32 rherveille
71 | // Core is now a Multimaster I2C controller
72 | //
73 | // Revision 1.5 2002/11/30 22:24:40 rherveille
74 | // Cleaned up code
75 | //
76 | // Revision 1.4 2002/10/30 18:10:07 rherveille
77 | // Fixed some reported minor start/stop generation timing issuess.
78 | //
79 | // Revision 1.3 2002/06/15 07:37:03 rherveille
80 | // Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
81 | //
82 | // Revision 1.2 2001/11/05 11:59:25 rherveille
83 | // Fixed wb_ack_o generation bug.
84 | // Fixed bug in the byte_controller statemachine.
85 | // Added headers.
86 | //
87 |
88 | //
89 | /////////////////////////////////////
90 | // Bit controller section
91 | /////////////////////////////////////
92 | //
93 | // Translate simple commands into SCL/SDA transitions
94 | // Each command has 5 states, A/B/C/D/idle
95 | //
96 | // start: SCL ~~~~~~~~~~\____
97 | // SDA ~~~~~~~~\______
98 | // x | A | B | C | D | i
99 | //
100 | // repstart SCL ____/~~~~\___
101 | // SDA __/~~~\______
102 | // x | A | B | C | D | i
103 | //
104 | // stop SCL ____/~~~~~~~~
105 | // SDA ==\____/~~~~~
106 | // x | A | B | C | D | i
107 | //
108 | //- write SCL ____/~~~~\____
109 | // SDA ==X=========X=
110 | // x | A | B | C | D | i
111 | //
112 | //- read SCL ____/~~~~\____
113 | // SDA XXXX=====XXXX
114 | // x | A | B | C | D | i
115 | //
116 |
117 | // Timing: Normal mode Fast mode
118 | ///////////////////////////////////////////////////////////////////////
119 | // Fscl 100KHz 400KHz
120 | // Th_scl 4.0us 0.6us High period of SCL
121 | // Tl_scl 4.7us 1.3us Low period of SCL
122 | // Tsu:sta 4.7us 0.6us setup time for a repeated start condition
123 | // Tsu:sto 4.0us 0.6us setup time for a stop conditon
124 | // Tbuf 4.7us 1.3us Bus free time between a stop and start condition
125 | //
126 |
127 | // synopsys translate_off
128 | `include "timescale.v"
129 | // synopsys translate_on
130 |
131 | `include "i2c_master_defines.v"
132 |
133 | module i2c_master_bit_ctrl(
134 | clk, rst, nReset,
135 | clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
136 | scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
137 | );
138 |
139 | //
140 | // inputs & outputs
141 | //
142 | input clk;
143 | input rst;
144 | input nReset;
145 | input ena; // core enable signal
146 |
147 | input [15:0] clk_cnt; // clock prescale value
148 |
149 | input [3:0] cmd;
150 | output cmd_ack; // command complete acknowledge
151 | reg cmd_ack;
152 | output busy; // i2c bus busy
153 | reg busy;
154 | output al; // i2c bus arbitration lost
155 | reg al;
156 |
157 | input din;
158 | output dout;
159 | reg dout;
160 |
161 | // I2C lines
162 | input scl_i; // i2c clock line input
163 | output scl_o; // i2c clock line output
164 | output scl_oen; // i2c clock line output enable (active low)
165 | reg scl_oen;
166 | input sda_i; // i2c data line input
167 | output sda_o; // i2c data line output
168 | output sda_oen; // i2c data line output enable (active low)
169 | reg sda_oen;
170 |
171 |
172 | //
173 | // variable declarations
174 | //
175 |
176 | reg sSCL, sSDA; // synchronized SCL and SDA inputs
177 | reg dscl_oen; // delayed scl_oen
178 | reg sda_chk; // check SDA output (Multi-master arbitration)
179 | reg clk_en; // clock generation signals
180 | wire slave_wait;
181 | // reg [15:0] cnt = clk_cnt; // clock divider counter (simulation)
182 | reg [15:0] cnt; // clock divider counter (synthesis)
183 |
184 | // state machine variable
185 | reg [16:0] c_state; // synopsys enum_state
186 |
187 | //
188 | // module body
189 | //
190 |
191 | // whenever the slave is not ready it can delay the cycle by pulling SCL low
192 | // delay scl_oen
193 | always @(posedge clk)
194 | dscl_oen <= #1 scl_oen;
195 |
196 | assign slave_wait = dscl_oen && !sSCL;
197 |
198 |
199 | // generate clk enable signal
200 | always @(posedge clk or negedge nReset)
201 | if(~nReset)
202 | begin
203 | cnt <= #1 16'h0;
204 | clk_en <= #1 1'b1;
205 | end
206 | else if (rst)
207 | begin
208 | cnt <= #1 16'h0;
209 | clk_en <= #1 1'b1;
210 | end
211 | else if ( ~|cnt || !ena)
212 | begin
213 | cnt <= #1 clk_cnt;
214 | clk_en <= #1 1'b1;
215 | end
216 | else if (slave_wait)
217 | begin
218 | cnt <= #1 cnt;
219 | clk_en <= #1 1'b0;
220 | end
221 | else
222 | begin
223 | cnt <= #1 cnt - 16'h1;
224 | clk_en <= #1 1'b0;
225 | end
226 |
227 |
228 | // generate bus status controller
229 | reg dSCL, dSDA;
230 | reg sta_condition;
231 | reg sto_condition;
232 |
233 | // synchronize SCL and SDA inputs
234 | // reduce metastability risc
235 | always @(posedge clk or negedge nReset)
236 | if (~nReset)
237 | begin
238 | sSCL <= #1 1'b1;
239 | sSDA <= #1 1'b1;
240 |
241 | dSCL <= #1 1'b1;
242 | dSDA <= #1 1'b1;
243 | end
244 | else if (rst)
245 | begin
246 | sSCL <= #1 1'b1;
247 | sSDA <= #1 1'b1;
248 |
249 | dSCL <= #1 1'b1;
250 | dSDA <= #1 1'b1;
251 | end
252 | else
253 | begin
254 | sSCL <= #1 scl_i;
255 | sSDA <= #1 sda_i;
256 |
257 | dSCL <= #1 sSCL;
258 | dSDA <= #1 sSDA;
259 | end
260 |
261 | // detect start condition => detect falling edge on SDA while SCL is high
262 | // detect stop condition => detect rising edge on SDA while SCL is high
263 | always @(posedge clk or negedge nReset)
264 | if (~nReset)
265 | begin
266 | sta_condition <= #1 1'b0;
267 | sto_condition <= #1 1'b0;
268 | end
269 | else if (rst)
270 | begin
271 | sta_condition <= #1 1'b0;
272 | sto_condition <= #1 1'b0;
273 | end
274 | else
275 | begin
276 | sta_condition <= #1 ~sSDA & dSDA & sSCL;
277 | sto_condition <= #1 sSDA & ~dSDA & sSCL;
278 | end
279 |
280 | // generate i2c bus busy signal
281 | always @(posedge clk or negedge nReset)
282 | if(!nReset)
283 | busy <= #1 1'b0;
284 | else if (rst)
285 | busy <= #1 1'b0;
286 | else
287 | busy <= #1 (sta_condition | busy) & ~sto_condition;
288 |
289 | // generate arbitration lost signal
290 | // aribitration lost when:
291 | // 1) master drives SDA high, but the i2c bus is low
292 | // 2) stop detected while not requested
293 | reg cmd_stop;
294 | always @(posedge clk or negedge nReset)
295 | if (~nReset)
296 | cmd_stop <= #1 1'b0;
297 | else if (rst)
298 | cmd_stop <= #1 1'b0;
299 | else if (clk_en)
300 | cmd_stop <= #1 cmd == `I2C_CMD_STOP;
301 |
302 | always @(posedge clk or negedge nReset)
303 | if (~nReset)
304 | al <= #1 1'b0;
305 | else if (rst)
306 | al <= #1 1'b0;
307 | else
308 | al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
309 |
310 |
311 | // generate dout signal (store SDA on rising edge of SCL)
312 | always @(posedge clk)
313 | if(sSCL & ~dSCL)
314 | dout <= #1 sSDA;
315 |
316 | // generate statemachine
317 |
318 | // nxt_state decoder
319 | parameter [16:0] idle = 17'b0_0000_0000_0000_0000;
320 | parameter [16:0] start_a = 17'b0_0000_0000_0000_0001;
321 | parameter [16:0] start_b = 17'b0_0000_0000_0000_0010;
322 | parameter [16:0] start_c = 17'b0_0000_0000_0000_0100;
323 | parameter [16:0] start_d = 17'b0_0000_0000_0000_1000;
324 | parameter [16:0] start_e = 17'b0_0000_0000_0001_0000;
325 | parameter [16:0] stop_a = 17'b0_0000_0000_0010_0000;
326 | parameter [16:0] stop_b = 17'b0_0000_0000_0100_0000;
327 | parameter [16:0] stop_c = 17'b0_0000_0000_1000_0000;
328 | parameter [16:0] stop_d = 17'b0_0000_0001_0000_0000;
329 | parameter [16:0] rd_a = 17'b0_0000_0010_0000_0000;
330 | parameter [16:0] rd_b = 17'b0_0000_0100_0000_0000;
331 | parameter [16:0] rd_c = 17'b0_0000_1000_0000_0000;
332 | parameter [16:0] rd_d = 17'b0_0001_0000_0000_0000;
333 | parameter [16:0] wr_a = 17'b0_0010_0000_0000_0000;
334 | parameter [16:0] wr_b = 17'b0_0100_0000_0000_0000;
335 | parameter [16:0] wr_c = 17'b0_1000_0000_0000_0000;
336 | parameter [16:0] wr_d = 17'b1_0000_0000_0000_0000;
337 |
338 | always @(posedge clk or negedge nReset)
339 | if (!nReset)
340 | begin
341 | c_state <= #1 idle;
342 | cmd_ack <= #1 1'b0;
343 | scl_oen <= #1 1'b1;
344 | sda_oen <= #1 1'b1;
345 | sda_chk <= #1 1'b0;
346 | end
347 | else if (rst | al)
348 | begin
349 | c_state <= #1 idle;
350 | cmd_ack <= #1 1'b0;
351 | scl_oen <= #1 1'b1;
352 | sda_oen <= #1 1'b1;
353 | sda_chk <= #1 1'b0;
354 | end
355 | else
356 | begin
357 | cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
358 |
359 | if (clk_en)
360 | case (c_state) // synopsys full_case parallel_case
361 | // idle state
362 | idle:
363 | begin
364 | case (cmd) // synopsys full_case parallel_case
365 | `I2C_CMD_START:
366 | c_state <= #1 start_a;
367 |
368 | `I2C_CMD_STOP:
369 | c_state <= #1 stop_a;
370 |
371 | `I2C_CMD_WRITE:
372 | c_state <= #1 wr_a;
373 |
374 | `I2C_CMD_READ:
375 | c_state <= #1 rd_a;
376 |
377 | default:
378 | c_state <= #1 idle;
379 | endcase
380 |
381 | scl_oen <= #1 scl_oen; // keep SCL in same state
382 | sda_oen <= #1 sda_oen; // keep SDA in same state
383 | sda_chk <= #1 1'b0; // don't check SDA output
384 | end
385 |
386 | // start
387 | start_a:
388 | begin
389 | c_state <= #1 start_b;
390 | scl_oen <= #1 scl_oen; // keep SCL in same state
391 | sda_oen <= #1 1'b1; // set SDA high
392 | sda_chk <= #1 1'b0; // don't check SDA output
393 | end
394 |
395 | start_b:
396 | begin
397 | c_state <= #1 start_c;
398 | scl_oen <= #1 1'b1; // set SCL high
399 | sda_oen <= #1 1'b1; // keep SDA high
400 | sda_chk <= #1 1'b0; // don't check SDA output
401 | end
402 |
403 | start_c:
404 | begin
405 | c_state <= #1 start_d;
406 | scl_oen <= #1 1'b1; // keep SCL high
407 | sda_oen <= #1 1'b0; // set SDA low
408 | sda_chk <= #1 1'b0; // don't check SDA output
409 | end
410 |
411 | start_d:
412 | begin
413 | c_state <= #1 start_e;
414 | scl_oen <= #1 1'b1; // keep SCL high
415 | sda_oen <= #1 1'b0; // keep SDA low
416 | sda_chk <= #1 1'b0; // don't check SDA output
417 | end
418 |
419 | start_e:
420 | begin
421 | c_state <= #1 idle;
422 | cmd_ack <= #1 1'b1;
423 | scl_oen <= #1 1'b0; // set SCL low
424 | sda_oen <= #1 1'b0; // keep SDA low
425 | sda_chk <= #1 1'b0; // don't check SDA output
426 | end
427 |
428 | // stop
429 | stop_a:
430 | begin
431 | c_state <= #1 stop_b;
432 | scl_oen <= #1 1'b0; // keep SCL low
433 | sda_oen <= #1 1'b0; // set SDA low
434 | sda_chk <= #1 1'b0; // don't check SDA output
435 | end
436 |
437 | stop_b:
438 | begin
439 | c_state <= #1 stop_c;
440 | scl_oen <= #1 1'b1; // set SCL high
441 | sda_oen <= #1 1'b0; // keep SDA low
442 | sda_chk <= #1 1'b0; // don't check SDA output
443 | end
444 |
445 | stop_c:
446 | begin
447 | c_state <= #1 stop_d;
448 | scl_oen <= #1 1'b1; // keep SCL high
449 | sda_oen <= #1 1'b0; // keep SDA low
450 | sda_chk <= #1 1'b0; // don't check SDA output
451 | end
452 |
453 | stop_d:
454 | begin
455 | c_state <= #1 idle;
456 | cmd_ack <= #1 1'b1;
457 | scl_oen <= #1 1'b1; // keep SCL high
458 | sda_oen <= #1 1'b1; // set SDA high
459 | sda_chk <= #1 1'b0; // don't check SDA output
460 | end
461 |
462 | // read
463 | rd_a:
464 | begin
465 | c_state <= #1 rd_b;
466 | scl_oen <= #1 1'b0; // keep SCL low
467 | sda_oen <= #1 1'b1; // tri-state SDA
468 | sda_chk <= #1 1'b0; // don't check SDA output
469 | end
470 |
471 | rd_b:
472 | begin
473 | c_state <= #1 rd_c;
474 | scl_oen <= #1 1'b1; // set SCL high
475 | sda_oen <= #1 1'b1; // keep SDA tri-stated
476 | sda_chk <= #1 1'b0; // don't check SDA output
477 | end
478 |
479 | rd_c:
480 | begin
481 | c_state <= #1 rd_d;
482 | scl_oen <= #1 1'b1; // keep SCL high
483 | sda_oen <= #1 1'b1; // keep SDA tri-stated
484 | sda_chk <= #1 1'b0; // don't check SDA output
485 | end
486 |
487 | rd_d:
488 | begin
489 | c_state <= #1 idle;
490 | cmd_ack <= #1 1'b1;
491 | scl_oen <= #1 1'b0; // set SCL low
492 | sda_oen <= #1 1'b1; // keep SDA tri-stated
493 | sda_chk <= #1 1'b0; // don't check SDA output
494 | end
495 |
496 | // write
497 | wr_a:
498 | begin
499 | c_state <= #1 wr_b;
500 | scl_oen <= #1 1'b0; // keep SCL low
501 | sda_oen <= #1 din; // set SDA
502 | sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
503 | end
504 |
505 | wr_b:
506 | begin
507 | c_state <= #1 wr_c;
508 | scl_oen <= #1 1'b1; // set SCL high
509 | sda_oen <= #1 din; // keep SDA
510 | sda_chk <= #1 1'b1; // check SDA output
511 | end
512 |
513 | wr_c:
514 | begin
515 | c_state <= #1 wr_d;
516 | scl_oen <= #1 1'b1; // keep SCL high
517 | sda_oen <= #1 din;
518 | sda_chk <= #1 1'b1; // check SDA output
519 | end
520 |
521 | wr_d:
522 | begin
523 | c_state <= #1 idle;
524 | cmd_ack <= #1 1'b1;
525 | scl_oen <= #1 1'b0; // set SCL low
526 | sda_oen <= #1 din;
527 | sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
528 | end
529 |
530 | endcase
531 | end
532 |
533 |
534 | // assign scl and sda output (always gnd)
535 | assign scl_o = 1'b0;
536 | assign sda_o = 1'b0;
537 |
538 | endmodule
539 |
--------------------------------------------------------------------------------
/sw/aardvark_c/aardvark.h:
--------------------------------------------------------------------------------
1 | /*=========================================================================
2 | | Aardvark Interface Library
3 | |--------------------------------------------------------------------------
4 | | Copyright (c) 2002-2008 Total Phase, Inc.
5 | | All rights reserved.
6 | | www.totalphase.com
7 | |
8 | | Redistribution and use in source and binary forms, with or without
9 | | modification, are permitted provided that the following conditions
10 | | are met:
11 | |
12 | | - Redistributions of source code must retain the above copyright
13 | | notice, this list of conditions and the following disclaimer.
14 | |
15 | | - Redistributions in binary form must reproduce the above copyright
16 | | notice, this list of conditions and the following disclaimer in the
17 | | documentation and/or other materials provided with the distribution.
18 | |
19 | | - Neither the name of Total Phase, Inc. nor the names of its
20 | | contributors may be used to endorse or promote products derived from
21 | | this software without specific prior written permission.
22 | |
23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 | | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 | | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 | | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 | | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 | | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 | | POSSIBILITY OF SUCH DAMAGE.
35 | |--------------------------------------------------------------------------
36 | | To access Aardvark devices through the API:
37 | |
38 | | 1) Use one of the following shared objects:
39 | | aardvark.so -- Linux shared object
40 | | aardvark.dll -- Windows dynamic link library
41 | |
42 | | 2) Along with one of the following language modules:
43 | | aardvark.c/h -- C/C++ API header file and interface module
44 | | aardvark_py.py -- Python API
45 | | aardvark.bas -- Visual Basic 6 API
46 | | aardvark.cs -- C# .NET source
47 | | aardvark_net.dll -- Compiled .NET binding
48 | ========================================================================*/
49 |
50 |
51 | #ifndef __aardvark_h__
52 | #define __aardvark_h__
53 |
54 | #ifdef __cplusplus
55 | extern "C" {
56 | #endif
57 |
58 |
59 | /*=========================================================================
60 | | TYPEDEFS
61 | ========================================================================*/
62 | #ifndef TOTALPHASE_DATA_TYPES
63 | #define TOTALPHASE_DATA_TYPES
64 |
65 | #ifndef _MSC_VER
66 | /* C99-compliant compilers (GCC) */
67 | #include
68 | typedef uint8_t u08;
69 | typedef uint16_t u16;
70 | typedef uint32_t u32;
71 | typedef uint64_t u64;
72 | typedef int8_t s08;
73 | typedef int16_t s16;
74 | typedef int32_t s32;
75 | typedef int64_t s64;
76 |
77 | #else
78 | /* Microsoft compilers (Visual C++) */
79 | typedef unsigned __int8 u08;
80 | typedef unsigned __int16 u16;
81 | typedef unsigned __int32 u32;
82 | typedef unsigned __int64 u64;
83 | typedef signed __int8 s08;
84 | typedef signed __int16 s16;
85 | typedef signed __int32 s32;
86 | typedef signed __int64 s64;
87 |
88 | #endif /* __MSC_VER */
89 |
90 | #endif /* TOTALPHASE_DATA_TYPES */
91 |
92 |
93 | /*=========================================================================
94 | | DEBUG
95 | ========================================================================*/
96 | /* Set the following macro to '1' for debugging */
97 | #define AA_DEBUG 0
98 |
99 |
100 | /*=========================================================================
101 | | VERSION
102 | ========================================================================*/
103 | #define AA_HEADER_VERSION 0x0500 /* v5.00 */
104 |
105 |
106 | /*=========================================================================
107 | | STATUS CODES
108 | ========================================================================*/
109 | /*
110 | * All API functions return an integer which is the result of the
111 | * transaction, or a status code if negative. The status codes are
112 | * defined as follows:
113 | */
114 | enum AardvarkStatus {
115 | /* General codes (0 to -99) */
116 | AA_OK = 0,
117 | AA_UNABLE_TO_LOAD_LIBRARY = -1,
118 | AA_UNABLE_TO_LOAD_DRIVER = -2,
119 | AA_UNABLE_TO_LOAD_FUNCTION = -3,
120 | AA_INCOMPATIBLE_LIBRARY = -4,
121 | AA_INCOMPATIBLE_DEVICE = -5,
122 | AA_COMMUNICATION_ERROR = -6,
123 | AA_UNABLE_TO_OPEN = -7,
124 | AA_UNABLE_TO_CLOSE = -8,
125 | AA_INVALID_HANDLE = -9,
126 | AA_CONFIG_ERROR = -10,
127 |
128 | /* I2C codes (-100 to -199) */
129 | AA_I2C_NOT_AVAILABLE = -100,
130 | AA_I2C_NOT_ENABLED = -101,
131 | AA_I2C_READ_ERROR = -102,
132 | AA_I2C_WRITE_ERROR = -103,
133 | AA_I2C_SLAVE_BAD_CONFIG = -104,
134 | AA_I2C_SLAVE_READ_ERROR = -105,
135 | AA_I2C_SLAVE_TIMEOUT = -106,
136 | AA_I2C_DROPPED_EXCESS_BYTES = -107,
137 | AA_I2C_BUS_ALREADY_FREE = -108,
138 |
139 | /* SPI codes (-200 to -299) */
140 | AA_SPI_NOT_AVAILABLE = -200,
141 | AA_SPI_NOT_ENABLED = -201,
142 | AA_SPI_WRITE_ERROR = -202,
143 | AA_SPI_SLAVE_READ_ERROR = -203,
144 | AA_SPI_SLAVE_TIMEOUT = -204,
145 | AA_SPI_DROPPED_EXCESS_BYTES = -205,
146 |
147 | /* GPIO codes (-400 to -499) */
148 | AA_GPIO_NOT_AVAILABLE = -400,
149 |
150 | /* I2C bus monitor codes (-500 to -599) */
151 | AA_I2C_MONITOR_NOT_AVAILABLE = -500,
152 | AA_I2C_MONITOR_NOT_ENABLED = -501
153 | };
154 | #ifndef __cplusplus
155 | typedef enum AardvarkStatus AardvarkStatus;
156 | #endif
157 |
158 |
159 | /*=========================================================================
160 | | GENERAL TYPE DEFINITIONS
161 | ========================================================================*/
162 | /* Aardvark handle type definition */
163 | typedef int Aardvark;
164 |
165 | /*
166 | * Deprecated type definitions.
167 | *
168 | * These are only for use with legacy code and
169 | * should not be used for new development.
170 | */
171 | typedef u08 aa_u08;
172 |
173 | typedef u16 aa_u16;
174 |
175 | typedef u32 aa_u32;
176 |
177 | typedef s08 aa_s08;
178 |
179 | typedef s16 aa_s16;
180 |
181 | typedef s32 aa_s32;
182 |
183 | /*
184 | * Aardvark version matrix.
185 | *
186 | * This matrix describes the various version dependencies
187 | * of Aardvark components. It can be used to determine
188 | * which component caused an incompatibility error.
189 | *
190 | * All version numbers are of the format:
191 | * (major << 8) | minor
192 | *
193 | * ex. v1.20 would be encoded as: 0x0114
194 | */
195 | struct AardvarkVersion {
196 | /* Software, firmware, and hardware versions. */
197 | u16 software;
198 | u16 firmware;
199 | u16 hardware;
200 |
201 | /* Firmware requires that software must be >= this version. */
202 | u16 sw_req_by_fw;
203 |
204 | /* Software requires that firmware must be >= this version. */
205 | u16 fw_req_by_sw;
206 |
207 | /* Software requires that the API interface must be >= this version. */
208 | u16 api_req_by_sw;
209 | };
210 | #ifndef __cplusplus
211 | typedef struct AardvarkVersion AardvarkVersion;
212 | #endif
213 |
214 |
215 | /*=========================================================================
216 | | GENERAL API
217 | ========================================================================*/
218 | /*
219 | * Get a list of ports to which Aardvark devices are attached.
220 | *
221 | * nelem = maximum number of elements to return
222 | * devices = array into which the port numbers are returned
223 | *
224 | * Each element of the array is written with the port number.
225 | * Devices that are in-use are ORed with AA_PORT_NOT_FREE (0x8000).
226 | *
227 | * ex. devices are attached to ports 0, 1, 2
228 | * ports 0 and 2 are available, and port 1 is in-use.
229 | * array => 0x0000, 0x8001, 0x0002
230 | *
231 | * If the array is NULL, it is not filled with any values.
232 | * If there are more devices than the array size, only the
233 | * first nmemb port numbers will be written into the array.
234 | *
235 | * Returns the number of devices found, regardless of the
236 | * array size.
237 | */
238 | #define AA_PORT_NOT_FREE 0x8000
239 | int aa_find_devices (
240 | int num_devices,
241 | u16 * devices
242 | );
243 |
244 |
245 | /*
246 | * Get a list of ports to which Aardvark devices are attached.
247 | *
248 | * This function is the same as aa_find_devices() except that
249 | * it returns the unique IDs of each Aardvark device. The IDs
250 | * are guaranteed to be non-zero if valid.
251 | *
252 | * The IDs are the unsigned integer representation of the 10-digit
253 | * serial numbers.
254 | */
255 | int aa_find_devices_ext (
256 | int num_devices,
257 | u16 * devices,
258 | int num_ids,
259 | u32 * unique_ids
260 | );
261 |
262 |
263 | /*
264 | * Open the Aardvark port.
265 | *
266 | * The port number is a zero-indexed integer.
267 | *
268 | * The port number is the same as that obtained from the
269 | * aa_find_devices() function above.
270 | *
271 | * Returns an Aardvark handle, which is guaranteed to be
272 | * greater than zero if it is valid.
273 | *
274 | * This function is recommended for use in simple applications
275 | * where extended information is not required. For more complex
276 | * applications, the use of aa_open_ext() is recommended.
277 | */
278 | Aardvark aa_open (
279 | int port_number
280 | );
281 |
282 |
283 | /*
284 | * Open the Aardvark port, returning extended information
285 | * in the supplied structure. Behavior is otherwise identical
286 | * to aa_open() above. If 0 is passed as the pointer to the
287 | * structure, this function is exactly equivalent to aa_open().
288 | *
289 | * The structure is zeroed before the open is attempted.
290 | * It is filled with whatever information is available.
291 | *
292 | * For example, if the firmware version is not filled, then
293 | * the device could not be queried for its version number.
294 | *
295 | * This function is recommended for use in complex applications
296 | * where extended information is required. For more simple
297 | * applications, the use of aa_open() is recommended.
298 | */
299 | struct AardvarkExt {
300 | /* Version matrix */
301 | AardvarkVersion version;
302 |
303 | /* Features of this device. */
304 | int features;
305 | };
306 | #ifndef __cplusplus
307 | typedef struct AardvarkExt AardvarkExt;
308 | #endif
309 |
310 | Aardvark aa_open_ext (
311 | int port_number,
312 | AardvarkExt * aa_ext
313 | );
314 |
315 |
316 | /* Close the Aardvark port. */
317 | int aa_close (
318 | Aardvark aardvark
319 | );
320 |
321 |
322 | /*
323 | * Return the port for this Aardvark handle.
324 | *
325 | * The port number is a zero-indexed integer.
326 | */
327 | int aa_port (
328 | Aardvark aardvark
329 | );
330 |
331 |
332 | /*
333 | * Return the device features as a bit-mask of values, or
334 | * an error code if the handle is not valid.
335 | */
336 | #define AA_FEATURE_SPI 0x00000001
337 | #define AA_FEATURE_I2C 0x00000002
338 | #define AA_FEATURE_GPIO 0x00000008
339 | #define AA_FEATURE_I2C_MONITOR 0x00000010
340 | int aa_features (
341 | Aardvark aardvark
342 | );
343 |
344 |
345 | /*
346 | * Return the unique ID for this Aardvark adapter.
347 | * IDs are guaranteed to be non-zero if valid.
348 | * The ID is the unsigned integer representation of the
349 | * 10-digit serial number.
350 | */
351 | u32 aa_unique_id (
352 | Aardvark aardvark
353 | );
354 |
355 |
356 | /*
357 | * Return the status string for the given status code.
358 | * If the code is not valid or the library function cannot
359 | * be loaded, return a NULL string.
360 | */
361 | const char * aa_status_string (
362 | int status
363 | );
364 |
365 |
366 | /*
367 | * Enable logging to a file. The handle must be standard file
368 | * descriptor. In C, a file descriptor can be obtained by using
369 | * the ANSI C function "open" or by using the function "fileno"
370 | * on a FILE* stream. A FILE* stream can be obtained using "fopen"
371 | * or can correspond to the common "stdout" or "stderr" --
372 | * available when including stdlib.h
373 | */
374 | int aa_log (
375 | Aardvark aardvark,
376 | int level,
377 | int handle
378 | );
379 |
380 |
381 | /*
382 | * Return the version matrix for the device attached to the
383 | * given handle. If the handle is 0 or invalid, only the
384 | * software and required api versions are set.
385 | */
386 | int aa_version (
387 | Aardvark aardvark,
388 | AardvarkVersion * version
389 | );
390 |
391 |
392 | /*
393 | * Configure the device by enabling/disabling I2C, SPI, and
394 | * GPIO functions.
395 | */
396 | enum AardvarkConfig {
397 | AA_CONFIG_GPIO_ONLY = 0x00,
398 | AA_CONFIG_SPI_GPIO = 0x01,
399 | AA_CONFIG_GPIO_I2C = 0x02,
400 | AA_CONFIG_SPI_I2C = 0x03,
401 | AA_CONFIG_QUERY = 0x80
402 | };
403 | #ifndef __cplusplus
404 | typedef enum AardvarkConfig AardvarkConfig;
405 | #endif
406 |
407 | #define AA_CONFIG_SPI_MASK 0x00000001
408 | #define AA_CONFIG_I2C_MASK 0x00000002
409 | int aa_configure (
410 | Aardvark aardvark,
411 | AardvarkConfig config
412 | );
413 |
414 |
415 | /*
416 | * Configure the target power pins.
417 | * This is only supported on hardware versions >= 2.00
418 | */
419 | #define AA_TARGET_POWER_NONE 0x00
420 | #define AA_TARGET_POWER_BOTH 0x03
421 | #define AA_TARGET_POWER_QUERY 0x80
422 | int aa_target_power (
423 | Aardvark aardvark,
424 | u08 power_mask
425 | );
426 |
427 |
428 | /*
429 | * Sleep for the specified number of milliseconds
430 | * Accuracy depends on the operating system scheduler
431 | * Returns the number of milliseconds slept
432 | */
433 | u32 aa_sleep_ms (
434 | u32 milliseconds
435 | );
436 |
437 |
438 |
439 | /*=========================================================================
440 | | ASYNC MESSAGE POLLING
441 | ========================================================================*/
442 | /*
443 | * Polling function to check if there are any asynchronous
444 | * messages pending for processing. The function takes a timeout
445 | * value in units of milliseconds. If the timeout is < 0, the
446 | * function will block until data is received. If the timeout is 0,
447 | * the function will perform a non-blocking check.
448 | */
449 | #define AA_ASYNC_NO_DATA 0x00000000
450 | #define AA_ASYNC_I2C_READ 0x00000001
451 | #define AA_ASYNC_I2C_WRITE 0x00000002
452 | #define AA_ASYNC_SPI 0x00000004
453 | #define AA_ASYNC_I2C_MONITOR 0x00000008
454 | int aa_async_poll (
455 | Aardvark aardvark,
456 | int timeout
457 | );
458 |
459 |
460 |
461 | /*=========================================================================
462 | | I2C API
463 | ========================================================================*/
464 | /* Free the I2C bus. */
465 | int aa_i2c_free_bus (
466 | Aardvark aardvark
467 | );
468 |
469 |
470 | /*
471 | * Set the I2C bit rate in kilohertz. If a zero is passed as the
472 | * bitrate, the bitrate is unchanged and the current bitrate is
473 | * returned.
474 | */
475 | int aa_i2c_bitrate (
476 | Aardvark aardvark,
477 | int bitrate_khz
478 | );
479 |
480 |
481 | /*
482 | * Set the bus lock timeout. If a zero is passed as the timeout,
483 | * the timeout is unchanged and the current timeout is returned.
484 | */
485 | int aa_i2c_bus_timeout (
486 | Aardvark aardvark,
487 | u16 timeout_ms
488 | );
489 |
490 |
491 | enum AardvarkI2cFlags {
492 | AA_I2C_NO_FLAGS = 0x00,
493 | AA_I2C_10_BIT_ADDR = 0x01,
494 | AA_I2C_COMBINED_FMT = 0x02,
495 | AA_I2C_NO_STOP = 0x04,
496 | AA_I2C_SIZED_READ = 0x10,
497 | AA_I2C_SIZED_READ_EXTRA1 = 0x20
498 | };
499 | #ifndef __cplusplus
500 | typedef enum AardvarkI2cFlags AardvarkI2cFlags;
501 | #endif
502 |
503 | /* Read a stream of bytes from the I2C slave device. */
504 | int aa_i2c_read (
505 | Aardvark aardvark,
506 | u16 slave_addr,
507 | AardvarkI2cFlags flags,
508 | u16 num_bytes,
509 | u08 * data_in
510 | );
511 |
512 |
513 | enum AardvarkI2cStatus {
514 | AA_I2C_STATUS_OK = 0,
515 | AA_I2C_STATUS_BUS_ERROR = 1,
516 | AA_I2C_STATUS_SLA_ACK = 2,
517 | AA_I2C_STATUS_SLA_NACK = 3,
518 | AA_I2C_STATUS_DATA_NACK = 4,
519 | AA_I2C_STATUS_ARB_LOST = 5,
520 | AA_I2C_STATUS_BUS_LOCKED = 6,
521 | AA_I2C_STATUS_LAST_DATA_ACK = 7
522 | };
523 | #ifndef __cplusplus
524 | typedef enum AardvarkI2cStatus AardvarkI2cStatus;
525 | #endif
526 |
527 | /*
528 | * Read a stream of bytes from the I2C slave device.
529 | * This API function returns the number of bytes read into
530 | * the num_read variable. The return value of the function
531 | * is a status code.
532 | */
533 | int aa_i2c_read_ext (
534 | Aardvark aardvark,
535 | u16 slave_addr,
536 | AardvarkI2cFlags flags,
537 | u16 num_bytes,
538 | u08 * data_in,
539 | u16 * num_read
540 | );
541 |
542 |
543 | /* Write a stream of bytes to the I2C slave device. */
544 | int aa_i2c_write (
545 | Aardvark aardvark,
546 | u16 slave_addr,
547 | AardvarkI2cFlags flags,
548 | u16 num_bytes,
549 | const u08 * data_out
550 | );
551 |
552 |
553 | /*
554 | * Write a stream of bytes to the I2C slave device.
555 | * This API function returns the number of bytes written into
556 | * the num_written variable. The return value of the function
557 | * is a status code.
558 | */
559 | int aa_i2c_write_ext (
560 | Aardvark aardvark,
561 | u16 slave_addr,
562 | AardvarkI2cFlags flags,
563 | u16 num_bytes,
564 | const u08 * data_out,
565 | u16 * num_written
566 | );
567 |
568 |
569 | /* Enable/Disable the Aardvark as an I2C slave device */
570 | int aa_i2c_slave_enable (
571 | Aardvark aardvark,
572 | u08 addr,
573 | u16 maxTxBytes,
574 | u16 maxRxBytes
575 | );
576 |
577 |
578 | int aa_i2c_slave_disable (
579 | Aardvark aardvark
580 | );
581 |
582 |
583 | /*
584 | * Set the slave response in the event the Aardvark is put
585 | * into slave mode and contacted by a Master.
586 | */
587 | int aa_i2c_slave_set_response (
588 | Aardvark aardvark,
589 | u08 num_bytes,
590 | const u08 * data_out
591 | );
592 |
593 |
594 | /*
595 | * Return number of bytes written from a previous
596 | * Aardvark->I2C_master transmission. Since the transmission is
597 | * happening asynchronously with respect to the PC host
598 | * software, there could be responses queued up from many
599 | * previous write transactions.
600 | */
601 | int aa_i2c_slave_write_stats (
602 | Aardvark aardvark
603 | );
604 |
605 |
606 | /* Read the bytes from an I2C slave reception */
607 | int aa_i2c_slave_read (
608 | Aardvark aardvark,
609 | u08 * addr,
610 | u16 num_bytes,
611 | u08 * data_in
612 | );
613 |
614 |
615 | /* Extended functions that return status code */
616 | int aa_i2c_slave_write_stats_ext (
617 | Aardvark aardvark,
618 | u16 * num_written
619 | );
620 |
621 |
622 | int aa_i2c_slave_read_ext (
623 | Aardvark aardvark,
624 | u08 * addr,
625 | u16 num_bytes,
626 | u08 * data_in,
627 | u16 * num_read
628 | );
629 |
630 |
631 | /*
632 | * Enable the I2C bus monitor
633 | * This disables all other functions on the Aardvark adapter
634 | */
635 | int aa_i2c_monitor_enable (
636 | Aardvark aardvark
637 | );
638 |
639 |
640 | /* Disable the I2C bus monitor */
641 | int aa_i2c_monitor_disable (
642 | Aardvark aardvark
643 | );
644 |
645 |
646 | /* Read the data collected by the bus monitor */
647 | #define AA_I2C_MONITOR_DATA 0x00ff
648 | #define AA_I2C_MONITOR_NACK 0x0100
649 | #define AA_I2C_MONITOR_CMD_START 0xff00
650 | #define AA_I2C_MONITOR_CMD_STOP 0xff01
651 | int aa_i2c_monitor_read (
652 | Aardvark aardvark,
653 | u16 num_bytes,
654 | u16 * data
655 | );
656 |
657 |
658 | /*
659 | * Configure the I2C pullup resistors.
660 | * This is only supported on hardware versions >= 2.00
661 | */
662 | #define AA_I2C_PULLUP_NONE 0x00
663 | #define AA_I2C_PULLUP_BOTH 0x03
664 | #define AA_I2C_PULLUP_QUERY 0x80
665 | int aa_i2c_pullup (
666 | Aardvark aardvark,
667 | u08 pullup_mask
668 | );
669 |
670 |
671 |
672 | /*=========================================================================
673 | | SPI API
674 | ========================================================================*/
675 | /*
676 | * Set the SPI bit rate in kilohertz. If a zero is passed as the
677 | * bitrate, the bitrate is unchanged and the current bitrate is
678 | * returned.
679 | */
680 | int aa_spi_bitrate (
681 | Aardvark aardvark,
682 | int bitrate_khz
683 | );
684 |
685 |
686 | /*
687 | * These configuration parameters specify how to clock the
688 | * bits that are sent and received on the Aardvark SPI
689 | * interface.
690 | *
691 | * The polarity option specifies which transition
692 | * constitutes the leading edge and which transition is the
693 | * falling edge. For example, AA_SPI_POL_RISING_FALLING
694 | * would configure the SPI to idle the SCK clock line low.
695 | * The clock would then transition low-to-high on the
696 | * leading edge and high-to-low on the trailing edge.
697 | *
698 | * The phase option determines whether to sample or setup on
699 | * the leading edge. For example, AA_SPI_PHASE_SAMPLE_SETUP
700 | * would configure the SPI to sample on the leading edge and
701 | * setup on the trailing edge.
702 | *
703 | * The bitorder option is used to indicate whether LSB or
704 | * MSB is shifted first.
705 | *
706 | * See the diagrams in the Aardvark datasheet for
707 | * more details.
708 | */
709 | enum AardvarkSpiPolarity {
710 | AA_SPI_POL_RISING_FALLING = 0,
711 | AA_SPI_POL_FALLING_RISING = 1
712 | };
713 | #ifndef __cplusplus
714 | typedef enum AardvarkSpiPolarity AardvarkSpiPolarity;
715 | #endif
716 |
717 | enum AardvarkSpiPhase {
718 | AA_SPI_PHASE_SAMPLE_SETUP = 0,
719 | AA_SPI_PHASE_SETUP_SAMPLE = 1
720 | };
721 | #ifndef __cplusplus
722 | typedef enum AardvarkSpiPhase AardvarkSpiPhase;
723 | #endif
724 |
725 | enum AardvarkSpiBitorder {
726 | AA_SPI_BITORDER_MSB = 0,
727 | AA_SPI_BITORDER_LSB = 1
728 | };
729 | #ifndef __cplusplus
730 | typedef enum AardvarkSpiBitorder AardvarkSpiBitorder;
731 | #endif
732 |
733 | /* Configure the SPI master or slave interface */
734 | int aa_spi_configure (
735 | Aardvark aardvark,
736 | AardvarkSpiPolarity polarity,
737 | AardvarkSpiPhase phase,
738 | AardvarkSpiBitorder bitorder
739 | );
740 |
741 |
742 | /* Write a stream of bytes to the downstream SPI slave device. */
743 | int aa_spi_write (
744 | Aardvark aardvark,
745 | u16 out_num_bytes,
746 | const u08 * data_out,
747 | u16 in_num_bytes,
748 | u08 * data_in
749 | );
750 |
751 |
752 | /* Enable/Disable the Aardvark as an SPI slave device */
753 | int aa_spi_slave_enable (
754 | Aardvark aardvark
755 | );
756 |
757 |
758 | int aa_spi_slave_disable (
759 | Aardvark aardvark
760 | );
761 |
762 |
763 | /*
764 | * Set the slave response in the event the Aardvark is put
765 | * into slave mode and contacted by a Master.
766 | */
767 | int aa_spi_slave_set_response (
768 | Aardvark aardvark,
769 | u08 num_bytes,
770 | const u08 * data_out
771 | );
772 |
773 |
774 | /* Read the bytes from an SPI slave reception */
775 | int aa_spi_slave_read (
776 | Aardvark aardvark,
777 | u16 num_bytes,
778 | u08 * data_in
779 | );
780 |
781 |
782 | /*
783 | * Change the output polarity on the SS line.
784 | *
785 | * Note: When configured as an SPI slave, the Aardvark will
786 | * always be setup with SS as active low. Hence this function
787 | * only affects the SPI master functions on the Aardvark.
788 | */
789 | enum AardvarkSpiSSPolarity {
790 | AA_SPI_SS_ACTIVE_LOW = 0,
791 | AA_SPI_SS_ACTIVE_HIGH = 1
792 | };
793 | #ifndef __cplusplus
794 | typedef enum AardvarkSpiSSPolarity AardvarkSpiSSPolarity;
795 | #endif
796 |
797 | int aa_spi_master_ss_polarity (
798 | Aardvark aardvark,
799 | AardvarkSpiSSPolarity polarity
800 | );
801 |
802 |
803 |
804 | /*=========================================================================
805 | | GPIO API
806 | ========================================================================*/
807 | /*
808 | * The following enumerated type maps the named lines on the
809 | * Aardvark I2C/SPI line to bit positions in the GPIO API.
810 | * All GPIO API functions will index these lines through an
811 | * 8-bit masked value. Thus, each bit position in the mask
812 | * can be referred back its corresponding line through the
813 | * enumerated type.
814 | */
815 | enum AardvarkGpioBits {
816 | AA_GPIO_SCL = 0x01,
817 | AA_GPIO_SDA = 0x02,
818 | AA_GPIO_MISO = 0x04,
819 | AA_GPIO_SCK = 0x08,
820 | AA_GPIO_MOSI = 0x10,
821 | AA_GPIO_SS = 0x20
822 | };
823 | #ifndef __cplusplus
824 | typedef enum AardvarkGpioBits AardvarkGpioBits;
825 | #endif
826 |
827 | /*
828 | * Configure the GPIO, specifying the direction of each bit.
829 | *
830 | * A call to this function will not change the value of the pullup
831 | * mask in the Aardvark. This is illustrated by the following
832 | * example:
833 | * (1) Direction mask is first set to 0x00
834 | * (2) Pullup is set to 0x01
835 | * (3) Direction mask is set to 0x01
836 | * (4) Direction mask is later set back to 0x00.
837 | *
838 | * The pullup will be active after (4).
839 | *
840 | * On Aardvark power-up, the default value of the direction
841 | * mask is 0x00.
842 | */
843 | #define AA_GPIO_DIR_INPUT 0
844 | #define AA_GPIO_DIR_OUTPUT 1
845 | int aa_gpio_direction (
846 | Aardvark aardvark,
847 | u08 direction_mask
848 | );
849 |
850 |
851 | /*
852 | * Enable an internal pullup on any of the GPIO input lines.
853 | *
854 | * Note: If a line is configured as an output, the pullup bit
855 | * for that line will be ignored, though that pullup bit will
856 | * be cached in case the line is later configured as an input.
857 | *
858 | * By default the pullup mask is 0x00.
859 | */
860 | #define AA_GPIO_PULLUP_OFF 0
861 | #define AA_GPIO_PULLUP_ON 1
862 | int aa_gpio_pullup (
863 | Aardvark aardvark,
864 | u08 pullup_mask
865 | );
866 |
867 |
868 | /*
869 | * Read the current digital values on the GPIO input lines.
870 | *
871 | * The bits will be ordered as described by AA_GPIO_BITS. If a
872 | * line is configured as an output, its corresponding bit
873 | * position in the mask will be undefined.
874 | */
875 | int aa_gpio_get (
876 | Aardvark aardvark
877 | );
878 |
879 |
880 | /*
881 | * Set the outputs on the GPIO lines.
882 | *
883 | * Note: If a line is configured as an input, it will not be
884 | * affected by this call, but the output value for that line
885 | * will be cached in the event that the line is later
886 | * configured as an output.
887 | */
888 | int aa_gpio_set (
889 | Aardvark aardvark,
890 | u08 value
891 | );
892 |
893 |
894 | /*
895 | * Block until there is a change on the GPIO input lines.
896 | * Pins configured as outputs will be ignored.
897 | *
898 | * The function will return either when a change has occurred or
899 | * the timeout expires. The timeout, specified in millisecods, has
900 | * a precision of ~16 ms. The maximum allowable timeout is
901 | * approximately 4 seconds. If the timeout expires, this function
902 | * will return the current state of the GPIO lines.
903 | *
904 | * This function will return immediately with the current value
905 | * of the GPIO lines for the first invocation after any of the
906 | * following functions are called: aa_configure,
907 | * aa_gpio_direction, or aa_gpio_pullup.
908 | *
909 | * If the function aa_gpio_get is called before calling
910 | * aa_gpio_change, aa_gpio_change will only register any changes
911 | * from the value last returned by aa_gpio_get.
912 | */
913 | int aa_gpio_change (
914 | Aardvark aardvark,
915 | u16 timeout
916 | );
917 |
918 |
919 |
920 |
921 | #ifdef __cplusplus
922 | }
923 | #endif
924 |
925 | #endif /* __aardvark_h__ */
926 |
--------------------------------------------------------------------------------
/sw/aardvark_c/aardvark.c:
--------------------------------------------------------------------------------
1 | /*=========================================================================
2 | | Aardvark Interface Library
3 | |--------------------------------------------------------------------------
4 | | Copyright (c) 2002-2008 Total Phase, Inc.
5 | | All rights reserved.
6 | | www.totalphase.com
7 | |
8 | | Redistribution and use in source and binary forms, with or without
9 | | modification, are permitted provided that the following conditions
10 | | are met:
11 | |
12 | | - Redistributions of source code must retain the above copyright
13 | | notice, this list of conditions and the following disclaimer.
14 | |
15 | | - Redistributions in binary form must reproduce the above copyright
16 | | notice, this list of conditions and the following disclaimer in the
17 | | documentation and/or other materials provided with the distribution.
18 | |
19 | | - Neither the name of Total Phase, Inc. nor the names of its
20 | | contributors may be used to endorse or promote products derived from
21 | | this software without specific prior written permission.
22 | |
23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 | | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 | | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 | | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 | | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 | | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 | | POSSIBILITY OF SUCH DAMAGE.
35 | |--------------------------------------------------------------------------
36 | | To access Aardvark devices through the API:
37 | |
38 | | 1) Use one of the following shared objects:
39 | | aardvark.so -- Linux shared object
40 | | aardvark.dll -- Windows dynamic link library
41 | |
42 | | 2) Along with one of the following language modules:
43 | | aardvark.c/h -- C/C++ API header file and interface module
44 | | aardvark_py.py -- Python API
45 | | aardvark.bas -- Visual Basic 6 API
46 | | aardvark.cs -- C# .NET source
47 | | aardvark_net.dll -- Compiled .NET binding
48 | ========================================================================*/
49 |
50 |
51 | /*=========================================================================
52 | | INCLUDES
53 | ========================================================================*/
54 | /* This #include can be customized to conform to the user's build paths. */
55 | #include "aardvark.h"
56 |
57 |
58 | /*=========================================================================
59 | | VERSION CHECK
60 | ========================================================================*/
61 | #define AA_CFILE_VERSION 0x0500 /* v5.00 */
62 | #define AA_REQ_SW_VERSION 0x0500 /* v5.00 */
63 |
64 | /*
65 | * Make sure that the header file was included and that
66 | * the version numbers match.
67 | */
68 | #ifndef AA_HEADER_VERSION
69 | # error Unable to include header file. Please check include path.
70 |
71 | #elif AA_HEADER_VERSION != AA_CFILE_VERSION
72 | # error Version mismatch between source and header files.
73 |
74 | #endif
75 |
76 |
77 | /*=========================================================================
78 | | DEFINES
79 | ========================================================================*/
80 | #define API_NAME "aardvark"
81 | #define API_DEBUG AA_DEBUG
82 | #define API_OK AA_OK
83 | #define API_UNABLE_TO_LOAD_LIBRARY AA_UNABLE_TO_LOAD_LIBRARY
84 | #define API_INCOMPATIBLE_LIBRARY AA_INCOMPATIBLE_LIBRARY
85 | #define API_UNABLE_TO_LOAD_FUNCTION AA_UNABLE_TO_LOAD_FUNCTION
86 | #define API_HEADER_VERSION AA_HEADER_VERSION
87 | #define API_REQ_SW_VERSION AA_REQ_SW_VERSION
88 |
89 |
90 | /*=========================================================================
91 | | LINUX AND DARWIN SUPPORT
92 | ========================================================================*/
93 | #if defined(__APPLE_CC__) && !defined(DARWIN)
94 | #define DARWIN
95 | #endif
96 |
97 | #if defined(linux) || defined(DARWIN)
98 |
99 | #include
100 | #include
101 | #include
102 | #include
103 | #include
104 |
105 | #ifdef DARWIN
106 | #define DLOPEN_NO_WARN
107 | extern int _NSGetExecutablePath (char *buf, unsigned long *bufsize);
108 | #endif
109 |
110 | #include
111 |
112 | #define DLL_HANDLE void *
113 | #define MAX_SO_PATH 256
114 |
115 | static char SO_NAME[MAX_SO_PATH+1] = API_NAME ".so";
116 |
117 | /*
118 | * These functions allow the Linux behavior to emulate
119 | * the Windows behavior as specified below in the Windows
120 | * support section.
121 | *
122 | * First, search for the shared object in the application
123 | * binary path, then in the current working directory.
124 | *
125 | * Searching the application binary path requires /proc
126 | * filesystem support, which is standard in 2.4.x kernels.
127 | *
128 | * If the /proc filesystem is not present, the shared object
129 | * will not be loaded from the execution path unless that path
130 | * is either the current working directory or explicitly
131 | * specified in LD_LIBRARY_PATH.
132 | */
133 | static int _checkPath (const char *path) {
134 | char *filename = (char *)malloc(strlen(path) +1 + strlen(SO_NAME) +1);
135 | int fd;
136 |
137 | // Check if the file is readable
138 | sprintf(filename, "%s/%s", path, SO_NAME);
139 | fd = open(filename, O_RDONLY);
140 | if (fd >= 0) {
141 | strncpy(SO_NAME, filename, MAX_SO_PATH);
142 | close(fd);
143 | }
144 |
145 | // Clean up and exit
146 | free(filename);
147 | return (fd >= 0);
148 | }
149 |
150 | static int _getExecPath (char *path, unsigned long maxlen) {
151 | #ifdef linux
152 | return readlink("/proc/self/exe", path, maxlen);
153 | #endif
154 |
155 | #ifdef DARWIN
156 | _NSGetExecutablePath(path, &maxlen);
157 | return maxlen;
158 | #endif
159 | }
160 |
161 | static void _setSearchPath () {
162 | char path[MAX_SO_PATH+1];
163 | int count;
164 | char *p;
165 |
166 | /* Make sure that SO_NAME is not an absolute path. */
167 | if (SO_NAME[0] == '/') return;
168 |
169 | /* Check the execution directory name. */
170 | memset(path, 0, sizeof(path));
171 | count = _getExecPath(path, MAX_SO_PATH);
172 |
173 | if (count > 0) {
174 | char *p = strrchr(path, '/');
175 | if (p == path) ++p;
176 | if (p != 0) *p = '\0';
177 |
178 | /* If there is a match, return immediately. */
179 | if (_checkPath(path)) return;
180 | }
181 |
182 | /* Check the current working directory. */
183 | p = getcwd(path, MAX_SO_PATH);
184 | if (p != 0) _checkPath(path);
185 | }
186 |
187 | #endif
188 |
189 |
190 | /*=========================================================================
191 | | WINDOWS SUPPORT
192 | ========================================================================*/
193 | #if defined(WIN32) || defined(_WIN32)
194 |
195 | #include
196 | #include
197 |
198 | #define DLL_HANDLE HINSTANCE
199 | #define dlopen(name, flags) LoadLibraryA(name)
200 | #define dlsym(handle, name) GetProcAddress(handle, name)
201 | #define dlerror() "Exiting program"
202 | #define SO_NAME API_NAME ".dll"
203 |
204 | /*
205 | * Use the default Windows DLL loading rules:
206 | * 1. The directory from which the application binary was loaded.
207 | * 2. The application's current directory.
208 | * 3a. [Windows NT/2000/XP only] 32-bit system directory
209 | * (default: c:\winnt\System32)
210 | * 3b. 16-bit system directory
211 | * (default: c:\winnt\System or c:\windows\system)
212 | * 4. The windows directory
213 | * (default: c:\winnt or c:\windows)
214 | * 5. The directories listed in the PATH environment variable
215 | */
216 | static void _setSearchPath () {
217 | /* Do nothing */
218 | }
219 |
220 | #endif
221 |
222 |
223 | /*=========================================================================
224 | | SHARED LIBRARY LOADER
225 | ========================================================================*/
226 | /* The error conditions can be customized depending on the application. */
227 | static void *_loadFunction (const char *name, int *result) {
228 | static DLL_HANDLE handle = 0;
229 | void * function = 0;
230 |
231 | /* Load the shared library if necessary */
232 | if (handle == 0) {
233 | u32 (*version) (void);
234 | u16 sw_version;
235 | u16 api_version_req;
236 |
237 | _setSearchPath();
238 | handle = dlopen(SO_NAME, RTLD_LAZY);
239 | if (handle == 0) {
240 | #if API_DEBUG
241 | fprintf(stderr, "Unable to load %s\n", SO_NAME);
242 | fprintf(stderr, "%s\n", dlerror());
243 | #endif
244 | *result = API_UNABLE_TO_LOAD_LIBRARY;
245 | return 0;
246 | }
247 |
248 | version = (void *)dlsym(handle, "c_version");
249 | if (version == 0) {
250 | #if API_DEBUG
251 | fprintf(stderr, "Unable to bind c_version() in %s\n",
252 | SO_NAME);
253 | fprintf(stderr, "%s\n", dlerror());
254 | #endif
255 | handle = 0;
256 | *result = API_INCOMPATIBLE_LIBRARY;
257 | return 0;
258 | }
259 |
260 | sw_version = (u16)((version() >> 0) & 0xffff);
261 | api_version_req = (u16)((version() >> 16) & 0xffff);
262 | if (sw_version < API_REQ_SW_VERSION ||
263 | API_HEADER_VERSION < api_version_req)
264 | {
265 | #if API_DEBUG
266 | fprintf(stderr, "\nIncompatible versions:\n");
267 |
268 | fprintf(stderr, " Header version = v%d.%02d ",
269 | (API_HEADER_VERSION >> 8) & 0xff, API_HEADER_VERSION & 0xff);
270 |
271 | if (sw_version < API_REQ_SW_VERSION)
272 | fprintf(stderr, "(requires library >= %d.%02d)\n",
273 | (API_REQ_SW_VERSION >> 8) & 0xff,
274 | API_REQ_SW_VERSION & 0xff);
275 | else
276 | fprintf(stderr, "(library version OK)\n");
277 |
278 |
279 | fprintf(stderr, " Library version = v%d.%02d ",
280 | (sw_version >> 8) & 0xff,
281 | (sw_version >> 0) & 0xff);
282 |
283 | if (API_HEADER_VERSION < api_version_req)
284 | fprintf(stderr, "(requires header >= %d.%02d)\n",
285 | (api_version_req >> 8) & 0xff,
286 | (api_version_req >> 0) & 0xff);
287 | else
288 | fprintf(stderr, "(header version OK)\n");
289 | #endif
290 | handle = 0;
291 | *result = API_INCOMPATIBLE_LIBRARY;
292 | return 0;
293 | }
294 | }
295 |
296 | /* Bind the requested function in the shared library */
297 | function = (void *)dlsym(handle, name);
298 | *result = function ? API_OK : API_UNABLE_TO_LOAD_FUNCTION;
299 | return function;
300 | }
301 |
302 |
303 | /*=========================================================================
304 | | FUNCTIONS
305 | ========================================================================*/
306 | static int (*c_aa_find_devices) (int, u16 *) = 0;
307 | int aa_find_devices (
308 | int num_devices,
309 | u16 * devices
310 | )
311 | {
312 | if (c_aa_find_devices == 0) {
313 | int res = 0;
314 | if (!(c_aa_find_devices = _loadFunction("c_aa_find_devices", &res)))
315 | return res;
316 | }
317 | return c_aa_find_devices(num_devices, devices);
318 | }
319 |
320 |
321 | static int (*c_aa_find_devices_ext) (int, u16 *, int, u32 *) = 0;
322 | int aa_find_devices_ext (
323 | int num_devices,
324 | u16 * devices,
325 | int num_ids,
326 | u32 * unique_ids
327 | )
328 | {
329 | if (c_aa_find_devices_ext == 0) {
330 | int res = 0;
331 | if (!(c_aa_find_devices_ext = _loadFunction("c_aa_find_devices_ext", &res)))
332 | return res;
333 | }
334 | return c_aa_find_devices_ext(num_devices, devices, num_ids, unique_ids);
335 | }
336 |
337 |
338 | static Aardvark (*c_aa_open) (int) = 0;
339 | Aardvark aa_open (
340 | int port_number
341 | )
342 | {
343 | if (c_aa_open == 0) {
344 | int res = 0;
345 | if (!(c_aa_open = _loadFunction("c_aa_open", &res)))
346 | return res;
347 | }
348 | return c_aa_open(port_number);
349 | }
350 |
351 |
352 | static Aardvark (*c_aa_open_ext) (int, AardvarkExt *) = 0;
353 | Aardvark aa_open_ext (
354 | int port_number,
355 | AardvarkExt * aa_ext
356 | )
357 | {
358 | if (c_aa_open_ext == 0) {
359 | int res = 0;
360 | if (!(c_aa_open_ext = _loadFunction("c_aa_open_ext", &res)))
361 | return res;
362 | }
363 | return c_aa_open_ext(port_number, aa_ext);
364 | }
365 |
366 |
367 | static int (*c_aa_close) (Aardvark) = 0;
368 | int aa_close (
369 | Aardvark aardvark
370 | )
371 | {
372 | if (c_aa_close == 0) {
373 | int res = 0;
374 | if (!(c_aa_close = _loadFunction("c_aa_close", &res)))
375 | return res;
376 | }
377 | return c_aa_close(aardvark);
378 | }
379 |
380 |
381 | static int (*c_aa_port) (Aardvark) = 0;
382 | int aa_port (
383 | Aardvark aardvark
384 | )
385 | {
386 | if (c_aa_port == 0) {
387 | int res = 0;
388 | if (!(c_aa_port = _loadFunction("c_aa_port", &res)))
389 | return res;
390 | }
391 | return c_aa_port(aardvark);
392 | }
393 |
394 |
395 | static int (*c_aa_features) (Aardvark) = 0;
396 | int aa_features (
397 | Aardvark aardvark
398 | )
399 | {
400 | if (c_aa_features == 0) {
401 | int res = 0;
402 | if (!(c_aa_features = _loadFunction("c_aa_features", &res)))
403 | return res;
404 | }
405 | return c_aa_features(aardvark);
406 | }
407 |
408 |
409 | static u32 (*c_aa_unique_id) (Aardvark) = 0;
410 | u32 aa_unique_id (
411 | Aardvark aardvark
412 | )
413 | {
414 | if (c_aa_unique_id == 0) {
415 | int res = 0;
416 | if (!(c_aa_unique_id = _loadFunction("c_aa_unique_id", &res)))
417 | return res;
418 | }
419 | return c_aa_unique_id(aardvark);
420 | }
421 |
422 |
423 | static const char * (*c_aa_status_string) (int) = 0;
424 | const char * aa_status_string (
425 | int status
426 | )
427 | {
428 | if (c_aa_status_string == 0) {
429 | int res = 0;
430 | if (!(c_aa_status_string = _loadFunction("c_aa_status_string", &res)))
431 | return 0;
432 | }
433 | return c_aa_status_string(status);
434 | }
435 |
436 |
437 | static int (*c_aa_log) (Aardvark, int, int) = 0;
438 | int aa_log (
439 | Aardvark aardvark,
440 | int level,
441 | int handle
442 | )
443 | {
444 | if (c_aa_log == 0) {
445 | int res = 0;
446 | if (!(c_aa_log = _loadFunction("c_aa_log", &res)))
447 | return res;
448 | }
449 | return c_aa_log(aardvark, level, handle);
450 | }
451 |
452 |
453 | static int (*c_aa_version) (Aardvark, AardvarkVersion *) = 0;
454 | int aa_version (
455 | Aardvark aardvark,
456 | AardvarkVersion * version
457 | )
458 | {
459 | if (c_aa_version == 0) {
460 | int res = 0;
461 | if (!(c_aa_version = _loadFunction("c_aa_version", &res)))
462 | return res;
463 | }
464 | return c_aa_version(aardvark, version);
465 | }
466 |
467 |
468 | static int (*c_aa_configure) (Aardvark, AardvarkConfig) = 0;
469 | int aa_configure (
470 | Aardvark aardvark,
471 | AardvarkConfig config
472 | )
473 | {
474 | if (c_aa_configure == 0) {
475 | int res = 0;
476 | if (!(c_aa_configure = _loadFunction("c_aa_configure", &res)))
477 | return res;
478 | }
479 | return c_aa_configure(aardvark, config);
480 | }
481 |
482 |
483 | static int (*c_aa_target_power) (Aardvark, u08) = 0;
484 | int aa_target_power (
485 | Aardvark aardvark,
486 | u08 power_mask
487 | )
488 | {
489 | if (c_aa_target_power == 0) {
490 | int res = 0;
491 | if (!(c_aa_target_power = _loadFunction("c_aa_target_power", &res)))
492 | return res;
493 | }
494 | return c_aa_target_power(aardvark, power_mask);
495 | }
496 |
497 |
498 | static u32 (*c_aa_sleep_ms) (u32) = 0;
499 | u32 aa_sleep_ms (
500 | u32 milliseconds
501 | )
502 | {
503 | if (c_aa_sleep_ms == 0) {
504 | int res = 0;
505 | if (!(c_aa_sleep_ms = _loadFunction("c_aa_sleep_ms", &res)))
506 | return res;
507 | }
508 | return c_aa_sleep_ms(milliseconds);
509 | }
510 |
511 |
512 | static int (*c_aa_async_poll) (Aardvark, int) = 0;
513 | int aa_async_poll (
514 | Aardvark aardvark,
515 | int timeout
516 | )
517 | {
518 | if (c_aa_async_poll == 0) {
519 | int res = 0;
520 | if (!(c_aa_async_poll = _loadFunction("c_aa_async_poll", &res)))
521 | return res;
522 | }
523 | return c_aa_async_poll(aardvark, timeout);
524 | }
525 |
526 |
527 | static int (*c_aa_i2c_free_bus) (Aardvark) = 0;
528 | int aa_i2c_free_bus (
529 | Aardvark aardvark
530 | )
531 | {
532 | if (c_aa_i2c_free_bus == 0) {
533 | int res = 0;
534 | if (!(c_aa_i2c_free_bus = _loadFunction("c_aa_i2c_free_bus", &res)))
535 | return res;
536 | }
537 | return c_aa_i2c_free_bus(aardvark);
538 | }
539 |
540 |
541 | static int (*c_aa_i2c_bitrate) (Aardvark, int) = 0;
542 | int aa_i2c_bitrate (
543 | Aardvark aardvark,
544 | int bitrate_khz
545 | )
546 | {
547 | if (c_aa_i2c_bitrate == 0) {
548 | int res = 0;
549 | if (!(c_aa_i2c_bitrate = _loadFunction("c_aa_i2c_bitrate", &res)))
550 | return res;
551 | }
552 | return c_aa_i2c_bitrate(aardvark, bitrate_khz);
553 | }
554 |
555 |
556 | static int (*c_aa_i2c_bus_timeout) (Aardvark, u16) = 0;
557 | int aa_i2c_bus_timeout (
558 | Aardvark aardvark,
559 | u16 timeout_ms
560 | )
561 | {
562 | if (c_aa_i2c_bus_timeout == 0) {
563 | int res = 0;
564 | if (!(c_aa_i2c_bus_timeout = _loadFunction("c_aa_i2c_bus_timeout", &res)))
565 | return res;
566 | }
567 | return c_aa_i2c_bus_timeout(aardvark, timeout_ms);
568 | }
569 |
570 |
571 | static int (*c_aa_i2c_read) (Aardvark, u16, AardvarkI2cFlags, u16, u08 *) = 0;
572 | int aa_i2c_read (
573 | Aardvark aardvark,
574 | u16 slave_addr,
575 | AardvarkI2cFlags flags,
576 | u16 num_bytes,
577 | u08 * data_in
578 | )
579 | {
580 | if (c_aa_i2c_read == 0) {
581 | int res = 0;
582 | if (!(c_aa_i2c_read = _loadFunction("c_aa_i2c_read", &res)))
583 | return res;
584 | }
585 | return c_aa_i2c_read(aardvark, slave_addr, flags, num_bytes, data_in);
586 | }
587 |
588 |
589 | static int (*c_aa_i2c_read_ext) (Aardvark, u16, AardvarkI2cFlags, u16, u08 *, u16 *) = 0;
590 | int aa_i2c_read_ext (
591 | Aardvark aardvark,
592 | u16 slave_addr,
593 | AardvarkI2cFlags flags,
594 | u16 num_bytes,
595 | u08 * data_in,
596 | u16 * num_read
597 | )
598 | {
599 | if (c_aa_i2c_read_ext == 0) {
600 | int res = 0;
601 | if (!(c_aa_i2c_read_ext = _loadFunction("c_aa_i2c_read_ext", &res)))
602 | return res;
603 | }
604 | return c_aa_i2c_read_ext(aardvark, slave_addr, flags, num_bytes, data_in, num_read);
605 | }
606 |
607 |
608 | static int (*c_aa_i2c_write) (Aardvark, u16, AardvarkI2cFlags, u16, const u08 *) = 0;
609 | int aa_i2c_write (
610 | Aardvark aardvark,
611 | u16 slave_addr,
612 | AardvarkI2cFlags flags,
613 | u16 num_bytes,
614 | const u08 * data_out
615 | )
616 | {
617 | if (c_aa_i2c_write == 0) {
618 | int res = 0;
619 | if (!(c_aa_i2c_write = _loadFunction("c_aa_i2c_write", &res)))
620 | return res;
621 | }
622 | return c_aa_i2c_write(aardvark, slave_addr, flags, num_bytes, data_out);
623 | }
624 |
625 |
626 | static int (*c_aa_i2c_write_ext) (Aardvark, u16, AardvarkI2cFlags, u16, const u08 *, u16 *) = 0;
627 | int aa_i2c_write_ext (
628 | Aardvark aardvark,
629 | u16 slave_addr,
630 | AardvarkI2cFlags flags,
631 | u16 num_bytes,
632 | const u08 * data_out,
633 | u16 * num_written
634 | )
635 | {
636 | if (c_aa_i2c_write_ext == 0) {
637 | int res = 0;
638 | if (!(c_aa_i2c_write_ext = _loadFunction("c_aa_i2c_write_ext", &res)))
639 | return res;
640 | }
641 | return c_aa_i2c_write_ext(aardvark, slave_addr, flags, num_bytes, data_out, num_written);
642 | }
643 |
644 |
645 | static int (*c_aa_i2c_slave_enable) (Aardvark, u08, u16, u16) = 0;
646 | int aa_i2c_slave_enable (
647 | Aardvark aardvark,
648 | u08 addr,
649 | u16 maxTxBytes,
650 | u16 maxRxBytes
651 | )
652 | {
653 | if (c_aa_i2c_slave_enable == 0) {
654 | int res = 0;
655 | if (!(c_aa_i2c_slave_enable = _loadFunction("c_aa_i2c_slave_enable", &res)))
656 | return res;
657 | }
658 | return c_aa_i2c_slave_enable(aardvark, addr, maxTxBytes, maxRxBytes);
659 | }
660 |
661 |
662 | static int (*c_aa_i2c_slave_disable) (Aardvark) = 0;
663 | int aa_i2c_slave_disable (
664 | Aardvark aardvark
665 | )
666 | {
667 | if (c_aa_i2c_slave_disable == 0) {
668 | int res = 0;
669 | if (!(c_aa_i2c_slave_disable = _loadFunction("c_aa_i2c_slave_disable", &res)))
670 | return res;
671 | }
672 | return c_aa_i2c_slave_disable(aardvark);
673 | }
674 |
675 |
676 | static int (*c_aa_i2c_slave_set_response) (Aardvark, u08, const u08 *) = 0;
677 | int aa_i2c_slave_set_response (
678 | Aardvark aardvark,
679 | u08 num_bytes,
680 | const u08 * data_out
681 | )
682 | {
683 | if (c_aa_i2c_slave_set_response == 0) {
684 | int res = 0;
685 | if (!(c_aa_i2c_slave_set_response = _loadFunction("c_aa_i2c_slave_set_response", &res)))
686 | return res;
687 | }
688 | return c_aa_i2c_slave_set_response(aardvark, num_bytes, data_out);
689 | }
690 |
691 |
692 | static int (*c_aa_i2c_slave_write_stats) (Aardvark) = 0;
693 | int aa_i2c_slave_write_stats (
694 | Aardvark aardvark
695 | )
696 | {
697 | if (c_aa_i2c_slave_write_stats == 0) {
698 | int res = 0;
699 | if (!(c_aa_i2c_slave_write_stats = _loadFunction("c_aa_i2c_slave_write_stats", &res)))
700 | return res;
701 | }
702 | return c_aa_i2c_slave_write_stats(aardvark);
703 | }
704 |
705 |
706 | static int (*c_aa_i2c_slave_read) (Aardvark, u08 *, u16, u08 *) = 0;
707 | int aa_i2c_slave_read (
708 | Aardvark aardvark,
709 | u08 * addr,
710 | u16 num_bytes,
711 | u08 * data_in
712 | )
713 | {
714 | if (c_aa_i2c_slave_read == 0) {
715 | int res = 0;
716 | if (!(c_aa_i2c_slave_read = _loadFunction("c_aa_i2c_slave_read", &res)))
717 | return res;
718 | }
719 | return c_aa_i2c_slave_read(aardvark, addr, num_bytes, data_in);
720 | }
721 |
722 |
723 | static int (*c_aa_i2c_slave_write_stats_ext) (Aardvark, u16 *) = 0;
724 | int aa_i2c_slave_write_stats_ext (
725 | Aardvark aardvark,
726 | u16 * num_written
727 | )
728 | {
729 | if (c_aa_i2c_slave_write_stats_ext == 0) {
730 | int res = 0;
731 | if (!(c_aa_i2c_slave_write_stats_ext = _loadFunction("c_aa_i2c_slave_write_stats_ext", &res)))
732 | return res;
733 | }
734 | return c_aa_i2c_slave_write_stats_ext(aardvark, num_written);
735 | }
736 |
737 |
738 | static int (*c_aa_i2c_slave_read_ext) (Aardvark, u08 *, u16, u08 *, u16 *) = 0;
739 | int aa_i2c_slave_read_ext (
740 | Aardvark aardvark,
741 | u08 * addr,
742 | u16 num_bytes,
743 | u08 * data_in,
744 | u16 * num_read
745 | )
746 | {
747 | if (c_aa_i2c_slave_read_ext == 0) {
748 | int res = 0;
749 | if (!(c_aa_i2c_slave_read_ext = _loadFunction("c_aa_i2c_slave_read_ext", &res)))
750 | return res;
751 | }
752 | return c_aa_i2c_slave_read_ext(aardvark, addr, num_bytes, data_in, num_read);
753 | }
754 |
755 |
756 | static int (*c_aa_i2c_monitor_enable) (Aardvark) = 0;
757 | int aa_i2c_monitor_enable (
758 | Aardvark aardvark
759 | )
760 | {
761 | if (c_aa_i2c_monitor_enable == 0) {
762 | int res = 0;
763 | if (!(c_aa_i2c_monitor_enable = _loadFunction("c_aa_i2c_monitor_enable", &res)))
764 | return res;
765 | }
766 | return c_aa_i2c_monitor_enable(aardvark);
767 | }
768 |
769 |
770 | static int (*c_aa_i2c_monitor_disable) (Aardvark) = 0;
771 | int aa_i2c_monitor_disable (
772 | Aardvark aardvark
773 | )
774 | {
775 | if (c_aa_i2c_monitor_disable == 0) {
776 | int res = 0;
777 | if (!(c_aa_i2c_monitor_disable = _loadFunction("c_aa_i2c_monitor_disable", &res)))
778 | return res;
779 | }
780 | return c_aa_i2c_monitor_disable(aardvark);
781 | }
782 |
783 |
784 | static int (*c_aa_i2c_monitor_read) (Aardvark, u16, u16 *) = 0;
785 | int aa_i2c_monitor_read (
786 | Aardvark aardvark,
787 | u16 num_bytes,
788 | u16 * data
789 | )
790 | {
791 | if (c_aa_i2c_monitor_read == 0) {
792 | int res = 0;
793 | if (!(c_aa_i2c_monitor_read = _loadFunction("c_aa_i2c_monitor_read", &res)))
794 | return res;
795 | }
796 | return c_aa_i2c_monitor_read(aardvark, num_bytes, data);
797 | }
798 |
799 |
800 | static int (*c_aa_i2c_pullup) (Aardvark, u08) = 0;
801 | int aa_i2c_pullup (
802 | Aardvark aardvark,
803 | u08 pullup_mask
804 | )
805 | {
806 | if (c_aa_i2c_pullup == 0) {
807 | int res = 0;
808 | if (!(c_aa_i2c_pullup = _loadFunction("c_aa_i2c_pullup", &res)))
809 | return res;
810 | }
811 | return c_aa_i2c_pullup(aardvark, pullup_mask);
812 | }
813 |
814 |
815 | static int (*c_aa_spi_bitrate) (Aardvark, int) = 0;
816 | int aa_spi_bitrate (
817 | Aardvark aardvark,
818 | int bitrate_khz
819 | )
820 | {
821 | if (c_aa_spi_bitrate == 0) {
822 | int res = 0;
823 | if (!(c_aa_spi_bitrate = _loadFunction("c_aa_spi_bitrate", &res)))
824 | return res;
825 | }
826 | return c_aa_spi_bitrate(aardvark, bitrate_khz);
827 | }
828 |
829 |
830 | static int (*c_aa_spi_configure) (Aardvark, AardvarkSpiPolarity, AardvarkSpiPhase, AardvarkSpiBitorder) = 0;
831 | int aa_spi_configure (
832 | Aardvark aardvark,
833 | AardvarkSpiPolarity polarity,
834 | AardvarkSpiPhase phase,
835 | AardvarkSpiBitorder bitorder
836 | )
837 | {
838 | if (c_aa_spi_configure == 0) {
839 | int res = 0;
840 | if (!(c_aa_spi_configure = _loadFunction("c_aa_spi_configure", &res)))
841 | return res;
842 | }
843 | return c_aa_spi_configure(aardvark, polarity, phase, bitorder);
844 | }
845 |
846 |
847 | static int (*c_aa_spi_write) (Aardvark, u16, const u08 *, u16, u08 *) = 0;
848 | int aa_spi_write (
849 | Aardvark aardvark,
850 | u16 out_num_bytes,
851 | const u08 * data_out,
852 | u16 in_num_bytes,
853 | u08 * data_in
854 | )
855 | {
856 | if (c_aa_spi_write == 0) {
857 | int res = 0;
858 | if (!(c_aa_spi_write = _loadFunction("c_aa_spi_write", &res)))
859 | return res;
860 | }
861 | return c_aa_spi_write(aardvark, out_num_bytes, data_out, in_num_bytes, data_in);
862 | }
863 |
864 |
865 | static int (*c_aa_spi_slave_enable) (Aardvark) = 0;
866 | int aa_spi_slave_enable (
867 | Aardvark aardvark
868 | )
869 | {
870 | if (c_aa_spi_slave_enable == 0) {
871 | int res = 0;
872 | if (!(c_aa_spi_slave_enable = _loadFunction("c_aa_spi_slave_enable", &res)))
873 | return res;
874 | }
875 | return c_aa_spi_slave_enable(aardvark);
876 | }
877 |
878 |
879 | static int (*c_aa_spi_slave_disable) (Aardvark) = 0;
880 | int aa_spi_slave_disable (
881 | Aardvark aardvark
882 | )
883 | {
884 | if (c_aa_spi_slave_disable == 0) {
885 | int res = 0;
886 | if (!(c_aa_spi_slave_disable = _loadFunction("c_aa_spi_slave_disable", &res)))
887 | return res;
888 | }
889 | return c_aa_spi_slave_disable(aardvark);
890 | }
891 |
892 |
893 | static int (*c_aa_spi_slave_set_response) (Aardvark, u08, const u08 *) = 0;
894 | int aa_spi_slave_set_response (
895 | Aardvark aardvark,
896 | u08 num_bytes,
897 | const u08 * data_out
898 | )
899 | {
900 | if (c_aa_spi_slave_set_response == 0) {
901 | int res = 0;
902 | if (!(c_aa_spi_slave_set_response = _loadFunction("c_aa_spi_slave_set_response", &res)))
903 | return res;
904 | }
905 | return c_aa_spi_slave_set_response(aardvark, num_bytes, data_out);
906 | }
907 |
908 |
909 | static int (*c_aa_spi_slave_read) (Aardvark, u16, u08 *) = 0;
910 | int aa_spi_slave_read (
911 | Aardvark aardvark,
912 | u16 num_bytes,
913 | u08 * data_in
914 | )
915 | {
916 | if (c_aa_spi_slave_read == 0) {
917 | int res = 0;
918 | if (!(c_aa_spi_slave_read = _loadFunction("c_aa_spi_slave_read", &res)))
919 | return res;
920 | }
921 | return c_aa_spi_slave_read(aardvark, num_bytes, data_in);
922 | }
923 |
924 |
925 | static int (*c_aa_spi_master_ss_polarity) (Aardvark, AardvarkSpiSSPolarity) = 0;
926 | int aa_spi_master_ss_polarity (
927 | Aardvark aardvark,
928 | AardvarkSpiSSPolarity polarity
929 | )
930 | {
931 | if (c_aa_spi_master_ss_polarity == 0) {
932 | int res = 0;
933 | if (!(c_aa_spi_master_ss_polarity = _loadFunction("c_aa_spi_master_ss_polarity", &res)))
934 | return res;
935 | }
936 | return c_aa_spi_master_ss_polarity(aardvark, polarity);
937 | }
938 |
939 |
940 | static int (*c_aa_gpio_direction) (Aardvark, u08) = 0;
941 | int aa_gpio_direction (
942 | Aardvark aardvark,
943 | u08 direction_mask
944 | )
945 | {
946 | if (c_aa_gpio_direction == 0) {
947 | int res = 0;
948 | if (!(c_aa_gpio_direction = _loadFunction("c_aa_gpio_direction", &res)))
949 | return res;
950 | }
951 | return c_aa_gpio_direction(aardvark, direction_mask);
952 | }
953 |
954 |
955 | static int (*c_aa_gpio_pullup) (Aardvark, u08) = 0;
956 | int aa_gpio_pullup (
957 | Aardvark aardvark,
958 | u08 pullup_mask
959 | )
960 | {
961 | if (c_aa_gpio_pullup == 0) {
962 | int res = 0;
963 | if (!(c_aa_gpio_pullup = _loadFunction("c_aa_gpio_pullup", &res)))
964 | return res;
965 | }
966 | return c_aa_gpio_pullup(aardvark, pullup_mask);
967 | }
968 |
969 |
970 | static int (*c_aa_gpio_get) (Aardvark) = 0;
971 | int aa_gpio_get (
972 | Aardvark aardvark
973 | )
974 | {
975 | if (c_aa_gpio_get == 0) {
976 | int res = 0;
977 | if (!(c_aa_gpio_get = _loadFunction("c_aa_gpio_get", &res)))
978 | return res;
979 | }
980 | return c_aa_gpio_get(aardvark);
981 | }
982 |
983 |
984 | static int (*c_aa_gpio_set) (Aardvark, u08) = 0;
985 | int aa_gpio_set (
986 | Aardvark aardvark,
987 | u08 value
988 | )
989 | {
990 | if (c_aa_gpio_set == 0) {
991 | int res = 0;
992 | if (!(c_aa_gpio_set = _loadFunction("c_aa_gpio_set", &res)))
993 | return res;
994 | }
995 | return c_aa_gpio_set(aardvark, value);
996 | }
997 |
998 |
999 | static int (*c_aa_gpio_change) (Aardvark, u16) = 0;
1000 | int aa_gpio_change (
1001 | Aardvark aardvark,
1002 | u16 timeout
1003 | )
1004 | {
1005 | if (c_aa_gpio_change == 0) {
1006 | int res = 0;
1007 | if (!(c_aa_gpio_change = _loadFunction("c_aa_gpio_change", &res)))
1008 | return res;
1009 | }
1010 | return c_aa_gpio_change(aardvark, timeout);
1011 | }
1012 |
1013 |
1014 |
--------------------------------------------------------------------------------