├── 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 | --------------------------------------------------------------------------------