Appendix C - Code Listing

Transcription

Appendix C - Code Listing
1 Appendix C – Code Listing
1 Appendix C – Code Listing ........................................................................................................... 1 1.1 DCM – Spartan 6 FPGA: HDL Code ................................................................................................... 2 1.1.1 adg714s3w.vhdl ............................................................................................................................................... 2 1.1.2 clockmanager.vhdl .......................................................................................................................................... 4 1.1.3 comm_fpga.vhdl ................................................................................................................................................ 7 1.1.4 dac_count.vhdl ................................................................................................................................................ 10 1.1.5 emulator.vhdl ................................................................................................................................................. 11 1.1.6 FSM.vhdl ........................................................................................................................................................... 19 1.1.7 FSM2.vhdl ......................................................................................................................................................... 21 1.1.8 ipm_fifo.vhdl .................................................................................................................................................... 24 1.1.9 platform.ucf ..................................................................................................................................................... 29 1.1.10 top_level.vhdl ............................................................................................................................................... 31 1.2 SOM – AtTiny261 ............................................................................................................................... 37 1.2.1 Makefile ............................................................................................................................................................. 37 1.2.2 USI_I2C_Port.c ................................................................................................................................................. 43 1.2.3 USI_I2C_Master.c ........................................................................................................................................... 47 1.2.4 USI_TWI_Master_h ........................................................................................................................................ 52 1.3 UIM – Cross Platform GTK Client .................................................................................................. 53 1.3.1 complile.sh ....................................................................................................................................................... 53 1.3.2 dcm_compile.sh ............................................................................................................................................. 53 1.3.3 dcmusb.c ........................................................................................................................................................... 53 1.3.4 dcmusb.h ........................................................................................................................................................... 57 1.3.5 dcmusb_unitTest.c ........................................................................................................................................ 58 1.3.6 dosa.c .................................................................................................................................................................. 59 1.3.7 fpga.sh ................................................................................................................................................................ 73 1.3.8 fpgaComm.c ..................................................................................................................................................... 74 1.3.9 ini.c ...................................................................................................................................................................... 76 1.3.10 ini.h ................................................................................................................................................................... 78 1.3.11 support.h ........................................................................................................................................................ 79 1.3.12 uim_config.c .................................................................................................................................................. 81 1.3.13 uim_config.h .................................................................................................................................................. 85 1.3.14 uim_functions.c ........................................................................................................................................... 87 1.4 uim_functions.h .................................................................................................................................. 92 1.4.1 uim_settings.txt .............................................................................................................................................. 93 1.4.2 userIOusb.c ...................................................................................................................................................... 94 1.4.3 userIOusb.h ................................................................................................................................................... 100 1.5 UIM-­‐E – Propeller P8X32A Embedded Controller ................................................................ 102 1.5.1 Basic_I2C_Driver.spin ................................................................................................................................ 102 1.5.2 Front_Panel_Control_001.spin .............................................................................................................. 106 1.5.3 Front_Panel_Inputs_001.spin ................................................................................................................. 111 1.5.4 pcFullDuplexSerial.spin ........................................................................................................................... 113 1.5.5 Quadrature_Encoder.spin ....................................................................................................................... 117 1.5.6 web4robot_lcd_001.spin .......................................................................................................................... 122 1.6 IPM ........................................................................................................................................................ 125 1.6.1 IPM VGA Spice Simulation (With Parasitics) .................................................................................. 125 1 1.1 DCM – Spartan 6 FPGA: HDL Code
1.1.1 adg714s3w.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
----------------------------------------------------------------------------- Company: Team Spectrum
-- Engineer: Jacob Dilles
--- Create Date:
13:02:12 11/21/2012
-- Design Name:
ADG714 Serial Protocol Adapter
---------------------------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity adg714s3w is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
reg_data : in STD_LOGIC_VECTOR (7 downto 0);
adg_sclk : out STD_LOGIC;
adg_sync : out STD_LOGIC;
adg_dout : out STD_LOGIC;
adg_reset : out STD_LOGIC);
end adg714s3w;
architecture Behavioral of adg714s3w is
-- signal holds the last data to check for a change
signal last_reg_data : STD_LOGIC_VECTOR (7 downto 0);
-- triggers latch and reset of different flag
signal latch_reg_data
: STD_LOGIC;
signal last_is_different : STD_LOGIC;
signal shifting, shifting_done
-- internal signals
signal adg_reset_flag : STD_LOGIC;
: STD_LOGIC;
constant
sreg_shift_ctl
: STD_LOGIC_VECTOR(0 to 63) :=
X"000000000000FFFF";
constant
sclk_shift_reg
: STD_LOGIC_VECTOR(0 to 63) :=
X"AAAAAAAAAAAAAAAA";-- X"AAAA" & "10 10 10 10 10 10 10 10" & X"AAAA";
constant
sync_shift_reg
: STD_LOGIC_VECTOR(0 to 63) :=
X"FFFF0000FFFFFFFF";-- X"FFFF" & "00 00 00 00 00 00 00 00" & X"FFFF";
signal
dout_shift_reg
: STD_LOGIC_VECTOR(0 to 63);
-- X"0000" & d7 d6 d5 d4 d3 d2 d1 d0 & X"0000";
alias d : STD_LOGIC_VECTOR(7 downto 0) is reg_data;
-- counters
constant
RESET_NCOUNTS
: INTEGER := 7 ;--2**15 - 1;
signal shift_reg_cnt
: INTEGER RANGE 0 to 63;
begin
mux_proc: process(clk) is
begin
if rising_edge(clk) then
shifting_done <= sreg_shift_ctl(shift_reg_cnt);
adg_sync
<= sync_shift_reg(shift_reg_cnt);
adg_dout
<= dout_shift_reg(shift_reg_cnt);
adg_sclk
<= sclk_shift_reg(shift_reg_cnt);
adg_reset
<= adg_reset_flag;
end if;
end process;
-- The actual shifted out data
shift_reg_proc: process(clk, reset) is
begin
if rising_edge(clk) then
2 68
if reset = '1' then
69
shift_reg_cnt <= 0;
70
else
71
if shifting = '0' then
72
shift_reg_cnt <= 0;
73
else
74
shift_reg_cnt <= shift_reg_cnt + 1;
75
end if;
76
end if;
77
end if;
78
end process shift_reg_proc;
79
80
81
-82
-- ensure we are not shifting before latching in data
83
-84
latch_in_proc: process(clk, reset) is
85
begin
86
if rising_edge(clk) then
87
if reset = '1' then
88
shifting <= '0';
89
dout_shift_reg <= (others => '0');
90
else
91
if shifting = '0' then
92
-- not shifting
93
if last_is_different = '0' then
94
-- no shift, no difference
95
shifting <= '0';
96
dout_shift_reg <= dout_shift_reg;
97
else
98
-- shifting start!
99
shifting <= '1';
100
dout_shift_reg <= X"0000" &
101
d(7) & d(7) & d(6) & d(6) & d(5) &
102 d(5) & d(4) & d(4) &
103
d(3) & d(3) & d(2) & d(2) & d(1) &
104 d(1) & d(0) & d(0) &
105
X"0000" & X"0000";
106
end if;
107
else
108
-- we are shifting
109
if shifting_done = '0' then
110
-- not done yet
111
dout_shift_reg <= dout_shift_reg;
112
shifting <= '1';
113
else
114
-- done
115
shifting <= '0';
116
dout_shift_reg <= dout_shift_reg;
117
end if;
118
end if;
119
end if;
120
end if;
121
end process latch_in_proc;
122
123
124
125
-126
-- Hold reset for a specified delay
127
-128
reset_proc: process(clk, reset) is
129
variable reset_cnt : INTEGER RANGE 0 to RESET_NCOUNTS;
130
begin
131
if rising_edge(clk) then
132
if reset = '1' then
133
reset_cnt := RESET_NCOUNTS;
134
adg_reset_flag <= '0'; -- active low
135
else
136
if reset_cnt = 0 then
137
reset_cnt := 0;
138
adg_reset_flag <= '1'; -- active low
139
else
140
reset_cnt := reset_cnt - 1;
3 141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 end
adg_reset_flag <= '0'; -- active low
end if;
end if;
end if;
end process reset_proc;
--- Monitor the register for change
-change_flag: process (clk, reset) is
begin
if rising_edge(clk) then
if reset = '1' then
last_reg_data <= (others => '0');
last_is_different <= '0';
else
-- change value
last_reg_data <= reg_data;
if last_reg_data = reg_data then
last_is_different <= '0';
else
last_is_different <= '1';
end if;
end if;
end if;
end process change_flag;
Behavioral;
1.1.2 clockmanager.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
------------------------------------
file: Clockmanager.vhd
(c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
This file contains confidential and proprietary information
of Xilinx, Inc. and is protected under U.S. and
international copyright and other intellectual property
laws.
DISCLAIMER
This disclaimer is not a license and does not grant any
rights to the materials distributed herewith. Except as
otherwise provided in a valid license issued to you by
Xilinx, and to the maximum extent permitted by applicable
law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
(2) Xilinx shall not be liable (whether in contract or tort,
including negligence, or under any other theory of
liability) for any loss or damage of any kind or nature
related to, arising under or in connection with these
materials, including for any direct, or any indirect,
special, incidental, or consequential loss or damage
(including loss of data, profits, goodwill, or any type of
loss or damage suffered as a result of any action brought
by a third party) even if such damage or loss was
reasonably foreseeable or Xilinx had been advised of the
possibility of the same.
CRITICAL APPLICATIONS
Xilinx products are not designed or intended to be failsafe, or for use in any application requiring fail-safe
performance, such as life-support or safety devices or
4 36 -- systems, Class III medical devices, nuclear facilities,
37 -- applications related to the deployment of airbags, or any
38 -- other applications that could lead to death, personal
39 -- injury, or severe property or environmental damage
40 -- (individually and collectively, "Critical
41 -- Applications"). Customer assumes the sole risk and
42 -- liability of any use of Xilinx products in Critical
43 -- Applications, subject only to applicable laws and
44 -- regulations governing limitations on product liability.
45 -46 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
47 -- PART OF THIS FILE AT ALL TIMES.
48 -49 -----------------------------------------------------------------------------50 -- User entered comments
51 -----------------------------------------------------------------------------52 -- None
53 -54 -----------------------------------------------------------------------------55 -- "Output
Output
Phase
Duty
Pk-to-Pk
Phase"
56 -- "Clock
Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
57 -----------------------------------------------------------------------------58 -- CLK_OUT1___200.000______0.000______50.0______150.969____235.738
59 -- CLK_OUT2____20.000______0.000______50.0______239.358____235.738
60 -- CLK_OUT3____50.000______0.000______50.0______198.618____235.738
61 -62 -----------------------------------------------------------------------------63 -- "Input Clock
Freq (MHz)
Input Jitter (UI)"
64 -----------------------------------------------------------------------------65 -- __primary_________100.000____________0.010
66
67 library ieee;
68 use ieee.std_logic_1164.all;
69 use ieee.std_logic_unsigned.all;
70 use ieee.std_logic_arith.all;
71 use ieee.numeric_std.all;
72
73 library unisim;
74 use unisim.vcomponents.all;
75
76 entity Clockmanager is
77 port
78 (-- Clock in ports
79
CLK_IN1
: in
std_logic;
80
-- Clock out ports
81
sys_clk
: out
std_logic;
82
IPM_clk
: out
std_logic;
83
SOM_clk
: out
std_logic;
84
-- Status and control signals
85
RESET_Clk
: in
std_logic;
86
LOCKED_clk
: out
std_logic
87 );
88 end Clockmanager;
89
90 architecture xilinx of Clockmanager is
91
attribute CORE_GENERATION_INFO : string;
92
attribute CORE_GENERATION_INFO of xilinx : architecture is "Clockmanager,clk_wiz_v3_2,{comp
onent_name=Clockmanager,use_phase_alignment=false,use_min_o_jitter=false,use_max_i_jitter=false,u
se_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_A
UTO,primtype_sel=PLL_BASE,num_out_clk=3,clkin1_period=10.0,clkin2_period=10.0,use_power_down=fals
e,use_reset=true,use_locked=true,use_inclk_stopped=false,use_status=false,use_freeze=false,use_cl
k_valid=false,feedback_type=SINGLE,clock_mgr_type=AUTO,manual_override=false}";
93
-- Input clock buffering / unused connectors
94
signal clkin1
: std_logic;
95
-- Output clock buffering / unused connectors
96
signal clkfbout
: std_logic;
97
signal clkout0
: std_logic;
98
signal clkout1
: std_logic;
99
signal clkout2
: std_logic;
100
signal clkout3_unused
: std_logic;
101
signal clkout4_unused
: std_logic;
102
signal clkout5_unused
: std_logic;
103
-- Unused status signals
5 104
105 begin
106
107
108
-- Input buffering
109
-------------------------------------110
clkin1_buf : IBUFG
111
port map
112
(O => clkin1,
113
I => CLK_IN1);
114
115
116
-- Clocking primitive
117
-------------------------------------118
-- Instantiation of the PLL primitive
119
-* Unused inputs are tied off
120
-* Unused outputs are labeled unused
121
122
pll_base_inst : PLL_BASE
123
generic map
124
(BANDWIDTH
=> "OPTIMIZED",
125
CLK_FEEDBACK
=> "CLKFBOUT",
126
COMPENSATION
=> "INTERNAL",
127
DIVCLK_DIVIDE
=> 1,
128
CLKFBOUT_MULT
=> 4,
129
CLKFBOUT_PHASE
=> 0.000,
130
CLKOUT0_DIVIDE
=> 2,
131
CLKOUT0_PHASE
=> 0.000,
132
CLKOUT0_DUTY_CYCLE
=> 0.500,
133
CLKOUT1_DIVIDE
=> 16,
134
CLKOUT1_PHASE
=> 0.000,
135
CLKOUT1_DUTY_CYCLE
=> 0.500,
136
CLKOUT2_DIVIDE
=> 80,
137
CLKOUT2_PHASE
=> 0.000,
138
CLKOUT2_DUTY_CYCLE
=> 0.500,
139
CLKIN_PERIOD
=> 10.0,
140
REF_JITTER
=> 0.010)
141
port map
142
-- Output clocks
143
(CLKFBOUT
=> clkfbout,
144
CLKOUT0
=> clkout0,
145
CLKOUT1
=> clkout1,
146
CLKOUT2
=> clkout2,
147
CLKOUT3
=> clkout3_unused,
148
CLKOUT4
=> clkout4_unused,
149
CLKOUT5
=> clkout5_unused,
150
-- Status and control signals
151
LOCKED
=> LOCKED_clk,
152
RST
=> RESET_Clk,
153
-- Input clock control
154
CLKFBIN
=> clkfbout,
155
CLKIN
=> clkin1);
156
157
-- Output buffering
158
------------------------------------159
160
161
clkout1_buf : BUFG
162
port map
163
(O
=> sys_clk,
164
I
=> clkout0);
165
166
167
168
clkout2_buf : BUFG
169
port map
170
(O
=> IPM_clk,
171
I
=> clkout1);
172
173
clkout3_buf : BUFG
174
port map
175
(O
=> SOM_clk,
176
I
=> clkout2);
6 177
178 end xilinx;
1.1.3 comm_fpga.vhdl
1 -2 -- Copyright (C) 2009-2012 Chris McClelland
3 -4 -- This program is free software: you can redistribute it and/or modify
5 -- it under the terms of the GNU Lesser General Public License as published by
6 -- the Free Software Foundation, either version 3 of the License, or
7 -- (at your option) any later version.
8 -9 -- This program is distributed in the hope that it will be useful,
10 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- GNU Lesser General Public License for more details.
13 -14 -- You should have received a copy of the GNU Lesser General Public License
15 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
16 -17 library ieee;
18
19 use ieee.std_logic_1164.all;
20 use ieee.numeric_std.all;
21
22 entity comm_fpga is
23
port(
24
-- FX2 interface
25
fx2Clk_in
: in
std_logic;
-- 48MHz clock from FX2
26
fx2FifoSel_out : out
std_logic;
-select FIFO: '0' for EP6OUT, '1' for EP8IN
27
fx2Data_io
: inout std_logic_vector(7 downto 0); -- 8-bit data to/from FX2
28
fx2Read_out
: out
std_logic;
-- asserted (activelow) when reading from FX2
29
fx2GotData_in : in
std_logic;
-- asserted (activehigh) when FX2 has data for us
30
fx2Write_out
: out
std_logic;
-- asserted (activelow) when writing to FX2
31
fx2GotRoom_in : in
std_logic;
-- asserted (activehigh) when FX2 has room for more data from us
32
fx2PktEnd_out : out
std_logic;
-- asserted (activelow) when a host read needs to be committed early
33
34
-- Channel read/write interface
35
chanAddr_out
: out
std_logic_vector(6 downto 0); -- the selected channel (0-127)
36
chanData_in
: in
std_logic_vector(7 downto 0); -data lines used when the host reads from a channel
37
chanRead_out
: out
std_logic;
-'1' means "on the next clock rising edge, put your next byte of data on chanData_in"
38
chanGotData_in : in
std_logic;
-channel logic can drive this low to say "I don't have data ready for you"
39
chanData_out
: out
std_logic_vector(7 downto 0); -data lines used when the host writes to a channel
40
chanWrite_out
: out
std_logic;
-'1' means "on the next clock rising edge, please accept the data on chanData_out"
41
chanGotRoom_in : in
std_logic
-channel logic can drive this low to say "I'm not ready for more data yet"
42
);
43 end comm_fpga;
44
45 architecture behavioural of comm_fpga is
46
-The read/write nomenclature here refers to the FPGA reading and writing the FX2 FIFOs, and is th
erefore
47
-of the opposite sense to the host's read and write. So host reads are fulfilled in the S_WRITE s
tate, and
48
-- vice-versa. Apologies for the confusion.
7 49
type StateType is (
50
S_IDLE,
51
S_GET_COUNT0,
52
S_GET_COUNT1,
53
S_GET_COUNT2,
54
S_GET_COUNT3,
55
S_BEGIN_WRITE,
56
S_WRITE,
57
S_END_WRITE_ALIGNED,
58
S_END_WRITE_NONALIGNED,
59
S_READ
60
);
61
constant FIFO_READ
: std_logic_vector(1 downto 0) := "10";
-assert fx2Read_out (active-low)
62
constant FIFO_WRITE
: std_logic_vector(1 downto 0) := "01";
-assert fx2Write_out (active-low)
63
constant FIFO_NOP
: std_logic_vector(1 downto 0) := "11";
-assert nothing
64
constant OUT_FIFO
: std_logic
:= '0';
-EP6OUT
65
constant IN_FIFO
: std_logic
:= '1';
-EP8IN
66
signal state, state_next
: StateType
:= S_IDLE;
67
signal fifoOp
: std_logic_vector(1 downto 0) := FIFO_NOP;
68
signal count, count_next
: unsigned(31 downto 0)
:= (others => '0'); -read/write count
69
signal addr, addr_next
: std_logic_vector(6 downto 0) := (others => '0'); -channel being accessed (0-127)
70
signal isWrite, isWrite_next
: std_logic
:= '0';
-is this access is an FX2 FIFO write or a read?
71
signal isAligned, isAligned_next : std_logic
:= '0';
-is this FX2 FIFO write block-aligned?
72
signal dataOut
: std_logic_vector(7 downto 0);
-data to be driven on fx2Data_io
73
signal driveBus
: std_logic;
-whether or not to drive fx2Data_io
74 begin
75
-- Infer registers
76
process(fx2Clk_in)
77
begin
78
if ( rising_edge(fx2Clk_in) ) then
79
state <= state_next;
80
count <= count_next;
81
addr <= addr_next;
82
isWrite <= isWrite_next;
83
isAligned <= isAligned_next;
84
end if;
85
end process;
86
87
-- Next state logic
88
process(
89
state, fx2Data_io, fx2GotData_in, fx2GotRoom_in, count, isAligned, isWrite, addr,
90
chanData_in, chanGotData_in, chanGotRoom_in)
91
begin
92
state_next <= state;
93
count_next <= count;
94
addr_next <= addr;
95
isWrite_next <= isWrite;
-- is the FPGA writing to the FX2?
96
isAligned_next <= isAligned; -- does this FIFO write end on a block (512-byte) boundary?
97
dataOut <= (others => '0');
98
driveBus <= '0';
-- don't drive fx2Data_io by default
99
fifoOp <= FIFO_READ;
-- read the FX2 FIFO by default
100
fx2PktEnd_out <= '1';
-- inactive: FPGA does not commit a short packet.
101
chanRead_out <= '0';
102
chanWrite_out <= '0';
103
104
case state is
105
when S_GET_COUNT0 =>
106
fx2FifoSel_out <= OUT_FIFO; -- Reading from FX2
107
if ( fx2GotData_in = '1' ) then
108
-- The count high word high byte will be available on the next clock edge.
109
count_next(31 downto 24) <= unsigned(fx2Data_io);
110
state_next <= S_GET_COUNT1;
8 111
end if;
112
113
when S_GET_COUNT1 =>
114
fx2FifoSel_out <= OUT_FIFO; -- Reading from FX2
115
if ( fx2GotData_in = '1' ) then
116
-- The count high word low byte will be available on the next clock edge.
117
count_next(23 downto 16) <= unsigned(fx2Data_io);
118
state_next <= S_GET_COUNT2;
119
end if;
120
121
when S_GET_COUNT2 =>
122
fx2FifoSel_out <= OUT_FIFO; -- Reading from FX2
123
if ( fx2GotData_in = '1' ) then
124
-- The count low word high byte will be available on the next clock edge.
125
count_next(15 downto 8) <= unsigned(fx2Data_io);
126
state_next <= S_GET_COUNT3;
127
end if;
128
129
when S_GET_COUNT3 =>
130
fx2FifoSel_out <= OUT_FIFO; -- Reading from FX2
131
if ( fx2GotData_in = '1' ) then
132
-- The count low word low byte will be available on the next clock edge.
133
count_next(7 downto 0) <= unsigned(fx2Data_io);
134
if ( isWrite = '1' ) then
135
state_next <= S_BEGIN_WRITE;
136
else
137
state_next <= S_READ;
138
end if;
139
end if;
140
141
when S_BEGIN_WRITE =>
142
fx2FifoSel_out <= IN_FIFO;
-- Writing to FX2
143
fifoOp <= FIFO_NOP;
144
if ( count(8 downto 0) = "000000000" ) then
145
isAligned_next <= '1';
146
else
147
isAligned_next <= '0';
148
end if;
149
state_next <= S_WRITE;
150
151
when S_WRITE =>
152
fx2FifoSel_out <= IN_FIFO;
-- Writing to FX2
153
if ( fx2GotRoom_in = '1' and chanGotData_in = '1' ) then
154
fifoOp <= FIFO_WRITE;
155
dataOut <= chanData_in;
156
driveBus <= '1';
157
chanRead_out <= '1';
158
count_next <= count - 1;
159
if ( count = 1 ) then
160
if ( isAligned = '1' ) then
161
state_next <= S_END_WRITE_ALIGNED; -- don't assert fx2PktEnd
162
else
163
state_next <= S_END_WRITE_NONALIGNED; -assert fx2PktEnd to commit small packet
164
end if;
165
end if;
166
else
167
fifoOp <= FIFO_NOP;
168
end if;
169
170
when S_END_WRITE_ALIGNED =>
171
fx2FifoSel_out <= IN_FIFO;
-- Writing to FX2
172
fifoOp <= FIFO_NOP;
173
state_next <= S_IDLE;
174
175
when S_END_WRITE_NONALIGNED =>
176
fx2FifoSel_out <= IN_FIFO;
-- Writing to FX2
177
fifoOp <= FIFO_NOP;
178
fx2PktEnd_out <= '0';
-- Active: FPGA commits the packet early.
179
state_next <= S_IDLE;
180
181
when S_READ =>
182
fx2FifoSel_out <= OUT_FIFO; -- Reading from FX2
9 183
if ( fx2GotData_in = '1' and chanGotRoom_in = '1') then
184
-- A data byte will be available on the next clock edge
185
chanWrite_out <= '1';
186
count_next <= count - 1;
187
if ( count = 1 ) then
188
state_next <= S_IDLE;
189
end if;
190
else
191
fifoOp <= FIFO_NOP;
192
end if;
193
194
-- S_IDLE and others
195
when others =>
196
fx2FifoSel_out <= OUT_FIFO; -- Reading from FX2
197
if ( fx2GotData_in = '1' ) then
198
-- The read/write flag and a seven-bit channel address will be available on the
199
-- next clock edge.
200
addr_next <= fx2Data_io(6 downto 0);
201
isWrite_next <= fx2Data_io(7);
202
state_next <= S_GET_COUNT0;
203
end if;
204
end case;
205
end process;
206
207
-- Drive stateless signals
208
fx2Read_out <= fifoOp(0);
209
fx2Write_out <= fifoOp(1);
210
chanAddr_out <= addr;
211
chanData_out <= fx2Data_io;
212
fx2Data_io <= dataOut when driveBus = '1' else (others => 'Z');
213 end behavioural;
1.1.4 dac_count.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dac_count is
PORT(
scan_pos : in STD_LOGIC_VECTOR(31 downto 0);
dac_clk : in STD_LOGIC;
dac_out : out STD_LOGIC;
wrld_clk : out STD_LOGIC
);
end dac_count;
architecture Behavioral of dac_count is
signal count : STD_LOGIC_VECTOR(4 downto 0);
signal shft_reg : STD_LOGIC_VECTOR(31 downto 0);
begin
PROCESS(dac_clk)
begin
if(rising_edge(dac_clk))then
dac_out <= shft_reg(conv_integer(count));
count <= count + 1;
if(count = "00000")then
shft_reg <= x"00" & scan_pos(31 downto 8);
end if;
end if;
end process;
wrld_clk <= count(4);
end Behavioral;
10 1.1.5 emulator.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity analog_interface is
port (
dac_clk : in std_logic;
adc_clk : in std_logic;
-- data signals
dac_data: in std_logic_vector(23 downto 0); -- 24 bit from DCM
adc_data: out std_logic_vector(15 downto 0); -- 16 bit to DCM
-- status signals
control: in std_logic_vector(7 downto 0); -- control register (TBD)
status : out std_logic_vector(7 downto 0) -- status register (TBD)
);
end entity;
architecture black_box_emulator of analog_interface is
type bram_rom is array(natural range <>) of std_logic_vector(15 downto 0);
-- this should fit in 4x 16x1K BRAMs (i.e. in the S3E-100)
constant EMULATOR_DATA : bram_rom(0 to 4095) := (
X"0000", X"0131", X"0126", X"0086", X"0089", X"0412", X"05f1",
X"02b8", X"03a0", X"0305", X"029a", X"0411", X"02f1", X"0533",
X"041b", X"0334", X"0023", X"04ac", X"0078", X"0284", X"0213",
X"0504", X"00a4", X"02b4", X"02f0", X"0382", X"0123", X"0373",
X"038b", X"056d", X"01f1", X"0391", X"0208", X"03c8", X"0236",
X"0196", X"0408", X"01a5", X"02c4", X"0365", X"0319", X"0392",
X"010c", X"01ec", X"05da", X"05fd", X"0130", X"0174", X"03bd",
X"02a3", X"048c", X"02b1", X"019d", X"059f", X"035d", X"0186",
X"028e", X"0414", X"01a8", X"0050", X"0497", X"035e", X"0263",
X"01c1", X"048e", X"0248", X"006e", X"021f", X"01f1", X"037a",
X"0352", X"02e2", X"0322", X"004d", X"02f9", X"048a", X"004b",
X"0374", X"00f8", X"0380", X"04ac", X"0227", X"04c2", X"05e1",
X"0487", X"016c", X"03dd", X"01af", X"04e3", X"03c8", X"00c7",
X"04a6", X"0387", X"00a8", X"01c4", X"0171", X"0309", X"05df",
X"00ef", X"024d", X"002e", X"0252", X"01c9", X"059a", X"035e",
X"0203", X"027e", X"0287", X"0394", X"0405", X"0277", X"0377",
X"0295", X"02e9", X"0262", X"0510", X"00c9", X"0138", X"012e",
X"0548", X"0260", X"036b", X"055b", X"0013", X"0164", X"01f9",
X"0599", X"04eb", X"028b", X"00c4", X"01a8", X"03b1", X"0285",
X"021c", X"023a", X"00f4", X"05ae", X"0233", X"0323", X"0073",
X"022c", X"012d", X"0679", X"0170", X"04df", X"0385", X"02e2",
X"01fe", X"03b6", X"0335", X"0046", X"02ca", X"02f3", X"0145",
X"042d", X"00c3", X"028a", X"02e7", X"03c8", X"025f", X"0207",
X"03fa", X"0566", X"0071", X"02e9", X"0501", X"02bb", X"0210",
X"025a", X"004d", X"0352", X"0362", X"01b6", X"0316", X"000b",
X"062c", X"0213", X"040e", X"0546", X"02ae", X"0332", X"0295",
X"00bb", X"02e4", X"0269", X"02a6", X"03e2", X"0006", X"00b2",
X"02a4", X"03b3", X"039b", X"0357", X"02b3", X"01bb", X"01a6",
X"01ee", X"025e", X"0085", X"0169", X"01c0", X"0690", X"034e",
X"02df", X"0143", X"02e3", X"0475", X"01bd", X"0351", X"0165",
X"0226", X"0119", X"00f9", X"03b3", X"013f", X"03a0", X"03c0",
X"0480", X"05ad", X"012f", X"01bf", X"0412", X"0021", X"04e9",
X"0292", X"0083", X"05aa", X"02a2", X"02da", X"028f", X"0373",
X"020f", X"02b3", X"03ba", X"01da", X"0293", X"03cb", X"0016",
X"00d4", X"0468", X"027e", X"0110", X"024a", X"0398", X"022c",
X"03dd", X"0198", X"0456", X"0397", X"00cf", X"0270", X"0310",
X"0317", X"0162", X"0317", X"000f", X"00fb", X"0147", X"0016",
X"0472", X"00b1", X"02c8", X"02ec", X"0292", X"027b", X"0495",
X"0093", X"04bd", X"02f1", X"01dd", X"0111", X"0203", X"02d7",
X"0264", X"0408", X"016f", X"05c8", X"0267", X"02ba", X"020a",
X"033f", X"02d8", X"037a", X"03c3", X"028c", X"0095", X"02a8",
X"02ad", X"021f", X"039d", X"050e", X"00c8", X"01fe", X"04b0",
X"04f1", X"021a", X"03be", X"028a", X"0622", X"0066", X"0234",
X"0135",
X"0292",
X"0466",
X"01f2",
X"0256",
X"02b7",
X"040a",
X"0208",
X"0041",
X"009a",
X"029b",
X"01c1",
X"01d8",
X"0267",
X"0279",
X"03f7",
X"02d6",
X"035d",
X"01be",
X"03ad",
X"02c1",
X"004e",
X"0213",
X"0381",
X"0250",
X"008b",
X"0285",
X"0097",
X"00dc",
X"0507",
X"0407",
X"02c9",
X"0020",
X"035b",
X"03c0",
X"023d",
X"0224",
X"02c0",
X"03d3",
X"0521",
X"0227",
X"03eb",
X"034d",
11 69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
X"02ee",
X"0083",
X"04d0",
X"037d",
X"0358",
X"03ab",
X"01d9",
X"0227",
X"0107",
X"03c7",
X"0452",
X"03a2",
X"0361",
X"01a8",
X"02fa",
X"038a",
X"053f",
X"0410",
X"04f9",
X"05d6",
X"05b5",
X"0367",
X"02f3",
X"01fb",
X"040f",
X"020e",
X"0263",
X"01ba",
X"0459",
X"04cc",
X"0039",
X"03b0",
X"00b6",
X"032b",
X"0430",
X"0796",
X"02f3",
X"0144",
X"0270",
X"0480",
X"0a49",
X"15f0",
X"8e3e",
X"3421",
X"0e40",
X"05d7",
X"053a",
X"054f",
X"02f5",
X"0419",
X"054d",
X"02f6",
X"0247",
X"01d0",
X"0338",
X"0109",
X"01e6",
X"0426",
X"04f0",
X"0572",
X"01e1",
X"03f8",
X"02b1",
X"0568",
X"0262",
X"0071",
X"02b8",
X"043c",
X"0448",
X"00f7",
X"012b",
X"0154",
X"040e",
X"028d",
X"0377",
X"0423",
X"0323",
X"0315",
X"03f7",
X"023c",
X"0264",
X"0284",
X"022e",
X"01a6",
X"0244",
X"01e3",
X"00fd",
X"0415",
X"0226",
X"024f",
X"01b6",
X"02bb",
X"020d",
X"0023",
X"04d3",
X"00ed",
X"01f9",
X"04a2",
X"0116",
X"027a",
X"02e1",
X"020f",
X"02db",
X"0455",
X"0236",
X"0140",
X"0396",
X"0404",
X"006a",
X"0306",
X"03d9",
X"080b",
X"08f1",
X"0b52",
X"1a9e",
X"afdf",
X"2b2e",
X"0c59",
X"054f",
X"04ce",
X"05cc",
X"0634",
X"03ea",
X"040d",
X"0342",
X"03e1",
X"034a",
X"050d",
X"0114",
X"011c",
X"04a9",
X"036d",
X"01e9",
X"00d3",
X"0216",
X"01a2",
X"0290",
X"02bd",
X"040f",
X"007a",
X"0491",
X"03a2",
X"0414",
X"0296",
X"049b",
X"019a",
X"0141",
X"04b0",
X"03d8",
X"03b5",
X"0353",
X"0015",
X"0431",
X"038c",
X"0309",
X"02f5",
X"029a",
X"0271",
X"02b5",
X"0182",
X"03d4",
X"0340",
X"0395",
X"01f9",
X"01be",
X"0048",
X"0660",
X"041e",
X"024a",
X"0215",
X"00a5",
X"018a",
X"00f8",
X"03af",
X"05e1",
X"02d1",
X"04f1",
X"046c",
X"01bc",
X"01a3",
X"036e",
X"053b",
X"0384",
X"05bb",
X"0439",
X"0447",
X"0b42",
X"214c",
X"c0cb",
X"2020",
X"0b95",
X"058a",
X"05a6",
X"029d",
X"04e3",
X"002c",
X"0135",
X"0463",
X"052f",
X"02df",
X"026f",
X"0232",
X"00f9",
X"0160",
X"05c6",
X"033f",
X"021a",
X"0127",
X"03f6",
X"01bd",
X"00aa",
X"02de",
X"03bd",
X"044b",
X"026f",
X"017b",
X"007c",
X"03b8",
X"00bd",
X"0265",
X"001b",
X"0307",
X"00f6",
X"01f8",
X"018c",
X"04ea",
X"030d",
X"0205",
X"035d",
X"04e7",
X"0442",
X"02dc",
X"04fa",
X"01d5",
X"01ba",
X"024a",
X"0292",
X"0009",
X"037b",
X"0236",
X"006c",
X"04ff",
X"031f",
X"0394",
X"030c",
X"049b",
X"0161",
X"01e9",
X"035b",
X"0449",
X"052f",
X"03af",
X"0266",
X"033d",
X"02e8",
X"01ae",
X"02f8",
X"0553",
X"05ce",
X"0b2d",
X"24ec",
X"b78b",
X"1d4a",
X"0cf3",
X"047c",
X"0724",
X"0280",
X"017a",
X"049b",
X"028e",
X"02e3",
X"00d5",
X"0344",
X"0043",
X"021b",
X"0341",
X"045d",
X"05e8",
X"0360",
X"0146",
X"008f",
X"019f",
X"006c",
X"03da",
X"0240",
X"0367",
X"0224",
X"0114",
X"0006",
X"0392",
X"0483",
X"030a",
X"0108",
X"00e7",
X"01f5",
X"037a",
X"04c1",
X"0369",
X"0196",
X"012d",
X"0291",
X"002b",
X"023b",
X"00ba",
X"03dc",
X"0279",
X"0550",
X"044f",
X"03be",
X"022e",
X"049c",
X"027c",
X"02b1",
X"040b",
X"0151",
X"0258",
X"01ab",
X"04fc",
X"03c0",
X"04da",
X"038a",
X"017a",
X"032d",
X"0514",
X"0328",
X"00fb",
X"047e",
X"02cd",
X"025b",
X"0435",
X"04cc",
X"0774",
X"0e10",
X"305e",
X"9c10",
X"17f0",
X"086e",
X"04d9",
X"0333",
X"045f",
X"00d1",
X"01a3",
X"0243",
X"0673",
X"006b",
X"00c5",
X"0377",
X"03fe",
X"0166",
X"0030",
X"02bc",
X"0228",
X"049f",
X"033f",
X"02c7",
X"0022",
X"017a",
X"0212",
X"01ff",
X"03bb",
X"03c2",
X"02cb",
X"005d",
X"044c",
X"014f",
X"0414",
X"003e",
X"0126",
X"009e",
X"008f",
X"03d0",
X"0250",
X"02f1",
X"01ec",
X"0332",
X"033d",
X"02c3",
X"02f5",
X"0264",
X"02f9",
X"04ef",
X"021b",
X"0214",
X"02f6",
X"01a9",
X"03e1",
X"00d6",
X"0371",
X"03df",
X"01a6",
X"0060",
X"0012",
X"0476",
X"03f9",
X"03ed",
X"039a",
X"0159",
X"02a1",
X"023b",
X"04e9",
X"02de",
X"05e1",
X"06b2",
X"0702",
X"0a47",
X"0fcf",
X"3e0f",
X"770f",
X"13c9",
X"071f",
X"0954",
X"049b",
X"0262",
X"020d",
X"03f3",
X"05a4",
X"06a0",
X"038f",
X"038d",
X"01da",
X"0428",
X"0040",
X"02b6",
X"00dd",
X"00df",
X"009a",
X"0231",
X"070f",
X"0134",
X"0323",
X"06ed",
X"008e",
X"0124",
X"01d8",
X"02be",
X"02a7",
X"04e4",
X"0164",
X"03fb",
X"02ab",
X"02c5",
X"0500",
X"0094",
X"02cb",
X"03d0",
X"02ed",
X"00a8",
X"04b7",
X"0215",
X"01c7",
X"0262",
X"023a",
X"0375",
X"0374",
X"00a0",
X"016b",
X"005f",
X"02c5",
X"028d",
X"0300",
X"0368",
X"01e0",
X"0418",
X"03aa",
X"04da",
X"0364",
X"02d7",
X"018a",
X"034a",
X"031c",
X"01f4",
X"01f8",
X"06ba",
X"02bb",
X"03cd",
X"0368",
X"04f1",
X"09a4",
X"1150",
X"4ff5",
X"581f",
X"12c7",
X"0abf",
X"06a2",
X"04cf",
X"03fe",
X"0088",
X"05b3",
X"0310",
X"03c0",
X"04a7",
X"0236",
X"0532",
X"02b0",
X"046a",
X"01d4",
X"020d",
X"0056",
X"0390",
X"023c",
X"04e7",
X"0527",
X"0376",
X"02ba",
X"03b9",
X"00b3",
X"0261",
X"0074",
X"04a8",
X"035c",
X"03af",
X"0326",
X"033a",
X"0533",
X"035d",
X"010c",
X"02c2",
X"05a5",
X"021e",
X"01b8",
X"02ec",
X"02e5",
X"069f",
X"0278",
X"0529",
X"06db",
X"047a",
X"0430",
X"0584",
X"0287",
X"0129",
X"0312",
X"0031",
X"0371",
X"0484",
X"0145",
X"0372",
X"027e",
X"01bd",
X"025f",
X"0556",
X"04b6",
X"040d",
X"013b",
X"0362",
X"0365",
X"05d0",
X"0486",
X"042b",
X"0779",
X"08f9",
X"1437",
X"6d8c",
X"457e",
X"0e6a",
X"0619",
X"04ea",
X"01c5",
X"02e3",
X"0157",
X"0201",
X"0027",
X"0416",
X"040a",
X"0341",
X"03a0",
X"0210",
X"021f",
X"016e",
X"01e3",
X"05dc",
X"00c6",
X"0301",
X"034b",
X"02d3",
X"0121",
X"0056",
X"0322",
X"019e",
X"004b",
X"0649",
X"01ca",
X"023d",
X"031e",
12 142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
X"032d",
X"005c",
X"03ac",
X"0324",
X"0218",
X"01b7",
X"02b8",
X"0371",
X"0183",
X"0075",
X"03b2",
X"043f",
X"0318",
X"01a9",
X"0382",
X"00cd",
X"0290",
X"01e8",
X"01ec",
X"01a7",
X"00df",
X"013b",
X"001f",
X"0431",
X"0193",
X"0022",
X"0262",
X"0425",
X"028b",
X"0475",
X"01d2",
X"032d",
X"0403",
X"0088",
X"02b5",
X"07b0",
X"01b5",
X"01da",
X"02e8",
X"0371",
X"0116",
X"005a",
X"0322",
X"0199",
X"0228",
X"026f",
X"02ab",
X"0579",
X"0210",
X"0082",
X"0153",
X"0367",
X"01e4",
X"030b",
X"0296",
X"035f",
X"03bd",
X"03b0",
X"0429",
X"02cb",
X"039e",
X"0442",
X"01a2",
X"04c2",
X"01c4",
X"02a1",
X"01a7",
X"04c4",
X"0553",
X"03cf",
X"0662",
X"05b3",
X"005f",
X"01a4",
X"00b0",
X"0210",
X"0366",
X"0121",
X"0484",
X"01ec",
X"00b6",
X"061b",
X"026f",
X"02fe",
X"0383",
X"05e2",
X"00db",
X"0101",
X"0303",
X"025d",
X"03cf",
X"03ca",
X"0289",
X"06b4",
X"042e",
X"02cc",
X"0253",
X"055e",
X"01f6",
X"00a6",
X"0316",
X"022a",
X"0354",
X"0345",
X"0459",
X"015a",
X"0296",
X"0311",
X"0473",
X"02b5",
X"01a2",
X"022d",
X"0363",
X"006c",
X"01a6",
X"005c",
X"00ed",
X"00eb",
X"01ee",
X"02d8",
X"04e6",
X"0008",
X"023d",
X"009b",
X"0303",
X"0219",
X"017a",
X"0009",
X"01d3",
X"01d7",
X"0075",
X"02c0",
X"041f",
X"008f",
X"0376",
X"0485",
X"0213",
X"037c",
X"043c",
X"01b9",
X"043f",
X"0569",
X"021e",
X"041c",
X"0574",
X"00ed",
X"04d6",
X"0425",
X"0026",
X"0228",
X"0379",
X"0315",
X"01da",
X"0450",
X"003d",
X"03f3",
X"00f9",
X"0277",
X"0370",
X"036a",
X"0045",
X"0303",
X"02a0",
X"0325",
X"0493",
X"01ec",
X"0213",
X"00c3",
X"001f",
X"02fe",
X"0151",
X"0271",
X"030d",
X"05fd",
X"02b7",
X"0095",
X"0272",
X"038d",
X"0424",
X"0306",
X"00ad",
X"0030",
X"009b",
X"0267",
X"051b",
X"028c",
X"01d7",
X"03f1",
X"03a0",
X"0252",
X"05f4",
X"01b6",
X"0009",
X"04ba",
X"02f8",
X"038a",
X"02e1",
X"0340",
X"0119",
X"05e2",
X"04ca",
X"0569",
X"0690",
X"0528",
X"04c2",
X"01cd",
X"01bf",
X"00cd",
X"01cf",
X"0172",
X"043a",
X"04b0",
X"021f",
X"0249",
X"00b8",
X"01a6",
X"031d",
X"02fb",
X"0493",
X"0186",
X"0034",
X"031d",
X"022f",
X"01ec",
X"0217",
X"0181",
X"0197",
X"0531",
X"01de",
X"0525",
X"0458",
X"04b0",
X"0577",
X"03d3",
X"029e",
X"0343",
X"01bb",
X"0431",
X"0163",
X"0256",
X"020f",
X"0236",
X"015f",
X"00f6",
X"00fc",
X"03d0",
X"02cd",
X"0145",
X"0306",
X"03c8",
X"012c",
X"01d8",
X"03a9",
X"034c",
X"0321",
X"0141",
X"03d9",
X"01e4",
X"02f9",
X"0310",
X"031d",
X"01b1",
X"0351",
X"020d",
X"01b0",
X"01c3",
X"001b",
X"0555",
X"017b",
X"0567",
X"026e",
X"0508",
X"01fe",
X"0384",
X"02f5",
X"0181",
X"0331",
X"0290",
X"0146",
X"01f1",
X"039c",
X"03e9",
X"02d8",
X"0565",
X"0657",
X"034e",
X"0184",
X"0228",
X"040b",
X"0491",
X"015b",
X"03e8",
X"0305",
X"0308",
X"0026",
X"017f",
X"0569",
X"0035",
X"0103",
X"0230",
X"0079",
X"051f",
X"0409",
X"0231",
X"0364",
X"022c",
X"0293",
X"02b2",
X"0289",
X"006f",
X"0383",
X"01cd",
X"039b",
X"059b",
X"02d1",
X"0404",
X"0217",
X"04a1",
X"007b",
X"0239",
X"0558",
X"0371",
X"0272",
X"00ee",
X"0238",
X"0017",
X"03f5",
X"0152",
X"0140",
X"0383",
X"031f",
X"02b0",
X"01bc",
X"031c",
X"0306",
X"0177",
X"036d",
X"0206",
X"0186",
X"05bb",
X"00e0",
X"0226",
X"01f5",
X"063b",
X"02ba",
X"0220",
X"020e",
X"009d",
X"015d",
X"0081",
X"0307",
X"04e4",
X"04e9",
X"01aa",
X"00d0",
X"0367",
X"032c",
X"03b5",
X"031d",
X"0293",
X"030c",
X"02dd",
X"0611",
X"01f9",
X"0108",
X"00ef",
X"0291",
X"0373",
X"03d0",
X"01c2",
X"03f0",
X"02fc",
X"049a",
X"0130",
X"00d2",
X"0435",
X"006e",
X"00e2",
X"03e7",
X"0315",
X"01be",
X"0150",
X"03ec",
X"00cb",
X"00f2",
X"03aa",
X"0342",
X"03c1",
X"0342",
X"06fe",
X"040a",
X"058d",
X"03f0",
X"0247",
X"049c",
X"02a1",
X"005d",
X"052e",
X"02d5",
X"0400",
X"03b4",
X"01f0",
X"01ca",
X"01d6",
X"0437",
X"02fe",
X"0103",
X"0250",
X"00b8",
X"00ac",
X"0265",
X"02cf",
X"02b5",
X"05a6",
X"01e7",
X"0264",
X"03b5",
X"03a7",
X"02b3",
X"0377",
X"0356",
X"019a",
X"0302",
X"02ce",
X"026c",
X"019e",
X"0654",
X"0473",
X"02dd",
X"02fe",
X"049a",
X"010c",
X"0303",
X"0030",
X"0350",
X"0352",
X"01ba",
X"0293",
X"02c6",
X"00e0",
X"0334",
X"01b1",
X"0153",
X"0034",
X"02d6",
X"034a",
X"0117",
X"02a5",
X"02f8",
X"004e",
X"01d4",
X"0150",
X"0321",
X"05d9",
X"01e2",
X"04c1",
X"05af",
X"03ba",
X"01f6",
X"020d",
X"0478",
X"00fb",
X"03f6",
X"041e",
X"01db",
X"01b0",
X"0416",
X"0176",
X"025a",
X"027c",
X"043d",
X"031a",
X"053f",
X"00b3",
X"0118",
X"0358",
X"0421",
X"005c",
X"02b8",
X"0230",
X"03c0",
X"0545",
X"03a9",
X"02f5",
X"00c9",
X"01e5",
X"02ba",
X"05e3",
X"00b2",
X"03dc",
X"0031",
X"0023",
X"0209",
X"0218",
X"0234",
X"01e5",
X"0403",
X"031a",
X"0425",
X"00f8",
X"0299",
X"01ac",
X"0369",
X"038c",
X"028d",
X"0216",
X"044b",
X"033c",
X"001a",
X"05d1",
X"0258",
X"0158",
X"0001",
X"039a",
X"0506",
X"038e",
X"0377",
X"00b9",
X"0272",
X"049a",
X"0494",
X"04fd",
X"0467",
X"034d",
X"0228",
X"057b",
X"047d",
X"005e",
X"0223",
X"0456",
X"03a6",
X"0600",
X"01aa",
X"0468",
X"012c",
X"00fa",
X"00be",
X"0313",
X"010a",
X"01ad",
X"0052",
X"005d",
X"01c0",
X"02e0",
X"03b8",
X"01e9",
X"02e9",
X"0270",
X"02a3",
X"02cb",
X"0324",
X"02bd",
X"0287",
X"055c",
X"008d",
X"021d",
X"03a1",
X"01c8",
X"02bc",
X"0054",
X"0318",
X"01d5",
X"04c3",
X"01d0",
X"014b",
X"00d3",
X"0473",
X"0418",
X"0444",
X"021e",
X"03d3",
X"0243",
X"0160",
X"0005",
X"0322",
X"0245",
X"0399",
X"025f",
X"0041",
X"03e4",
X"0444",
X"0161",
X"0297",
X"0366",
13 215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
X"04c5",
X"053f",
X"02b9",
X"0272",
X"0529",
X"053f",
X"0030",
X"0635",
X"0bed",
X"1db5",
X"bc74",
X"263d",
X"0a6f",
X"094c",
X"0678",
X"020b",
X"0383",
X"05ed",
X"0345",
X"0318",
X"0195",
X"0300",
X"04b8",
X"0186",
X"0323",
X"01f6",
X"03ee",
X"031b",
X"030e",
X"00ec",
X"031e",
X"0119",
X"0237",
X"01bb",
X"0463",
X"02b1",
X"0093",
X"0210",
X"02ac",
X"04c6",
X"00e1",
X"00e3",
X"03ea",
X"03b0",
X"0129",
X"0336",
X"01c6",
X"0470",
X"01b7",
X"01ad",
X"0321",
X"04a7",
X"0236",
X"0050",
X"020c",
X"02e7",
X"035a",
X"02b0",
X"02cd",
X"00da",
X"01d2",
X"016f",
X"0694",
X"033f",
X"00f0",
X"0334",
X"00cc",
X"0112",
X"02d6",
X"037c",
X"002c",
X"0170",
X"01d3",
X"01b1",
X"03f5",
X"046a",
X"03cb",
X"0223",
X"06a8",
X"04f8",
X"0546",
X"0aaa",
X"2422",
X"bf2b",
X"1e78",
X"0b27",
X"083b",
X"0500",
X"0360",
X"0500",
X"04f1",
X"0451",
X"0390",
X"026b",
X"0067",
X"03e9",
X"0151",
X"034b",
X"027b",
X"0326",
X"03a4",
X"0194",
X"022e",
X"038e",
X"03cb",
X"017b",
X"0694",
X"0516",
X"025a",
X"020f",
X"015c",
X"0265",
X"002d",
X"03b9",
X"025b",
X"04dc",
X"00c9",
X"023e",
X"01de",
X"0061",
X"0192",
X"00ef",
X"0337",
X"0188",
X"03b8",
X"0047",
X"0407",
X"0486",
X"036d",
X"031e",
X"02e0",
X"009e",
X"025d",
X"043b",
X"038e",
X"036d",
X"026b",
X"0417",
X"0190",
X"04cd",
X"0083",
X"03e4",
X"0311",
X"04af",
X"0294",
X"0270",
X"03a1",
X"0119",
X"058b",
X"02fb",
X"049d",
X"0550",
X"03e3",
X"0771",
X"0cbc",
X"2d54",
X"a400",
X"18b5",
X"0aa4",
X"0695",
X"042b",
X"019a",
X"03ad",
X"053e",
X"0326",
X"0128",
X"021a",
X"0504",
X"02c8",
X"05d4",
X"0432",
X"0447",
X"00dd",
X"04a0",
X"055b",
X"0129",
X"03ab",
X"03db",
X"017d",
X"0280",
X"0318",
X"01c4",
X"03da",
X"0237",
X"0270",
X"01c2",
X"02f1",
X"037c",
X"01b9",
X"01ee",
X"0495",
X"015e",
X"0113",
X"0117",
X"038c",
X"03b3",
X"0244",
X"02cc",
X"0143",
X"02a6",
X"0234",
X"00e1",
X"0187",
X"023e",
X"00a7",
X"03e2",
X"011f",
X"05cf",
X"03ca",
X"028d",
X"0009",
X"04cc",
X"05ac",
X"0258",
X"0082",
X"011e",
X"03b1",
X"03bb",
X"026a",
X"02f8",
X"0296",
X"0432",
X"047f",
X"0442",
X"02a0",
X"060a",
X"0a91",
X"0e62",
X"3b52",
X"7d38",
X"121b",
X"0951",
X"0639",
X"04e7",
X"04c5",
X"025e",
X"03b7",
X"02d2",
X"0244",
X"02bf",
X"030f",
X"02bb",
X"045d",
X"04df",
X"0297",
X"018e",
X"00d0",
X"02bd",
X"01e0",
X"0203",
X"01f9",
X"01bf",
X"01d1",
X"026a",
X"0543",
X"01f5",
X"04e6",
X"01f9",
X"01bb",
X"0245",
X"02e1",
X"025f",
X"03d6",
X"0118",
X"01fc",
X"0208",
X"01d8",
X"036b",
X"041e",
X"03b2",
X"03d3",
X"021f",
X"0263",
X"023f",
X"01f1",
X"026b",
X"014e",
X"044b",
X"04fb",
X"035d",
X"0301",
X"0201",
X"005c",
X"04b9",
X"02be",
X"03af",
X"0216",
X"041d",
X"01f2",
X"00a1",
X"0215",
X"03af",
X"033f",
X"0369",
X"05ce",
X"0133",
X"0774",
X"0537",
X"0722",
X"0bc9",
X"1281",
X"4d81",
X"5f9d",
X"12e0",
X"0891",
X"0317",
X"0491",
X"04ca",
X"0608",
X"0516",
X"029b",
X"04f8",
X"02e8",
X"0530",
X"02ca",
X"0533",
X"0194",
X"016d",
X"0441",
X"040d",
X"05cf",
X"03d2",
X"05ed",
X"02de",
X"0279",
X"02d8",
X"0216",
X"0233",
X"01ec",
X"030a",
X"0224",
X"005d",
X"03e1",
X"02b8",
X"01b1",
X"00d8",
X"02bd",
X"0349",
X"02f3",
X"02af",
X"02f6",
X"0406",
X"03f8",
X"04b3",
X"035c",
X"0217",
X"006b",
X"0131",
X"0338",
X"01fe",
X"0373",
X"0407",
X"024d",
X"01d5",
X"06e4",
X"00a1",
X"018f",
X"0122",
X"0233",
X"0263",
X"0176",
X"04a3",
X"03da",
X"0322",
X"0110",
X"037f",
X"0350",
X"0284",
X"0215",
X"02c9",
X"029e",
X"05b8",
X"0694",
X"1308",
X"6652",
X"468e",
X"0fdd",
X"081b",
X"05b4",
X"02e7",
X"03c4",
X"04af",
X"01fa",
X"0516",
X"012c",
X"0252",
X"047e",
X"02ef",
X"029f",
X"0409",
X"0086",
X"0194",
X"0237",
X"03dc",
X"0423",
X"03fe",
X"010f",
X"0496",
X"02f3",
X"0529",
X"043e",
X"0327",
X"01a9",
X"0079",
X"00c8",
X"043f",
X"0439",
X"05ee",
X"014c",
X"0232",
X"03e0",
X"03ba",
X"0276",
X"0496",
X"02c0",
X"02a5",
X"02d9",
X"02a6",
X"046a",
X"03e1",
X"0155",
X"02c7",
X"032a",
X"0325",
X"03e9",
X"0445",
X"02cd",
X"01e0",
X"02ec",
X"0446",
X"0079",
X"0104",
X"0164",
X"03f9",
X"0534",
X"036a",
X"00fc",
X"04cc",
X"0337",
X"018f",
X"075c",
X"0317",
X"0294",
X"05f8",
X"04a2",
X"083a",
X"18a2",
X"8523",
X"366a",
X"0f50",
X"07a9",
X"06ea",
X"0429",
X"0266",
X"03fe",
X"01f5",
X"0542",
X"036e",
X"040e",
X"0261",
X"02aa",
X"0564",
X"01c4",
X"0093",
X"03b7",
X"0540",
X"052e",
X"0215",
X"01a6",
X"01bf",
X"016d",
X"0128",
X"04fb",
X"01b4",
X"042e",
X"0239",
X"0148",
X"02c9",
X"054f",
X"0272",
X"0336",
X"00b9",
X"0072",
X"0079",
X"036b",
X"0266",
X"0489",
X"0737",
X"0539",
X"0259",
X"031a",
X"0374",
X"008e",
X"009d",
X"0382",
X"0187",
X"02b5",
X"024b",
X"0508",
X"01ac",
X"039b",
X"0063",
X"02ef",
X"04d7",
X"0342",
X"02b1",
X"02ac",
X"023f",
X"0574",
X"05a5",
X"0401",
X"0391",
X"04c5",
X"055e",
X"0341",
X"03f6",
X"0324",
X"0546",
X"08e6",
X"19cb",
X"a9ce",
X"2ed3",
X"0b2a",
X"0826",
X"085e",
X"053a",
X"05e2",
X"0191",
X"0358",
X"0262",
X"0184",
X"0500",
X"0392",
X"00c8",
X"0383",
X"0115",
X"0209",
X"0162",
X"032a",
X"02a0",
X"0225",
X"017b",
X"0692",
X"03a5",
X"0089",
X"02f1",
X"041b",
X"0391",
X"0500",
X"03a7",
X"003e",
X"038b",
X"0219",
X"0158",
X"0519",
X"0153",
X"0481",
X"04e8",
X"04ab",
X"0536",
X"064d",
X"00d0",
X"0284",
X"0228",
X"0400",
X"0310",
X"0103",
X"047e",
X"030e",
X"0397",
X"0618",
X"03ae",
X"0430",
X"01ad",
X"00aa",
X"02ce",
X"01ee",
X"0343",
X"01d1",
X"05a9",
X"01bf",
X"0082",
X"05fd",
X"020c",
14 288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
X"0154",
X"030b",
X"0367",
X"05f8",
X"03db",
X"020d",
X"0238",
X"01fa",
X"0522",
X"02a9",
X"0228",
X"0103",
X"00e3",
X"02f7",
X"0152",
X"0167",
X"01cc",
X"02bc",
X"03fb",
X"0329",
X"012e",
X"027c",
X"039e",
X"0493",
X"0153",
X"035c",
X"0223",
X"031d",
X"027e",
X"03d6",
X"007f",
X"004f",
X"002f",
X"00d7",
X"02bf",
X"034b",
X"04dc",
X"04d4",
X"02bc",
X"038f",
X"04b2",
X"021e",
X"02b5",
X"0181",
X"05e1",
X"04f6",
X"031e",
X"0608",
X"0597",
X"0d9e",
X"2aab",
X"a9bd",
X"1b33",
X"08f2",
X"0435",
X"040e",
X"047e",
X"0606",
X"0380",
X"05df",
X"02a9",
X"03d1",
X"050e",
X"01dd",
X"01d5",
X"0402",
X"0640",
X"0227",
X"0265",
X"0184",
X"025d",
X"030b",
X"0312",
X"01e5",
X"0079",
X"01f7",
X"03c5",
X"0252",
X"01e4",
X"0517",
X"000d",
X"0494",
X"04ab",
X"058a",
X"02eb",
X"0281",
X"02a3",
X"0077",
X"04c5",
X"04a3",
X"01f7",
X"0272",
X"0027",
X"025a",
X"04e2",
X"014e",
X"03b9",
X"0399",
X"0389",
X"02d3",
X"02e3",
X"037e",
X"018d",
X"033c",
X"075b",
X"0016",
X"0466",
X"0212",
X"03d8",
X"0406",
X"04fc",
X"054d",
X"0351",
X"0405",
X"0230",
X"08fe",
X"0482",
X"04a9",
X"02d9",
X"0833",
X"04d3",
X"0654",
X"0d17",
X"34f8",
X"85ad",
X"1797",
X"04e7",
X"025d",
X"053d",
X"0105",
X"040a",
X"05d7",
X"02cc",
X"0200",
X"03e9",
X"021b",
X"01cd",
X"059b",
X"047e",
X"02fa",
X"03e7",
X"0193",
X"00f8",
X"02ce",
X"0219",
X"0396",
X"0167",
X"04f9",
X"04d1",
X"03c7",
X"0386",
X"02a1",
X"046a",
X"0019",
X"0372",
X"025b",
X"00a0",
X"02ff",
X"04f7",
X"03eb",
X"036b",
X"010b",
X"00f7",
X"03c2",
X"038a",
X"0326",
X"009c",
X"011a",
X"071d",
X"03b2",
X"0201",
X"00da",
X"0353",
X"0303",
X"011a",
X"047b",
X"0420",
X"01ef",
X"02e5",
X"027f",
X"00bd",
X"02d9",
X"0399",
X"033b",
X"00cc",
X"0279",
X"03bf",
X"02bb",
X"01ce",
X"022b",
X"0769",
X"0228",
X"06ee",
X"06d5",
X"0803",
X"0fbd",
X"48c7",
X"65ef",
X"12a2",
X"0d4f",
X"060f",
X"0245",
X"0279",
X"02c3",
X"059f",
X"02af",
X"02b4",
X"021a",
X"0195",
X"078c",
X"02aa",
X"0350",
X"02d8",
X"03de",
X"034c",
X"028e",
X"0403",
X"02b0",
X"01e7",
X"0467",
X"03c5",
X"03eb",
X"04d9",
X"0193",
X"031f",
X"00f0",
X"01ea",
X"03ab",
X"022c",
X"031e",
X"03e6",
X"01e6",
X"04b8",
X"03d0",
X"0206",
X"01bb",
X"0026",
X"02c7",
X"032c",
X"02b2",
X"00bc",
X"02de",
X"02ee",
X"01a2",
X"0029",
X"0529",
X"03d2",
X"0471",
X"0154",
X"028d",
X"02a7",
X"00ec",
X"0401",
X"03d4",
X"0302",
X"02bb",
X"033b",
X"0317",
X"0250",
X"019c",
X"02e3",
X"0299",
X"05bc",
X"0350",
X"042b",
X"04a2",
X"05bf",
X"06f2",
X"1326",
X"6374",
X"494e",
X"11a8",
X"063a",
X"06d7",
X"038f",
X"0655",
X"03b7",
X"0185",
X"0435",
X"0332",
X"0154",
X"0501",
X"02d2",
X"007a",
X"01c0",
X"0226",
X"05b4",
X"02ad",
X"030a",
X"01ce",
X"0210",
X"0318",
X"040c",
X"0311",
X"02de",
X"0429",
X"0234",
X"03e0",
X"0159",
X"0329",
X"02e8",
X"0519",
X"01aa",
X"04f2",
X"0350",
X"03e2",
X"044a",
X"0394",
X"04d6",
X"025e",
X"030e",
X"0410",
X"03f6",
X"0329",
X"0546",
X"032e",
X"03c2",
X"0244",
X"01c9",
X"0252",
X"004f",
X"04c5",
X"000a",
X"018b",
X"022a",
X"053a",
X"02a8",
X"0379",
X"0192",
X"02b5",
X"01d5",
X"0511",
X"050f",
X"042e",
X"0602",
X"0240",
X"03da",
X"030c",
X"05ad",
X"066a",
X"0b13",
X"15ac",
X"7e55",
X"3d90",
X"0df3",
X"060d",
X"0547",
X"0305",
X"0334",
X"001c",
X"0543",
X"036c",
X"01ec",
X"04c8",
X"02bd",
X"0232",
X"050c",
X"03ef",
X"02a6",
X"016f",
X"0086",
X"037a",
X"0498",
X"0238",
X"0118",
X"0741",
X"0416",
X"00c1",
X"01ff",
X"0406",
X"0216",
X"04ba",
X"03e1",
X"0630",
X"01eb",
X"0774",
X"00b7",
X"0404",
X"031d",
X"0248",
X"04d8",
X"001e",
X"034b",
X"0115",
X"01c4",
X"016a",
X"00e4",
X"0291",
X"035b",
X"0436",
X"03b4",
X"019a",
X"02a6",
X"0163",
X"00e6",
X"029e",
X"03af",
X"02ae",
X"032b",
X"0289",
X"0364",
X"05fa",
X"0062",
X"02d1",
X"01fa",
X"028f",
X"03dc",
X"03d4",
X"02f7",
X"04db",
X"0367",
X"0698",
X"068f",
X"099a",
X"179d",
X"a224",
X"2e4a",
X"0cb8",
X"0582",
X"0507",
X"039b",
X"0456",
X"027c",
X"0277",
X"0347",
X"01d1",
X"01a2",
X"0330",
X"03df",
X"02f7",
X"038d",
X"0211",
X"00a7",
X"01ea",
X"02c5",
X"02bd",
X"01d3",
X"0359",
X"03a0",
X"01e4",
X"0299",
X"0360",
X"019d",
X"03b8",
X"03ff",
X"02ec",
X"02dd",
X"0267",
X"014c",
X"022a",
X"0038",
X"02eb",
X"01dc",
X"01d1",
X"05e2",
X"039c",
X"025b",
X"03b6",
X"018f",
X"03be",
X"02ab",
X"012f",
X"04be",
X"0419",
X"02ce",
X"0300",
X"028c",
X"040e",
X"0342",
X"046c",
X"019e",
X"008b",
X"016e",
X"0262",
X"032b",
X"016a",
X"0070",
X"01ad",
X"059a",
X"027e",
X"04f0",
X"0284",
X"0262",
X"0460",
X"0281",
X"086c",
X"0c23",
X"1da6",
X"bd43",
X"269e",
X"0d44",
X"074b",
X"016f",
X"052b",
X"05cb",
X"0358",
X"03e7",
X"02eb",
X"02fc",
X"004a",
X"00c2",
X"03e9",
X"031a",
X"00b3",
X"0359",
X"0282",
X"0457",
X"01f8",
X"0116",
X"031e",
X"029a",
X"02eb",
X"0456",
X"03b1",
X"04c6",
X"01a8",
X"03d5",
X"046a",
X"045b",
X"05ca",
X"024f",
X"0499",
X"0588",
X"0243",
X"0226",
X"0128",
X"0445",
X"0149",
X"0035",
X"0397",
X"02ef",
X"02d6",
X"0439",
X"0168",
X"0459",
X"0408",
X"025b",
X"0082",
X"009f",
X"01fc",
X"02b4",
X"00e0",
X"026f",
X"040f",
X"026d",
X"042e",
X"054b",
X"02ad",
X"0280",
X"04c5",
X"0481",
X"01b4",
X"019a",
X"02c9",
X"03da",
X"02f0",
X"055b",
X"0781",
X"0a70",
X"0c2a",
X"2395",
X"c187",
X"1db4",
X"0b5c",
X"0a13",
X"039b",
X"01df",
X"05c5",
X"01d4",
X"0380",
X"00c8",
X"0361",
X"042a",
X"02e5",
X"00fb",
X"01fe",
X"038b",
X"0214",
X"00eb",
X"03dc",
X"01e1",
X"00eb",
X"0394",
X"03ef",
15 361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
X"0497",
X"0316",
X"0076",
X"0505",
X"046c",
X"00dc",
X"033c",
X"01e7",
X"043a",
X"02da",
X"0520",
X"0246",
X"01e4",
X"00e4",
X"021f",
X"03af",
X"0204",
X"02d1",
X"02b1",
X"0254",
X"01c0",
X"0367",
X"02c7",
X"027c",
X"00dc",
X"026a",
X"01b1",
X"00d3",
X"004a",
X"01bf",
X"0042",
X"030b",
X"0399",
X"0389",
X"00b7",
X"0373",
X"049f",
X"01d9",
X"027e",
X"03b4",
X"00eb",
X"00f5",
X"0181",
X"040b",
X"0268",
X"03f2",
X"00d6",
X"00ab",
X"0464",
X"0706",
X"00f7",
X"03c9",
X"026d",
X"0259",
X"01a8",
X"0331",
X"01bc",
X"04e2",
X"02e7",
X"03a1",
X"00e4",
X"046b",
X"02df",
X"03aa",
X"037f",
X"016a",
X"04c6",
X"039b",
X"0453",
X"022e",
X"053d",
X"0074",
X"0302",
X"0195",
X"0334",
X"03f0",
X"0314",
X"00ca",
X"02c7",
X"01ed",
X"021f",
X"048c",
X"0100",
X"061f",
X"02a9",
X"01aa",
X"0324",
X"0162",
X"0293",
X"0491",
X"0225",
X"026e",
X"0478",
X"0255",
X"02e6",
X"00b6",
X"035d",
X"03fa",
X"0472",
X"0503",
X"0165",
X"0319",
X"03b5",
X"01cc",
X"0572",
X"0197",
X"0127",
X"03e5",
X"032b",
X"0693",
X"0331",
X"02c0",
X"0410",
X"007d",
X"0277",
X"0081",
X"0102",
X"052b",
X"01d3",
X"0446",
X"0435",
X"00fc",
X"0181",
X"0102",
X"02be",
X"0455",
X"01bf",
X"0164",
X"00e4",
X"040b",
X"024f",
X"03c1",
X"02eb",
X"000b",
X"0332",
X"0606",
X"058a",
X"00c5",
X"0395",
X"00ae",
X"0338",
X"0179",
X"0475",
X"01f8",
X"02c9",
X"01b1",
X"04be",
X"02e6",
X"0212",
X"05d1",
X"039c",
X"0440",
X"029c",
X"02ba",
X"0117",
X"024c",
X"045c",
X"03e8",
X"012c",
X"019f",
X"031d",
X"0160",
X"0164",
X"0237",
X"05bf",
X"027d",
X"04c8",
X"035f",
X"00ca",
X"0020",
X"03bf",
X"0200",
X"0110",
X"01e2",
X"00a8",
X"007a",
X"0144",
X"0289",
X"057d",
X"0299",
X"0413",
X"03c0",
X"0348",
X"05c1",
X"06a8",
X"0549",
X"01de",
X"047b",
X"0327",
X"0394",
X"02ad",
X"04b8",
X"0035",
X"02ac",
X"01e9",
X"026e",
X"00e8",
X"0346",
X"026a",
X"02d6",
X"01ed",
X"0303",
X"0430",
X"0390",
X"01d8",
X"0168",
X"001e",
X"0424",
X"03b2",
X"032e",
X"03d6",
X"034b",
X"027f",
X"0228",
X"02fd",
X"00b8",
X"03a9",
X"01d6",
X"038e",
X"03b8",
X"009b",
X"00a6",
X"05f9",
X"0363",
X"0389",
X"0297",
X"01be",
X"0412",
X"01c0",
X"02d8",
X"0409",
X"03a8",
X"0230",
X"023d",
X"0354",
X"0261",
X"049c",
X"03da",
X"045f",
X"0390",
X"012f",
X"0420",
X"0269",
X"0015",
X"012b",
X"0166",
X"03dc",
X"04c1",
X"03d8",
X"0710",
X"0068",
X"0357",
X"043b",
X"01e5",
X"02bc",
X"0110",
X"03c1",
X"0152",
X"0303",
X"01b7",
X"0412",
X"01c7",
X"0230",
X"0194",
X"034a",
X"0438",
X"0135",
X"0346",
X"0074",
X"03a9",
X"03a3",
X"03b5",
X"0329",
X"02f2",
X"0310",
X"0253",
X"00bb",
X"02cb",
X"034a",
X"0027",
X"013d",
X"0282",
X"027f",
X"03a8",
X"01f4",
X"012e",
X"01d2",
X"00c8",
X"0257",
X"01be",
X"019c",
X"057f",
X"0175",
X"0405",
X"016e",
X"0276",
X"04a2",
X"02b0",
X"02bc",
X"0410",
X"0489",
X"014e",
X"0494",
X"05cf",
X"03d0",
X"0003",
X"02b6",
X"048f",
X"0054",
X"0350",
X"0075",
X"02eb",
X"0263",
X"0323",
X"04ef",
X"0250",
X"0265",
X"0126",
X"01e6",
X"0207",
X"0240",
X"0255",
X"0282",
X"0656",
X"02aa",
X"035c",
X"05cf",
X"015f",
X"03e0",
X"0219",
X"0214",
X"00ee",
X"028f",
X"0388",
X"0091",
X"0271",
X"02fc",
X"0234",
X"0276",
X"0400",
X"0213",
X"04fe",
X"01d4",
X"0253",
X"0010",
X"0138",
X"0278",
X"0487",
X"0411",
X"00db",
X"0096",
X"0472",
X"03e3",
X"023d",
X"02ad",
X"0284",
X"021a",
X"01e8",
X"022d",
X"0416",
X"01f3",
X"0138",
X"0260",
X"03fd",
X"0280",
X"0253",
X"03fb",
X"003d",
X"005b",
X"046c",
X"0387",
X"005a",
X"0557",
X"00ee",
X"0343",
X"04f9",
X"02bf",
X"0282",
X"007a",
X"04b2",
X"05ee",
X"04a6",
X"0469",
X"00b5",
X"03fb",
X"0221",
X"0597",
X"0336",
X"038a",
X"0011",
X"0388",
X"0461",
X"01c3",
X"01d9",
X"009b",
X"0527",
X"004d",
X"017a",
X"0209",
X"0770",
X"005a",
X"0131",
X"03ca",
X"01bc",
X"0392",
X"0450",
X"01d4",
X"02ff",
X"02d6",
X"011c",
X"02cd",
X"0180",
X"0087",
X"0244",
X"002d",
X"0238",
X"030d",
X"0474",
X"0226",
X"017b",
X"03c3",
X"01be",
X"017a",
X"0371",
X"022e",
X"03a0",
X"03fa",
X"04e5",
X"0152",
X"0022",
X"02e7",
X"038e",
X"04a9",
X"0418",
X"03fc",
X"0327",
X"0340",
X"01ac",
X"00f7",
X"001a",
X"0264",
X"00f2",
X"0325",
X"02e2",
X"0201",
X"02a5",
X"03da",
X"0010",
X"033b",
X"04f6",
X"00da",
X"020f",
X"022c",
X"029e",
X"03de",
X"02d8",
X"0392",
X"0205",
X"03a6",
X"00a0",
X"0328",
X"0182",
X"07c9",
X"0051",
X"0310",
X"0281",
X"03f0",
X"0002",
X"047a",
X"02a2",
X"0435",
X"0307",
X"02e4",
X"0000",
X"050a",
X"0163",
X"030d",
X"0326",
X"0134",
X"041a",
X"0259",
X"02d2",
X"0493",
X"00f8",
X"0363",
X"03c3",
X"0070",
X"000e",
X"0316",
X"039a",
X"0307",
X"01d6",
X"0266",
X"0071",
X"02db",
X"05d6",
X"03ee",
X"047d",
X"0561",
X"03f2",
X"0241",
X"0271",
X"0577",
X"0197",
X"0458",
X"01dd",
X"03a3",
X"02c9",
X"044b",
X"02ef",
X"0339",
X"01bd",
X"041f",
X"0288",
X"013e",
X"0354",
X"021a",
X"0041",
X"0563",
X"02c8",
X"0411",
X"01ac",
X"0269",
X"05a4",
X"0308",
X"0636",
X"0574",
X"02e4",
X"0215",
X"015e",
X"01f0",
X"038c",
X"0138",
X"01d5",
X"0340",
X"00bb",
X"030d",
X"029e",
X"02c1",
X"01cb",
X"021e",
X"0067",
X"0256",
X"03e5",
X"0156",
X"02c7",
X"03ab",
X"0377",
X"02a5",
X"02a1",
X"02b5",
X"022b",
X"0233",
X"0290",
X"00e2",
X"007c",
X"028e",
X"021c",
X"03a7",
X"067b",
X"0378",
X"01f9",
X"0200",
X"047d",
X"0384",
X"0266",
X"03c0",
X"0296",
X"0420",
X"02ac",
X"0151",
X"0231",
X"05e3",
X"0383",
X"05de",
X"0468",
X"041f",
X"031b",
X"0380",
X"00ca",
X"04b7",
X"0366",
X"0103",
X"01ea",
16 434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
X"0420",
X"0391",
X"03b5",
X"048c",
X"0249",
X"040d",
X"0461",
X"02ce",
X"00c0",
X"0335",
X"025a",
X"0514",
X"05f5",
X"0547",
X"03a0",
X"045d",
X"0b00",
X"0fc7",
X"4630",
X"6c6f",
X"12f7",
X"079e",
X"060b",
X"0589",
X"04af",
X"0451",
X"057f",
X"04d5",
X"037c",
X"0486",
X"02f4",
X"0255",
X"035d",
X"02f6",
X"0306",
X"01a7",
X"044c",
X"02a9",
X"04ce",
X"0417",
X"0411",
X"029c",
X"028f",
X"0334",
X"0176",
X"03bd",
X"02ad",
X"019a",
X"0382",
X"01a6",
X"004a",
X"0615",
X"00fd",
X"05a7",
X"00da",
X"001d",
X"0373",
X"0525",
X"0350",
X"00cc",
X"0258",
X"0429",
X"03a2",
X"05fb",
X"02a9",
X"0146",
X"02ff",
X"01e7",
X"00d7",
X"022d",
X"012c",
X"04b4",
X"03c2",
X"0424",
X"02c8",
X"021e",
X"053d",
X"00ab",
X"0101",
X"0361",
X"02e6",
X"00fe",
X"0450",
X"02e5",
X"0367",
X"0470",
X"0244",
X"0605",
X"0a55",
X"09d9",
X"14aa",
X"5b63",
X"52c1",
X"110a",
X"096a",
X"048d",
X"0671",
X"0145",
X"0372",
X"035c",
X"0353",
X"0313",
X"012e",
X"029b",
X"03cb",
X"038c",
X"030e",
X"006b",
X"0520",
X"01fc",
X"01ae",
X"0213",
X"01bd",
X"01dd",
X"03a3",
X"0528",
X"044a",
X"0238",
X"0337",
X"04e9",
X"0267",
X"0543",
X"03a5",
X"0194",
X"02dd",
X"0016",
X"00c8",
X"044b",
X"00b5",
X"0355",
X"0323",
X"005c",
X"05ad",
X"03ab",
X"02a4",
X"00b1",
X"056b",
X"043d",
X"0131",
X"03a2",
X"03ba",
X"01b8",
X"030f",
X"024b",
X"005f",
X"02c0",
X"0084",
X"02af",
X"0277",
X"02b5",
X"0239",
X"0234",
X"039a",
X"01ab",
X"030e",
X"011f",
X"020d",
X"0432",
X"04bd",
X"01d7",
X"0560",
X"0637",
X"09e1",
X"1683",
X"7638",
X"3d41",
X"107b",
X"08a8",
X"04c8",
X"0551",
X"0430",
X"03fb",
X"0458",
X"007d",
X"03c6",
X"028f",
X"0302",
X"02fa",
X"045d",
X"0450",
X"01e2",
X"0522",
X"0103",
X"021a",
X"0276",
X"02cf",
X"013e",
X"005f",
X"02cf",
X"0319",
X"019d",
X"05c2",
X"03dd",
X"0237",
X"0194",
X"031b",
X"037a",
X"01fb",
X"0139",
X"0135",
X"0139",
X"0064",
X"020d",
X"0135",
X"00dd",
X"0143",
X"0044",
X"02a0",
X"0489",
X"008b",
X"0153",
X"04c0",
X"0245",
X"01b7",
X"040a",
X"0442",
X"01e5",
X"031f",
X"036d",
X"036f",
X"015b",
X"021d",
X"04fe",
X"00ae",
X"039a",
X"039a",
X"0176",
X"0007",
X"0266",
X"00fc",
X"0367",
X"0346",
X"078d",
X"0448",
X"0821",
X"0a26",
X"19c6",
X"9ab7",
X"31d2",
X"0e88",
X"07ae",
X"06b5",
X"0352",
X"0688",
X"0292",
X"0336",
X"058f",
X"0278",
X"0019",
X"036c",
X"03e5",
X"03a6",
X"0011",
X"022c",
X"029b",
X"0342",
X"0094",
X"02a1",
X"033e",
X"04c9",
X"0063",
X"0260",
X"032a",
X"033a",
X"03fc",
X"0221",
X"0243",
X"041f",
X"01f9",
X"023b",
X"020b",
X"0038",
X"0513",
X"016a",
X"0195",
X"0426",
X"02b7",
X"04de",
X"00c7",
X"0354",
X"0189",
X"02db",
X"00a6",
X"0021",
X"0097",
X"0151",
X"01d6",
X"029f",
X"014d",
X"0225",
X"02c8",
X"0559",
X"026d",
X"019f",
X"0184",
X"03c6",
X"00cc",
X"04ee",
X"022b",
X"05d0",
X"0292",
X"0452",
X"059c",
X"0416",
X"0036",
X"01cd",
X"06c0",
X"0654",
X"08fc",
X"1e77",
X"b64a",
X"28dd",
X"0b8f",
X"085a",
X"05cb",
X"0478",
X"04b7",
X"00dc",
X"037f",
X"00f3",
X"0026",
X"002e",
X"0411",
X"0371",
X"0219",
X"03d3",
X"03e2",
X"00d7",
X"04e8",
X"00a6",
X"01d7",
X"01d3",
X"03b2",
X"045e",
X"02a5",
X"03c2",
X"01c5",
X"0317",
X"0278",
X"0165",
X"03ac",
X"006d",
X"0577",
X"00b6",
X"031c",
X"0236",
X"0301",
X"02a4",
X"037e",
X"04d9",
X"01b9",
X"0453",
X"0236",
X"0099",
X"0071",
X"0329",
X"0036",
X"009e",
X"023d",
X"01fd",
X"0648",
X"020e",
X"0352",
X"0460",
X"0446",
X"0274",
X"009c",
X"006b",
X"04b8",
X"029a",
X"062b",
X"012f",
X"01a7",
X"04bb",
X"021e",
X"0352",
X"050a",
X"0309",
X"0577",
X"0567",
X"0bb6",
X"0b64",
X"21e6",
X"c547",
X"21a2",
X"0a52",
X"069b",
X"0519",
X"030b",
X"07fa",
X"0319",
X"02cd",
X"03f8",
X"03f7",
X"0010",
X"0213",
X"02c8",
X"03f5",
X"03b2",
X"01c3",
X"013e",
X"0444",
X"0158",
X"0364",
X"043d",
X"0026",
X"0160",
X"00fd",
X"0425",
X"0197",
X"047b",
X"00f4",
X"03eb",
X"0503",
X"0387",
X"0341",
X"04ea",
X"03fd",
X"0392",
X"010c",
X"0129",
X"03ad",
X"0087",
X"044a",
X"03cf",
X"02a6",
X"01fd",
X"01d6",
X"0508",
X"04f0",
X"0113",
X"0276",
X"0144",
X"0022",
X"011a",
X"038e",
X"0187",
X"003e",
X"028d",
X"01dd",
X"02d3",
X"01df",
X"01dc",
X"0199",
X"03b4",
X"023e",
X"01bb",
X"026a",
X"022b",
X"0326",
X"0381",
X"04fd",
X"0297",
X"0899",
X"0aba",
X"270d",
X"ae41",
X"19a0",
X"09ce",
X"094c",
X"06fa",
X"04f4",
X"0300",
X"0130",
X"024b",
X"03e9",
X"0367",
X"02e7",
X"066f",
X"0573",
X"0438",
X"03ee",
X"02ea",
X"00b3",
X"055b",
X"022a",
X"0285",
X"0262",
X"0515",
X"0527",
X"03c9",
X"01b1",
X"0231",
X"01f7",
X"0164",
X"033b",
X"0097",
X"02ba",
X"009e",
X"02d0",
X"026e",
X"024f",
X"01bf",
X"00bc",
X"0407",
X"029a",
X"02a2",
X"03a3",
X"037d",
X"04cb",
X"01da",
X"0094",
X"036b",
X"0061",
X"0241",
X"037f",
X"00bc",
X"0209",
X"026a",
X"0403",
X"0381",
X"058a",
X"0338",
X"01d5",
X"05a8",
X"0440",
X"02d5",
X"02d4",
X"043f",
X"069d",
X"030e",
X"03ca",
X"0326",
X"07d2",
X"02b8",
X"052e",
X"050b",
X"0e64",
X"34ff",
X"8dfa",
X"190f",
X"09f2",
X"0724",
X"040b",
X"0660",
X"034a",
X"045e",
X"0582",
X"048c",
X"02a5",
X"0177",
X"02a7",
X"03d5",
X"0501",
X"016d",
X"01db",
X"0192",
X"00a1",
X"03cd",
X"0192",
X"02a7",
X"037a",
X"031a",
X"00d0",
X"01d5",
X"038c",
X"0266",
X"0448",
X"01d2",
X"028a",
X"0416",
X"021a",
X"0249",
X"03af",
X"03b0",
X"04e8",
X"021f",
X"0106",
X"03fe",
X"03ac",
X"017a",
X"0502",
X"022a",
X"04ce",
X"0594",
X"0080",
X"045c",
X"0798",
X"028d",
X"0249",
X"0285",
X"0250",
X"012f",
X"0368",
17 507 X"05ed", X"028d", X"0530", X"04db", X"037d", X"01d6", X"03f9", X"0009",
508 X"0509", X"029d", X"00da", X"001d", X"0205", X"04a5", X"02cf", X"023f",
509 X"020a", X"01c2", X"01ad", X"02c6", X"02b8", X"0150", X"00f7", X"0178",
510 X"0266", X"0442", X"0163", X"01e5", X"0280", X"0192", X"01ff", X"0040",
511 X"01d6", X"0209", X"0307", X"0186", X"037e", X"01db", X"01df", X"029f",
512 X"0370", X"03e1", X"00e6", X"0313", X"003f", X"0542", X"01c6", X"022c",
513 X"0275", X"0417", X"003f", X"03b6", X"023f", X"068d", X"02a8", X"036a",
514 X"02b2", X"013f", X"01f3", X"03a9", X"02db", X"04ca", X"03ce", X"02ca",
515 X"02b9", X"0184", X"02c2", X"01fb", X"011e", X"021b", X"04bf", X"02e7",
516 X"0212", X"046d", X"01b2", X"03a7", X"018c", X"0434", X"0228", X"05a8",
517 X"00f9", X"01e8", X"01da", X"02fb", X"014b", X"0430", X"0328", X"064e",
518 X"02c0", X"04e0", X"01cc", X"01dd", X"02bb", X"004d", X"01d0", X"06be",
519 X"01b6", X"0084", X"0519", X"0326", X"024d", X"04ba", X"02df", X"032e",
520 X"0406", X"0298", X"00d5", X"030a", X"012f", X"04cd", X"0196", X"0334",
521 X"00ab", X"019e", X"059d", X"049e", X"001a", X"0289", X"0421", X"0341",
522 X"0124", X"0348", X"0038", X"0102", X"0351", X"039e", X"00a8", X"01ea",
523 X"012b", X"01a6", X"02ec", X"03d6", X"037a", X"0312", X"048d", X"0336",
524 X"02a6", X"0508", X"019f", X"01b5", X"0188", X"0529", X"026f", X"031e",
525 X"02f8", X"0190", X"0059", X"02b1", X"0369", X"0012", X"0555", X"0386",
526 X"0130", X"0357", X"02ab", X"0156", X"0149", X"0380", X"0290", X"028a",
527 X"0155", X"004e", X"01b1", X"016f", X"0117", X"00ef", X"0361", X"00a1",
528 X"054e", X"00d2", X"01b2", X"03ee", X"02d2", X"017b", X"04b4", X"00a7",
529 X"02a8", X"0236", X"0234", X"0453", X"02eb", X"0302", X"0372", X"0221",
530 X"022e", X"04d3", X"0244", X"0538", X"00ad", X"0324", X"02b1", X"0235",
531 X"00c8", X"0460", X"0404", X"030f", X"018b", X"025b", X"0457", X"0474",
532 X"0059", X"0142", X"02b7", X"034e", X"02eb", X"037f", X"0053", X"041e",
533 X"03c4", X"0319", X"01ad", X"00f7", X"0509", X"024b", X"0245", X"0357",
534 X"0238", X"04e0", X"03c2", X"041e", X"0069", X"0211", X"0295", X"05e9",
535 X"0169", X"013a", X"01d4", X"0306", X"0056", X"0036", X"041c", X"0164",
536 X"00df", X"034d", X"01d5", X"015b", X"037e", X"03d8", X"047c", X"03c9",
537 X"05d2", X"0215", X"0008", X"007e", X"0397", X"0193", X"01cd", X"01f0"
538 );
539
540 signal z0, z1, z2, z3, z4, sv : unsigned(13 downto 0) := (others => '0'); -fir filter on input
541
542 signal bram_addr, bram_addr_reg : unsigned(11 downto 0):=(others => '0'); -for BRAM inference
543 signal bram_data : std_logic_vector(15 downto 0):= (others => '0');
544
545 begin
546
547 fir_proc:
548 process(adc_clk) is begin
549
if rising_edge(adc_clk) then
550 -if sys_rst = '1' then
551
-- z1 <= (others => '0');
552
-- z2 <= (others => '0');
553
-- z3 <= (others => '0');
554
-- z4 <= (others => '0');
555 -else
556
z1 <= z0;
557
z2 <= z1;
558
z3 <= z2;
559
z4 <= z3;
560 -end if;
561
end if;
562 end process;
563
564 z0 <= "00"&unsigned(dac_data(23 downto 12));-- take top 12 bits
565 sv <= z1+z2+z3+z4;
566 bram_addr <= sv(13 downto 2); -- 4th order FIR v1/4 + v2/4 + v3/4 + v4/4
567
568
569 read_bram:
570 process(dac_clk) is begin
571
if rising_edge(dac_clk) then
572
bram_addr_reg <= bram_addr;
573
end if;
574 end process;
575 bram_data <= EMULATOR_DATA(to_integer(bram_addr_reg));
576
577 adc_data <= bram_data;
18 578
579
580 end architecture black_box_emulator;
1.1.6 FSM.vhdl
1 library IEEE;
2 use IEEE.STD_LOGIC_1164.ALL;
3 use IEEE.STD_LOGIC_UNSIGNED.ALL;
4
5 -- Uncomment the following library declaration if using
6 -- arithmetic functions with Signed or Unsigned values
7 --use IEEE.NUMERIC_STD.ALL;
8
9 -- Uncomment the following library declaration if instantiating
10 -- any Xilinx primitives in this code.
11 --library UNISIM;
12 --use UNISIM.VComponents.all;
13
14 entity FSM is
15 PORT(
16
clk
: in
STD_LOGIC;
17
reset
: in
STD_LOGIC;
18
ipm_fifo_empty
: in
STD_LOGIC;
19
cmd
: in
STD_LOGIC_VECTOR(7 downto 0);
20
scan_min
: in
STD_LOGIC_VECTOR(31 downto 0);
21
scan_max
: in STD_LOGIC_VECTOR(31 downto 0);
22
scan_step
: in STD_LOGIC_VECTOR(31 downto 0);
23
smp_step
: in STD_LOGIC_VECTOR(31 downto 0);
24
scan_pos
: out STD_LOGIC_VECTOR(31 downto 0);
25
status
: out STD_LOGIC_VECTOR(7 downto 0);
26
sample_en
: out STD_LOGIC;
27
cmd_reg_reset
: out STD_LOGIC);
28 end FSM;
29
30 architecture Behavioral of FSM is
31 TYPE state IS (ST_WAIT,ST_INIT,ST_CHK,ST_ERR_PAR,ST_ERR_MEM,ST_ERR_SCAN,ST_PRESCAN,ST_SCAN,ST
_FIFO_WAIT);
32 signal cur_state,next_state : state;
33
34 TYPE status_array_type IS ARRAY(state) of STD_LOGIC_VECTOR(7 downto 0); -array of potential statuses
35 constant state_to_status : status_array_type :=(
36
ST_WAIT
=>
x"00",
37
ST_INIT
=>
x"43",
38
ST_CHK
=>
x"54",
39
ST_ERR_PAR =>
x"60",
40
ST_ERR_MEM =>
x"62",
41
ST_ERR_SCAN =>
x"61",
42
ST_PRESCAN =>
x"54",
43
ST_SCAN
=>
x"55",
44
ST_FIFO_WAIT=>
x"56"
45 );
46
47 --TEMP SIGNALS
48 signal track_sps,scan_diff, t_sps,t_scan_pos : STD_LOGIC_VECTOR(31 downto 0):=(others=>'0');
49 signal check_nsamp1, check_nsamp2 : STD_LOGIC_VECTOR(63 downto 0):=(others=>'0');
50 --random constants to take care of
51 constant SCAN_BEGIN
: STD_LOGIC_VECTOR(7 downto 0) := x"53";
52 constant SCAN_ABORT_CMD
: STD_LOGIC_VECTOR(7 downto 0) := x"00";
53 constant SCAN_PRECOLL
: STD_LOGIC_VECTOR(7 downto 0) := x"54";
54 constant SCAN_COLL
: STD_LOGIC_VECTOR(7 downto 0) := x"55";
55 constant SCAN_POSTCOLL
: STD_LOGIC_VECTOR(7 downto 0) := x"56";
56 constant ERR_BADPAR
: STD_LOGIC_VECTOR(7 downto 0) := x"60";
57 constant ERR_FAULTSCAN
: STD_LOGIC_VECTOR(7 downto 0) := x"61";
58 constant ERR_NOMEM
: STD_LOGIC_VECTOR(7 downto 0) := x"61";
59 constant MAXMEM
: STD_LOGIC_VECTOR(31 downto 0) := x"01000000";
60
61 begin
19 62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
--heavy_math: process(clk) is
--begin
-- if rising_edge(clk) then
scan_diff <= scan_max - scan_min;
check_nsamp1 <= ((scan_max - scan_min)*smp_step) ;
check_nsamp2 <= (MAXMEM*scan_step);
-- end if;
--end process;
--process for moore based output
mealy_fsm:process(clk,reset)
begin
if(reset = '1')then
cur_state <= ST_WAIT;
elsif(rising_edge(clk))then
cmd_reg_reset <= '0';
sample_en <= '0';
CASE cur_state IS
--wait until UIM has asked for values
WHEN ST_WAIT =>
sample_en <= '0'; --don't write values from the FIFO
t_scan_pos <=x"00000000";
if(cmd = SCAN_BEGIN) then
next_state <= ST_INIT;
else
next_state <= cur_state;
end if;
--load values into registers
WHEN ST_INIT =>
--fpga_ready <= '1'; --write values to FIFO
next_state <= ST_CHK;
--check for correct parameters
WHEN ST_CHK =>
--if(ipm_fifo_empty = '1')then --is FIFO empty?
--next_state <= ST_FIFO_WAIT;
if(scan_min >= scan_max) then -- failing here?
next_state <= ST_ERR_PAR;
elsif(scan_step > scan_diff) then -- failing here?
next_state <= ST_ERR_PAR;
--elsif ( check_nsamp1 < check_nsamp2 )then
-- next_state <= ST_ERR_MEM;
else
next_state <= ST_PRESCAN;
end if;
--scan the minimum
WHEN ST_PRESCAN =>
--fpga_ready <= '1'; --start writing values to FIFO
t_scan_pos <= scan_min;
next_state <= ST_SCAN;
track_sps <= (others=>'0');
--full scanning function
WHEN ST_SCAN =>
if(cmd = SCAN_ABORT_CMD) then
next_state <= ST_ERR_SCAN;
else
sample_en <= '1'; --begin writing values from FIFO
if (track_sps >= smp_step) then
track_sps <= (others=>'0');
t_scan_pos <= t_scan_pos + scan_step;
else
track_sps <= track_sps + x"00000001"; -- increment to SPS value
end if;
if(t_scan_pos > scan_max) then
--sample_en <= '0';
next_state <= ST_FIFO_WAIT;
20 135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
else
--sample_en <= '0';
next_state <= cur_state;
end if;
end if;
--Wait until FIFO has
WHEN ST_FIFO_WAIT =>
if(ipm_fifo_empty
cmd_reg_reset
next_state <=
else
next_state <=
end if;
finished being read
= '1') then
<= '1';
ST_WAIT;
cur_state;
--invalid scan input state
WHEN ST_ERR_PAR =>
if(cmd = x"00") then
next_state <= ST_WAIT;
else
next_state <= cur_state; --I think this is wrong (infinite loop)
end if;
--no memory available
WHEN ST_ERR_MEM =>
if(cmd = ERR_NOMEM) then
next_state <= ST_WAIT;
else
next_state <= cur_state;
end if;
--Something went wrong with the scanning
WHEN ST_ERR_SCAN =>
if(cmd = ERR_FAULTSCAN) then
next_state <= ST_WAIT;
else
next_state <= cur_state;
end if;
END CASE;
cur_state <= next_state;
end if;
END process;
scan_pos <= t_scan_pos;
status <= state_to_status(cur_state);
end Behavioral;
1.1.7 FSM2.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity FSM2 is
PORT(
clk
reset
ipm_fifo_empty
: in
: in
: in
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
21 19
cmd
: in
STD_LOGIC_VECTOR(7 downto 0);
20
scan_min
: in
STD_LOGIC_VECTOR(31 downto 0);
21
scan_max
: in STD_LOGIC_VECTOR(31 downto 0);
22
scan_step
: in STD_LOGIC_VECTOR(31 downto 0);
23
smp_step
: in STD_LOGIC_VECTOR(31 downto 0);
24
scan_start
: in
STD_LOGIC_VECTOR(31 downto 0);
25
scan_stop
: in
STD_LOGIC_VECTOR(31 downto 0);
26
overview_scan_step
: in STD_LOGIC_VECTOR(31 downto 0);
27
scan_pos
: out STD_LOGIC_VECTOR(31 downto 0);
28
status
: out STD_LOGIC_VECTOR(7 downto 0);
29
overview_en
: out STD_LOGIC;
30
sample_en
: out STD_LOGIC;
31
som_status
: out STD_LOGIC;
32
cmd_reg_reset
: out STD_LOGIC);
33 end FSM2;
34
35 architecture Behavioral of FSM2 is
36 TYPE state IS (ST_WAIT,ST_INIT,ST_CHK,ST_ERR_PAR,ST_ERR_MEM,ST_ERR_SCAN,ST_PRESCAN,ST_SCAN,ST
_FIFO_WAIT);
37 signal
38
--cur_state,
39
next_state : state;
40 alias cur_state : state is next_state ;
41
42 TYPE status_array_type IS ARRAY(state) of STD_LOGIC_VECTOR(7 downto 0); -array of potential statuses
43 constant state_to_status : status_array_type :=(
44
ST_WAIT
=>
x"00",
45
ST_INIT
=>
x"43",
46
ST_CHK
=>
x"54",
47
ST_ERR_PAR =>
x"60",
48
ST_ERR_MEM =>
x"62",
49
ST_ERR_SCAN =>
x"61",
50
ST_PRESCAN =>
x"54",
51
ST_SCAN
=>
x"55",
52
ST_FIFO_WAIT=>
x"56"
53 );
54
55 --TEMP SIGNALS
56 signal track_sps,track_oss, t_sps,t_scan_pos
: STD_LOGIC_VECTOR(31 downto 0);
57 --signal scan_diff
: STD_LOGIC_VECTOR(31 downto 0);
58 signal t_sample_en,t_overview_en
: STD_LOGIC;
59 -signal check_nsamp1, check_nsamp2
: STD_LOGIC_VECTOR(63 downto 0)
:=(others=>'0');
60 --random constants to take care of
61 constant SCAN_BEGIN
: STD_LOGIC_VECTOR(7 downto 0) := x"53";
62 constant SCAN_ABORT_CMD
: STD_LOGIC_VECTOR(7 downto 0) := x"00";
63 constant SCAN_PRECOLL
: STD_LOGIC_VECTOR(7 downto 0) := x"54";
64 constant SCAN_COLL
: STD_LOGIC_VECTOR(7 downto 0) := x"55";
65 constant SCAN_POSTCOLL
: STD_LOGIC_VECTOR(7 downto 0) := x"56";
66 constant ERR_BADPAR
: STD_LOGIC_VECTOR(7 downto 0) := x"60";
67 constant ERR_FAULTSCAN
: STD_LOGIC_VECTOR(7 downto 0) := x"61";
68 constant ERR_NOMEM
: STD_LOGIC_VECTOR(7 downto 0) := x"62";
69 constant MAXMEM
: STD_LOGIC_VECTOR(31 downto 0) := x"01000000";
70
71 begin
72
73
74 --process for moore based output
75 mealy_fsm:process(clk,reset)
76 begin
77
if(reset = '1')then
78
cur_state <= ST_WAIT;
79
elsif(rising_edge(clk))then
80
--som_status <= '1';
81
cmd_reg_reset <= '0';
82
83
CASE cur_state IS
84
85
--wait until UIM has asked for values
86
WHEN ST_WAIT =>
87
t_scan_pos <= (others=>'0');
22 88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
track_sps
track_oss
<= (others=>'0');
<= (others=>'0');
if(cmd = SCAN_BEGIN) then
next_state <= ST_INIT;
else
next_state <= ST_WAIT;
end if;
--load values into registers
WHEN ST_INIT =>
t_scan_pos <= (others=>'0');
track_sps <= (others=>'0');
track_oss <= (others=>'0');
next_state
<= ST_CHK;
--check for correct parameters
WHEN ST_CHK =>
t_scan_pos <= (others=>'0');
track_sps <= (others=>'0');
track_oss <= (others=>'0');
--if(ipm_fifo_empty = '1')then --is FIFO empty?
--next_state <= ST_FIFO_WAIT;
--if(scan_min >= scan_max) then -- failing here?
-- next_state <= ST_ERR_PAR;
--elsif(scan_step > scan_diff) then -- failing here?
-- next_state <= ST_ERR_PAR;
--elsif ( check_nsamp1 < check_nsamp2 )then
-- next_state <= ST_ERR_MEM;
--else
next_state <= ST_PRESCAN;
--end if;
--scan the minimum
WHEN ST_PRESCAN =>
t_scan_pos <= scan_start;
next_state <= ST_SCAN;
track_sps
track_oss
<= (others=>'0');
<= (others=>'0');
--full scanning function
WHEN ST_SCAN =>
--som_status <= '0';
t_scan_pos <= t_scan_pos + scan_step;
if(t_sample_en='1')then
track_sps <= (others=>'0');
else
track_sps <= track_sps + 1;
end if;
if(t_overview_en ='1')then
track_oss <= (others=>'0');
else
track_oss <= track_oss + 1;
end if;
if(cmd = SCAN_ABORT_CMD) then
next_state <= ST_ERR_SCAN;
elsif
(t_scan_pos > scan_stop) then
next_state <= ST_FIFO_WAIT;
else
next_state <= ST_SCAN;
end if;
--Wait until FIFO
WHEN ST_FIFO_WAIT
t_scan_pos <=
track_sps <=
track_oss <=
has finished being read
=>
(others=>'0');
(others=>'0');
(others=>'0');
23 161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
if(ipm_fifo_empty
cmd_reg_reset
next_state <=
else
next_state <=
end if;
= '1') then
<= '1';
ST_WAIT;
ST_FIFO_WAIT;
--invalid scan input state
WHEN ST_ERR_PAR =>
t_scan_pos <= (others=>'0');
track_sps <= (others=>'0');
track_oss <= (others=>'0');
if(cmd = x"00") then
next_state <= ST_WAIT;
else
next_state <= ST_ERR_PAR;
end if;
--no memory available
WHEN ST_ERR_MEM =>
t_scan_pos <= (others=>'0');
track_sps <= (others=>'0');
track_oss <= (others=>'0');
if(cmd = ERR_NOMEM) then
next_state <= ST_WAIT;
else
next_state <= ST_ERR_MEM;
end if;
--Something went wrong with the scanning
WHEN ST_ERR_SCAN =>
t_scan_pos <= (others=>'0');
track_sps <= (others=>'0');
track_oss <= (others=>'0');
if(cmd = ERR_FAULTSCAN) then
next_state <= ST_WAIT;
else
next_state <= ST_ERR_SCAN;
end if;
END CASE;
-- cur_state <= next_state;
end if;
END process;
t_sample_en <= '1' when ((t_scan_pos > scan_min) AND
(t_scan_pos < scan_max) AND
(cur_state = ST_SCAN) AND
(track_sps >= smp_step))
else '0';
t_overview_en <= '1' when ((t_scan_pos > scan_start) AND
(t_scan_pos < scan_stop) AND
(cur_state = ST_SCAN) AND
(track_oss >= overview_scan_step))
else '0';
sample_en <= t_sample_en;
overview_en <= t_overview_en;
scan_pos <= t_scan_pos;
status <= state_to_status(cur_state);
end Behavioral;
1.1.8 ipm_fifo.vhdl
1
2
3
4
5
6
--------------------------------------------------------------------------------This file is owned and controlled by Xilinx and must be used solely
--for design, simulation, implementation and creation of design files
--limited to Xilinx devices or technologies. Use with non-Xilinx
--devices or technologies is expressly prohibited and immediately
--terminates your license.
--
24 7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
---XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY
--FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
--PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE
--IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS
--MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY
--CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY
--RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY
--DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
--IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
--REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
--INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE.
----Xilinx products are not intended for use in life support appliances,
--devices, or systems. Use in such applications are expressly
--prohibited.
----(c) Copyright 1995-2012 Xilinx, Inc.
--All rights reserved.
----------------------------------------------------------------------------------------------------------------------------------------------------------------- You must compile the wrapper file IPM_FIFO.vhd when simulating
-- the core, IPM_FIFO. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY IPM_FIFO IS
PORT (
rst : IN STD_LOGIC;
wr_clk : IN STD_LOGIC;
rd_clk : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
full : OUT STD_LOGIC;
overflow : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
rd_data_count : OUT STD_LOGIC_VECTOR(10 DOWNTO 0)
);
END IPM_FIFO;
ARCHITECTURE IPM_FIFO_a OF IPM_FIFO IS
-- synthesis translate_off
COMPONENT wrapped_IPM_FIFO
PORT (
rst : IN STD_LOGIC;
wr_clk : IN STD_LOGIC;
rd_clk : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
full : OUT STD_LOGIC;
overflow : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
rd_data_count : OUT STD_LOGIC_VECTOR(10 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_IPM_FIFO USE ENTITY XilinxCoreLib.fifo_generator_v8_3(behavioral)
GENERIC MAP (
25 80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
c_add_ngc_constraint => 0,
c_application_type_axis => 0,
c_application_type_rach => 0,
c_application_type_rdch => 0,
c_application_type_wach => 0,
c_application_type_wdch => 0,
c_application_type_wrch => 0,
c_axi_addr_width => 32,
c_axi_aruser_width => 1,
c_axi_awuser_width => 1,
c_axi_buser_width => 1,
c_axi_data_width => 64,
c_axi_id_width => 4,
c_axi_ruser_width => 1,
c_axi_type => 0,
c_axi_wuser_width => 1,
c_axis_tdata_width => 64,
c_axis_tdest_width => 4,
c_axis_tid_width => 8,
c_axis_tkeep_width => 4,
c_axis_tstrb_width => 4,
c_axis_tuser_width => 4,
c_axis_type => 0,
c_common_clock => 0,
c_count_type => 0,
c_data_count_width => 13,
c_default_value => "BlankString",
c_din_width => 64,
c_din_width_axis => 1,
c_din_width_rach => 32,
c_din_width_rdch => 64,
c_din_width_wach => 32,
c_din_width_wdch => 64,
c_din_width_wrch => 2,
c_dout_rst_val => "0",
c_dout_width => 8,
c_enable_rlocs => 0,
c_enable_rst_sync => 1,
c_error_injection_type => 0,
c_error_injection_type_axis => 0,
c_error_injection_type_rach => 0,
c_error_injection_type_rdch => 0,
c_error_injection_type_wach => 0,
c_error_injection_type_wdch => 0,
c_error_injection_type_wrch => 0,
c_family => "spartan6",
c_full_flags_rst_val => 1,
c_has_almost_empty => 0,
c_has_almost_full => 0,
c_has_axi_aruser => 0,
c_has_axi_awuser => 0,
c_has_axi_buser => 0,
c_has_axi_rd_channel => 0,
c_has_axi_ruser => 0,
c_has_axi_wr_channel => 0,
c_has_axi_wuser => 0,
c_has_axis_tdata => 0,
c_has_axis_tdest => 0,
c_has_axis_tid => 0,
c_has_axis_tkeep => 0,
c_has_axis_tlast => 0,
c_has_axis_tready => 1,
c_has_axis_tstrb => 0,
c_has_axis_tuser => 0,
c_has_backup => 0,
c_has_data_count => 0,
c_has_data_counts_axis => 0,
c_has_data_counts_rach => 0,
c_has_data_counts_rdch => 0,
c_has_data_counts_wach => 0,
c_has_data_counts_wdch => 0,
c_has_data_counts_wrch => 0,
c_has_int_clk => 0,
26 153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
c_has_master_ce => 0,
c_has_meminit_file => 0,
c_has_overflow => 1,
c_has_prog_flags_axis => 0,
c_has_prog_flags_rach => 0,
c_has_prog_flags_rdch => 0,
c_has_prog_flags_wach => 0,
c_has_prog_flags_wdch => 0,
c_has_prog_flags_wrch => 0,
c_has_rd_data_count => 1,
c_has_rd_rst => 0,
c_has_rst => 1,
c_has_slave_ce => 0,
c_has_srst => 0,
c_has_underflow => 0,
c_has_valid => 0,
c_has_wr_ack => 0,
c_has_wr_data_count => 0,
c_has_wr_rst => 0,
c_implementation_type => 2,
c_implementation_type_axis => 1,
c_implementation_type_rach => 1,
c_implementation_type_rdch => 1,
c_implementation_type_wach => 1,
c_implementation_type_wdch => 1,
c_implementation_type_wrch => 1,
c_init_wr_pntr_val => 0,
c_interface_type => 0,
c_memory_type => 1,
c_mif_file_name => "BlankString",
c_msgon_val => 1,
c_optimization_mode => 0,
c_overflow_low => 0,
c_preload_latency => 0,
c_preload_regs => 1,
c_prim_fifo_type => "8kx4",
c_prog_empty_thresh_assert_val => 4,
c_prog_empty_thresh_assert_val_axis => 1022,
c_prog_empty_thresh_assert_val_rach => 1022,
c_prog_empty_thresh_assert_val_rdch => 1022,
c_prog_empty_thresh_assert_val_wach => 1022,
c_prog_empty_thresh_assert_val_wdch => 1022,
c_prog_empty_thresh_assert_val_wrch => 1022,
c_prog_empty_thresh_negate_val => 5,
c_prog_empty_type => 0,
c_prog_empty_type_axis => 5,
c_prog_empty_type_rach => 5,
c_prog_empty_type_rdch => 5,
c_prog_empty_type_wach => 5,
c_prog_empty_type_wdch => 5,
c_prog_empty_type_wrch => 5,
c_prog_full_thresh_assert_val => 8189,
c_prog_full_thresh_assert_val_axis => 1023,
c_prog_full_thresh_assert_val_rach => 1023,
c_prog_full_thresh_assert_val_rdch => 1023,
c_prog_full_thresh_assert_val_wach => 1023,
c_prog_full_thresh_assert_val_wdch => 1023,
c_prog_full_thresh_assert_val_wrch => 1023,
c_prog_full_thresh_negate_val => 8188,
c_prog_full_type => 0,
c_prog_full_type_axis => 5,
c_prog_full_type_rach => 5,
c_prog_full_type_rdch => 5,
c_prog_full_type_wach => 5,
c_prog_full_type_wdch => 5,
c_prog_full_type_wrch => 5,
c_rach_type => 0,
c_rd_data_count_width => 11,
c_rd_depth => 65536,
c_rd_freq => 1,
c_rd_pntr_width => 16,
c_rdch_type => 0,
c_reg_slice_mode_axis => 0,
27 226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
c_reg_slice_mode_rach => 0,
c_reg_slice_mode_rdch => 0,
c_reg_slice_mode_wach => 0,
c_reg_slice_mode_wdch => 0,
c_reg_slice_mode_wrch => 0,
c_underflow_low => 0,
c_use_common_overflow => 0,
c_use_common_underflow => 0,
c_use_default_settings => 0,
c_use_dout_rst => 1,
c_use_ecc => 0,
c_use_ecc_axis => 0,
c_use_ecc_rach => 0,
c_use_ecc_rdch => 0,
c_use_ecc_wach => 0,
c_use_ecc_wdch => 0,
c_use_ecc_wrch => 0,
c_use_embedded_reg => 0,
c_use_fifo16_flags => 0,
c_use_fwft_data_count => 1,
c_valid_low => 0,
c_wach_type => 0,
c_wdch_type => 0,
c_wr_ack_low => 0,
c_wr_data_count_width => 14,
c_wr_depth => 8192,
c_wr_depth_axis => 1024,
c_wr_depth_rach => 16,
c_wr_depth_rdch => 1024,
c_wr_depth_wach => 16,
c_wr_depth_wdch => 1024,
c_wr_depth_wrch => 16,
c_wr_freq => 1,
c_wr_pntr_width => 13,
c_wr_pntr_width_axis => 10,
c_wr_pntr_width_rach => 4,
c_wr_pntr_width_rdch => 10,
c_wr_pntr_width_wach => 4,
c_wr_pntr_width_wdch => 10,
c_wr_pntr_width_wrch => 4,
c_wr_response_latency => 1,
c_wrch_type => 0
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_IPM_FIFO
PORT MAP (
rst => rst,
wr_clk => wr_clk,
rd_clk => rd_clk,
din => din,
wr_en => wr_en,
rd_en => rd_en,
dout => dout,
full => full,
overflow => overflow,
empty => empty,
rd_data_count => rd_data_count
);
-- synthesis translate_on
END IPM_FIFO_a;
28 1.1.9 platform.ucf
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
Copyright (C) 2009-2012 Chris McClelland
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
#===============================================================================
# Standard interfaces
#===============================================================================
NET "clk"
LOC="L15";
NET "reset"
LOC="T15";
#===============================================================================
# USB interface
#===============================================================================
NET "fx2Clk_in"
LOC="C10" | IOSTANDARD=LVTTL;
# IFCLK
NET "fx2Addr_out<0>" LOC="A14" | IOSTANDARD=LVTTL;
# PA4/FIFOADR0
NET "fx2Addr_out<1>" LOC="B14" | IOSTANDARD=LVTTL;
# PA5/FIFOADR1
NET
NET
NET
NET
NET
NET
NET
NET
"fx2Data_io<0>"
"fx2Data_io<1>"
"fx2Data_io<2>"
"fx2Data_io<3>"
"fx2Data_io<4>"
"fx2Data_io<5>"
"fx2Data_io<6>"
"fx2Data_io<7>"
LOC="A2"
LOC="D6"
LOC="C6"
LOC="B3"
LOC="A3"
LOC="B4"
LOC="A4"
LOC="C5"
|
|
|
|
|
|
|
|
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
#
#
#
#
#
#
#
#
PB0/FD0
PB1/FD1
PB2/FD2
PB3/FD3
PB4/FD4
PB5/FD5
PB6/FD6
PB7/FD7
NET "fx2Read_out"
NET "fx2OE_out"
NET "fx2GotData_in"
LOC="F13"
LOC="A15"
LOC="C15"
| IOSTANDARD=LVTTL;
| IOSTANDARD=LVTTL;
| IOSTANDARD=LVTTL;
# RDY0/SLRD
# PA2/SLOE
# CTL2/FLAGC
NET "fx2Write_out"
NET "fx2GotRoom_in"
NET "fx2PktEnd_out"
LOC="E13"
LOC="A9"
LOC="C4"
| IOSTANDARD=LVTTL;
| IOSTANDARD=LVTTL;
| IOSTANDARD=LVTTL;
# RDY1/SLWR
# CTL1/FLAGB
# PA6/PKTEND
#===============================================================================
# On-board peripheral signals
#===============================================================================
NET "led_out<0>"
LOC="U18" | IOSTANDARD=LVTTL;
NET "led_out<1>"
LOC="M14" | IOSTANDARD=LVTTL;
NET "led_out<2>"
LOC="N14" | IOSTANDARD=LVTTL;
NET "led_out<3>"
LOC="L14" | IOSTANDARD=LVTTL;
NET "led_out<4>"
LOC="M13" | IOSTANDARD=LVTTL;
NET "led_out<5>"
LOC="D4"
| IOSTANDARD=LVTTL;
NET "led_out<6>"
LOC="P16" | IOSTANDARD=LVTTL;
NET "led_out<7>"
LOC="N12" | IOSTANDARD=LVTTL;
NET
NET
NET
NET
NET
NET
NET
NET
"sw_in<0>"
"sw_in<1>"
"sw_in<2>"
"sw_in<3>"
"sw_in<4>"
"sw_in<5>"
"sw_in<6>"
"sw_in<7>"
LOC="A10"
LOC="D14"
LOC="C14"
LOC="P15"
LOC="P12"
LOC="R5"
LOC="T5"
LOC="E4"
|
|
|
|
|
|
|
|
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
#
#
#
#
#
#
#
#
SW0
SW1
SW2
SW3
SW4
SW5
SW6
SW7
29 #===============================================================================
#VGA GAIN SIGNALS
#===============================================================================
NET "adg_dout"
LOC="R11"
| IOSTANDARD=LVTTL; #5
NET "adg_sclk"
LOC="T12"
| IOSTANDARD=LVTTL; #6
NET "adg_sync"
LOC="N10"
| IOSTANDARD=LVTTL; #7
NET "adg_reset"
LOC="M10"
| IOSTANDARD=LVTTL; #8
#===============================================================================
#SOM SIGNALS
#===============================================================================
PIN "clk_mngr_inst/clkout2_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;
#PIN "clk_mngr_inst/clkout3_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;
#For higher quality SOM
#NET "SOM_wclk" LOC="V9" | IOSTANDARD=LVTTL; # Bank = 2, Pin name = IO_L62P_D5 JA CLK_N - 1
#NET "SOM_bclk" LOC="T3" | IOSTANDARD=LVTTL; # Bank = 2, Pin name = IO_L62N_D6 JA D0_N - 2
#NET "som_start" LOC ="V4" | IOSTANDARD=LVTTL; #JA D0_P - 4
#NET "som_data" LOC="T9" | IOSTANDARD=LVTTL; # Bank = 2, Pin name = IO_L64N_D9, JA CLK_P - 3
#NET "som_error" LOC="T4" | IOSTANDARD=LVTTL;
#For low quality SOM
NET "som_data<0>" LOC
name = JA-D0_N
NET "som_data<1>" LOC
name = JA-D0_P
NET "som_data<2>" LOC
name = JA-D2_N
NET "som_data<3>" LOC
name = JA-D2_P
NET "som_data<4>"
LOC
name = JA-CLK_N
NET "som_data<5>"
LOC
name = JA-CLK_P
NET "som_data<6>" LOC
name = JA-D1_N
NET "som_data<7>" LOC
name = JA-D1_P
= "T3" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L62N_D6,
Sch
= "R3" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L62P_D5,
Sch
= "P6" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L64N_D9,
Sch
= "N5" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L64P_D8,
Sch
= "V9" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L32N_GCLK28, Sch
= "T9" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L32P_GCLK29, Sch
= "V4" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L63N,
Sch
= "T4" | IOSTANDARD=LVTTL; # Bank = 2,
Pin name = IO_L63P,
Sch
NET "hv_en"
LOC = "U16"| IOSTANDARD=LVTTL;
#===============================================================================
#IPM SIGNALS
#===============================================================================
NET "IPM_clk_out" LOC="R10" | IOSTANDARD=LVTTL;
NET "IPM_clk_in" LOC="U10" | IOSTANDARD=LVTTL;
#NET "IPM_clk_in" CLOCK_DEDICATED_ROUTE=FALSE;
## onboard VHDCI
#IPM
IO
#0 BB1-14
VHCDI
FPGA
25 IO14-P U8
NET "IPM_Data<0>" LOC =
Sch name = EXP-IO14_P
#1 BB1-13 23 IO13-P M8
UCF
"U8"|
IOSTANDARD=LVTTL;
NET "IPM_Data<1>" LOC = "M8"|
Sch name = EXP-IO13_P
#2 BB2-28 59 IO14-N V8
IOSTANDARD=LVTTL;
NET "IPM_Data<2>" LOC
Sch name = EXP-IO14_N
#3 BB2-27 57 IO13-N
=
"V8"|
IOSTANDARD=LVTTL;
#
#
Bank
Bank
Bank
=
=
=
2,
2,
2,
Pin
Pin
Pin
name
name
name
=
=
=
IO_L41P,
*IO_L40P,
IO_L41N_VREF,
N8
NET "IPM_Data<3>" LOC = "N8"|
Sch name = EXP-IO13_N
#4 BB2-26 56 IO12-N T8
IOSTANDARD=LVTTL;
NET "IPM_Data<4>" LOC = "T8"| IOSTANDARD=LVTTL;
Sch name = EXP-IO12_N
#5 BB2-25 54 IO11-N V10
NET "IPM_Data<5>" LOC = "V10"| IOSTANDARD=LVTTL;
Sch name = EXP-IO11_N
#6 BB2-24 49 IO10-N T10
#
#
Bank
# Bank = 2,
# Bank = 2,
=
2,
Pin
name
=
*IO_L40N,
Pin name = IO_L31N_GCLK30_D15,
Pin name = IO_L30N_GCLK0_USERCCLK,
30 NET "IPM_Data<6>"
LOC = "T10"| IOSTANDARD=LVTTL;
Sch name = EXP-IO10_N
#7 BB2-23 47 IO9-N
V11
NET "IPM_Data<7>"
LOC =
Sch name = EXP-IO9_N
#8 BB2-22 46 IO8-N
N9
"V11"|
NET "IPM_Data<8>"
LOC =
Sch name = EXP-IO8_N
#9 BB2-21 44 IO7-N
P11
"N9"|
NET "IPM_Data<9>"
LOC =
Sch name = EXP-IO7_N
#10 BB2-20 43 IO6-N
V12
"P11"|
NET "IPM_Data<10>"
LOC =
Sch name = EXP-IO6_N
#11 BB2-19 41 IO5-N
T11
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
"V12"|
IOSTANDARD=LVTTL;
IOSTANDARD=LVTTL;
NET "IPM_Data<11>"
LOC = "T11"| IOSTANDARD=LVTTL;
Sch name = EXP-IO5_N
#12 BB2-18 40 IO4-N
N11
NET "IPM_Data<12>"
LOC =
Sch name = EXP-IO4_N
#13 BB2-17 38 IO3-N
V13
"N11"|
IOSTANDARD=LVTTL;
NET "IPM_Data<13>"
LOC = "V13"| IOSTANDARD=LVTTL;
Sch name = EXP-IO3_N
#14 BB2-16 37 IO2-N
V15
NET "IPM_Data<14>"
LOC =
Sch name = EXP-IO2_N
#15 BB2-15 35 IO1-N
V16
"V15"|
IOSTANDARD=LVTTL;
NET "IPM_Data<15>"
LOC = "V16"| IOSTANDARD=LVTTL;
Sch name = EXP-IO1_N
# Bank = 2,
Pin name = IO_L29N_GCLK2,
#
Bank
=
2,
#
Bank
=
2,
Pin
name
=
*IO_L22N,
#
Bank
=
2,
Pin
name
=
*IO_L20N,
Bank
=
2,
Pin
name
=
*IO_L19N,
#
# Bank = 2,
#
Bank
=
Bank
=
# Bank = 2,
name
=
IO_L23N,
Pin name = IO_L16N_VREF,
2,
# Bank = 2,
#
Pin
Pin
name
=
*IO_L15N,
Pin name = IO_L14N_D12,
2,
Pin
name
=
*IO_L5N,
Pin name = IO_L2N_CMPMOSI,
#===============================================================================
# Timing constraint of FX2 48MHz clock "fx2Clk_in"
#===============================================================================
NET "fx2Clk_in" TNM_NET = "fx2Clk_in";
TIMESPEC "TS_clk" = PERIOD "fx2Clk_in" 20 ns HIGH 50 %;
1.1.10
top_level.vhdl
1 library ieee;
2
3 use ieee.std_logic_1164.all;
4 use ieee.STD_LOGIC_UNSIGNED.all;
5
6 entity top_level is
7
port(
8
--Clocks
9
clk
: in
STD_LOGIC;
-standard atlys clock
10
IPM_clk_in
: in
STD_LOGIC;
--IPM input clock
11
IPM_data
: in
STD_LOGIC_VECTOR(15 downto 0); -- IPM DATA
12
IPM_clk_out
: out
STD_LOGIC;
--IPM output clock
13
--SOM_bclk
: out
STD_LOGIC;
--bit clock for SOM
14
--SOM_wclk
: out
STD_LOGIC;
--World clock for SOM
15
som_data
: out
STD_LOGIC_VECTOR(7 downto 0);
--signal to send DAC data from
16
adg_sclk
: out STD_LOGIC;
17
adg_sync
: out STD_LOGIC;
18
adg_dout
: out STD_LOGIC;
31 19
adg_reset
: out STD_LOGIC;
20
hv_en
: out STD_LOGIC;
21
-- FX2 interface ---------------------------------------------------------------------------22
fx2Clk_in
: in
std_logic;
-- 48MHz clock from FX2
23
fx2Addr_out
: out
std_logic_vector(1 downto 0); -select FIFO: "10" for EP6OUT, "11" for EP8IN
24
fx2Data_io
: inout std_logic_vector(7 downto 0); -- 8-bit data to/from FX2
25
26
-- When EP6OUT selected:
27
fx2Read_out
: out
std_logic;
-- asserted (activelow) when reading from FX2
28
fx2OE_out
: out
std_logic;
-- asserted (activelow) to tell FX2 to drive bus
29
fx2GotData_in : in
std_logic;
-- asserted (activehigh) when FX2 has data for us
30
31
-- When EP8IN selected:
32
fx2Write_out : out
std_logic;
-- asserted (activelow) when writing to FX2
33
fx2GotRoom_in : in
std_logic;
-- asserted (activehigh) when FX2 has room for more data from us
34
fx2PktEnd_out : out
std_logic;
-- asserted (activelow) when a host read needs to be committed early
35
36
-- Onboard peripherals ---------------------------------------------------------------------37
reset
: in STD_LOGIC;
38
led_out
: out
std_logic_vector(7 downto 0); -- eight LEDs
39
sw_in
: in
std_logic_vector(7 downto 0) -- eight switches
40
);
41 end top_level;
42
43 architecture behavioral of top_level is
44
--CONSTANTS
45
constant stream_reg
: INTEGER := 1;
46
constant overview_stream_reg
: INTEGER := 2;
47
constant minval_min_addr
: INTEGER := 32;
48
constant maxval_min_addr
: INTEGER := 36;
49
constant increment_min_addr : INTEGER := 40;
50
constant sps_min_addr
: INTEGER := 44;
51
constant scanstart_min_addr : INTEGER := 48;
52
constant scanstop_min_addr
: INTEGER := 52;
53
constant overview_min_addr
: INTEGER := 56;
54
55
constant vga_gain_reg
: INTEGER := 64;
56
constant gpio_reg
: INTEGER := 68;
57
constant uim_cmd_reg
: INTEGER := 126;
58
constant fsm_status
: INTEGER := 127;
59
--random signals
60
signal rst_high
: STD_LOGIC
:= '0';
--make a default level high reset
61
-- Channel read/write interface ---------------------------------------------------------------62
signal chanAddr : std_logic_vector(6 downto 0); -- the selected channel (0-127)
63
64
-- Host >> FPGA pipe:
65
signal h2fData
: std_logic_vector(7 downto 0); -data lines used when the host writes to a channel
66
signal h2fValid : std_logic;
-'1' means "on the next clock rising edge, please accept the data on h2fData"
67
signal h2fReady : std_logic;
-channel logic can drive this low to say "I'm not ready for more data yet"
68
69
-- Host << FPGA pipe:
70
signal f2hData
: std_logic_vector(7 downto 0); -data lines used when the host reads from a channel
71
signal f2hValid : std_logic;
-channel logic can drive this low to say "I don't have data ready for you"
72
signal f2hReady : std_logic;
-'1' means "on the next clock rising edge, put your next byte of data on f2hData"
73
-- --------------------------------------------------------------------------------------------74
signal t_IPM_data
:
STD_LOGIC_VECTOR(15 downto 0); -- IPM DATA
32 75
-- Needed so that the comm_fpga module can drive both fx2Read_out and fx2OE_out
76
signal fx2Read
: std_logic;
77
--CLOCK_MANAGER SIGNALS
78
signal sys_clko
: STD_LOGIC;
79
signal SOM_clko
: STD_LOGIC;
80
signal clk_lck
: STD_LOGIC;
81
signal IPM_clko
: STD_LOGIC;
82
signal bclk
: STD_LOGIC;
83
84
--FIFO signals
85
signal ipm_fifo_in
: STD_LOGIC_VECTOR(63 dow
nto 0);
86
signal rd_data_count,rd_data_count_overview
: STD_LOGIC_VECTOR(10 downto 0);
87
signal get_sample,data_stream_enable,ipm_fifo_empty : STD_LOGIC;
88
signal ipm_fifo_empty_overview,get_overview_sample,data_stream_enable_overview
: STD
_LOGIC;
89
signal ready
: STD_LOGIC;
90
signal ipm_fifo_out,ipm_fifo_out_overview
: STD_LOGIC_VECTOR(7 downto 0
);
91
92
--FSM signals
93
signal t_scan_min,t_scan_max,t_scan_step,t_sps,scan_posit : STD_LOGIC_VECTOR(31 downto 0)
:=(others=>'0');
94
signal t_scan_start,t_scan_stop,t_overview_scan : STD_LOGIC_VECTOR(31 downto 0):=(others=
>'0');
95
-signal fsm_status
: STD_LOGIC_VECTOR(7 downto 0);
96
signal cmd_rst
: STD_LOGIC;
97
signal t_f2hReady
: STD_LOGIC;
98
signal t_ipm_fifo_empty
: STD_LOGIC;
99
signal t_som_start
: STD_LOGIC;
100
--register Signals
101
TYPE regArray IS ARRAY (0 TO 127) OF STD_LOGIC_VECTOR(7 downto 0);
102
signal reg_next,reg : regArray :=((others=>(others=>'0')));
103 begin
104
--reset is active high
105
rst_high <= NOT(reset);
106
IPM_clk_out <= IPM_clko;
107
hv_en <= reg(gpio_reg)(0);
108
--t_IPM_data <= IPM_data;
109
110
111 fakefir: block is
112
signal d0, d1, d2, d3, d4, d5, d6, d7 : std_logic_vector(18 downto 0);
113
signal sum : std_logic_vector(18 downto 0);
114 begin
115
116
fakefirproc: process is
117
begin
118
if rising_edge(IPM_clk_in) then
119
if rst_high = '1' then
120
d0 <= (others => '0');
121
d1 <= (others => '0');
122
d2 <= (others => '0');
123
d3 <= (others => '0');
124
d4 <= (others => '0');
125
d5 <= (others => '0');
126
d6 <= (others => '0');
127
d7 <= (others => '0');
128
else
129
d0 <= "000" & IPM_data;
130
d1 <= d0;
131
d2 <= d1;
132
d3 <= d2;
133
d4 <= d3;
134
d5 <= d4;
135
d6 <= d5;
136
d7 <= d6;
137
sum <= d0+d1+d2+d3+d4+d5+d6+d7;
138
end if;
139
end if;
140
end process fakefirproc;
141
33 142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
t_IPM_data <= sum(18 downto 3);
end block fakefir;
gain_stage: entity work.adg714s3w
port map(
clk
=> bclk,
reset => rst_high,
reg_data => reg(vga_gain_reg),
adg_sclk => adg_sclk,
adg_sync => adg_sync,
adg_dout => adg_dout,
adg_reset => adg_reset
);
--filter_FIR: entity work.IPM_filt
--port map(
-- clk => IPM_clk_in,
-- rfd => open,
-- rdy => open,
-- din => IPM_data,
-- dout => t_IPM_data
--);
-- som_start <= t_som_start;
-- SOM_bclk <= bclk;
--fake values to test
-- test_blockram: entity work.analog_interface
-- port map(
-dac_clk => bclk,
-adc_clk => IPM_clko,
-dac_data => scan_posit(31 downto 8),
-adc_data => t_IPM_data,
-control => x"00",
-status => open
-- );
--SOM Instantiation
-- som_inst : entity work.dac_count
-- port map(
-scan_pos => scan_posit,
-dac_clk => bclk,
-dac_out => som_data,
-wrld_clk => SOM_wclk
-);
--CLOCK GENERATOR GOES HERE
clk_mngr_inst: entity work.clockmanager
port map(
--CLOCK INPUT
CLK_IN1 => clk,
--CLOCK OUTPUTS
sys_clk => sys_clko,
IPM_clk => IPM_clko,
SOM_clk => bclk,
--Status/Control signals
RESET_Clk => rst_high,
LOCKED_clk => clk_lck
);
--IPM FIFO DECLARATION GOES HERE
ipm_fifo : entity work.IPM_FIFO
PORT MAP (
rst => rst_high,
--wr_clk => IPM_clk_in,
wr_clk => IPM_clk_in,
rd_clk => fx2Clk_in,
din => ipm_fifo_in,
wr_en => get_sample,
rd_en => data_stream_enable,
dout => ipm_fifo_out,
full => open, --needs work
overflow => open, --needs work
empty => ipm_fifo_empty,
rd_data_count => rd_data_count
);
34 215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 -283
284
285
286
287
ipm_fifo_overview: entity work.IPM_FIFO
port map(
rst => rst_high,
--wr_clk => IPM_clk_in,
wr_clk => IPM_clk_in,
rd_clk => fx2Clk_in,
din => ipm_fifo_in,
wr_en => get_overview_sample,
rd_en => data_stream_enable_overview,
dout => ipm_fifo_out_overview,
full => open, --needs work
overflow => open, --needs work
empty => ipm_fifo_empty_overview,
rd_data_count => rd_data_count_overview
);
som_data <= scan_posit(31 downto 24);
ipm_fifo_in <= scan_posit(31 downto 0) & t_IPM_data(15 downto 0) & x"0BAD";
data_stream_enable <= (f2hReady) when chanAddr = "0000001" else '0';
data_stream_enable_overview <= (f2hReady) when chanAddr = "0000010" else '0';
--Generator for 128 registers and for the code for registers to take in new data
decodeGen: FOR I IN 2 TO 126 GENERATE
blk1: block is
signal reset_reg : std_logic;
begin
cmd_rst_gen:if i = 126 generate
reset_reg <= cmd_rst or rst_high ;
end generate;
everything_else: if i < 126 generate
reset_reg <= rst_high ;
end generate;
reg_next(i)
<= h2fdata when i = CONV_INTEGER(chanAddr) else reg(i);
-- Infer registers
process(reset_reg, fx2Clk_in, h2fValid)
begin
if reset_reg='1' then
reg(i) <= x"00";
elsif ( rising_edge(fx2Clk_in) ) and h2fValid = '1' then
reg(i)
<= reg_next(i);
end if;
end process;
end block;
END GENERATE;
t_ipm_fifo_empty <= ipm_fifo_empty AND ipm_fifo_empty_overview;
--FINITE STATE MACHINE GOES HERE
sys_FSM: entity work.FSM2
port map(
clk => IPM_clk_in,
--ipm_clk => IPM_clk_in,
reset => rst_high,
ipm_fifo_empty => t_ipm_fifo_empty,
cmd => reg(uim_cmd_reg),
scan_min => t_scan_min,
scan_max => t_scan_max,
scan_step => t_scan_step,
smp_step => t_sps,
scan_start => t_scan_start,
scan_stop => t_scan_stop,
overview_scan_step => t_overview_scan,
scan_pos => scan_posit,
status => reg(fsm_status),
sample_en => get_sample,
overview_en => get_overview_sample,
som_status => open, --t_som_start,
cmd_reg_reset => cmd_rst
);
t_scan_min <=
(reg(minval_min_addr +3)
& reg(minval_min_addr +2)
35 288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
&
&
t_scan_max <=
(reg(maxval_min_addr +3)
& reg(maxval_min_addr +2)
& reg(maxval_min_addr +1)
& reg(maxval_min_addr +0));
t_scan_step <=
t_sps
reg(minval_min_addr +1)
reg(minval_min_addr +0));
(reg(increment_min_addr +3)
& reg(increment_min_addr +2)
& reg(increment_min_addr +1)
& reg(increment_min_addr +0));
<=
&
&
&
t_scan_start<=
t_scan_stop<=
(reg(sps_min_addr +3)
reg(sps_min_addr +2)
reg(sps_min_addr +1)
reg(sps_min_addr +0));
(reg(scanstart_min_addr +3)
& reg(scanstart_min_addr +2)
& reg(scanstart_min_addr +1)
& reg(scanstart_min_addr +0));
(reg(scanstop_min_addr +3)
& reg(scanstop_min_addr +2)
& reg(scanstop_min_addr +1)
& reg(scanstop_min_addr +0));
t_overview_scan<=(reg(overview_min_addr +3)
& reg(overview_min_addr +2)
& reg(overview_min_addr +1)
& reg(overview_min_addr +0));
WITH chanAddr SELECT
f2hdata <= ipm_fifo_out
when "0000001",
ipm_fifo_out_overview
when "0000010",
reg(fsm_status)
when "1111111",
reg(CONV_INTEGER(chanAddr)) when others;
led_out <= reg(CONV_INTEGER(sw_in(6 downto 0))) when sw_in(7) = '1'
else scan_posit(31 downto 24) when sw_in = "00000001"
--"0000001" & t_som_start when sw_in(7) = '1'
else rd_data_count(10 downto 3);
h2fReady <= '1';
f2hValid <= '1';
-- CommFPGA module
fx2Read_out <= fx2Read;
fx2OE_out <= fx2Read;
fx2Addr_out(1) <= '1'; -- Use EP6OUT/EP8IN, not EP2OUT/EP4IN.
comm_fpga : entity work.comm_fpga
port map(
-- FX2 interface
fx2Clk_in
=> fx2Clk_in,
fx2FifoSel_out => fx2Addr_out(0),
fx2Data_io
=> fx2Data_io,
fx2Read_out
=> fx2Read,
fx2GotData_in => fx2GotData_in,
fx2Write_out
=> fx2Write_out,
fx2GotRoom_in => fx2GotRoom_in,
fx2PktEnd_out => fx2PktEnd_out,
-- Channel read/write interface
chanAddr_out
=> chanAddr,
h2fData_out
=> h2fData,
h2fValid_out
=> h2fValid,
h2fReady_in
=> h2fReady,
f2hData_in
=> f2hData,
36 361
f2hValid_in
362
f2hReady_out
363
);
364
365 end behavioral;
366
367
368
=> f2hValid,
=> f2hReady
1.2 SOM – AtTiny261
1.2.1 Makefile
1 # ---------------------------------------------------------------------------2 # Makefile to compile and link test program
3 # Based on makefile by: Peter Fleury
4 # Originally based on WinAVR Makefile Template written by Eric B. Weddington, Jˆrg Wunsch, et
al.
5 #
6 # Adjust F_CPU below to the clock frequency in Mhz of your AVR target
7 #
8 # ---------------------------------------------------------------------------9
10 # MCU name
11 MCU = attiny261
12
13
14 # Processor frequency.
15 #
This will define a symbol, F_CPU, in all source code files equal to the
16 #
processor frequency. You can then use this symbol in your source code to
17 #
calculate timings. Do NOT tack on a 'UL' at the end, this will be done
18 #
automatically to create a 32-bit value in your source code.
19 F_CPU = 7372800
20
21
22 # Output format. (can be srec, ihex, binary)
23 FORMAT = ihex
24
25
26 # Target file name (without extension).
27 TARGET = USI_I2C_Port
28
29
30 # List C source files here. (C dependencies are automatically generated.)
31 SRC = $(TARGET).c USI_TWI_Master.c
32
33
34 # List Assembler source files here.
35 #
Make them always end in a capital .S. Files ending in a lowercase .s
36 #
will not be considered source files but generated files (assembler
37 #
output from the compiler), and will be deleted upon "make clean"!
38 #
Even though the DOS/Win* filesystem matches both .s and .S the same,
39 #
it will preserve the spelling of the filenames, and gcc itself does
40 #
care about how the name is spelled on its command-line.
41 ASRC =
42
43
44 # Optimization level, can be [0, 1, 2, 3, s].
45 #
0 = turn off optimization. s = optimize for size.
46 #
(Note: 3 is not always the best optimization level. See avr-libc FAQ.)
47 OPT = s
48
49
50 # Debugging format.
51 #
Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
52 #
AVR Studio 4.10 requires dwarf-2.
53 #
AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
54 DEBUG = dwarf-2
37 55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# List any extra directories to look for include files here.
#
Each directory must be seperated by a space.
#
Use forward slashes for directory separators.
#
For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =
# Compiler flag to set the C Standard level.
#
c89
= "ANSI" C
#
gnu89 = c89 plus GCC extensions
#
c99
= ISO C99 standard (not yet fully implemented)
#
gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here
#CDEFS = -DF_CPU=$(F_CPU)UL
# Place -I options here
CINCS =
#---------------- Compiler Options ---------------# -g*:
generate debugging information
# -O*:
optimization level
# -f...:
tuning, see GCC manual and avr-libc documentation
# -Wall...:
warning level
# -Wa,...:
tell GCC to pass this to the assembler.
#
-adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Assembler Options ---------------# -Wa,...:
tell GCC to pass this to the assembler.
# -ahlms:
create listing
# -gstabs:
have the assembler create line number information; note that
#
for use in COFF files, additional information about filenames
#
and function names needs to be present in the assembler source
#
files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
#---------------- Library Options ---------------# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
38 128 SCANF_LIB =
129 #SCANF_LIB = $(SCANF_LIB_MIN)
130 #SCANF_LIB = $(SCANF_LIB_FLOAT)
131
132
133 MATH_LIB = -lm
134
135
136
137 #---------------- External Memory Options ---------------138
139 # 64 KB of external RAM, starting after internal RAM (ATmega128!),
140 # used for variables (.data/.bss) and heap (malloc()).
141 #EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
142
143 # 64 KB of external RAM, starting after internal RAM (ATmega128!),
144 # only used for heap (malloc()).
145 #EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
146
147 EXTMEMOPTS =
148
149
150
151 #---------------- Linker Options ---------------152 # -Wl,...:
tell GCC to pass this to linker.
153 #
-Map:
create map file
154 #
--cref:
add cross reference to map file
155 LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
156 LDFLAGS += $(EXTMEMOPTS)
157 LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
158
159
160
161 #---------------- Programming Options (avrdude) ---------------162
163 # Programming hardware: alf avr910 avrisp bascom bsd
164 # dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
165 #
166 # Type: avrdude -c ?
167 # to get a full listing.
168 #
169 AVRDUDE_PROGRAMMER = usbtiny
170
171 # com1 = serial port. Use lpt1 to connect to parallel port.
172 #AVRDUDE_PORT = lpt1
# programmer connected to serial device
173
174 AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m U efuse:w:0x01:m
175 #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
176
177
178 # Uncomment the following if you want avrdude's erase cycle counter.
179 # Note that this counter needs to be initialized first using -Yn,
180 # see avrdude manual.
181 #AVRDUDE_ERASE_COUNTER = -y
182
183 # Uncomment the following if you do /not/ wish a verification to be
184 # performed after programming the device.
185 #AVRDUDE_NO_VERIFY = -V
186
187 # Increase verbosity level. Please use this when submitting bug
188 # reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
189 # to submit bug reports.
190 #AVRDUDE_VERBOSE = -v -v
191
192 AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER)
193 AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
194 AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
195 AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
196
197
198
199 #---------------- Debugging Options ----------------
39 200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
#
just set to localhost unless doing some sort of crazy debugging when
#
avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin -------MSG_END = -------- end -------MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(SRC:.c=.lst) $(ASRC:.S=.lst)
# Compiler flags to generate dependency files.
40 273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
build: elf hex eep lss sym
elf:
hex:
eep:
lss:
sym:
$(TARGET).elf
$(TARGET).hex
$(TARGET).eep
$(TARGET).lss
$(TARGET).sym
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Generate avr-gdb config/init file which does the following:
#
define the reset signal, load the target file, connect to target, and set
#
a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
41 346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
42 419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) .dep/*
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config
1.2.2 USI_I2C_Port.c
1
2
3
4
5
6
7
8
9
10
/*
* GccApplication3.c
*
* Created: 11/1/2012 2:32:46 PM
* Author: Mary Hatfield
*/
#include <avr/interrupt.h>
//#define F_CPU 8000000UL
#include <util/delay.h>
// Sets up the default speed for delay.h
43 11 #include <avr/io.h>
12 #include "USI_TWI_Master.h"
13
14 // LED and Button Ports - specific to ATtiny261
15 #define P_LED_1
PB4
// used for init & data signal (for Debug)
16 #define P_LED_2
PB5
// used for debug
17 #define P_LED_3
PB6
18 #define P_LED_4
PA7
19
20 //DAC ports
21 #define P_DAC_ZEROL PA0
22 #define P_DAC_MDI
PA1
23 #define P_DAC_MC
PA2
24 #define P_DAC_MS
PA4
25 #define P_DAC_RST
PB3
26
27 //Checking state
28 #define P_HV_EN
PB6
29 #define P_HV_GOOD
PA7
30 #define P_AIN
PA6
31 #define P_AOUT
PA5
32
33 //FPGA Ports
34 #define P_FPGA_58
PB7
35 //#define P_FPGA_76 PB2
36 #define P_FPGA_95
PB1
37 #define P_FPGA_17
PB0
38 #define PIN_FPGA
PINB
39
40 #define CLK_PERIOD 200
41 #define SNOOZE 100
42 #define TSTBIT(REG, BIT) (REG & (1 << BIT))
43
44 void blinkEm( uint8_t count, uint8_t led);
45 void shift_out(int addr, int data);
46 void ADCinit (void);
47 unsigned long Read_ADC(void);
48 int DCM_GO(void);
49
50 void main( void )
51 {
52
enum{
53
INIT,
54
PROGRAM,
55
WAIT_FOR_DCM,
56
UNMUTE_DAC,
57
CHECKING,
58
MUTE_DAC,
59
} state;
60
state = INIT;
61
62
/* Initialize LED blinkers, out/inputs */
63
DDRB = _BV(P_LED_1) | _BV(P_LED_2) | _BV(P_HV_EN) | _BV(P_DAC_RST);
64
DDRA = _BV(P_HV_GOOD) | _BV(P_DAC_MDI) | _BV(P_DAC_MC) | _BV(P_DAC_MS) | _BV(P_AIN) | _BV
(P_AOUT);
65
while(1){
66
unsigned long result;
67
int i=0;
68
69
if (PIN_FPGA & _BV(P_FPGA_95)) //if DCM says go, turn off light
70
{
71
PORTB |= _BV(P_HV_EN);
72
}
73
else
74
{
75
PORTB &= ~_BV(P_HV_EN);
76
}
77
78
79
80
81
switch(state){
case INIT:
USI_TWI_Master_Initialise();
PORTB |= _BV(P_DAC_RST);
//reset, start fresh
44 82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
PORTB &= ~_BV(P_DAC_RST);
state = PROGRAM;
break;
case PROGRAM:
shift_out (0x10, 0xFF);
//write to MDI
shift_out (0x11, 0xFF);
shift_out(0x12, 0x21);
//(21 MUTE on, 20 MUTE off)
shift_out(0x13,0x08);
//(08 HV low, 18 HV high)
shift_out(0x14,0x11);
shift_out(0x15,0x01);
shift_out(0x96,0x00);
shift_out(0x97,0x00);
state = WAIT_FOR_DCM;
break;
case WAIT_FOR_DCM:
i=DCM_GO();
if (i=0)
{
state=WAIT_FOR_DCM;
}
else
{
state=UNMUTE_DAC;
}
break;
case UNMUTE_DAC:
shift_out(0x12, 0x20);
//UNMUTE
shift_out(0x13,0x18);
//HV EN HIGH- light LED_3
state = CHECKING;
// blinkEm(4,P_LED_1);
//debug
break;
case CHECKING:
ADCinit();
//check Ain versus Aout, assign diff to int, check int to accepted value
result = Read_ADC();
//if good, light LED_4
i=DCM_GO();
if (i=0)
{
state=CHECKING;
}
else
{
state=MUTE_DAC;
}
break;
case MUTE_DAC:
shift_out(0x12, 0x21);
//MUTE
shift_out(0x13,0x08);
//HV EN LOW- unlight LED_3
PORTB |= _BV(P_FPGA_17);
//flag FPGA
_delay_ms(100);
state = WAIT_FOR_DCM;
break;
default:
state = INIT;
break;
}
}
return;
}
/*-----------------------------------------------------------------------** DCM_GO - function to see if DCM is ready
** ---------------------------------------------------------------------*/
int DCM_GO(void){
uint8_t but1;
uint8_t but1a;
uint8_t oldBut=0;
int state=0;
PORTB = _BV(P_FPGA_95);
but1 = ~PIN_FPGA & _BV(P_FPGA_95);
if (but1 != oldBut)
// look at buttons, invert
45 155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
{
//_delay_ms(100);
// 100ms @ 1MHz clock.
but1a = ~PIN_FPGA & _BV(P_FPGA_95);
// read again
if (but1a == but1)
// button has changed
{
oldBut = but1;
if (oldBut > 0)
// Switch is pressed
{
state=1;
}
}
}
else
{
state=0;
}
return state;
}
/*-----------------------------------------------------------------------** blinkEm - function to blink LED for count passed in
**
Assumes that leds are all on the same port. 1MHz Clock rate.
** ---------------------------------------------------------------------*/
void blinkEm( uint8_t count, uint8_t led){
#if 0
uint8_t i;
while (count > 0){
PORTB |= _BV(led);
for (i=0;i<5;i++)
{
_delay_ms(400);
}
PORTB &= ~_BV(led);
for (i=0;i<5;i++)
{
_delay_ms(400);
}
count--;
}
#endif
}
/*-----------------------------------------------------------------------** shift_out - function to pass DAC commands serially
**
_delay_ms(CLK_PERIOD) where the CLK_PERIOD = 200 for now.
**
1MHz Clock rate.
** ---------------------------------------------------------------------*/
void shift_out(int addr, int data){
int i;
PORTB &= ~_BV(P_DAC_MS);
//set MS to allow writing to MDI
//_delay_ms(200);
for(i=7; i>=0; i--){
//clk = 0
PORTA &= ~_BV(P_DAC_MC);
if ((addr>>i)&(0x01))
PORTA |= _BV(P_DAC_MDI);
else
PORTA &= ~_BV(P_DAC_MDI);
_delay_us(20);
//clk = 1;
PORTA |= _BV(P_DAC_MC);
_delay_us(20);
}
for(i=7; i>=0; i--){
//clk = 0
PORTA &= ~_BV(P_DAC_MC);
if ((data>>i)&(0x01))
PORTA |= _BV(P_DAC_MDI);
46 228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
else
PORTA &= ~_BV(P_DAC_MDI);
_delay_us(20);
//clk = 1;
PORTA |= _BV(P_DAC_MC);
_delay_us(20);
}
PORTB |= _BV(P_DAC_MS);
PORTA &= ~_BV(P_DAC_MDI);
PORTA &= ~_BV(P_DAC_MC);
//_delay_ms(200);
//shut off MDI writing
}
/*-----------------------------------------------------------------------** ADCinit - function to initialize ADC
**
set for differential comparison, ADC4 and ADC5 pin,
**
multiplying diff by 20x, clk at 125kHz
** ---------------------------------------------------------------------*/
void ADCinit (void) {
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (0 << ADPS0);
ADMUX |= (0 << REFS1) | (0 << REFS0) | (1 << MUX4) | (1 << MUX2);
ADCSRA |= (1 << ADEN);
_delay_us(5);
}
/*-----------------------------------------------------------------------** Read_ADC - function to begin ADC conversions
**
** ---------------------------------------------------------------------*/
unsigned long Read_ADC(void) {
uint16_t adc_rez=0;
ADCSRA |= (1 << ADSC);
// Start AD Conversions
while ( TSTBIT(ADCSRA, ADSC));
adc_rez = ADCL+256*ADCH;
return(adc_rez);
}
1.2.3 USI_I2C_Master.c
1 #include <avr/interrupt.h>
2 //#define F_CPU 8000000UL
// Sets up the default speed for delay.h
3 #include <util/delay.h>
4 #include <avr/io.h>
5 #include "USI_TWI_Master.h"
6
7 unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char * , unsigned char );
8 unsigned char USI_TWI_Master_Transfer( unsigned char );
9 unsigned char USI_TWI_Master_Stop( void );
10 unsigned char USI_TWI_Master_Start( void );
11
12 union USI_TWI_state
13 {
14
unsigned char errorState;
// Can reuse the TWI_state for error states since it will
not be needed if there is an error.
15
struct
16
{
17
unsigned char addressMode
: 1;
18
unsigned char masterWriteDataMode : 1;
19
unsigned char memReadMode
: 1;
20
unsigned char unused
: 5;
21
};
22 }
USI_TWI_state;
23
24 /*--------------------------------------------------------------25 USI TWI single master initialization function
26 ---------------------------------------------------------------*/
27 void USI_TWI_Master_Initialise( void )
47 28 {
29
PORT_USI |= (1<<PIN_USI_SDA);
// Enable pullup on SDA, to set high as released st
ate.
30
PORT_USI |= (1<<PIN_USI_SCL);
// Enable pullup on SCL, to set high as released st
ate.
31
32
DDR_USI |= (1<<PIN_USI_SCL);
// Enable SCL as output.
33
DDR_USI |= (1<<PIN_USI_SDA);
// Enable SDA as output.
34
35
USIDR
= 0xFF;
// Preload dataregister with "released level" data.
36
USICR
= (0<<USISIE)|(0<<USIOIE)|
// Disable Interrupts.
37
(1<<USIWM1)|(0<<USIWM0)|
// Set USI in Twowire mode.
38
(1<<USICS1)|(0<<USICS0)|(1<<USICLK)|
// Software stobe as counte
r clock source
39
(0<<USITC);
40
USISR
=
(1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|
// Clear flags,
41
(0x0<<USICNT0);
// and reset counter.
42 }
43
44 /*--------------------------------------------------------------45 Use this function to get hold of the error message from the last transmission
46 ---------------------------------------------------------------*/
47 unsigned char USI_TWI_Get_State_Info( void )
48 {
49
return ( USI_TWI_state.errorState );
// Return error state.
50 }
51 /*--------------------------------------------------------------52 USI Random (memory) Read function. This function sets up for call
53 to USI_TWI_Start_Transceiver_With_Data which does the work.
54 Doesn't matter if read/write bit is set or cleared, it'll be set
55 correctly in this function.
56
57 The msgSize is passed to USI_TWI_Start_Transceiver_With_Data.
58
59 Success or error code is returned. Error codes are defined in
60 USI_TWI_Master.h
61 ---------------------------------------------------------------*/
62 unsigned char USI_TWI_Start_Random_Read( unsigned char *msg, unsigned char msgSize)
63 {
64
*(msg) &= ~(TRUE<<TWI_READ_BIT);
// clear the read bit if it's set
65
USI_TWI_state.errorState = 0;
66
USI_TWI_state.memReadMode = TRUE;
67
68
return (USI_TWI_Start_Transceiver_With_Data( msg, msgSize));
69 }
70 /*--------------------------------------------------------------71 USI Normal Read / Write Function
72 Transmit and receive function. LSB of first byte in buffer
73 indicates if a read or write cycles is performed. If set a read
74 operation is performed.
75
76 Function generates (Repeated) Start Condition, sends address and
77 R/W, Reads/Writes Data, and verifies/sends ACK.
78
79 Success or error code is returned. Error codes are defined in
80 USI_TWI_Master.h
81 ---------------------------------------------------------------*/
82 unsigned char USI_TWI_Start_Read_Write( unsigned char *msg, unsigned char msgSize)
83 {
84
85
USI_TWI_state.errorState = 0;
// Clears all mode bits also
86
87
return (USI_TWI_Start_Transceiver_With_Data( msg, msgSize));
88
89 }
90 /*--------------------------------------------------------------91 USI Transmit and receive function. LSB of first byte in buffer
92 indicates if a read or write cycles is performed. If set a read
93 operation is performed.
94
95 Function generates (Repeated) Start Condition, sends address and
96 R/W, Reads/Writes Data, and verifies/sends ACK.
48 97
98 This function also handles Random Read function if the memReadMode
99 bit is set. In that case, the function will:
100 The address in memory will be the second
101 byte and is written *without* sending a STOP.
102 Then the Read bit is set (lsb of first byte), the byte count is
103 adjusted (if needed), and the function function starts over by sending
104 the slave address again and reading the data.
105
106 Success or error code is returned. Error codes are defined in
107 USI_TWI_Master.h
108 ---------------------------------------------------------------*/
109 unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
110 {
111
unsigned char const tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|
//
Prepare register value to: Clear flags, and
112
(0x0<<USICNT0);
// set U
SI to shift 8 bits i.e. count 16 clock edges.
113
unsigned char const tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|
//
Prepare register value to: Clear flags, and
114
(0xE<<USICNT0);
// set US
I to shift 1 bit i.e. count 2 clock edges.
115
unsigned char *savedMsg;
116
unsigned char savedMsgSize;
117
118 //This clear must be done before calling this function so that memReadMode can be specified.
119 // USI_TWI_state.errorState = 0;
// Clears all mode bits also
120
121
USI_TWI_state.addressMode = TRUE;
// Always true for first byte
122
123 #ifdef PARAM_VERIFICATION
124
if(msg > (unsigned char*)RAMEND)
// Test if address is outside SRAM space
125
{
126
USI_TWI_state.errorState = USI_TWI_DATA_OUT_OF_BOUND;
127
return (FALSE);
128
}
129
if(msgSize <= 1)
// Test if the transmission buffer is empt
y
130
{
131
USI_TWI_state.errorState = USI_TWI_NO_DATA;
132
return (FALSE);
133
}
134 #endif
135
136 #ifdef NOISE_TESTING
// Test if any unexpected conditions have
arrived prior to this execution.
137
if( USISR & (1<<USISIF) )
138
{
139
USI_TWI_state.errorState = USI_TWI_UE_START_CON;
140
return (FALSE);
141
}
142
if( USISR & (1<<USIPF) )
143
{
144
USI_TWI_state.errorState = USI_TWI_UE_STOP_CON;
145
return (FALSE);
146
}
147
if( USISR & (1<<USIDC) )
148
{
149
USI_TWI_state.errorState = USI_TWI_UE_DATA_COL;
150
return (FALSE);
151
}
152 #endif
153
154
if ( !(*msg & (1<<TWI_READ_BIT)) )
// The LSB in the address byte determines
if is a masterRead or masterWrite operation.
155
{
156
USI_TWI_state.masterWriteDataMode = TRUE;
157
}
158
159 // if (USI_TWI_state.memReadMode)
160 // {
161
savedMsg = msg;
162
savedMsgSize = msgSize;
49 163 // }
164
165
if ( !USI_TWI_Master_Start( ))
166
{
167
return (FALSE);
// Send a START condition on the TWI bus.
168
}
169
170 /*Write address and Read/Write data */
171
do
172
{
173
/* If masterWrite cycle (or inital address tranmission)*/
174
if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode)
175
{
176
/* Write a byte */
177
PORT_USI &= ~(1<<PIN_USI_SCL);
// Pull SCL LOW.
178
USIDR
= *(msg++);
// Setup data.
179
USI_TWI_Master_Transfer( tempUSISR_8bit );
// Send 8 bits on bus.
180
181
/* Clock and verify (N)ACK from slave */
182
DDR_USI &= ~(1<<PIN_USI_SDA);
// Enable SDA as input.
183
if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) )
184
{
185
if ( USI_TWI_state.addressMode )
186
USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
187
else
188
USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
189
return (FALSE);
190
}
191
192
if ((!USI_TWI_state.addressMode) && USI_TWI_state.memReadMode)// means memory start add
ress has been written
193
{
194
msg = savedMsg;
// start at slave address again
195
*(msg) |= (TRUE<<TWI_READ_BIT); // set the Read Bit on Slave address
196
USI_TWI_state.errorState = 0;
197
USI_TWI_state.addressMode = TRUE;
// Now set up for the Read cycle
198
msgSize = savedMsgSize;
// Set byte count correctly
199
// NOte that the length should be Slave adrs byte + # bytes to read + 1 (gets decreme
nted below)
200
if ( !USI_TWI_Master_Start( ))
201
{
202
USI_TWI_state.errorState = USI_TWI_BAD_MEM_READ;
203
return (FALSE);
// Send a START condition on the TWI bu
s.
204
}
205
}
206
else
207
{
208
USI_TWI_state.addressMode = FALSE;
// Only perform address transmission on
ce.
209
}
210
}
211
/* Else masterRead cycle*/
212
else
213
{
214
/* Read a data byte */
215
DDR_USI
&= ~(1<<PIN_USI_SDA);
// Enable SDA as input.
216
*(msg++) = USI_TWI_Master_Transfer( tempUSISR_8bit );
217
218
/* Prepare to generate ACK (or NACK in case of End Of Transmission) */
219
if( msgSize == 1)
// If transmission of last byte was perfor
med.
220
{
221
USIDR = 0xFF;
// Load NACK to confirm End Of Transmissio
n.
222
}
223
else
224
{
225
USIDR = 0x00;
// Load ACK. Set data register bit 7 (outp
ut for SDA) low.
226
}
227
USI_TWI_Master_Transfer( tempUSISR_1bit );
// Generate ACK/NACK.
228
}
50 229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
}while( --msgSize) ;
if (!USI_TWI_Master_Stop())
{
return (FALSE);
}
// Until all data sent/received.
// Send a STOP condition on the TWI bus.
/* Transmission successfully completed*/
return (TRUE);
}
/*--------------------------------------------------------------Core function for shifting data in and out from the USI.
Data to be sent has to be placed into the USIDR prior to calling
this function. Data read, will be return'ed from the function.
---------------------------------------------------------------*/
unsigned char USI_TWI_Master_Transfer( unsigned char temp )
{
USISR = temp;
// Set USISR according to temp.
// Prepare clocking.
temp = (0<<USISIE)|(0<<USIOIE)|
// Interrupts disabled
(1<<USIWM1)|(0<<USIWM0)|
// Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(1<<USICLK)|
// Software clock strobe as source.
(1<<USITC);
// Toggle Clock Port.
do
{
_delay_us(T2_TWI);
USICR = temp;
// Generate positve SCL edge.
while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.
_delay_us(T4_TWI);
USICR = temp;
// Generate negative SCL edge.
}while( !(USISR & (1<<USIOIF)) );
// Check for transfer complete.
_delay_us(T2_TWI);
temp = USIDR;
USIDR = 0xFF;
DDR_USI |= (1<<PIN_USI_SDA);
// Read out data.
// Release SDA.
// Enable SDA as output.
return temp;
// Return the data from the USIDR
}
/*--------------------------------------------------------------Function for generating a TWI Start Condition.
---------------------------------------------------------------*/
unsigned char USI_TWI_Master_Start( void )
{
/* Release SCL to ensure that (repeated) Start can be performed */
PORT_USI |= (1<<PIN_USI_SCL);
// Release SCL.
while( !(PORT_USI & (1<<PIN_USI_SCL)) );
// Verify that SCL becomes high.
_delay_us(T2_TWI);
/* Generate Start Condition */
PORT_USI &= ~(1<<PIN_USI_SDA);
_delay_us(T4_TWI);
PORT_USI &= ~(1<<PIN_USI_SCL);
PORT_USI |= (1<<PIN_USI_SDA);
// Force SDA LOW.
// Pull SCL LOW.
// Release SDA.
#ifdef SIGNAL_VERIFY
if( !(USISR & (1<<USISIF)) )
{
USI_TWI_state.errorState = USI_TWI_MISSING_START_CON;
return (FALSE);
}
#endif
return (TRUE);
}
/*--------------------------------------------------------------Function for generating a TWI Stop Condition. Used to release
the TWI bus.
---------------------------------------------------------------*/
unsigned char USI_TWI_Master_Stop( void )
{
PORT_USI &= ~(1<<PIN_USI_SDA);
// Pull SDA low.
PORT_USI |= (1<<PIN_USI_SCL);
// Release SCL.
51 302
while( !(PIN_USI & (1<<PIN_USI_SCL)) ); // Wait for SCL to go high.
303
_delay_us(T4_TWI);
304
PORT_USI |= (1<<PIN_USI_SDA);
// Release SDA.
305
_delay_us(T2_TWI);
306
307 #ifdef SIGNAL_VERIFY
308
if( !(USISR & (1<<USIPF)) )
309
{
310
USI_TWI_state.errorState = USI_TWI_MISSING_STOP_CON;
311
return (FALSE);
312
}
313 #endif
314
315
return (TRUE);
316 }
1.2.4 USI_TWI_Master_h
1 //********** Defines **********//
2
3 // Defines controlling timing limits - SCL <= 100KHz.
4
5 #define SYS_CLK
1000.0 // [kHz]
Default for ATtiny2313
6
7 // For use with _delay_us()
8 #define T2_TWI
5
// >4,7us
9 #define T4_TWI
4
// >4,0us
10
11 // Defines error code generating
12 //#define PARAM_VERIFICATION
13 //#define NOISE_TESTING
14 #define SIGNAL_VERIFY
// This should probably be on always.
15
16 /****************************************************************************
17
Bit and byte definitions
18 ****************************************************************************/
19 #define TWI_READ_BIT 0
// Bit position for R/W bit in "address byte".
20 #define TWI_ADR_BITS 1
// Bit position for LSB of the slave address bits in the init by
te.
21 #define TWI_NACK_BIT 0
// Bit position for (N)ACK bit.
22
23 // Note these have been renumbered from the Atmel Apps Note. Most likely errors are now
24 //
lowest numbers so they're easily recognized as LED flashes.
25 #define USI_TWI_NO_DATA
0x08 // Transmission buffer is empty
26 #define USI_TWI_DATA_OUT_OF_BOUND
0x09 // Transmission buffer is outside SRAM space
27 #define USI_TWI_UE_START_CON
0x07 // Unexpected Start Condition
28 #define USI_TWI_UE_STOP_CON
0x06 // Unexpected Stop Condition
29 #define USI_TWI_UE_DATA_COL
0x05 // Unexpected Data Collision (arbitration)
30 #define USI_TWI_NO_ACK_ON_DATA
0x02 // The slave did not acknowledge all data
31 #define USI_TWI_NO_ACK_ON_ADDRESS
0x01 // The slave did not acknowledge the address
32 #define USI_TWI_MISSING_START_CON
0x03 // Generated Start Condition not detected on bus
33 #define USI_TWI_MISSING_STOP_CON
0x04 // Generated Stop Condition not detected on bus
34 #define USI_TWI_BAD_MEM_READ
0x0A // Error during external memory read
35
36 // Device dependant defines - These for ATtiny2313.
37
38
#define DDR_USI
DDRB
39
#define PORT_USI
PORTB
40
#define PIN_USI
PINB
41
#define PORT_USI_SDA
PORTB5
42
#define PORT_USI_SCL
PORTB7
43
#define PIN_USI_SDA
PINB5
44
#define PIN_USI_SCL
PINB7
45
46 // General defines
47 #define TRUE 1
48 #define FALSE 0
49
50 //********** Prototypes **********//
51
52 52
53
54
55
void
USI_TWI_Master_Initialise( void );
unsigned char USI_TWI_Start_Random_Read( unsigned char * , unsigned char );
unsigned char USI_TWI_Start_Read_Write( unsigned char * , unsigned char );
unsigned char USI_TWI_Get_State_Info( void ); 1.3 UIM – Cross Platform GTK Client
1.3.1 complile.sh
1 #!/bin/sh
2
3 TARGNAME=team_spectrum
4 SRC_FILES="userIOusb.c dosa.c dcmusb.c ini.c uim_config.c"
5 FPGALIB=$HOME/Important_Files/RPi/libfpgalink-20120507
6 gcc -m64 -O3 -g -std=gnu99 \
7
-I$FPGALIB -I$FPGALIB/hdl/common\
8
-Wl,--relax,--gc-sections,-rpath,\$ORIGIN,-rpath-link,$FPGALIB/linux.x86_64/rel \
9
-o $TARGNAME $SRC_FILES -L$FPGALIB/linux.x86_64/rel -lfpgalink -lerror \
10
$(pkg-config --cflags gtk+-2.0 gmodule-2.0 --libs glib-2.0 gtkdatabox )
11 #gcc $SRC_FILES $(pkg-config --cflags gtk+-2.0 gmodule-2.0 --libs glib-2.0)
12 #gcc -o team_spectrum $SRC_FILES $(pkg-config --cflags gtk+-2.0 gmodule-2.0 --libs glib2.0 gtkdatabox )
13 echo "it's over"
1.3.2 dcm_compile.sh
1 #!/bin/sh
2
3 TARGNAME=dcmusb_test
4 SRC_FILES="dcmusb_unitTest.c dcmusb.c"
5 FPGALIB=$HOME/Important_Files/RPi/libfpgalink-20120507
6 gcc -m64 -O3 -g -std=c99 \
7
-I$FPGALIB -I$FPGALIB/hdl/common\
8
-Wl,--relax,--gc-sections,-rpath,\$ORIGIN,-rpath-link,$FPGALIB/linux.x86_64/rel \
9
-o $TARGNAME $SRC_FILES -L$FPGALIB/linux.x86_64/rel -lfpgalink -lerror \
10
$(pkg-config --cflags gtk+-2.0 gmodule-2.0 --libs glib-2.0 gtkdatabox )
11 #gcc $SRC_FILES $(pkg-config --cflags gtk+-2.0 gmodule-2.0 --libs glib-2.0)
12 #gcc -o team_spectrum $SRC_FILES $(pkg-config --cflags gtk+-2.0 gmodule-2.0 --libs glib2.0 gtkdatabox )
13 echo "it's over"
1.3.3 dcmusb.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include
#include
#include
#include
#include
"dcmusb.h"
<stdio.h>
<stdint.h>
<stdlib.h>
"libfpgalink.h"
#define
#define
TIMEOUT_MS 1000
BUFFER_SIZE 1024
uint8 *buffer;
const char *error = NULL;
bool isCommCapable;
int fpga_init(void)
{
//fpgalink initialization function.required in order for proper communication to occur
53 17
flInitialise();
18
19
//allocate proper amount of size for the data buffer
20
buffer = malloc(BUFFER_SIZE*sizeof(uint8));
21
return 0;
22 }
23
24 int fpga_connect(const char *vp, struct FLContext **handle)
25 {
26
//return variable(rv) instantiation and boolean flag
27
int rv = 0,status;
28
bool flag,isNeroCapable;
29
char *xsvfFile = "commfpga_system.xsvf";
30
31
//vendor and product ID for atlys 6. This ID is permanent and will thus never
32
//change unless we use a different fpga
33
const char * ivp = "1443:0007";
34
35
//load standard cypress FX2 firmware
36
rv = flLoadStandardFirmware(ivp, vp, "D0234", &error);
37
38
//try opening the fpga communication channel
39
rv = flOpen(vp,handle,NULL);
40
41
//this is if the open function fails and the fpga is not ready yet
42
if(rv)
43
{
44
//run through a loop if a vendor and product ID is given(done by default)
45
if (ivp)
46
{
47
int count = 60;
48
49
//try loading the cypress fx2 firmware again
50
rv = flLoadStandardFirmware(ivp, vp, "D0234", &error);
51
52
//waits until device communicates that it is available (NEEDED)
53
//loops in the do/while loop until fpga communicates that it is ready to communic
ate
54
do
55
{
56
fflush(stdout);
57
58
//flSleep is exactly like a traditional linux sleep command, waits for 100ms
59
flSleep(1000);
60
61
//tests to make sure the device is available
62
rv = flIsDeviceAvailable(vp, &flag, &error);
63
count--;
64
} while ( !flag && count );
65
66
//if the system fails then print a failure statement to comand line
67
if ( !flag )
68
{
69
fprintf(stderr, "FPGALink device did not renumerate properly as %s\n", vp);
70
}
71
72
//now open communication with fpga
73
rv = flOpen(vp, handle, &error);
74
}
75
isNeroCapable = flIsNeroCapable(*handle);
76
if ( xsvfFile ) {
77
//printf("Playing \"%s\" into the JTAG chain on FPGALink device %s...\n", xsvfFil
e, vp);
78
if ( isNeroCapable ) {
79
status = flPlayXSVF(*handle, xsvfFile, &error);
80
rv = status;
81
//CHECK(18);
82
}
83
else {
84
fprintf(stderr, "XSVF play requested but device at %s does not support NeroJT
AG\n", vp);
85
//FAIL(19);
86
rv = status;
54 87
}
88
}
89
}
90
return rv;
91 }
92
93 int fpga_disconnect(struct FLContext *handle)
94 {
95
//run function to close communication with fpga
96
printf("closing FPGA\n");
97
flClose(handle);
98
return 0;
99 }
100
101 int fpga_wrReg8(struct FLContext *handle,int regNo, int val)
102 {
103
//load 8 bit version of value into data buffer
104
*buffer = (uint8)(0xff&val);
105
106
//initialize return value
107
int rv = 0;
108
109
//set up variable to a function that checks that the fpga is ready to communicate
110
isCommCapable = flIsCommCapable(handle);
111
if( isCommCapable )
112
{
113
//run function to write 1 byte to fpga (handle is the struct to communicate with the
fpga
114
//regNo is the register number, 1 is the amount of bytes, buffer is the data, and err
or
115
//is the error number if there is one (0 is success))
116
rv = flWriteChannel(handle,TIMEOUT_MS, (uint8)regNo, 1, buffer, &error);
117
}
118
else
119
//fpga is not ready to communicate
120
printf("could not send data to fpga");
121
if(rv)
122
showFPGAerror(rv);
123
return rv;
124 }
125
126 int fpga_wrReg32(struct FLContext *handle,int regNoBase, int val)
127 {
128
int i,rv=0;
129
uint8 *temp_buff=buffer;
130
//guarentee endianess by individually loading the 32 bit value to the buffer byte by byte
131
buffer[0] = (uint8)(0xff&val);
132
buffer[1] = (uint8)(0xff&(val>>8));
133
buffer[2] = (uint8)(0xff&(val>>16));
134
buffer[3] = (uint8)(0xff&(val>>24));
135
//printf("Buffer is: %c,%c,%c,%c",buffer[0],buffer[1],buffer[2],buffer[3]);
136
//set up variable to a function that checks that the fpga is ready to communicate
137
isCommCapable = flIsCommCapable(handle);
138
if( isCommCapable )
139
{
140
//run function to write 1 byte to fpga (handle is the struct to communicate with the
fpga
141
//regNoBase is the register number base register, 1 is the amount of bytes, buffer is
the data,
142
//and error is the error number if there is one (0 is success))
143
for(i=0;i<4;i++){
144
rv = flWriteChannel(handle,TIMEOUT_MS, (uint8)regNoBase+i, 1, temp_buff++, &error
);
145
if(rv){
146
showFPGAerror(rv);
147
return rv;
148
}
149
}
150
}
151
else
152
//fpga is not ready to communicate
153
printf("could not send data to fpga");
154
return rv;
55 155 }
156
157 int fpga_rdReg8(struct FLContext *handle,int regNo, int *val)
158 {
159
int rv=0;
160
//set up variable to a function that checks that the fpga is ready to communicate
161
isCommCapable = flIsCommCapable(handle);
162
if( isCommCapable )
163
{
164
//read from the register number into the buffer
165
rv = flReadChannel(handle, TIMEOUT_MS, (uint8)regNo, 1, buffer, &error);
166
}
167
else
168
printf("fpga not ready to communicate\n");
169
170
//load the value in the buffer into the output val
171
*val = *(buffer);
172
if(rv)
173
showFPGAerror(rv);
174
return rv;
175 }
176
177 int fpga_rdReg32(struct FLContext *handle,int regNoBase,int *val)
178 {
179
int rv=0,i;
180
uint8 *temp_buff=buffer;
181
//set up variable to a function that checks that the fpga is ready to communicate
182
isCommCapable = flIsCommCapable(handle);
183
if( isCommCapable )
184
{
185
//read from the register number into the buffer starting at regNoBase
186
*val=0;
187
for(i=0;i<4;i++){
188
rv = flReadChannel(handle, TIMEOUT_MS, (uint8)regNoBase+i, 1, temp_buff++, &error
);
189
if(rv){
190
showFPGAerror(rv);
191
return rv;
192
}
193
}
194
}
195
else
196
printf("fpga not ready to communicate\n");
197
//load the values in the buffer in proper endianess into val
198
*val = *(buffer) | (*(buffer+1)<<8) | (*(buffer+2)<<16) | (*(buffer+3)<<24);
199
200
return rv;
201 }
202
203 int fpga_rdStream(struct FLContext *handle, uint32 timeout, uint8 chan, uint32 count, uint8 *
buf)
204 {
205
int rv=0;
206
int i;
207
isCommCapable = flIsCommCapable(handle);
208
if( isCommCapable )
209
{
210
//for(i=0;i<count;i++){
211
rv = flReadChannel(handle, timeout, chan, count, buf,&error);
212
//printf("value: %c\n",*buf);
213
//}
214
}
215
else
216
printf("fpga not ready to communicate\n");
217
if(rv)
218
showFPGAerror(rv);
219
return rv;
220 }
221
222 void showFPGAerror(int rv){
223 switch(rv){
224
case
FL_SUCCESS:
printf("libFPGAlink: The operation completed successfully. (%d)\n
",rv);
56 225
break;
226
case
FL_ALLOC_ERR:
printf("libFPGAlink: There was a memory allocation error.(%d)\n",
rv);
227
break;
228
case
FL_USB_ERR:
printf("libFPGAlink: There was some USBrelated problem.(%d)\n",rv);
229
break;
230
case
FL_PROTOCOL_ERR:
printf("libFPGAlink: The device is probably not a valid \b FP
GALink device.(%d)\n",rv);
231
break;
232
case
FL_SYNC_ERR:
printf("libFPGAlink: The library was unable to synchronise the de
vice's bulk endpoints.(%d)\n",rv);
233
break;
234
case
FL_FX2_ERR:
printf("libFPGAlink: There was some problem talking to the FX2 ch
ip.(%d)\n",rv);
235
break;
236
case
FL_JTAG_ERR:
printf("libFPGAlink: There was some problem with the NeroJTAG int
erface.(%d)\n",rv);
237
break;
238
case
FL_FILE_ERR:
printf("libFPGAlink: There was a filerelated problem.(%d)\n",rv);
239
break;
240
case
FL_WBUF_ERR:
printf("libFPGAlink: There was some problem with the write buffer
.(%d)\n",rv);
241
break;
242
case
FL_BUF_INIT_ERR:
printf("libFPGAlink: The CSVF buffer could not be allocated.(
%d)\n",rv);
243
break;
244
case
FL_BUF_APPEND_ERR:
printf("libFPGAlink: The CSVF buffer could not be grown.(
%d)\n",rv);
245
break;
246
case
FL_BUF_LOAD_ERR:
printf("libFPGAlink: The XSVF file could not be loaded.(%d)\n
",rv);
247
break;
248
case
FL_UNSUPPORTED_CMD_ERR:
printf("libFPGAlink: The XSVF file contains an unsupp
orted command.(%d)\n",rv);
249
break;
250
case
FL_UNSUPPORTED_DATA_ERR:
printf("libFPGAlink: The XSVF file contains an unsupp
orted XENDIR or XENDDR.(%d)\n",rv);
251
break;
252
case
FL_UNSUPPORTED_SIZE_ERR:
printf("libFPGAlink: The XSVF file requires more buff
er space than is available.(%d)\n",rv);
253
break;
254
case
FL_SVF_PARSE_ERR:
printf("libFPGAlink: The SVF file was not parseable.(%d)\
n",rv);
255
break;
256
case
FL_INTERNAL_ERR:
printf("libFPGAlink: An internal error occurred. Please r
eport it!(%d)\n",rv);
257
break;
258
default:
printf("libFPGAlink: An undeclared error occurred:(%d)\n",rv);
259
}
260 }
1.3.4 dcmusb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Team Spectrum UIM to DCM interface definition
/* Kevin Nicotera and Jacob Dilles
/* 9/7/2012
#include "libfpgalink.h"
*/
*/
*/
//call this first to initialize communication with the fpga
int fpga_init(void);
//connect to FPGA
//pass pointer to pointer to flContext and fpga_connect will initialize the struct
int fpga_connect(const char *vp, struct FLContext **handle);
//disconnect from FPGA
int fpga_disconnect(struct FLContext *handle);
57 16 //write 8 bits to DCM register number x
17 //val[ 7 downto 0] => REG(regNoBase);
18 int fpga_wrReg8(struct FLContext *handle,int regNo, int val);
19
20 //write 32 bits to DCM starting at register number regNoBase
21 //val[31 downto 24] => REG(regNoBase + 3);
22 //val[23 downto 16] => REG(regNoBase + 2);
23 //val[15 downto 8] => REG(regNoBase + 1);
24 //val[ 7 downto 0] => REG(regNoBase);
25 int fpga_wrReg32(struct FLContext *handle,int regNoBase, int val);
26
27 //read 8 bits from DCM register number x to UIM
28 //REG(regNoBase) => val[ 7 downto 0];
29 int fpga_rdReg8(struct FLContext *handle,int regNo, int *val);
30
31 //read 32 bits from DCM to UIM starting at register number regNoBase
32 //REG(regNoBase + 3) => val[ 31 downto 24];
33 //REG(regNoBase + 2) => val[ 23 downto 16];
34 //REG(regNoBase + 1) => val[ 15 downto
8];
35 //REG(regNoBase)
=> val[ 7 downto
0];
36 int fpga_rdReg32(struct FLContext *handle,int regNoBase,int *val);
37
38
39 int fpga_rdStream(struct FLContext *handle, uint32 timeout, uint8 chan, uint32 count, uint8 *b
uf);
40
41 void showFPGAerror(int rv);
1.3.5 dcmusb_unitTest.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
f)
34
35
36
37
38
39
40
#include "dcmusb.h"
#include <stdio.h>
#include "libfpgalink.h"
#define SCAN_MIN_REG (0x32)
#define SCAN_MAX_REG (0x36)
#define SCAN_STEP_REG (0x40)
#define SPS_REG (0x44)
#define UI_CMD_REG (0x7E)
#define FPGA_CMD_REG (0x7F)
#define STREAM_REG (0x00)
#define
#define
#define
#define
CMD_START (0x53)
STATUS_IDLE (0x00)
CMD_ABORT (0x00)
BAD_PARAM (0x60)
void debug(int step);
int main(void)
{
struct FLContext *handle = NULL;
const char *vp = "1443:0007";
char regValue;
char buff[10000];
int i,num=1;
printf("FPGALink device %s\n",vp);
debug(0);
fpga_init();
debug(1);
fpga_connect(vp,&handle);
debug(2);
//printf("%ld\n",sizeof(int));
fpga_wrReg8(handle,SCAN_MIN_REG,num);
//fpga_rdStream(struct FLContext *handle, uint32 timeout, uint8 chan, uint32 count, uint8 *bu
for(num=0; num<1000; num++){
fpga_rdStream(handle,1000,STREAM_REG,10000,buff);
for(i=0;i<10000;i++){
if(buff[i]){
printf("got some data: %d\n",buff[i]);
}
}
58 41
42
43
44
45
46
47
48
49
}
debug(3);
fpga_disconnect(handle);
debug(4);
}
void debug(int step)
{
printf("at step %d\n",step);
}
1.3.6 dosa.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ry;
19
20
21
22
23
24
25
26
27
28
29
30
",
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "support.h"
#define DATA_LEN (8200)
#define OVERVIEW_DATA_LEN (4000)
#define OVERVIEW_SCAN_STEP (((1<<31)/OVERVIEW_DATA_LEN)*2)
#define START_VALUE_DEF (0)
#define STOP_VALUE_DEF (0xFFFFFF00)
#define REFRESH_RATE_DEF (10)/*hertz*/
#define IPM_CLK_FREQ_DEF (25000000)
#define GAIN_STAGE (7)
//#define PRNTTEST
#define FTDI_COMM (1)
//#define NO_PERFORM
uint32_t STOP_VALUE,START_VALUE,IPM_CLK_FREQ,REFRESH_RATE,SCAN_STEP;
static int width,center;
_scanStr s;
int context, str_len, text_pos, interval=100, slow_interval=4000, context, entry_num=0, rota
int settings_flag = 1, gain;
const char* str2,*begin_entry = "0000000.000";
static const char gain_lookup[16] = {0x00,0x81,0x42,0xC3,
0x24,0xA5,0x66,0xE7,
0x18,0x99,0x5A,0xDB,
0x3C,0xBD,0x7E,0xFF};
const guint grlen = DATA_LEN-10;
float x[DATA_LEN],y[DATA_LEN],ox[DATA_LEN],oy[DATA_LEN],ramp[DATA_LEN],low_marker[2]
,high_marker[2];
static float low_marker_height[]={0,ADC_MAX},high_marker_height[]={0,ADC_MAX};
static char* label_names[] = {"Run Mode","Window","Samples/FSR","Offset","Laser Wavelength",
"Mirror Reflect.","Mirror Spacing","Min Voltage","Max Voltage
"Gain","FSR","Finesse"};
char *volt_div_label = "Hz/Div: 0",*amp_div_label = "A/Div: 0",
*hertz_rate_label = "Hz Rate: 0",pixel_diff_str,amp_diff_str,hz_diff_str;
static char* setting_names[] = {"setting1","setting2","Save configuration","Save data"};
volatile unsigned int drawing;
struct FLContext *handle = NULL;
/******* This function is called by exit(int) *****/
void onExit (void)
{
int rv;
do{
fpga_wrReg8(handle,GPIO_REG,HV_OFF);
}while(!fpga_rdReg8(handle,GPIO_REG,&rv) || !rv);
fpga_wrReg8(handle,UI_CMD_REG,CMD_ABORT);//stop the fpga from running
fpga_disconnect(handle);
printf ("Closing FPGA safely and exiting program\n");
// should call gtk_main_quit() here
}
int main( int argc, char **argv )
{
/****************************************/
/* Local Variables to the main function */
/****************************************/
59 57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
****/
91
*/
92
*/
93
/
94
****/
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
****/
112
*/
113
s */
114
*/
115
****/
116
117
118
119
int i;
if(load_ini_config()){
//complain
}
/************************************************/
/* Initializations for GTK+ and the main window */
/************************************************/
gtk_init( &argc, &argv );
//Create Base Design:
GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //create top level window
gtk_widget_set_size_request (window, 1060, 600);//set size of window
g_signal_connect (GTK_OBJECT (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);//allow user to close window
gtk_window_set_title (GTK_WINDOW (window),
"Team Spectrum: Digital Optical Spectrum Analyzer");//set title of window
/****************************************************************/
/*
Set Up Graphing Area of Main Window
*/
/* This section lays out the graphing are of the main window
*/
/*
as specified in the design document
*/
/****************************************************************/
//Create split between graphing area and settings area
GtkWidget *hpane1 = gtk_hpaned_new();
gtk_container_add (GTK_CONTAINER (window), hpane1);
//Create vertical box area for both graphs
GtkWidget *graph_vbox = gtk_vbox_new(FALSE,0);
//pack with respect to beginning of hpane(leftmost)
gtk_paned_add1(GTK_PANED(hpane1),graph_vbox);
/****************************************************************************************
/*
High Resolution Graph Settings
/*This area is to set up the high resolution graph.
This will allow someone
/*to obtain a better visual of information of certain parts of the optical spectrum
*
/****************************************************************************************
//create databox for high resolution picture of selected spectrum
gtk_databox_create_box_with_scrollbars_and_rulers (
&databox_highres, &databoxcontainer_highres,
FALSE, FALSE, TRUE, TRUE);
//settings for high res graph
gtk_databox_set_total_limits (GTK_DATABOX(databox_highres),0, 250000, 300, 0);
gtk_box_pack_start(GTK_BOX(graph_vbox), databoxcontainer_highres, 0, 0, 0 );
//force a minimum size for the graph
gtk_widget_set_size_request(databoxcontainer_highres,700,450);
//allow for zooming
gtk_databox_set_enable_zoom (GTK_DATABOX(databox_highres), TRUE);
//hopefully get a grid
GtkDataboxGraph* high_res_gr = gtk_databox_grid_new (20, 40, &gridColor, 0);
//set background color
gtk_widget_modify_bg(databox_highres, GTK_STATE_NORMAL,&bgColor);
/****************************************************************************************
/*
/*
/*
Center Section for Volts/Div and other Information
This will display information for the graphs including (hopefully) x and y coordinate
and definitely will include Volts/Div as specified in design document
/****************************************************************************************
//center area for selected data
GtkWidget *hbox1 = gtk_hbox_new(FALSE,0);
//gtk_paned_add2(GTK_PANED(hpane1),vbox2);
gtk_box_pack_start(GTK_BOX(graph_vbox), hbox1, 0,0,0);
60 120
121
122
123
124
125
126
127
GtkWidget *lowerGraphDiv = gtk_label_new("Hz/Div: ");
GtkWidget *upperGraphDiv = gtk_label_new("A/Div: ");
GtkWidget *graphRate = gtk_label_new("Hz Rate: ");
gtk_box_pack_start(GTK_BOX(hbox1),lowerGraphDiv,1,0,0);
gtk_box_pack_start(GTK_BOX(hbox1),upperGraphDiv,1,0,0);
gtk_box_pack_start(GTK_BOX(hbox1),graphRate,1,0,0);
128
/*
129
/*
130
/*
131
/****************************************************************************************
/****************************************************************************************
/
Low Resolution Graph Settings
*
/
This area is to set up the high resolution graph.
This will allow
*
/
the user to "see the big picture" of the optical spectrum
*
/
/
132
//low resolution graph for big picture of spectrum
133
//gtk_box_pack_start(GTK_BOX(vbox1), lowres_window, 0, 0, 0 );
134
gtk_databox_create_box_with_scrollbars_and_rulers (
135
&databox_lowres, &databoxcontainer_lowres,
136
FALSE, FALSE, TRUE, TRUE);
137
//gtk_databox_set_total_limits (GTK_DATABOX(databox_lowres),0, 250000, 300, 0);
138
gtk_box_pack_start(GTK_BOX(graph_vbox), databoxcontainer_lowres, 0, 0, 0 );
139
gtk_widget_set_size_request(databoxcontainer_lowres,700,115);
140
GtkDataboxGraph* low_res_gr = gtk_databox_grid_new (5, 40, &gridColor, 1);
141
gtk_widget_modify_bg(databox_lowres, GTK_STATE_NORMAL,&bgColor);
142
gtk_databox_graph_add (GTK_DATABOX (databox_lowres), low_res_gr);
143
144
/****************************************************************/
145
/*
Set Up Settings Area of Main Window
*/
146
/* This section lays out the settings area of the main window */
147
/*
as specified in the design document
*/
148
/****************************************************************/
149
//Create vertical box area for settings
150
GtkWidget *vbox2 = gtk_vbox_new(FALSE,0);
151
//pack with respect to the end of the hpane(rightmost)
152
gtk_paned_add2(GTK_PANED(hpane1),vbox2);
153
154
//create settings panel with column of labels with text entries
155
GtkWidget *databuttons = gtk_vbutton_box_new();
156
gtk_box_set_spacing(GTK_BOX(databuttons),10);
157
gtk_box_pack_start(GTK_BOX(vbox2), databuttons, 0, 0, 0 );
158
159
//create labels with text entries
160
//for loop to create all the text entries and labels
161
for(i=0;i<9;i++){
162
button_hbox[i] = gtk_hbox_new(FALSE,0);
163
gtk_container_add(GTK_CONTAINER(databuttons),button_hbox[i]);
164
button_label[i] = gtk_label_new(label_names[i]);
165
gtk_box_pack_start(GTK_BOX(button_hbox[i]), button_label[i], 1, 0, 1 );
166
button_entry[i] = gtk_entry_new_with_max_length(MAX_ENTRY);
167
gtk_editable_set_editable(GTK_EDITABLE(button_entry[i]),TRUE);
168
gtk_entry_set_editable(GTK_ENTRY(button_entry[i]), TRUE);
169
gtk_editable_insert_text(GTK_EDITABLE(button_entry[i]),begin_entry,11,entry_pos);
170
gtk_widget_set_can_focus(button_entry[i],TRUE);
171
gtk_box_pack_start(GTK_BOX(button_hbox[i]), button_entry[i], 1, 0, 1 );
172
}
173
174
/****************************************************************/
175
/*
Runtime Functions
*/
176
/* This are is for functions that will be started at runtime
*/
177
/* such as the graphing system and serial input system
*/
178
/****************************************************************/
179
//create signals for graphing functions
180
//Display contents and run program
181
gtk_widget_show_all (window);
182 /*#ifdef FTDIComm
183
//Serial Input stuff//
184
// Set up the shutdown stuff;
185
setupShutdown();
186
187
fsm_enabled = TRUE;
61 188 //Begins the FSM taking in values from the user from hardware
189
190
// use defined value (OS specific)
191
//printf("about to enable the userIO\n");
192
char* ftdi_name = FTDI_DEV;
193
GIOChannel *deviceChannel;
194
//deviceChannel = g_io_channel_unix_new(0);
195
//g_io_add_watch(deviceChannel, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL , &doBackgroundIOops,
NULL);
196
// Open the file descripter
197
if( openFTDIfd(ftdi_name, &deviceChannel) != 0 ){
198
printf("Could not open %s\n",ftdi_name);
199
terminate(1);
200
}
201 #endif*/
202
//Initialize and setup FPGA communication
203
const char *vp = "1443:0007";
204
fpga_init();
205
fpga_connect(vp,&handle);
206
fpga_wrReg8(handle,GPIO_REG,HV_ON);
207
scanStr s = scan_init((1<<31)+(1<<29),1<<29,DATA_LEN);
208
g_timeout_add(1,&dcmFSM,s);
209
210
//g_signal_connect(G_OBJECT(graph_vbox),"graph_func",G_CALLBACK(graph_func),NULL);
211
gtk_main();
212
return 0;
213 }
214
215 /****************************************************************/
216 /*
dcmFSM Function
*/
217 /*
inputs: fpga scan struct
*/
218 /*
outputs: TRUE or FALSE to continue running
*/
219 /*
Functions: finite state machine to take in new values
*/
220 /*
wait for the FPGA to finish or graph data
*/
221 /****************************************************************/
222 gint dcmFSM(gpointer s){
223
int stat = 1;
224
static int count = 0;
225
if(fpga_rdReg8(handle,FPGA_CMD_REG,&stat)){
226
printf("error reading fpga\n");
227
return FALSE;
228
}
229
switch(state){
230
case START_SCAN:
231
//scan_init(center,width,DATA_LEN);
232
start_scan(s);
233
state = WAIT_FOR_DATA;
234
break;
235
case WAIT_FOR_DATA:
236
count++;
237
if(stat == FIFO_WAIT){
238
state = GRAPH;
239
}
240
break;
241
case GRAPH:
242 #ifdef PRNTTEST
243
printf("spins before status ok: %d\n",count);
244 #endif
245
count = 0;
246
graph_func(s);
247 #if 0
248
return FALSE;
249 #endif
250
state = START_SCAN;
251
break;
252
default:
253
state = START_SCAN;
254
}
255
return TRUE;
256 }
257
258 /****************************************************************/
259 /*
start_scan Function
*/
62 260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/*
inputs: fpga scan struct
*/
/*
outputs: errors from writing to the FPGA
*/
/*
Function: writes information to the FPGA to determine
*/
/*
when to start,stop,step size,samples per step */
/****************************************************************/
int start_scan(scanStr s){
int rv = 0;
rv = fpga_rdReg8(handle,FPGA_CMD_REG,&(s->status));
//rv = fpga_wrReg8(handle,GAIN_REG,0);
/* Min value for the overview (0) */
rv = fpga_wrReg32(handle,START_REG,START_VALUE);
/* Max value for the overview (max int value) */
rv = fpga_wrReg32(handle,STOP_REG,((uint32_t)STOP_VALUE)-(s->scan_step));
/* create reasonable step size to handle drawing */
rv = fpga_wrReg32(handle,OVERVIEW_STEP_REG,(s->over_per_step)-1);//scan_step for overview
rv
rv
rv
rv
=
=
=
=
fpga_wrReg32(handle,SCAN_MIN_REG,s->scan_min);//scan_min
fpga_wrReg32(handle,SCAN_MAX_REG,s->scan_max);//scan_max
fpga_wrReg32(handle,SCAN_STEP_REG,s->scan_step);//samples per step
fpga_wrReg32(handle,SPS_REG,(s->samples_per_step)-1);//scan_step
rv = fpga_rdReg8(handle,FPGA_CMD_REG,&(s->status));
rv = fpga_wrReg8(handle,GAIN_REG,gain_lookup[gain]);
rv = fpga_wrReg8(handle,UI_CMD_REG,CMD_START);
rv = fpga_rdReg8(handle,FPGA_CMD_REG,&(s->status));
#ifdef PRNTTEST
printf("Line 274 status=%d\n",s->status);
#endif
return rv;
}
/************************************************************************/
/*
read_data Function
*/
/*
inputs: buffer register, x array, y array
*/
/*
outputs: return value of error(zero for no error)
*/
/*
Function: reads either the overview buffer register or high
*/
/*
resolution register for all of the values to graph
*/
/************************************************************************/
#define INVERSE_WORD ( (1.0) / (double)(1<<16) )
#define SCALE_ADC_Y(y)
(float)(((double)(((uint32_t)(y))>>16))*INVERSE_WORD)
int read_data(int reg,float *x,float *y,scanStr s)
{
int i,rv=0;
static uint8_t buff[DATA_LEN*8 + 64];
fpga_rdStream(handle,FPGA_TIMEOUT,reg, DATA_LEN*8+8, buff);
uint32_t * ibuf = (uint32_t*) buff;
uint32_t xt, yt;
uint32_t miny=1<<30,maxy=0, minx=1<<30,maxx=0;
/* save the values as a float for graphing using gtkdatabox */
//if(reg == OVERVIEW_STREAM_REG){or
for(i = 0; i < DATA_LEN; i++){
xt = ntohl((uint32_t) *(ibuf++));
yt = ntohl((uint32_t) *(ibuf++));
miny = yt < miny ? yt : miny;
maxy = yt > maxy ? yt : maxy;
minx = xt < minx ? xt : minx;
maxx = xt > maxx ? xt : maxx;
if( (yt&0xFFF) == 0xBAD)
{
y[rv] = SCALE_ADC_Y(yt);
//y[rv] = (float)(yt&~(0xfff));
//ramp[rv] = (float)(xt); // find me a better home
x[rv] = (float)xt; // scale factor eventually
rv++;
}
}
#ifdef PRNTTEST
printf("X: %u - %u
Y: %f - %f\n", minx, maxx,SCALE_ADC_Y(miny),SCALE_ADC_Y(maxy));
printf("finished for loop (got %d valid)\n",rv);
#endif
return rv;
63 333 }
334
335 /********************************************************************************/
336 /*
graph_func Function
*/
337 /*
inputs: fpga scan struct
*/
338 /*
outputs: gint(same as int) that is either TRUE or FALSE to
*/
339 /*
determine whether to continue drawing(TRUE) or not
*/
340 /*
(FALSE)
*/
341 /*
Function: takes values from the buffer registers and graphs
*/
342 /*
the values onto gtkdatabox graphs. After the first
*/
343 /*
draw, the graphs must be removed to not cause memory leaks
*/
344 /********************************************************************************/
345 gint graph_func(void *_s){
346
int stat = 1,rv;
347
348
const guint line_size = 1;
349
static int marker_points = 2;
350
351
static int firstTime=1;
352 #ifndef NO_PERFORM
353
struct timeval start ,end;
354
long mtime, seconds, useconds;
355
gettimeofday(&start,NULL);
356 #endif
357
358
359
fpga_rdReg8(handle,FPGA_CMD_REG,&stat);
360
if(stat != FIFO_WAIT){
361
return TRUE;
362
}
363
364
365
scanStr s = (scanStr) _s;
366
/* Set the markers to the user defined spot, specifically scan_min and scan_max */
367
low_marker[0] = s->scan_min;
368
low_marker[1] = s->scan_min;
369
high_marker[0] = s->scan_max;
370
high_marker[1] = s->scan_max;
371
372
373
374
if(firstTime == 1){
375
firstTime = 0;
376
377
378
}
379
else{
380
//gtk_databox_graph_remove(GTK_DATABOX(databox_lowres),low_res_graph);
381
//gtk_databox_graph_remove(GTK_DATABOX(databox_lowres),lower_marker);
382
//gtk_databox_graph_remove(GTK_DATABOX(databox_lowres),upper_marker);
383
//gtk_databox_graph_remove(GTK_DATABOX(databox_lowres),low_res_ramp);
384
//gtk_databox_graph_remove(GTK_DATABOX(databox_highres),high_res_graph);
385
}
386
387
388
389
/* Get the values from the FPGA for the high res graph then graph it */
390
gtk_databox_set_total_limits(GTK_DATABOX(databox_highres),s->scan_min,s>scan_max,ADC_MAX,0);
391
rv = read_data(STREAM_REG,x,y,s);
392
393 #ifdef PRNTTEST
394
printf("return value for STREAM_REG: %d\n",rv);
395 #endif
396
397
/* Get the values from the FPGA for the low res graph then graph it */
398
/* and graph scan_min and scan_max as cursors on the low res graph */
399
rv = read_data(OVERVIEW_STREAM_REG,ox,oy,s);
400 #ifdef PRNTTEST
401
printf("return value for OVERVIEW_STREAM_REG: %d\n",rv);
402 #endif
403
/* Add the graphs back onto the gtkdatabox container widget */
404
high_res_graph = gtk_databox_lines_new(rv,x,y,&cyan,line_size);
64 405
high_res_grid = gtk_databox_grid_new (20, 40, &white, 0);
406
gtk_databox_graph_add (GTK_DATABOX (databox_highres), high_res_grid);
407
low_res_graph = gtk_databox_lines_new(rv,ox,oy,&cyan,line_size);
408
//low_res_ramp = gtk_databox_lines_new(grlen,ox,ramp,&red,line_size);
409
lower_marker = gtk_databox_lines_new(marker_points,low_marker,low_marker_height,&cyan
,line_size);
410
upper_marker = gtk_databox_lines_new(marker_points,high_marker,high_marker_height,&cy
an,line_size);
411
gtk_databox_graph_add(GTK_DATABOX(databox_lowres),low_res_graph);
412
//gtk_databox_graph_add(GTK_DATABOX(databox_lowres),low_res_ramp);
413
gtk_databox_graph_add(GTK_DATABOX(databox_lowres),lower_marker);
414
gtk_databox_graph_add(GTK_DATABOX(databox_lowres),upper_marker);
415
gtk_databox_graph_add(GTK_DATABOX(databox_highres),high_res_graph);
416
gtk_databox_set_total_limits(GTK_DATABOX(databox_lowres),START_VALUE,STOP_VALUE,ADC_M
AX,0);
417
//gtk_databox_auto_rescale(GTK_DATABOX(databox_lowres),0.005);
418
419
gtk_widget_queue_draw (GTK_WIDGET (databox_lowres));
420
gtk_widget_queue_draw (GTK_WIDGET (databox_highres));
421 #ifndef NO_PERFORM
422
gettimeofday(&end,NULL);
423
seconds = end.tv_sec - start.tv_sec;
424
useconds = end.tv_usec - start.tv_usec;
425
mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
426
static int decount = 0;
427
printf("Graph Calc time: %ld milliseconds,%d\n",mtime,decount++);
428 #endif
429
drawing = 0;
430
fpga_wrReg8(handle,UI_CMD_REG,CMD_START);
431
return TRUE;
432 }
433
434 /********************************************************************************/
435 /*
button Functions
*/
436 /*
inputs: nothing
*/
437 /*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
438 /*
Function: These functions right now just toggle the leds on the buttons */
439 /*
with the exception being that pressed cursor will display
*/
440 /*
the settings window
*/
441 /********************************************************************************/
442 gint uim_pressed_home(void){
443
uim_led_toggle(BTN_HOME);
444
return FALSE;
445 }
446
447 gint uim_pressed_measure(void){
448
uim_led_toggle(BTN_MEASURE);
449
return FALSE;
450 }
451
452 //for right now this will be the settings button
453 gint uim_pressed_cursor(void){
454
uim_led_toggle(BTN_CURSOR);
455
if(settings_flag == 1){
456
settings();
457
settings_flag = 1 - settings_flag;
458
context = 5;
459
}
460
else{
461
printf("this should close the settings window\n");
462
gtk_widget_destroy(settings_window);
463
settings_flag = 1 - settings_flag;
464
context = 0;
465
}
466
return FALSE;
467 }
468
469 gint uim_pressed_memory(void){
470
uim_led_toggle(BTN_MEMORY);
471
return FALSE;
472 }
473
474 gint uim_pressed_power(void){
65 475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
uim_led_toggle(BTN_POWER);
return FALSE;
}
/********************************************************************************/
/*
rotary encoder button Functions
*/
/*
inputs: nothing
*/
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: These functions switch the context of the UIM-E finite state */
/*
machine. They include toggles to simplify the mechanism
*/
/********************************************************************************/
gint uim_pressed_k0(void){
static int x = 0;
/* If your in the Home State this will switch between the home state
*/
/* and the Field Select State
*/
if(context == 0){
x = 1-x;
if(x == 1){
context = 1;
}
else{
context = 0;
}
}
/* If your in the Field Select State this will switch between the home state
*/
/* and the Field Select State
*/
else if(context == 1){
x = 1-x;
if(x ==1){
context = 1;
}
else{
context = 0;
}
}
/* If your in the Edit Field State this will switch between the edit field state*/
/* and the Field Select State
*/
else if(context == 2){
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str2);
context = 1;
}
return FALSE;
}
gint uim_pressed_k1(void){
static int x = 0;
/* This will save the modified value and return from the Edit Field State to*/
/* the Field Sele(2*width)/(ss*DATA_LEN)ct state
*/
if(context == 1){
x = 1-x;
if(x == 1){
str2 = gtk_entry_get_text(GTK_ENTRY(button_entry[entry_num]));
entry_pos[entry_num] = 7;
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]);
context = 2;
}
else if(x == 0){
context = 1;
}
}
else if(context == 2){
context == 1;
}
return FALSE;
}
/************************************************************************************/
/*
rotary encoder rotation Functions
*/
/*
inputs: integer value(positive or negative) denoting
*/
/*
denoting the number or ticks on the rotary encoder */
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: These functions apply rotary movement to the text entries
*/
66 547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
/************************************************************************************/
gint uim_rotated_k0(int n)
{
rotary = 0;
/* Run functions dependent on the state the UIM is in at the time */
if(context == 0){
//printf("in home context\n");
uim_state_home(n);
}
else if(context == 1){
uim_state_field_select(n);
}
else if(context == 2){
uim_state_edit_field(n);
}
else if(context == 5){
uim_settings_choice(n);
}
return FALSE;
}
gint uim_rotated_k1(int n){
rotary = 1;
/* Run functions dependent on the state the UIM is in at the time*/
if(context == 0){
uim_state_home(n);
}
else if(context == 2){
uim_state_edit_field(n);
}
else if(context == 5){
uim_settings_choice(n);
}
return FALSE;
}
/************************************************************************************/
/*
Number Pad Functions
*/
/*
inputs: character that should be a ASCII number or * or #
*/
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: This function will apply a number to the
*/
/*
text entry that is selected
*/
/************************************************************************************/
gint uim_pressed_number(char num){
if(context == 0){
gain = num-'0';
printf("changing the gain level to %d (%x)\n",gain,gain_lookup[gain]);
}
if(context == 3){
/* This will add values to the text entry selected*/
char str[] = {num,0};
gtk_editable_insert_text(GTK_EDITABLE(button_entry[entry_num]),str,1,entry_pos);
if(entry_pos[entry_num] < 11){
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]++)
;
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
}
else{
context = 1;
}
}
else{
printf("this isn't implemented yet\n");
}
return FALSE;
}
/* If the user presses star then the system will either change context */
/* or clear the text entry and change the context to manually change the value */
gint uim_pressed_star(void){
if(context == 1){
context = 3;
str2 = gtk_entry_get_text(GTK_ENTRY(button_entry[entry_num]));
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),"");
67 619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
);
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
}
else if(context == 3){
context = 1;
}
else{
printf("this function hasn't been implemented yet\n");
}
return FALSE;
}
gint uim_pressed_pound(void){
if(context == 3){
/* Delete a value or save value and go back to field select state*/
if (entry_num >= 8){
entry_num = 8;
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str2);
context = 1;
} else{
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]-}
}
else if(context == 2){
/* Save the value and go back to field select state */
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str2);
context = 1;
}
return FALSE;
}
/************************************************************************************/
/*
UIM STATE HOME Function
*/
/*
inputs: integer value that is positive or negative
*/
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: Move the cursor on the graphs to obtain expansion and offset
*/
/************************************************************************************/
gint uim_state_home(int n){
/* Get two pixels values that are right next to each other then subtract them */
/* to get the distance of one pixel for scaling purposes */
//pixel1 = gtk_databox_pixel_to_value_x(GTK_DATABOX(databox_lowres),center);
//pixel2 = gtk_databox_pixel_to_value_x(GTK_DATABOX(databox_lowres),center-1);
//pixel_diff= pixel1 - pixel2;
#undef MAX_WIDTH
#define MAX_WIDTH ((STOP_VALUE_DEF-START_VALUE_DEF)/2)
//static int64_t width=MAX_WIDTH/2,center=START_VALUE_DEF+MAX_WIDTH;
int64_t pixel_diff = width/MIN_WIDTH;
int64_t temp_width,temp_center;
if(abs(n) > 8){
n *= 2;
}
n *= 2;
if(rotary == 1){
width += pixel_diff*n;
if(width+center > STOP_VALUE){
width = STOP_VALUE-center-1;
}
printf("The width+center is: %ld\n",width);
if(center-width < 0){
width = center-1;
}
printf("The center-width is: %ld\n",width);
if(width < MIN_WIDTH){
width = MIN_WIDTH;
}
printf("The smallest width is: %ld\n",width);
if(!((2*width)/(SCAN_STEP*DATA_LEN))){
width = (SCAN_STEP*DATA_LEN)>>1;
}
}
else if(rotary == 0){
center += pixel_diff*n;
if(center < width){
68 691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
center = width + 1;
}
if(center > (STOP_VALUE-width)){
center = STOP_VALUE-width-1;
}
}
//set the values on the middle section in between the graphs
//pixel_diff2 = 5*pixel_diff;
//amp1 = gtk_databox_pixel_to_value_y(GTK_DATABOX(databox_highres),0);
//amp2 = gtk_databox_pixel_to_value_y(GTK_DATABOX(databox_highres),5);
//sprintf(&pixel_diff_str,"Hz/Div: %f",pixel_diff2);
//sprintf(&amp_diff_str,"Amp/Div: %f",amp_diff);
//sprintf(&hz_diff_str,"Hz Rate: %f",pixel_diff);
//gtk_label_set_text(GTK_LABEL(lowerGraphDiv),&pixel_diff_str);
//gtk_label_set_text(GTK_LABEL(upperGraphDiv),&amp_diff_str);
//gtk_label_set_text(GTK_LABEL(graphRate),&hz_diff_str);
scan_init((int)center,(int)width,DATA_LEN);
return FALSE;
}
/************************************************************************************/
/*
UIM STATE FIELD SELECT Function
*/
/*
inputs: integer value that is positive or negative
*/
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: Rotate through the text entry fields next to the graphs
*/
/************************************************************************************/
gint uim_state_field_select(int n){
static int last = 0;
/* make a text entry grab mouse focus manually since there will be no mouse */
if(n == last){
last = 0;
if(n >= DIR_CW){
if(entry_num >= 9){
entry_num = 1;
gtk_widget_grab_focus(button_entry[entry_num]);
}
else{
entry_num = entry_num + 1;
gtk_widget_grab_focus(button_entry[entry_num]);
}
}
else if(n <= DIR_CCW){
if(entry_num <= 1){
entry_num = 9;
gtk_widget_grab_focus(button_entry[entry_num]);
}
else{
entry_num = entry_num - 1;
gtk_widget_grab_focus(button_entry[entry_num]);
}
}
}
else{
//slow down the rotation so it is one text entry per click
last = n;
}
return FALSE;
}
/************************************************************************************/
/*
UIM STATE EDIT FIELD Function
*/
/*
inputs: integer value that is positive or negative
*/
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: add/subtract one on the text entry value on each rotary click
*/
/*
wrapping the carry to the next significant bit and hold at
*/
/*
MAX_VALUE(999999.999) and MIN_VALUE(000000.000) also change
*/
/*
the position to start adding and subtracting
*/
/************************************************************************************/
gint uim_state_edit_field(int n){
static int last = 0;
/* add/subtract rotary encoder is being used*/
69 764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
if(rotary == 1){
int i,j,store=-1,flag=0;
char* str3 = gtk_editable_get_chars(GTK_EDITABLE(button_entry[entry_num]),0,11);
i = entry_pos[entry_num];
if(n == last){
last = 0;
/* Add to the value in the text entry with carry to next value*/
if(n >= DIR_CW){
do{
if(str3[i] == '.'){
str3[i] = '.';
i=i-n;
flag = 1;
}
else{
str3[i]=str3[i]+n;
if(str3[i] > '9'){
if(i == 0){
str3[i] = '9';
flag = 0;
}
else{
str3[i] = '0';
i=i-n;
flag = 1;
}
}
else{
flag = 0;
}
}
}while(flag);
}
/* Subtract from the value in the text entry with carry */
else if(n <= DIR_CCW){
for(j=0;j<=i;j++){
if(str3[j] > '0'){
store = j;
}
}
do{
if(str3[i] == '.'){
str3[i] = '.';
i--;
flag = 1;
}
else if(store == -1){
str3[i] = '0';
flag = 0;
}
else if(store >= 0){
if(i == store){
str3[i]--;
}
else if(i > store){
str3[i] = '9';
}
if(i != 0){
i--;
flag = 1;
}
else{
flag = 0;
}
}
}while(flag);
}
}
else{
last = n;
}
/* set the text entry with the updated value and change the position if necessary */
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str3);
70 837
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]);
838
}
839
/* change the starting position */
840
else if(rotary == 0){
841
if(n == last){
842
if(n >= DIR_CW){
843
if(entry_pos[entry_num] >= 10){
844
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]=10);
845
}
846
else{
847
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]++);
848
}
849
}
850
else if(n <= DIR_CCW){
851
if(entry_pos[entry_num] < 1){
852
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]=0);
853
}
854
else{
855
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]--);
856
}
857
}
858
}
859
/* Wait for a click on the rotary encoder */
860
else{
861
last = n;
862
}
863
}
864
return FALSE;
865 }
866
867 /********************************************************************/
868 /*
Settings Window Function
*/
869 /*
inputs: nothing
*/
870 /*
outputs: nothing
*/
871 /*
Function: open a settings window for saving
*/
872 /*
values and other potential function
*/
873 /********************************************************************/
874 void settings(void){
875
int i;
876
//Create Settings window
877
settings_window = gtk_window_new (GTK_WINDOW_POPUP);
878
gtk_widget_set_size_request (settings_window, 300, 200);
879
//g_signal_connect (GTK_OBJECT (settings_window), "destroy",
880
// G_CALLBACK (gtk_main_quit), NULL);
881
//set title of window
882
gtk_window_set_title (GTK_WINDOW (settings_window),
883
"Team Spectrum: DOSA Settings");
884
885
GtkWidget *settingbuttons = gtk_vbutton_box_new();
886
gtk_box_set_spacing(GTK_BOX(settingbuttons),4);
887
gtk_container_add(GTK_CONTAINER(settings_window), settingbuttons);
888
889
for(i=0;i<4;i++){
890
setting_hbox[i] = gtk_hbox_new(FALSE,0);
891
gtk_container_add(GTK_CONTAINER(settingbuttons),setting_hbox[i]);
892
setting_button[i] = gtk_button_new_with_label(setting_names[i]);
893
gtk_widget_set_can_focus(setting_button[i],TRUE);
894
gtk_box_pack_start(GTK_BOX(setting_hbox[i]), setting_button[i], 1, 0, 1);
895
}
896
/* Connect asynchronous signals to buttons to asynchronously run settings functions */
897
g_signal_new("save_config",G_TYPE_OBJECT,G_SIGNAL_RUN_FIRST,0,NULL,NULL,
898
NULL,G_TYPE_NONE,0);
899
g_signal_new("save_data",G_TYPE_OBJECT,G_SIGNAL_RUN_FIRST,0,NULL,NULL,
900
NULL,G_TYPE_NONE,0);
901
g_signal_connect(G_OBJECT(settings_window),"save_config",G_CALLBACK(cb_save_config),NULL)
;
902
g_signal_connect(G_OBJECT(settings_window),"save_data",G_CALLBACK(cb_save_data),NULL);
903
gtk_widget_show_all (settings_window);
904 }
71 905
906 /****************************************************************************************/
907 /*
Settings Window Callback Functions
*
/
908 /*
inputs: nothing
*
/
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
/*
outputs: gint (either TRUE OR FALSE though always will be FALSE)
*/
/*
Function: save the configuration values to a file (9 text entries on the right) */
/*
also save data from the fpga to a different file
*/
/****************************************************************************************/
gint cb_save_config(void){
FILE *fp;
int i;
fp = fopen("DOSA_configuration","w");//write configuration
if(fp != NULL){
for(i=0;i<9;i++){
char* str3 = gtk_editable_get_chars(GTK_EDITABLE(button_entry[entry_num]),0,11);
fputs (str3,fp);
}
}
fclose(fp);
return FALSE;
}
gint cb_save_data(void){
FILE *fp;
int i;
return FALSE;
}
void uim_settings_choice(int n){
static int last = 0;
/* make a text entry grab mouse focus manually since there will be no mouse */
if(last == 1){
last = 0;
if(n == DIR_CW){
if(entry_num >= 4){
entry_num = 1;
gtk_widget_grab_focus(button_entry[entry_num]);
}
else{
entry_num = entry_num + 1;
gtk_widget_grab_focus(button_entry[entry_num]);
}
}
else if(n == DIR_CCW){
if(entry_num <= 1){
entry_num = 4;
gtk_widget_grab_focus(button_entry[entry_num]);
}
else{
entry_num = entry_num - 1;
gtk_widget_grab_focus(button_entry[entry_num]);
}
}
}
else{
//slow down the rotation so it is one text entry per click
last++;
}
}
/****************************************************************/
/*
scan_init Function
*/
/*
inputs: center and width of desired high res graph */
/*
and number of points to graph
*/
/*
outputs: struct of necessary values to send to FPGA */
/*
Function: determines samples per step, scan min, scan
*/
/*
scan max, scan step, and number of points and */
/*
saves to the scanStr struct
*/
/****************************************************************/
scanStr scan_init(uint32_t center,uint32_t width,int num_points){
assert(center > 0);
72 976
assert(width > 0);
977
assert(num_points > 0);
978
979
int sps = (2*width)/(SCAN_STEP*DATA_LEN);
980
int oss = (STOP_VALUE-START_VALUE)/(SCAN_STEP*DATA_LEN);
981
/* determine values using equations */
982
s.status = 0;
983
s.scan_min=center-width;
984
s.scan_max=center+width;
985
s.samples_per_step = sps;
986
s.scan_step=SCAN_STEP;
987
s.over_per_step = oss;
988
s.count = DATA_LEN; //s.x_vals=x;s.y_vals=y;
989 #ifndef PRNTTEST
990
printf("status=%u\n num_points=%u\n scan_min=%u\n scan_max=%u\n sps=%u\n scan_step=%u\n o
verview_per_step=%u\n center=%u\n width=%u\n",s.status,s.count,s.scan_min,s.scan_max,s.samples_pe
r_step,s.scan_step,s.over_per_step,center,width);
991 #endif
992
assert(s.scan_max > s.scan_min);
993
assert(s.scan_step > 0);
994
995
return &s;
996 }
997
998
999 int load_ini_config(void){
1000
st_configuration config;
1001
int rv;
1002
//TBI -Loadfrom ini
1003
STOP_VALUE = STOP_VALUE_DEF;
1004
START_VALUE =START_VALUE_DEF;
1005
IPM_CLK_FREQ =IPM_CLK_FREQ_DEF;
1006
REFRESH_RATE=REFRESH_RATE_DEF;
1007
// Calculate other static vals
1008
1009
if(!scanf_settings(&config)){
1010
STOP_VALUE = (uint32_t)((config.stop_voltage)*(double)(config.som_steps_per_volt));
1011
START_VALUE = (uint32_t)((config.start_voltage)*(double)(config.som_steps_per_volt));
1012
IPM_CLK_FREQ = (uint32_t)(config.ipm_clk_freq);
1013
REFRESH_RATE = (uint32_t)(config.refresh_rate);
1014 #ifdef PRNTTEST
1015
printf("stop value: %f\nstart value: %f\noutput steps per volt: %u\n",config.stop_vol
tage,config.start_voltage,config.som_steps_per_volt);
1016 #endif
1017
}
1018
SCAN_STEP= (STOP_VALUE-START_VALUE)/(IPM_CLK_FREQ/REFRESH_RATE);
1019
//gtk_editable_set_text(GTK_EDITABLE(button_entry[i]),begin_entry,11,entry_pos);
1020 #ifdef PRNTTEST
1021
printf(" start value %u\n stop value %u\n IPM Frequency %u\n Refresh Rate %u\n",START_VAL
UE, STOP_VALUE, IPM_CLK_FREQ, REFRESH_RATE);
1022
printf("SS: %d\n",SCAN_STEP);
1023 #endif
1024
center = ((STOP_VALUE-START_VALUE)/2)+START_VALUE;
1025
width = ((STOP_VALUE-START_VALUE)/4);
1026
return 0;
1027 }
1.3.7 fpga.sh
1
2
3
4
5
6
7
8
9
#!/bin/sh
TARGNAME=fpgalink_test
FPGALIB=$HOME/Important_Files/RPi/libfpgalink-20120507
gcc -m64 -O3 -g -Wall -Wextra -Wundef -pedantic-errors -std=c99 -Wstrict-prototypes \
-Wno-missing-field-initializers -I$FPGALIB -I$FPGALIB/hdl/common\
-Wl,--relax,--gc-sections,-rpath,\$ORIGIN,-rpath-link,$FPGALIB/linux.x86_64/rel \
-o $TARGNAME dcmusb_unitTest.c dcmusb.c -L$FPGALIB/linux.x86_64/rel -lfpgalink -lerror
echo "finished"
73 10 # gcc -m64 -O3 -Wall -Wextra -Wundef -pedantic-errors -std=c99 -Wstrict-prototypes -Wnomissing-field-initializers -I../.. -I../../../../common -Wl,--relax,--gc-sections,rpath,\$ORIGIN,-rpath-link,../../linux.x86_64/rel -o ../../linux.x86_64/rel/fpgalink *.c L../../linux.x86_64/rel –lfpgalink
1.3.8 fpgaComm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
* Copyright (C) 2009-2012 Chris McClelland
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <libfpgalink.h>
#include "args.h"
#define CHECK(x) \
if ( status != FL_SUCCESS ) {
returnCode = x;
fprintf(stderr, "%s\n", error);
flFreeError(error);
goto cleanup;
}
\
\
\
\
\
int main(int argc, const char *argv[]) {
int returnCode;
struct FLContext *handle = NULL;
FLStatus status;
const char *error = NULL;
uint8 byte = 0x10;
uint8 buf[256];
bool flag;
bool isNeroCapable, isCommCapable;
uint32 fileLen;
uint8 *buffer = NULL;
uint32 numDevices, scanChain[16], i;
const char *vp = NULL, *ivp = NULL, *jtagPort = NULL, *xsvfFile = NULL, *dataFile = NULL;
bool scan = false, usbPower = false;
const char *const prog = argv[0];
//printf("FPGALink \"C\" Example Copyright (C) 2011 Chris McClelland\n\n");
argv++;
argc--;
while ( argc ) {
if ( argv[0][0] != '-' ) {
unexpected(prog, *argv);
FAIL(1);
}
switch ( argv[0][1] ) {
case 'v'://needed
GET_ARG("v", vp, 2);
break;
case 'i'://don't need should be taken out
GET_ARG("i", ivp, 3);
break;
case 'f':
GET_ARG("f", dataFile, 6);
break;
74 64
default:
65
invalid(prog, argv[0][1]);
66
FAIL(7);
67
}
68
argv++;
69
argc--;
70
}
71
if ( !vp ) {
72
missing(prog, "v <VID:PID>");//checks for a specified vendor id and product id
73
FAIL(8);
74
}
75
76
flInitialise();//initialize fpgalink
77
78
printf("Attempting to open connection to FPGALink device %s...\n", vp);
79
status = flOpen(vp, &handle, NULL);//open fpgalink
80
if ( status ) {
81
if ( ivp ) {
82
int count = 60;
83
printf("Loading firmware into %s...\n", ivp);
84
status = flLoadStandardFirmware(ivp, vp, jtagPort, &error);
85
CHECK(10);
86
87
printf("Awaiting renumeration");
88
flSleep(1000);
89
do {
90
printf(".");
91
fflush(stdout);
92
flSleep(100);
93
status = flIsDeviceAvailable(vp, &flag, &error);
94
CHECK(11);
95
count--;
96
} while ( !flag && count );
97
printf("\n");
98
if ( !flag ) {
99
fprintf(stderr, "FPGALink device did not renumerate properly as %s\n", vp);
100
FAIL(12);
101
}
102
103
printf("Attempting to open connection to FPGLink device %s again...\n", vp);
104
status = flOpen(vp, &handle, &error);
105
CHECK(13);
106
} else {
107
fprintf(stderr, "Could not open FPGALink device at %s and no initial VID:PID was
supplied\n", vp);
108
FAIL(14);
109
}
110
}
111
112
isNeroCapable = flIsNeroCapable(handle);
113
isCommCapable = flIsCommCapable(handle);
114
115
if ( dataFile && !isCommCapable ) {
116
fprintf(stderr, "Data file load requested but device at %s does not support CommFPGA\
n", vp);
117
FAIL(20);
118
}
119
120
if ( isCommCapable ) {
121
printf("Writing channel 0x01 to zero count...\n");
122
byte = 0x01;
123
status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error);
124
CHECK(21);
125
126
if ( dataFile ) {
127
buffer = flLoadFile(dataFile, &fileLen);
128
if ( buffer ) {
129
uint16 checksum = 0x0000;
130
uint32 i;
131
for ( i = 0; i < fileLen; i++ ) {
132
checksum += buffer[i];
133
}
134
printf(
75 135
"Writing %0.2f MiB (checksum 0x%04X) from %s to FPGALink device %s...\n",
136
(double)fileLen/(1024*1024), checksum, dataFile, vp);
137
status = flWriteChannel(handle, 30000, 0x00, fileLen, buffer, &error);
138
CHECK(22);
139
} else {
140
fprintf(stderr, "Unable to load file %s!\n", dataFile);
141
FAIL(23);
142
}
143
}
144
}
145
146
returnCode = 0;
147
148 cleanup:
149
flFreeFile(buffer);
150
flClose(handle);
151
return returnCode;
152 }
1.3.9 ini.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* inih -- simple .INI file parser
inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:
http://code.google.com/p/inih/
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ini.h"
#if !INI_USE_STACK
#include <stdlib.h>
#endif
#define MAX_SECTION 50
#define MAX_NAME 50
/* Strip whitespace chars off end of given string, in place. Return s. */
static char* rstrip(char* s)
{
char* p = s + strlen(s);
while (p > s && isspace(*--p))
*p = '\0';
return s;
}
/* Return pointer to first non-whitespace char in given string. */
static char* lskip(const char* s)
{
while (*s && isspace(*s))
s++;
return (char*)s;
}
/* Return pointer to first char c or ';' comment in given string, or pointer to
null at end of string if neither found. ';' must be prefixed by a whitespace
character to register as a comment. */
static char* find_char_or_comment(const char* s, char c)
{
int was_whitespace = 0;
while (*s && *s != c && !(was_whitespace && *s == ';')) {
was_whitespace = isspace(*s);
s++;
76 49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
}
return (char*)s;
}
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
static char* strncpy0(char* dest, const char* src, size_t size)
{
strncpy(dest, src, size);
dest[size - 1] = '\0';
return dest;
}
/* See documentation in header file. */
int ini_parse_file(FILE* file,
int (*handler)(void*, const char*, const char*,
const char*),
void* user)
{
/* Uses a fair bit of stack (use heap instead if you need to) */
#if INI_USE_STACK
char line[INI_MAX_LINE];
#else
char* line;
#endif
char section[MAX_SECTION] = "";
char prev_name[MAX_NAME] = "";
char* start;
char* end;
char* name;
char* value;
int lineno = 0;
int error = 0;
#if !INI_USE_STACK
line = (char*)malloc(INI_MAX_LINE);
if (!line) {
return -2;
}
#endif
/* Scan through file line by line */
while (fgets(line, INI_MAX_LINE, file) != NULL) {
lineno++;
start = line;
#if INI_ALLOW_BOM
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
(unsigned char)start[1] == 0xBB &&
(unsigned char)start[2] == 0xBF) {
start += 3;
}
#endif
start = lskip(rstrip(start));
if (*start == ';' || *start == '#') {
/* Per Python ConfigParser, allow '#' comments at start of line */
}
#if INI_ALLOW_MULTILINE
else if (*prev_name && *start && start > line) {
/* Non-black line with leading whitespace, treat as continuation
of previous name's value (as per Python ConfigParser). */
if (!handler(user, section, prev_name, start) && !error)
error = lineno;
}
#endif
else if (*start == '[') {
/* A "[section]" line */
end = find_char_or_comment(start + 1, ']');
if (*end == ']') {
*end = '\0';
strncpy0(section, start + 1, sizeof(section));
*prev_name = '\0';
77 122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
}
else if (!error) {
/* No ']' found on section line */
error = lineno;
}
}
else if (*start && *start != ';') {
/* Not a comment, must be a name[=:]value pair */
end = find_char_or_comment(start, '=');
if (*end != '=') {
end = find_char_or_comment(start, ':');
}
if (*end == '=' || *end == ':') {
*end = '\0';
name = rstrip(start);
value = lskip(end + 1);
end = find_char_or_comment(value, '\0');
if (*end == ';')
*end = '\0';
rstrip(value);
/* Valid name[=:]value pair found, call handler */
strncpy0(prev_name, name, sizeof(prev_name));
if (!handler(user, section, name, value) && !error)
error = lineno;
}
else if (!error) {
/* No '=' or ':' found on name[=:]value line */
error = lineno;
}
}
}
#if !INI_USE_STACK
free(line);
#endif
return error;
}
/* See documentation in header file. */
int ini_parse(const char* filename,
int (*handler)(void*, const char*, const char*, const char*),
void* user)
{
FILE* file;
int error;
file = fopen(filename, "r");
if (!file)
return -1;
error = ini_parse_file(file, handler, user);
fclose(file);
return error;
}
1.3.10
1
2
3
4
5
6
7
8
9
10
11
12
ini.h
/* inih -- simple .INI file parser
inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:
http://code.google.com/p/inih/
*/
#ifndef __INI_H__
#define __INI_H__
78 13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/* Make this header file easier to include in C++ code */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
/* Parse given INI-style file. May have [section]s, name=value pairs
(whitespace stripped), and comments starting with ';' (semicolon). Section
is "" if name=value pair parsed before any section heading. name:value
pairs are also supported as a concession to Python's ConfigParser.
For each name=value pair parsed, call handler function with given user
pointer as well as section, name, and value (data only valid for duration
of handler call). Handler should return nonzero on success, zero on error.
Returns 0 on success, line number of first error on parse error (doesn't
stop on first error), -1 on file open error, or -2 on memory allocation
error (only when INI_USE_STACK is zero).
*/
int ini_parse(const char* filename,
int (*handler)(void* user, const char* section,
const char* name, const char* value),
void* user);
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
close the file when it's finished -- the caller must do that. */
int ini_parse_file(FILE* file,
int (*handler)(void* user, const char* section,
const char* name, const char* value),
void* user);
/* Nonzero to allow multi-line value parsing, in the style of Python's
ConfigParser. If allowed, ini_parse() will call the handler with the same
name for each subsequent line parsed. */
#ifndef INI_ALLOW_MULTILINE
#define INI_ALLOW_MULTILINE 1
#endif
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
the file. See http://code.google.com/p/inih/issues/detail?id=21 */
#ifndef INI_ALLOW_BOM
#define INI_ALLOW_BOM 1
#endif
/* Nonzero to use stack, zero to use heap (malloc/free). */
#ifndef INI_USE_STACK
#define INI_USE_STACK 1
#endif
/* Maximum line length for any line in INI file. */
#ifndef INI_MAX_LINE
#define INI_MAX_LINE 200
#endif
#ifdef __cplusplus
}
#endif
#endif /* __INI_H__ */
1.3.11
1
2
3
4
5
6
7
8
#include
#include
#include
#include
#include
#include
#include
#include
support.h
<sys/time.h>
<stdio.h>
<unistd.h>
<gtk/gtk.h>
<gdk/gdk.h>
<glib.h>
<gio/gio.h>
<gtkdatabox.h>
79 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<gtkdatabox_points.h>
<gtkdatabox_ruler.h>
<gtkdatabox_lines.h>
<gtkdatabox_grid.h>
<math.h>
<cairo.h>
<stdlib.h>
<string.h>
<stdint.h>
<assert.h>
<pthread.h>
<netinet/in.h>
"ini.h"
"uim_config.h"
"userIOusb.h"
"dcmusb.h"
#ifndef __SUPPORT_H__
#define __SUPPORT_H__
#define MAX_ENTRY (11)
#define MAX_WIDTH (250000)
#define MIN_WIDTH (400)
#define ADC_MAX (1)
//GDK colors
GdkColor bgColor = { 0, 0, 0, 0 };//set background to black
GdkColor gridColor = { 0, 65000, 65000, 65000 };//set gridlines to white
GdkColor red = { 0, 65000, 0, 0};//set graph lines to red
GdkColor cyan = {0, 0, 65000, 65000};//create cyan lines
GdkColor white = { 0, 65000, 65000, 65000 };//set gridlines to white
GtkWidget *button_hbox[9];
GtkWidget *button_label[9];
GtkWidget *button_entry[9];
GtkEditable *entry_editable[9];
GtkWidget
GtkWidget
GtkWidget
GtkWidget
*settings_window;
*setting_hbox[4];
*setting_label[4];
*setting_button[4];
GtkWidget *lowerGraphDiv;
GtkWidget *upperGraphDiv;
GtkWidget *graphRate;
//declare upper graph global so the entire program can gain access to information
GtkWidget* databox_highres = 0;
GtkWidget* databoxcontainer_highres = 0;
GtkDataboxGraph *high_res_graph;
GtkDataboxGraph* high_res_grid;
//declare lower graph global so function can access everything
GtkWidget* databox_lowres;
GtkWidget* databoxcontainer_lowres;
GtkDataboxGraph *low_res_graph;
GtkDataboxGraph *lower_marker;
GtkDataboxGraph *upper_marker;
GtkDataboxGraph *low_res_grid;
GtkDataboxGraph *low_res_ramp;
int entry_pos[9]={1,1,1,1,1,1,1,1,1};
//scan range function
//scan range defines
#define SCAN_MIN_REG (32)
#define SCAN_MAX_REG (36)
#define SCAN_STEP_REG (40)
#define SPS_REG (44)
#define START_REG (48)
#define STOP_REG (52)
#define OVERVIEW_STEP_REG (56)
#define UI_CMD_REG (0x7E)
#define FPGA_CMD_REG (0x7F)
#define STREAM_REG (1)
#define OVERVIEW_STREAM_REG (2)
80 82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#define GAIN_REG (64)
#define GPIO_REG (68)
#define
#define
#define
#define
#define
#define
#define
#define RUN_TIME_INT (1000)
#define FPGA_TIMEOUT (100000000)
#define MAX_POINTS (700)
enum state_t{
START_SCAN,
WAIT_FOR_DATA,
GRAPH
}state = START_SCAN;
typedef struct {
uint32_t status;
uint32_t count;
uint32_t scan_min;
uint32_t scan_max;
uint32_t samples_per_step;
uint32_t over_per_step;
uint32_t scan_step;
int *x_vals;
int *y_vals;
}_scanStr;
typedef _scanStr *scanStr;
/*************************/
/* Function Prototypes */
/*************************/
void onExit(void);
void settings(void);
void request_redraw(void);
gint graph_func(gpointer graph);
gint start_scan(scanStr);
gint cb_save_config(void);
gint cb_save_data(void);
scanStr scan_init(uint32_t center,uint32_t width, int num_points);
int read_data(int reg,float *x,float *y,scanStr);
gint dcmFSM(gpointer s);
void uim_settings_choice(int n);
int load_ini_config(void);
#endif /* __SUPPORT_H__ */
1.3.12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CMD_START (0x53)
STATUS_IDLE (0x00)
CMD_ABORT (0x00)
BAD_PARAM (0x60)
FIFO_WAIT (0x56)
HV_ON (1)
HV_OFF (0)
uim_config.c
/** Settings IO
Digital Optical Spectrum Analyzer
/** Team Spectrum - George Mason University
/** Jacob Dilles <jdilles@gmu.edu> 11 November 2012
**/
**/
**/
/* Standard Includes */
#include <stdio.h>
/* FILE, printf, scanf, etc.. */
#include <math.h>
/* NAN, log10, etc.. */
#include <errno.h>
/* perror */
#include <stdint.h>
/* uint32_t */
#include <string.h>
/* strcmp */
#include <stdlib.h>
/* atoi */
/* Project Includes */
#include "ini.h"
#include "uim_config.h"
81 17 #define _f(x) ((double)x)
/* force floating point */
18
19 #define BOLD(x) "\033[1m" x "\033[0m"
20 #define RED(x) "\033[31m" x "\033[39m"
21
22 /* Internal functions */
23 double f2si( double number, char * prefix );
24 double si2f( const char* s );
25 static int cfg_handler(void* user, const char* section, const char* name, const char* value);
26
27 #if _DEMO_INI_
28 /* Demo */
29 int main(int argc, char** argv)
30 {
31
st_configuration config;
32
33
int rv = scanf_settings(&config);
34
printf("Reading returned: %d\n", rv);
35
rv = printf_settings(&config);
36
printf("Writing returned: %d\n", rv);
37
return 0;
38 }
39 #endif
40
41
42 /* Read the settings from a specific file */
43 int fscanf_settings(FILE * file, st_configuration* pcfg)
44 {
45
int errLine;
46
47
/* attempt to parse configuration file using the INI library */
48
errLine = ini_parse_file(file, cfg_handler, pcfg);
49
50
if(errLine) printf("Settings file error on line: %d\n",errLine);
51
52
return errLine;
53 }
54
55 /* Call to set this file up */
56 int scanf_settings(st_configuration* pcfg )
57 {
58
int errLine;
59
60
/* attempt to parse configuration file using the INI library */
61
errLine = ini_parse(SETTINGS_FILE_NAME, cfg_handler, pcfg);
62
63
/* No errors! */
64
if(errLine == 0)
65
{
66
#if _DEBUG_INI_
67
sout("Got settings OK");
68
#endif
69
return 0;
70
}
71
72
if( errLine < 0)
73
{
74
fprintf(stderr, "Settings file '%s' not found, writing defaults...\n", SETTINGS_FILE_
NAME);
75
}
76
else
77
{
78
fprintf(stderr, BOLD(RED("WARNING: ")) RED("Settings file error: ") "%d:%s\n",errLine
, SETTINGS_FILE_NAME);
79
}
80
81
return 1;
82 }
83
84
85
86 /* function that gets called by the ini.c */
87 static int cfg_handler(void* user, const char* section, const char* name,
82 88
const char* value)
89 {
90
st_configuration* pcfg = (st_configuration*)user;
91
#define _SECTION(s) (strcmp(section, s) == 0)
92
#define _NAME(n)
(strcmp(name, n) == 0)
93
#define _PARSEF(x)
return (pcfg->x=si2f(value)) != NAN
94
#define _PARSES(x)
(strncpy( (pcfg->x), value, sizeof( (pcfg->x) )))
95
96
#if _DEBUG_INI_
97
printf("Handeler Called! Section=%s Name=%s Value=%s\n", section, name, value);
98
#endif
99
100
if(_SECTION("config")){
101
if(_NAME("version")) pcfg->version = atoi(value);
102
else return 0;
103
}else if(_SECTION("dcm")){
104
/* no underscores */
105
if(_NAME("stop voltage")) _PARSEF(stop_voltage);
106
else if(_NAME("start voltage")) _PARSEF(start_voltage);
107
else if(_NAME("ipm clock frequency")) _PARSEF(ipm_clk_freq);
108
else if(_NAME("refresh rate")) _PARSEF(refresh_rate);
109
else if(_NAME("free spectral range")) _PARSEF(fsr);
110
else if(_NAME("volts per fsr")) _PARSEF(volts_per_fsr);
111
else if(_NAME("output steps per volt")) pcfg->som_steps_per_volt=atoi(value);
112
/* not found */
113
else return 0;
114
} else if(_SECTION("data")){
115
/* no underscores */
116
if(_NAME("output path")) _PARSES(output_path);
117
else if(_NAME("output type")) _PARSES(output_type);
118
/* with underscores */
119
else if(_NAME("output_path")) _PARSES(output_path);
120
else if(_NAME("output_type")) _PARSES(output_type);
121
/* not found */
122
else return 0;
123
} else {
124
return 0;
125
}
126
127
#undef _NAME
128
#undef _SECTION
129
#undef _PARSEF
130
#undef _PARSES
131
return 1;
132 }
133
134 /* Prints the settings to stdout */
135 int printf_settings(st_configuration* pcfg)
136 {
137
return fprintf_settings(stdout, pcfg);
138 }
139
140 /* Prints the settings */
141 int fprintf_settings(FILE * file, st_configuration* pcfg)
142 {
143
char prefix[2]={0,0};
144
int rv = 0;
145
#define _SECTION(n)
rv |= fprintf(file, "[%s]\n", n)
146
#define _PRINTFL(n, v, u) rv |= fprintf(file, "%s = %lf %s%s\n", n, f2si(pcfg>v,prefix), prefix, u)
147
#define _PRINTFS(k, v)
rv |= fprintf(file, "%s = %s\n", k, pcfg->v)
148
#define _PRINTS(k, v)
rv |= fprintf(file, "%s = %s\n", k, v)
149
#define _BR()
rv |= fprintf(file, "\n")
150
_SECTION("config");
151
_PRINTS("version", "1");
152
_BR();
153 /*
154
_SECTION("sfpi");
155
_PRINTFL("free spectral range", free_spectral_range, "Hz");
156
_PRINTFL("mirror reflectivity", mirror_reflectivity*100, "%" );
157
_PRINTFL("mirror spacing", mirror_spacing, "m");
158
_PRINTFL("displacement per volt", mirror_displacement_per_volt, "m");
159
_PRINTFL("laser wavelength", laser_wavelength, "m");
83 160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
_PRINTFL("voltage min", voltage_min, "V");
_PRINTFL("voltage max", voltage_max, "V");
_PRINTFL("max scan frequency", scan_freq, "Hz");
_BR();
_SECTION("data");
_PRINTFS("output path", output_path);
_PRINTFS("output type", output_type);
_BR();
*/
#undef
#undef
#undef
#undef
return
_SECTION
_PRINTFL
_PRINTFS
_PRINTS
rv;
}
/* Scale a number for SI representation */
double f2si(double number, char * prefix)
{
const static char si_prefix[8 + 1 + 8] =
{
'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm',
0,
'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
};
int log1000;
int minus;
// Check for wacko conditions
if( isnan(number) || isinf(number) || number == 0.0)
{
*prefix = 0;
return number;
}
// Fix for log of negative number
minus = number < 0.0;
if(minus) number = -number;
// Determine prefix based on power of 1000
log1000 = (int) floor( (log10(number) / 3) );
if(log1000 >=
{
number /=
*prefix =
}
else
{
*prefix =
}
//log1000
-8 && log1000 <= 8) /* Prefixes only cover 1000^-8 .. 1000^8*/
(double) pow(1000.0, log1000);
si_prefix[log1000+8];
/* number too big for metric prefix */
0;
if(minus) number = -number;
// restore minus
return number;
}
/* Parse a string to a double with support for SI prefixes on units */
double si2f(const char* s)
{
char prefix[5], c;
double value, scale;
int rv;
/* parse the floating point number + 1-4 character extension*/
rv = sscanf(s, " %1$lf %2$5s", &value, prefix);
84 233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 }
#if _DEBUG_INI_
printf("si2f: rv=%d value=%lf prefix=%s\n", rv, value, prefix);
#endif
switch(rv)
{
case 0:
return NAN;
case 1:
return value;
case 2:
c = prefix[0];
break;
default:
/* Unknown */
perror("Problem reading floating point string");
return NAN;
}
/* look up the si prefix (see http://en.wikipedia.org/wiki/Metric_prefix)*/
switch(c)
{
case 'Y':
scale = _f(1.0e+24);
break;
case 'Z':
scale = _f(1.0e+21);
break;
case 'E':
scale = _f(1.0e+18);
break;
case 'P':
scale = _f(1.0e+15);
break;
case 'T':
scale = _f(1.0e+12);
break;
case 'G':
scale = _f(1.0e+9);
break;
case 'M':
scale = _f(1.0e+6);
break;
case 'k':
scale = _f(1.0e+3);
break;
case 'h':
scale = _f(1.0e+2);
break;
case 'd':
scale = _f(1.0e-1);
break;
case 'c':
scale = _f(1.0e-2);
break;
case 'm':
scale = _f(1.0e-3);
break;
case 'u':
scale = _f(1.0e-6);
break;
case 'n':
scale = _f(1.0e-9);
break;
case 'p':
scale = _f(1.0e-12);
break;
case 'f':
scale = _f(1.0e-15);
break;
case 'a':
scale = _f(1.0e-18);
break;
case 'z':
scale = _f(1.0e-21);
break;
case 'y':
scale = _f(1.0e-24);
break;
case '%':
scale = _f(1.0e-2);
break; /* not strictly si, but useful*/
default:
scale = _f(1.0 );
break; /* unknown, ignore */
}
/* scale by si unit */
value *= scale;
return value;
1.3.13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uim_config.h
/** Settings IO
Digital Optical Spectrum Analyzer
/** Team Spectrum - George Mason University
/** Jacob Dilles <jdilles@gmu.edu> 11 November 2012
**/
**/
**/
/*
; Team Spectrum DOSA Sample Configuration File
; Note, metric prefixes should be accepted, but the actual SI unit is not
; validated (so, for example, 1.5 mm is a valid frequency (0.0015 hz)
[config]
version = 1
; Configuration Versioning
; Version 1
[sfpi]
free spectral range = 1.5 GHz
mirror reflectivity = 99.9999 %
; Free spectral range (FSR) of SPFI cavity
; Mirror reflectivity (either % or 0.999...)
85 17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
mirror spacing = 15 mm
displacement per volt = 4 mm
laser wavelength = 785.80 nm
voltage min = 15 V
voltage max = 450 V
max scan frequency = 10 Hz
;
;
;
;
;
;
Mirror spacing
SFPI
Nominal wavelength, for auto-locking
minimum allowable voltage for cavity
maximum allowable voltage for cavity
scan frequency limit
[data]
output path = /data
output type = csv
; Output file extension and kind
*/
#ifndef __UIM_CONFIG_H
#define __UIM_CONFIG_H
/** --------- START INCLUDE FILE ------------- */
/* Define to 1 to enable print statements in the handler/parsers */
#define _DEBUG_INI_ (0)
/* Define to 1 to enable demo of reading/writing INI */
#define _DEMO_INI_ (0)
#define SETTINGS_FILE_NAME
"uim_settings.txt"
#define
#define
#define
#define
SOM_CODE_MIN
SOM_CODE_MAX
SOM_VOLTAGE_MIN
SOM_VOLTAGE_MAX
(4095.0)
(2147483647.0)
(4.0)
(496.0)
#define
#define
#define
#define
IPM_CODE_MIN
IPM_CODE_MAX
IPM_VOLTAGE_MIN
IPM_VOLTAGE_MAX
(2147483647.0)
(0.0)
(0.0)
(3.0)
#define
#define
#define
#define
VGA_CODE_MIN
VGA_CODE_MAX
VGA_GAIN_MIN
VGA_GAIN_MAX
(0.0)
(15.0)
(4000.0)
(1258925.0)
/* The struct to hold configuration data */
typedef struct {
int version;
float start_voltage;
float stop_voltage;
float ipm_clk_freq;
float refresh_rate;
int som_steps_per_volt;
/* SFPI parameters */
double fsr;
double mirror_reflectivity;
double mirror_spacing;
double volts_per_fsr;
double laser_wavelength;
/* Min/Max Limits */
double voltage_min;
double voltage_max;
/* Scanning params */
double scan_freq;
/*File Output Stuff*/
char output_path[128];
char output_type[8];
} st_configuration;
/* Read settings in. Non-zero return indicates error */
int scanf_settings( st_configuration* pcfg );
int fscanf_settings(FILE * file, st_configuration* pcfg);
/* Debug print current settings to stdout */
86 90
91
92
93
94
95
int printf_settings(st_configuration* pcfg);
int fprintf_settings(FILE * file, st_configuration* pcfg);
/** --------- END INCLUDE FILE ------------- */
#endif
1.3.14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
uim_functions.c
#include "uim_functions.h"
//declare upper graph global so the entire program can gain access to information
GtkWidget* databox_highres = 0;
GtkWidget* databoxcontainer_highres = 0;
GtkDataboxGraph *high_res_graph;
GtkDataboxGraph* high_res_grid;
//declare lower graph global so function can access everything
GtkWidget* databox_lowres;
GtkWidget* databoxcontainer_lowres;
GtkDataboxGraph *low_res_graph;
GtkDataboxGraph *lower_marker;
GtkDataboxGraph *upper_marker;
GtkDataboxGraph *low_res_grid;
GtkDataboxGraph *low_res_ramp;
GtkWidget *button_hbox[9];
GtkWidget *button_label[9];
GtkWidget *button_entry[9];
GtkEditable *entry_editable[9];
const char* str2;
char * pixel_diff_str,amp_diff_str,hz_diff_str;
int context,entry_num=0,rotary;
extern int entry_pos[9]={1,1,1,1,1,1,1,1,1};
float amp1,amp2,amp_diff,pixel1,
pixel2,pixel_diff,pixel_diff2,width=50,center=50,temp_width,temp_center;
gint uim_pressed_home(void){
uim_led_toggle(BTN_HOME);
return FALSE;
}
gint uim_pressed_measure(void){
uim_led_toggle(BTN_MEASURE);
return FALSE;
}
gint uim_pressed_cursor(void){
uim_led_toggle(BTN_CURSOR);
settings();
return FALSE;
}
gint uim_pressed_memory(void){
uim_led_toggle(BTN_MEMORY);
return FALSE;
}
gint uim_pressed_power(void){
uim_led_toggle(BTN_POWER);
return FALSE;
}
// knobs x, y
gint uim_pressed_k0(void){
static int x = 0;
if(context == 0){
x = 1-x;
if(x == 1){
context = 1;
87 62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
}
else{
context = 0;
}
}
else if(context == 1){
x = 1-x;
if(x ==1){
context = 1;
}
else{
context = 0;
}
}
else if(context == 2){
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str2);
context = 1;
}
return FALSE;
}
gint uim_pressed_k1(void){
static int x = 0;
if(context == 1){
x = 1-x;
if(x == 1){
str2 = gtk_entry_get_text(GTK_ENTRY(button_entry[entry_num]));
entry_pos[entry_num] = 7;
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]);
context = 2;
}
else if(x == 0){
context = 1;
}
}
else if(context == 2){
context == 1;
}
return FALSE;
}
gint uim_rotated_k0(int n)
{
rotary = 0;
if(context == 0){
//printf("in home context\n");
g_timeout_add(1,(GSourceFunc)(uim_state_home(n)),NULL);
}
else if(context == 1){
g_timeout_add(1,(GSourceFunc)(uim_state_field_select(n)),NULL);
}
else if(context == 2){
g_timeout_add(1,(GSourceFunc)(uim_state_edit_field(n)),NULL);
}
return FALSE;
} // -1 = ccw, 1 = cw
//dependent on context but should rotate arrows at top of graphs and go through text entries
gint uim_rotated_k1(int n){
rotary = 1;
if(context == 0){
g_timeout_add(1,(GSourceFunc)(uim_state_home(n)),NULL);
}
else if(context == 2){
g_timeout_add(1,(GSourceFunc)(uim_state_edit_field(n)),NULL);
}
return FALSE;
}
// keypad
// num := 0..9
//initialize position array so cursor is in correct spot
88 135
136
137
138
139
140
141
;
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
);
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
gint uim_pressed_number(char num){
if(context = 3){
char str[] = {num,0};
gtk_editable_insert_text(GTK_EDITABLE(button_entry[entry_num]),str,1,entry_pos);
//gtk_entry_append_text(GTK_ENTRY(button_entry[entry_num]),str);
if(entry_pos[entry_num] < 11){
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]++)
}
else{
context = 1;
}
}
else{
printf("this isn't implemented yet\n");
}
return FALSE;
}
gint uim_pressed_star(void){
if(context == 1){
context = 3;
str2 = gtk_entry_get_text(GTK_ENTRY(button_entry[entry_num]));
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),"");
}
else if(context == 3){
context = 1;
}
else{
printf("this function hasn't been implemented yet\n");
}
return FALSE;
}
gint uim_pressed_pound(void){
if(context == 3){
if (entry_num >= 8){
entry_num = 8;
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str2);
context = 1;
} else{
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]-}
}
else if(context == 2){
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str2);
context = 1;
}
return FALSE;
}
gint uim_state_home(int n){
pixel1 = gtk_databox_pixel_to_value_x(GTK_DATABOX(databox_lowres),center);
pixel2 = gtk_databox_pixel_to_value_x(GTK_DATABOX(databox_lowres),center-1);
pixel_diff= pixel1 - pixel2;
if(rotary == 1){
if(n == DIR_CW){
//clockwise = zoom in
//use the difference in x-values displayed
//on graph to create proper scaling
temp_width = width - pixel_diff;
if(temp_width < MIN_WIDTH){
width = width;
}
else if(center - temp_width < MIN_WIDTH){
width = width;
}
else if(center + temp_width > MAX_WIDTH){
width = width;
}
89 206
else{
207
width = temp_width;
208
}
209
//printf("the pix difference is: %f\n",pixel_diff);
210
}
211
else if(n == DIR_CCW){
212
//counter clockwise = zoom out
213
//use the difference in x-values displayed
214
//on graph to create proper scaling
215
temp_width = width + pixel_diff;
216
if(temp_width > MAX_WIDTH){
217
width = width;
218
}
219
else if(center + temp_width > MAX_WIDTH){
220
width = width;
221
}
222
else if(center - temp_width < MIN_WIDTH){
223
width = width;
224
}
225
else{
226
width = temp_width;
227
}
228
}
229
}
230
else if(rotary == 0){
231
if(n == DIR_CW){
232
//clockwise = move the center right
233
temp_center = center + pixel_diff;
234
if(temp_center+width > MAX_WIDTH){
235
center = center;
236
}
237
else{
238
center = temp_center;
239
}
240
//printf("the pix difference is: %f\n",pixel_diff);
241
}
242
else if(n == DIR_CCW){
243
//counter clockwise = move the center left
244
temp_center = center - pixel_diff;
245
if(temp_center - width < MIN_WIDTH){
246
center = center;
247
}
248
else{
249
center = temp_center;
250
}
251
}
252
}
253
254
pixel_diff2 = 5*pixel_diff;
255
amp1 = gtk_databox_pixel_to_value_y(GTK_DATABOX(databox_highres),0);
256
amp2 = gtk_databox_pixel_to_value_y(GTK_DATABOX(databox_highres),5);
257
amp_diff= 5*(amp1 - amp2);
258
259
sprintf(&pixel_diff_str,"Hz/Div: %f",pixel_diff2);
260
sprintf(&amp_diff_str,"Amp/Div: %f",amp_diff);
261
sprintf(&hz_diff_str,"Hz Rate: %f",pixel_diff);
262
//gtk_label_set_text(GTK_LABEL(lowerGraphDiv),&pixel_diff_str);
263
//gtk_label_set_text(GTK_LABEL(upperGraphDiv),&amp_diff_str);
264
//gtk_label_set_text(GTK_LABEL(graphRate),&hz_diff_str);
265
return FALSE;
266 }
267
268 gint uim_state_field_select(int n){
269
static int last = 0;
270
if(n == last){
271
last = 0;
272
if(n == DIR_CW){
273
if(entry_num >= 9){
274
entry_num = 1;
275
gtk_widget_grab_focus(button_entry[entry_num]);
276
}
277
else{
278
entry_num = entry_num + 1;
90 279
gtk_widget_grab_focus(button_entry[entry_num]);
280
}
281
}
282
else if(n == DIR_CCW){
283
if(entry_num <= 1){
284
entry_num = 9;
285
gtk_widget_grab_focus(button_entry[entry_num]);
286
}
287
else{
288
entry_num = entry_num - 1;
289
gtk_widget_grab_focus(button_entry[entry_num]);
290
}
291
}
292
}
293
else{
294
last = n;
295
}
296
return FALSE;
297 }
298
299 gint uim_state_edit_field(int n){
300
static int last = 0;
301
if(rotary == 1){
302
int i,j,store=-1,flag=0;
303
char* str3 = gtk_editable_get_chars(GTK_EDITABLE(button_entry[entry_num]),0,11);
304
i = entry_pos[entry_num];
305
if(n == last){
306
last = 0;
307
if(n == DIR_CW){
308
do{
309
if(str3[i] == '.'){
310
str3[i] = '.';
311
i=i-n;
312
flag = 1;
313
}
314
else{
315
str3[i]=str3[i]+n;
316
if(str3[i] > '9'){
317
if(i == 0){
318
str3[i] = '9';
319
flag = 0;
320
}
321
else{
322
str3[i] = '0';
323
i=i-n;
324
flag = 1;
325
}
326
}
327
else{
328
flag = 0;
329
}
330
}
331
}while(flag);
332
}
333
else if(n == DIR_CCW){
334
for(j=0;j<=i;j++){
335
if(str3[j] > '0'){
336
store = j;
337
}
338
}
339
do{
340
if(str3[i] == '.'){
341
str3[i] = '.';
342
i--;
343
flag = 1;
344
}
345
else if(store == -1){
346
str3[i] = '0';
347
flag = 0;
348
}
349
else if(store >= 0){
350
if(i == store){
351
str3[i]--;
91 352
}
353
else if(i > store){
354
str3[i] = '9';
355
}
356
if(i != 0){
357
i--;
358
flag = 1;
359
}
360
else{
361
flag = 0;
362
}
363
}
364
}while(flag);
365
}
366
}
367
else{
368
last = n;
369
}
370
gtk_entry_set_text(GTK_ENTRY(button_entry[entry_num]),str3);
371
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry_num]);
372
}
373
else if(rotary == 0){
374
if(n == last){
375
if(n == DIR_CW){
376
if(entry_pos[entry_num] >= 10){
377
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]=10);
378
}
379
else{
380
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]++);
381
}
382
}
383
else if(n == DIR_CCW){
384
if(entry_pos[entry_num] < 1){
385
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]=0);
386
}
387
else{
388
gtk_entry_set_position(GTK_ENTRY(button_entry[entry_num]),entry_pos[entry
_num]--);
389
}
390
}
391
}
392
else{
393
last = n;
394
}
395
}
396
return FALSE;
397 }
1.4 uim_functions.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<gtk/gtk.h>
<glib.h>
<gio/gio.h>
<stdlib.h>
<fcntl.h>
<termios.h>
<string.h>
<errno.h> // errno
<gtkdatabox.h>
<gtkdatabox_points.h>
<gtkdatabox_ruler.h>
<gtkdatabox_lines.h>
<gtkdatabox_grid.h>
#define MAX_ENTRY 11
#define MAX_WIDTH 250000
#define MIN_WIDTH 700
92 18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
BTN_HOME 'A'
BTN_MEASURE 'B'
BTN_CURSOR 'C'
BTN_MEMORY 'D'
BTN_POWER 'P'
BTN_K0 'X'
BTN_K1 'Y'
K0_CCW '<'
K0_CW '>'
K1_CCW '{'
K1_CW '}'
#define DIR_CW 1 // -1 = counter clockwise
#define DIR_CCW -1 // -1 = counter clockwise
// buttons A-D, P
extern gint uim_pressed_home(void);
extern gint uim_pressed_measure(void);
extern gint uim_pressed_cursor(void);
extern gint uim_pressed_memory(void);
extern gint uim_pressed_power(void);
// knobs x,
extern gint
extern gint
extern gint
extern gint
y
uim_pressed_k0(void);
uim_pressed_k1(void);
uim_rotated_k0(int n); // -1 = ccw, 1 = cw
uim_rotated_k1(int n); // -1 = ccw, 1 = cw
// keypad
extern gint uim_pressed_number(char num); // num := 0..9
extern gint uim_pressed_star(void);
extern gint uim_pressed_pound(void);
extern
extern
extern
extern
gint
gint
gint
gint
uim_state_home(int n);
uim_state_field_select(int n);
uim_state_keypad_entry(int n);
uim_state_edit_field(int n);
1.4.1 uim_settings.txt
1 ; Team Spectrum DOSA Configuration File
2 ; Note, metric prefixes should be accepted, but the actual SI unit is not
3 ; validated (so, for example, 1.5 mm is a valid frequency (0.0015 hz)
4
5 [config]
; Configuration Versioning
6 version = 1
; Version 1
7
8 [dcm]
9 free spectral range = 1.5 GHz
; Free spectral range (FSR) of SPFI cavity
10 ;mirror reflectivity = 99.9998 %
; Mirror reflectivity (either % or 0.999...)
11 ;mirror spacing = 15 mm
; Mirror spacing
12 ;gain = 4 mm
; SFPI
13 ;laser wavelength = 785.80 nm
; Nominal wavelength, for auto-locking
14 start voltage = 15 V
; minimum allowable voltage for cavity
15 stop voltage = 450 V
; maximum allowable voltage for cavity
16 refresh rate = 10 Hz
; scan frequency limit
17 volts per fsr = 62.5 V
;volts per free spectral range
18 output steps per volt = 8418135 ;code points on DAC
19 ipm clock frequency = 25 MHz
;adc sample freq
20
21 [data]
22 output path = /data
23 output type = csv
; Output file extension
24
93 1.4.2 userIOusb.c
1 #include "userIOusb.h"
2
3 GIOChannel *deviceChannel;
4 //#define __USE_STD
5 //#define _DEBUG
6
7 void uim_rx(char c)
8 {
9
if(fsm_enabled)
10
{
11
if(FSMrunning == 1)
12
{
13
if(c >= '0' && c <= '9')
14
uim_pressed_number(c); // Handle numeric entry
15
else
16
{
17
switch (c){
18
case BTN_HOME:
19
g_timeout_add(1,(GSourceFunc)(&uim_pressed_home),NULL);
20
break;
21
case BTN_MEASURE:
22
g_timeout_add(1,(GSourceFunc)(&uim_pressed_measure),NULL);
23
break;
24
case BTN_CURSOR:
25
g_timeout_add(1,(GSourceFunc)(&uim_pressed_cursor),NULL);
26
break;
27
case BTN_MEMORY:
28
g_timeout_add(1,(GSourceFunc)(&uim_pressed_memory),NULL);
29
break;
30
case BTN_POWER:
31
g_timeout_add(1,(GSourceFunc)(&uim_pressed_power),NULL);
32
break;
33
case BTN_K0:
34
g_timeout_add(1,(GSourceFunc)(&uim_pressed_k0),NULL);
35
break;
36
case BTN_K1:
37
g_timeout_add(1,(GSourceFunc)(&uim_pressed_k1),NULL);
38
break;
39
case '*':
40
g_timeout_add(1,(GSourceFunc)(&uim_pressed_star),NULL);//do for all c
ases
41
break;
42
case '#':
43
g_timeout_add(1,(GSourceFunc)(&uim_pressed_pound),NULL);
44
break;
45
case K0_CCW:
46
uim_rotated_k0(DIR_CCW); // -1 = ccw, 1 = cw
47
break;
48
case K0_CW:
49
uim_rotated_k0(DIR_CW); // -1 = ccw, 1 = cw
50
break;
51
case K1_CCW:
52
uim_rotated_k1(DIR_CCW); // -1 = ccw, 1 = cw
53
break;
54
case K1_CW:
55
uim_rotated_k1(DIR_CW); // -1 = ccw, 1 = cw
56
break;
57
default:
58
// TODO RMDEBUG
59
printf("Unknown character returned '%c'\n",c);
60
break;
61
}
62
}
63
}
64
}
65
else
66
printf("RX logic disabled for '%c'\n", c);
67
//FSMrunning = 0;
68
//return TRUE;
94 69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
}
// Outputs
int uim_output_str(char* str)
{
if(!ftdi_fd)
{
fprintf(stderr,"File not open??");
return FALSE;
}
return write(ftdi_fd, str, strlen(str));
}
int uim_test_connected()
{
return ftdi_fd != 0;
}
/****** Helper to set up shutdown stuff ***********/
void setupShutdown(void)
{
// Set up the program to handle system signals gracefully
// see http://www.cplusplus.com/reference/clibrary/csignal/signal/
void (*prev_fn)(int);
prev_fn = signal(SIGINT, terminate);
if (prev_fn==SIG_IGN)
{
signal (SIGINT,SIG_IGN);
fprintf(stderr,"Could not register sigterm_handler!\n");
}
// Add exit notifier (called on exit(n) )
atexit (onExit);
}
/******* Called on SIGINT (^c) after being registered by singal() ******/
void terminate( int parameter )
{
// Attempt to close the serial port
if(ftdi_fd == 0) // open() == 0 indicates it was never opened
{
// TODO RMDEBUG
printf("FTDI device never opened...\n");
}
else if(close(ftdi_fd) == 0) // close() == 0 indicates sucess
{
// TODO RMDEBUG
printf("FTDI device descriptor closed.\n");
}
else
{
fprintf(stderr,"FTDI device descriptor failed to close.\n");
}
// Exit nicely
exit(parameter);
}
/**
* Configures a non-blocking 115200/8n1 FTDI connnection on the specified
* filename.
*
* Returns 0 if the FTDI device was opened, otherwise -1
*/
int openFTDIfd(char* filename,GIOChannel **deviceChannelP)
{
////// Locals //////
95 142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
int result;
int tty_fd;
struct termios tio;
int nloop;
int nread;
//
//
//
//
//
Result of last opperation
File discriptor number from UNIX 'open'
Struct modifying the paramaters of the serial term
loops to wait for bootup
bytes read from the stream
#ifdef _DEBUG
printf("openFTDIfd -> Called\n");
#endif
/*
Ensure that the file exists
* see http://linux.die.net/man/2/access , #include <unistd.h>
F_OK - validate that the file exists
*/
result = access(filename, F_OK);
if( result != 0)
{
fprintf(stderr,"FTDI device %s does not exist.\n", filename);
return 2;
}
/**
Ensure read/write permissions.
R_OK - ability to read
W_OK - ability to write
*/
result = access(filename, R_OK | W_OK);
if( result != 0) {
fprintf(stderr,"FTDI device %s permission denied: %s\n", filename, strerror( errno ))
return 3;
}
/**
Open the terminal using UNIX IO
* See http://rabbit.eng.miami.edu/info/functions/unixio.html
* This function returns a file desriptor number, or 0 if the file could
* not be opened.
O_RDWR - read and write
O_NONBLOCK - don't block reads
O_NOCTTY - don't allow FTDI device to kill connection with ^C
*/
//tty_fd = open(FTDI_DEV, O_RDWR | O_NONBLOCK );//| O_NOCTTY); //add nonblocking IO
tty_fd = open(FTDI_DEV, O_RDWR );//| O_NOCTTY);
#ifdef _DEBUG
printf("openFTDIfd -> FD#= %d\n", tty_fd);
#endif
if(tty_fd <= 0) {
fprintf(stderr,"FTDI device %s can not be opened:%s\n", filename, strerror( errno ));
return 4;
}
/**
Zero out TIO struct
* inc: string.h
*/
memset(&tio,0,sizeof(tio));
/**
Configure the serial terminal
* inc: termios.h
* ref1: http://linux.die.net/man/3/tcsetattr
* ref2: http://en.wikibooks.org/wiki/Serial_Programming/termios
* ref3: http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
*/
// Input mode: raw
tio.c_iflag = 0;
96 214
// Output mode: raw
215
tio.c_oflag = 0;
216
217
// Local mode: raw
218
tio.c_lflag = 0;
219
220
// Control modes: [ref2][ref3]
221
// CS8
- 8n1 (8bit,no parity,1 stopbit)
222
// CREAD
- enable reciever
223
// CLOCAL - ignore modem control lines
224
tio.c_cflag = CS8 | CREAD | CLOCAL;
225
226
/* So called "Non-Canonical Input Processing" [ref3] is controlled by VMIN
227
and VTIME:
228
If MIN > 0 and TIME = 0, MIN sets the number of characters to receive
229
before the read is satisfied. As TIME is zero, the timer is not used.
230
If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will be
231
satisfied if a single character is read, or TIME is exceeded
232
(t = TIME *0.1 s). If TIME is exceeded, no character will be returned.
233
If MIN > 0 and TIME > 0, TIME serves as an inter-character timer.
234
The read will be satisfied if MIN characters are received, or the time
235
between two characters exceeds TIME. The timer is restarted every time
236
a character is received and only becomes active after the first
237
character has been received.
238
If MIN = 0 and TIME = 0, read will be satisfied immediately.
239
*/
240
tio.c_cc[VMIN] = 0;
241
tio.c_cc[VTIME] = 10;
242
243
// Set the baudrate to 115200 bits/second
244
cfsetospeed(&tio,B115200);
// TX speed = 115200 baud
245
cfsetispeed(&tio,B115200);
// RX speed = 115200 baud
246
247
// Apply attributes set above
248
// TCSANOW - do it imedialty [ref1]
249
result = tcsetattr(tty_fd,TCSANOW,&tio);
250
if( result != 0 ) {
251
fprintf(stderr,"FTDI device %s can not be configured.\n", filename);
252
terminate(5);
253
}
254
255 #ifdef _DEBUG
256
printf("openFTDIfd -> Configured (EAGIN=%d)\n", EAGAIN);
257 #endif
258
259
char* spam = "::\n"; // invalid combo for the SPIN fsm, returns an error
260
// wait for bootup
261
for(nloop = 0; nloop < PROPELLER_STARTUP_WAIT_SPINS; nloop++)
262
{
263
//
264
// Write out the invalid string (which will cause the prop to error)
265
//
266
//int write( int handle, void *buffer, int nbyte );
267
result = write(tty_fd, spam, 3);
268
269 #ifdef _DEBUG
270
if(result < 0 )
271
printf( "Spin loop write error (loop=%d): %d %s\n", nloop, errno, strerror( errno
) );
272
else
273
printf("Waiting for feedback (loop=%d), wrote %d bytes\n", nloop, result);
274 #endif
275
276
//
277
// Sleep, give the system a chance to catch up
278
//
279
usleep(PROPELLER_STARTUP_WAIT_USEC);
280
281
//
282
// Try to read some bytes back, which would indicate that it started
283
//
284
//int read( int handle, void *buffer, int nbyte );
285
nread = read(tty_fd, buff, 16);
97 286
287 #ifdef _DEBUG
288
if(nread < 0)
289
printf( "Spin loop read error (loop=%d): %d %s\n", nloop, errno, strerror( errno
) );
290
else
291
printf("Got %d bytes of data (loop %d)\n", nread, nloop);
292 #endif
293
294
if(nread > 0){
295
break;
296
}
297
298
}
299
300
// At this point, either we have read some bytes or timed out
301
// the former condition is indicated by a postive nread
302
if(nread > 0)
303
{
304
// as long as there is stuff in the buffer, drain
305
while(nread > 0)
306
{
307
// try to read again
308
nread = read(tty_fd, buff, 16); // drain the stream
309 #ifdef _DEBUG
310
if(nread < 0)
311
//perror( "Error draining data" );
312
printf( "Drain loop read error: %d %s\n", errno, strerror( errno ) );
313
else
314
printf("Drained %d bytes of data.\n", nread);
315 #endif
316
}
317
318
// Set the global varaible, and return 0
319
ftdi_fd = tty_fd;
320 #ifdef _DEBUG
321
printf("ftdi_fd=%d \n", (int)ftdi_fd);
322 #endif
323
deviceChannel= (*deviceChannelP) = g_io_channel_unix_new(fileno(fdopen(tty_fd,"rw+"))
);
324
325
pthread_t thread;
326
return pthread_create(&thread,NULL ,&doBackgroundIOopsLoop,NULL);
327
}
328
329
// No dice. Something went wrong
330
fprintf(stderr,"FTDI device %s timed out without a response.\n", filename);
331
332
// failure
333
return 5;
334 }
335
336
337
338
// keep track of state
339
int btn_state = 0;
340
341 int uim_led_set(char btn, int val){
342
if(btn< 'A' || btn> 'Z') {
343 #ifdef _DEBUG
344
printf("You're an idiot %d\n",btn);
345 #endif
346
return 1; // not a valid button
347
}
348
349
// select correct bit of state
350
int mask = 1<<(btn - 'A');
351
352
// command string x\0
353
char cmd[2] = " ";
354
355
if(val){
356
// turn on
98 357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
cmd[0] = btn;
btn_state |= mask;
} else {
// A->a turn off
cmd[0] = btn+0x20;
btn_state &= ~mask;
}
return uim_output_str(cmd);
}
int uim_led_toggle(char btn){
if(btn< 'A' || btn> 'Z') {
#ifdef _DEBUG
printf("You're an idiot %d\n",btn);
#endif
return 1; // not a valid button
}
// select correct bit of state
int mask = 1<<(btn - 'A');
// command string x\0
char cmd[2] = " ";
if(mask & btn_state){
// already set, need to turn off
cmd[0] = btn+0x20;
} else {
cmd[0] = btn;
}
uim_output_str(cmd);
// toggle state variable
btn_state ^= mask;
return 0;
}
extern volatile unsigned int drawing;
void *doBackgroundIOopsLoop(){
while(1){
//printf("the io loop\n");
if((doBackgroundIOops(deviceChannel,G_IO_IN,NULL))){
//if(counter >=3){
drawing = 2;
//request_redraw();
//counter = 0;
//}
//else
//counter++;
}
while(drawing){
//pthread_yield();
sched_yield();
//sleep(.01);
}
}
}
gboolean doBackgroundIOops(GIOChannel *deviceChannel,GIOCondition condition,gpointer data)
{
int nread;
#ifdef __USE_STD
int result;
// Read from stdin
result = scanf("%s",buff);
if(result < 0)
{
perror("Error writing to stream");
99 430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
terminate(1);
} else if(result > 0)
{
write(ftdi_fd, buff, (unsigned)strlen(buff));
#ifdef _DEBUG
printf("%s\n", buff);
#endif
}
#endif
//nread = g_io_channel_read_chars(deviceChannel,buff,128,NULL,NULL);
nread = read(ftdi_fd, buff, 128);
if(nread < 0)
{
perror("Error reading stream");
terminate(1);
}
else if(nread > 0)
{
#ifdef __USE_STD
buff[nread] = 0;
printf("%s\n", buff);
#else
int i=0;
printf("nread = %d\n",nread);
for(i = 0; i < nread; i++){
FSMrunning = 1;
//input = buff[i];
uim_rx(buff[i]);
}
FSMrunning = 0;
return TRUE;
#endif
}
return FALSE;
}
1.4.3 userIOusb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/* Kevin Nicotera */
/* 9/8/12
*/
//includes
//#include "uim_functions.h"
#include <stdio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h> // errno
//defines
#define FTDI_DEV "/dev/ttyUSB0" // UIM-E board
#define PROPELLER_STARTUP_WAIT_USEC 1000*200 // 50ms
#define PROPELLER_STARTUP_WAIT_SPINS 40
//2 seconds = 40 * 50ms
#define _ECHO_I2C_VERSION ":4cXfe24?"
#define
#define
#define
#define
#define
#define
BTN_HOME 'A'
BTN_MEASURE 'B'
BTN_CURSOR 'C'
BTN_MEMORY 'D'
BTN_POWER 'P'
BTN_K0 'X'
100 33 #define BTN_K1 'Y'
34 #define K0_CCW '<'
35 #define K0_CW '>'
36 #define K1_CCW '{'
37 #define K1_CW '}'
38
39 #define DIR_CW 1 // -1 = counter clockwise
40 #define DIR_CCW -1 // -1 = counter clockwise
41 //****************** GLOBALS
42 int ftdi_fd; // fd of the tty port
43 int fsm_enabled; // enable/disable for FSM processing
44
45 char buff[256]; // buffer for exchanging info
46 //char* buffpos = buff;
47 /*
48 //This function will set appropriate settings to communicate with the front panel
49 void initFrontPanel(void);
50
51 //Takes in data from deviceChannel
52 //input/output channel (FTDI device/ttyUSB0) deviceChannel, condition to enter, data
53 gboolean handleSerialInput(GIOChannel *deviceChannel,GIOCondition condition,gpointer data);
54
55 //Send data to front panel
56 //input/output channel (FTDI device/ttyUSB0) deviceChannel, condition to enter, data
57 gboolean handleSerialOutput(GIOChannel *deviceChannel,GIOCondition condition,gpointer data);
58 */
59
60 //**************** FUNCTION PROTOTYPES ***********************///
61 int openFTDIfd(char* filename,GIOChannel **deviceChannel);
62
63 // These functions are exit helpers
64 void setupShutdown(void);
65 void terminate( int parameter );
66 extern void onExit(void);
67 extern void request_redraw(void);
68
69 /////////////////////////
70 // buttons A-D, P
71 gint uim_pressed_home(void);
72 gint uim_pressed_measure(void);
73 gint uim_pressed_cursor(void);
74 gint uim_pressed_memory(void);
75 gint uim_pressed_power(void);
76
77 // knobs x, y
78 gint uim_pressed_k0(void);
79 gint uim_pressed_k1(void);
80 gint uim_rotated_k0(int n); // -1 = ccw, 1 = cw
81 gint uim_rotated_k1(int n); // -1 = ccw, 1 = cw
82
83 // keypad
84 gint uim_pressed_number(char num); // num := 0..9
85 gint uim_pressed_star(void);
86 gint uim_pressed_pound(void);
87
88 gint uim_state_home(int n);
89 gint uim_state_field_select(int n);
90 gint uim_state_keypad_entry(int n);
91 gint uim_state_edit_field(int n);
92
93 // Front Panel Handler (internal)
94 gboolean doBackgroundIOops(GIOChannel *deviceChannel,GIOCondition condition,gpointer data); /
/ handler
95 void *doBackgroundIOopsLoop();
96 void uim_rx(char c);
97
98 int FSMrunning;
99 char input;
100 // Outputs
101 int uim_output_str(char* str);
102 int uim_led_toggle(char btn);
103 // Tests
104 int uim_test_connected(); // Tests to see if the UIM is connected. TRUE=yes, FALSE = no
101 1.5 UIM-E – Propeller P8X32A Embedded Controller
1.5.1 Basic_I2C_Driver.spin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
''
''
''
''
Basic I2C Routines Version 1.1.1 - Jacob DIlles
Written by Michael Green and copyright (©) 2007
Permission is given to use this in any program for the Parallax
Propeller processor as long as this copyright notice is included.
'' This is a minimal version of an I2C driver in SPIN. It assumes
'' that the SDA pin is one higher than the SCL pin. It assumes that
'' neither the SDA nor the SCL pins have pullups, so drives both.
''
''
''
''
These routines are primarily intended for reading and writing EEPROMs.
The low level I2C are provided for use with other devices, but the
read/write byte routines assume a standard I2C serial EEPROM with a
16 bit device address register, paged writes, and acknowledge polling.
''
''
''
''
''
''
''
''
''
''
''
All of these read/write routines accept an EEPROM address up to 19
bits (512K) even though the EEPROM addressing scheme normally allows
for only 16 bits of addressing. The upper 3 bits are used as part of
the device select code and these routines will take the upper 3 bits
of the address and "or" it with the supplied device select code bits
3-1 which are used to select a particular EEPROM on an I2C bus. There
are two schemes for selecting 64K "banks" in 128Kx8 EEPROMs. Atmel's
24LC1024 EEPROMs allow simple linear addressing up to 256Kx8 ($00000
to $3FFFF). Microchip's 24LC1025 allows for up to 512Kx8, but in two
areas: $00000 to $3FFFF and $40000 to $7FFFF. Each EEPROM provides
a 64K "bank" in each area. See the device datasheets for details.
''
''
''
''
''
This will work with the boot EEPROM and does not require a pull-up
resistor on the SCL line (but does on the SDA line ... about 4.7K to
+3.3V). According to the Philips I2C specification, both pull-ups
are required. Many devices will tolerate the absence of a pull-up
on SCL. Some may tolerate the absence of a pull-up on SDA as well.
''
''
''
''
Initialize may have to be called once at the beginning of your
program. Sometimes an I2C device is left in an invalid state. This
will reset the device to a known state so it will respond to the I2C
start transition (sent out by the i2cStart routine).
'' To read from or write to an EEPROM on pins 28/29 like the boot EEPROM:
'' CON
''
eepromAddress = $7000
'' VAR
''
byte buffer[32]
'' OBJ
''
i2c : "Minimal_I2C_Driver"
'' PRI readIt
''
if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
''
abort ' an error occurred during the read
'' PRI writeIt | startTime
''
if i2c.WritePage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
''
abort ' an error occured during the write
''
startTime := cnt ' prepare to check for a timeout
''
repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, eepromAddress)
''
if cnt - startTime > clkfreq / 10
''
abort ' waited more than a 1/10 second for the write to finish
'' Note that the read and write use something called paged reads/writes.
'' This means that any read using ReadPage must fit entirely in one
'' EEPROM if you have several attached to one set of pins. For writes,
102 64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
''
''
''
''
''
''
''
''
any write using i2cWritePage must fit entirely within a page of the
EEPROM. Usually these pages are either 32, 64, 128 or 256 bytes in
size depending on the manufacturer and device type. 32 bytes is a
good limit for the number of bytes to be written at a time if you
don't know the specific page size (and the write must fit completely
within a multiple of the page size). The WriteWait waits for the
write operation to complete. Alternatively, you could wait for 5ms
since currently produced EEPROMs will finish within that time.
CON
ACK
NAK
Xmit
Recv
BootPin
EEPROM
=
=
=
=
=
=
DAT
scl
sda
0
1
0
1
28
$A0
'
'
'
'
'
'
byte
byte
outa[SCL] := 1
dira[SCL] := 1
dira[SDA] := 0
repeat 9
outa[SCL] := 0
outa[SCL] := 1
if ina[SDA]
quit
' An I2C device may be left in an
' invalid state and may need to be
'
reinitialized. Drive SCL hig
' Set SDA as input
' Put out up to 9 clock pulses
' Repeat if SDA not driven high
' by the EEPROM
' SDA goes HIGH to LOW with SCL HIGH
outa[SCL]~~
dira[SCL]~~
outa[SDA]~~
dira[SDA]~~
outa[SDA]~
outa[SCL]~
PUB Stop
Acknowledge
No Acknowledge
Direction Transmit
Direction Receive
Boot EEPROM SCL Pin
EEPROM Device Address
28
29
PUB Initialize(argSCL, argSDA)
scl := argSCL
sda := argSDA
PUB Start
I2C
I2C
I2C
I2C
I2C
I2C
' Initially drive SCL HIGH
' Initially drive SDA HIGH
' Now drive SDA LOW
' Leave SCL LOW
' SDA goes LOW to HIGH with SCL High
outa[SCL]~~
outa[SDA]~~
dira[SCL]~
dira[SDA]~
' Drive SCL HIGH
' then SDA HIGH
' Now let them float
' If pullups present, they'll stay HIGH
PUB Write(data) : ackbit
'' Write i2c data. Data byte is output MSB first, SDA data line is valid
'' only while the SCL line is HIGH. Data is always 8 bits (+ ACK/NAK).
'' SDA is assumed LOW and SCL and SDA are both left in the LOW state.
ackbit := 0
data <<= 24
repeat 8
outa[SDA] := (data <-= 1) & 1
outa[SCL]~~
outa[SCL]~
dira[SDA]~
outa[SCL]~~
ackbit := ina[SDA]
outa[SCL]~
outa[SDA]~
dira[SDA]~~
' Output data to SDA
' Toggle SCL from LOW to HIGH to LOW
' Set SDA to input for ACK/NAK
' Sample SDA when SCL is HIGH
' Leave SDA driven LOW
PUB Read( ackbit): data
'' Read in i2c data, Data byte is output MSB first, SDA data line is
'' valid only while the SCL line is HIGH. SCL and SDA left in LOW state.
data := 0
103 137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
dira[SDA]~
repeat 8
outa[SCL]~~
data := (data << 1) | ina[SDA]
outa[SCL]~
outa[SDA] := ackbit
dira[SDA]~~
outa[SCL]~~
outa[SCL]~
outa[SDA]~
' Make SDA an input
' Receive data from SDA
' Sample SDA when SCL is HIGH
' Output ACK/NAK to SDA
' Toggle SCL from LOW to HIGH to LOW
' Leave SDA driven LOW
PUB ReadPage(devSel, addrReg, dataPtr, count) : ackbit
'' Read in a block of i2c data. Device select code is devSel. Device starting
'' address is addrReg. Data address is at dataPtr. Number of bytes is count.
'' The device select code is modified using the upper 3 bits of the 19 bit addrReg.
'' Return zero if no errors or the acknowledge bits if an error occurred.
devSel |= addrReg >> 15 & %1110
Start
' Select the device & send address
ackbit := Write(devSel | Xmit)
ackbit := (ackbit << 1) | Write(addrReg >> 8 & $FF)
ackbit := (ackbit << 1) | Write(addrReg & $FF)
Start
' Reselect the device for reading
ackbit := (ackbit << 1) | Write(devSel | Recv)
repeat count - 1
byte[dataPtr++] := Read(ACK)
byte[dataPtr++] := Read(NAK)
Stop
return ackbit
PUB ReadByte(devSel, addrReg) : data
'' Read in a single byte of i2c data. Device select code is devSel. Device
'' starting address is addrReg. The device select code is modified using the
'' upper 3 bits of the 19 bit addrReg. This returns true if an error occurred.
if ReadPage(devSel, addrReg, @data, 1)
return -1
PUB ReadWord(devSel, addrReg) : data
'' Read in a single word of i2c data. Device select code is devSel. Device
'' starting address is addrReg. The device select code is modified using the
'' upper 3 bits of the 19 bit addrReg. This returns true if an error occurred.
if ReadPage(devSel, addrReg, @data, 2)
return -1
PUB ReadLong(devSel, addrReg) : data
'' Read in a single long of i2c data. Device select code is devSel. Device
'' starting address is addrReg. The device select code is modified using the
'' upper 3 bits of the 19 bit addrReg. This returns true if an error occurred.
'' Note that you can't distinguish between a return value of -1 and true error.
if ReadPage(devSel, addrReg, @data, 4)
return -1
PUB WritePage(devSel, addrReg, dataPtr, count) : ackbit
'' Write out a block of i2c data. Device select code is devSel. Device starting
'' address is addrReg. Data address is at dataPtr. Number of bytes is count.
'' The device select code is modified using the upper 3 bits of the 19 bit addrReg.
'' Most devices have a page size of at least 32 bytes, some as large as 256 bytes.
'' Return zero if no errors or the acknowledge bits if an error occurred. If
'' more than 31 bytes are transmitted, the sign bit is "sticky" and is the
'' logical "or" of the acknowledge bits of any bytes past the 31st.
devSel |= addrReg >> 15 & %1110
Start
' Select the device & send address
ackbit := Write(devSel | Xmit)
ackbit := (ackbit << 1) | Write(addrReg >> 8 & $FF)
ackbit := (ackbit << 1) | Write(addrReg & $FF)
repeat count
' Now send the data
ackbit := ackbit << 1 | ackbit & $80000000 ' "Sticky" sign bit
ackbit |= Write(byte[dataPtr++])
Stop
return ackbit
PUB WriteByte(devSel, addrReg, data)
'' Write out a single byte of i2c data. Device select code is devSel. Device
'' starting address is addrReg. The device select code is modified using the
104 210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
'' upper 3 bits of the 19 bit addrReg. This returns true if an error occurred.
if WritePage(devSel, addrReg, @data, 1)
return true
' james edit - wait for 5ms for page write to complete (80_000 * 5 = 400_000)
waitcnt(400_000 + cnt)
return false
PUB WriteWord(devSel, addrReg, data)
'' Write out a single word of i2c data. Device select code is devSel. Device
'' starting address is addrReg. The device select code is modified using the
'' upper 3 bits of the 19 bit addrReg. This returns true if an error occurred.
'' Note that the word value may not span an EEPROM page boundary.
if WritePage(devSel, addrReg, @data, 2)
return true
' james edit - wait for 5ms for page write to complete (80_000 * 5 = 400_000)
waitcnt(400_000 + cnt)
return false
PUB WriteLong(devSel, addrReg, data)
'' Write out a single long of i2c data. Device select code is devSel. Device
'' starting address is addrReg. The device select code is modified using the
'' upper 3 bits of the 19 bit addrReg. This returns true if an error occurred.
'' Note that the long word value may not span an EEPROM page boundary.
if WritePage(devSel, addrReg, @data, 4)
return true
' james edit - wait for 5ms for page write to complete (80_000 * 5 = 400_000)
waitcnt(400_000 + cnt)
return false
PUB WriteWait(devSel, addrReg) : ackbit
'' Wait for a previous write to complete. Device select code is devSel. Device
'' starting address is addrReg. The device will not respond if it is busy.
'' The device select code is modified using the upper 3 bits of the 18 bit addrReg.
'' This returns zero if no error occurred or one if the device didn't respond.
devSel |= addrReg >> 15 & %1110
Start
ackbit := Write(devSel | Xmit)
Stop
return ackbit
' *************** JAMES'S Extra BITS *********************
PUB devicePresent(deviceAddress) : ackbit
' send the deviceAddress and listen for the ACK
Start
ackbit := Write(deviceAddress | 0)
Stop
if ackbit == ACK
return true
else
return false
PUB writeLocation(device_address, register, value)
start
write(device_address)
write(register)
write(value)
stop
PUB readLocation(device_address, register) : value
start
write(device_address | 0)
write(register)
start
write(device_address | 1)
value := read(NAK)
stop
return value
'************************************* Jacob's extra bits
PUB writeString(device_address, arrayPtr )
start
105 283
write(device_address)
284
repeat while byte[ arrayPtr]
285
write( byte[ arrayPtr++] )
286
stop
287
288 PUB writeBytes(device_address, arrayPtr, n)
289
start
290
write(device_address)
291
repeat n
292
write( byte[arrayPtr++] )
293
stop
294
295 PUB writeBytesRaw( arrayPtr, n)
296
start
297
repeat n
298
write( byte[arrayPtr++] )
299
stop
300
301 PUB writeReadRaw( arrayPtr, n) : value | addr
302
addr := byte[arrayPtr]
303
start
304
repeat n
305
write( byte[arrayPtr++] )
306
start
307
write(addr | 1)
308
value := read(NAK)
309
stop
310
return value 1.5.2 Front_Panel_Control_001.spin
1 {
2
Front Panel Control - UIM Embedded - Team Spectrum
3
4
George Mason University Senior Design Project 2012
5
6
File:
Front Panel Controller
7
Author:
Jacob Dilles <jdilles@gmu.edu>
8
Descrip: Top level file for managing the UIM-E devices
9 }
10
11
12 CON
13
_clkmode = xtal1 + pll16x
ck mode * crystal frequency = 80 MHz
14
_xinfreq = 5_000_000
15
16
17
18
scl
= 28
19
sda
= 29
20
utx
= 30
21
urx
= 31
22
23
knob
= 8
' k1=8/9, k0=10/11
24
25
26
led
= 17
27
28
29
ledp
= 22
30
leda
= 25
31
ledb
= 24
32
ledc
= 27
33
ledd
= 26
34
35
sysrelay = 16
36
extint
= 18
37
38
39
CR = $0D
'Standard clo
106 40
41
SHORT_DELAY = 45_000_000
42
43 OBJ
44
term
: "PcFullDuplexSerial"
45
i2cObject
: "basic_i2c_driver"
46
knobs
: "Quadrature_Encoder"
47
lcd
: "web4robot_lcd_001"
48
btns
: "Front_Panel_Inputs_001"
49 VAR
50
byte
i, temp
51
52
long
delta
53
54 PUB Main
55
56
dira := 0
57
58
dira[leda] := 1
59
dira[ledb] := 1
60
dira[ledc] := 1
61
dira[ledd] := 1
62
dira[ledp] := 1
63
dira[led] := 1
64
dira[sysrelay] := 1
65
66
67
'term.str( string("Restart", 13) )
68
outa[led] := 1
69
70
{Set up the Keypad object}
71
'kp.Init
72
btns.Init
73
74
{Set up the Rotary Encoder object
75
knobs.Start(knob, 2, 2, @rotarybuff) }
76
77
{Start up the i2c master}
78
i2cObject.Initialize(SCL, SDA)
79
80
{Start the LCD}
81
lcd.Start
82
'lcd.off
83
84
' Define the logo
85
lcd.charmap(1, @LOGO1)
86
lcd.charmap(2, @LOGO2)
87
lcd.charmap(3, @LOGO3)
88
lcd.charmap(4, @LOGO4)
89
90
' Write the logo
91
lcd.clear
92
lcd.str(String("Team Spectrum ",4,1,2,3,4))
93
' Write some text so there is something to read
94
' while the RPi boots.
95
lcd.line(2)
96
lcd.str(String("DOSA is starting up "))
97
98
'If no usb host is found, for some reason the USB FTDI chip
99
' will reset the Propeller. So at least show a little animation
100
' rather than flashing over and over
101
lcd.line(3)
102
lcd.str(String("Please standby
"))
103
waitcnt(clkfreq/2+cnt)
104
lcd.line(3)
105
lcd.str(String("Please standby.
"))
106
waitcnt(clkfreq/2+cnt)
107
lcd.line(3)
108
lcd.str(String("Please standby.. "))
109
waitcnt(clkfreq/2+cnt)
110
term.start(urx, utx,0,115200)
' start the serial terminal here for smoother ani
mation
111
lcd.line(3)
107 112
lcd.str(String("Please standby... "))
113
waitcnt(clkfreq/2+cnt)
114
115
' Start serial terminal
116
'term.start(urx, utx,0,115200)
' see above
117
118
' Some more text, to show we have a valid serial link
119
lcd.line(3)
120
lcd.str(String("Reticulating Splines"))
121
waitcnt(SHORT_DELAY+cnt)
122
lcd.line(3)
123
lcd.str(String("Igniting Arc Reactor"))
124
waitcnt(SHORT_DELAY+cnt)
125
lcd.line(3)
126
lcd.str(String("Magnetizing Neutrons"))
127
waitcnt(SHORT_DELAY+cnt)
128
lcd.line(3)
129
lcd.str(String("Redimensioning Units"))
130
waitcnt(SHORT_DELAY+cnt)
131
lcd.line(3)
132
lcd.str(String("Cranking Up Past 11 "))
133
waitcnt(SHORT_DELAY+cnt)
134
lcd.line(3)
135
lcd.str(@clearline)
136
137 {wait for first serial character}
138
i := 0
139
lcd.line(3)
140
temp := "."
141
repeat while term.rxtime(100) == -1
142
if i == 20
143
i := 0
144
lcd.line(3)
145
if temp == "."
146
temp := " "
147
else
148
temp := "."
149
else
150
i++
151
lcd.out(temp)
152
term.tx(".")
153
154
lcd.line(2)
155
lcd.str(@clearline)
156
lcd.line(3)
157
lcd.str(@clearline)
158
159
{Main Infinate Loop}
160
repeat
161
btns.getChars(@msg)
162
term.str(@msg)
163
164
165
166
doFSM(term.rxcheck)
167
outa[led] := 1
' blink the light to let us know it's
alive
168
waitcnt(clkfreq/10+cnt)
169
doFSM(term.rxcheck)
170
outa[led] := 0
171
waitcnt(clkfreq/10+cnt)
172
173
174 PRI DoFSM(c) | hex
175
if c == -1
176
Return FALSE
177
178
179 { ' Remove me to enable debugging
180
term.hex(c,2)
181
term.tx(" ")
182
term.hex(k, 2)
183
term.tx(" ")
108 184
if (c => $20) AND (c =< $7F)
185
term.tx(c)
186
term.tx(CR)
187 }
188
case state
189
WAITING:
190
k := 0
191
case c
192
"p": outa[ledp] := 0
193
"P": outa[ledp] := 1
194
"a": outa[leda] := 0
195
"A": outa[leda] := 1
196
"b": outa[ledb] := 0
197
"B": outa[ledb] := 1
198
"c": outa[ledc] := 0
199
"C": outa[ledc] := 1
200
"d": outa[ledd] := 0
201
"D": outa[ledd] := 1
202
"s": outa[sysrelay]:= 0
203
"S": outa[sysrelay]:= 1
204
"l": lcd.Off
205
"L": lcd.On
206
"h": lcd.home
207
"0": lcd.line(0)
208
"1": lcd.line(1)
209
"2": lcd.line(2)
210
"3": lcd.line(3)
211
"k": lcd.clear
212
"u": lcd.underline(FALSE)
213
"U": lcd.underline(TRUE)
214
"j": lcd.blink(FALSE)
215
"J": lcd.blink(TRUE)
216
":": state := ADDRESS0
217
"?": term.tx("!")
218
$27: doFSM($22)
219
$22: doFSM(":")
220
doFSM("4")
221
doFSM("C")
222
doFSM("'")
223
"T": lcd.str(String("Team Spectrum
224
ADDRESS0:
225
hex := hex2nib( c )
226
if hex == -1
227
term.str(term.str(@badhex))
228
term.dec(c)
229
state := WAITING
230
else
231
buff[k] := hex << 5
232
state := ADDRESS1
233
ADDRESS1:
234
hex := hex2nib( c )
235
if hex == -1
236
term.str(@badhex)
237
term.dec(c)
238
state := WAITING
239
else
240
buff[k++] |= ((hex <<1) & $1E)
241
state := ADDRESS2
242
ADDRESS2:
243
'term.str(string(13,"+A3 "))
244
'term.dec(buff[0])
245
case c
246
"X": state := HIGHBITS
247
"x": state := HIGHBITS
248
$22: state := STRSEND
249
$27: state := STRSEND
250
OTHER:
251
state := waiting
252
term.str(@badhex)
253
term.dec(c)
254
HIGHBITS:
255
'term.str(string(13,"+HB "))
256
case c
' echo to show we're alive
",4,1,2,3,4))
' debug
109 257
CR:
258
if k > 0
259
' Send here
260
i2cObject.writeBytesRaw(@buff, k)
261
'repeat c from 0 to k
262
'term.hex(buff[c], 2)
263
else
264
term.str(string("No data to send!",13))
265
state := WAITING
266
"?":
267
c := i2cObject.writeReadRaw(@buff, k)
268
term.hex(c,2)
269
term.tx(CR)
270
state := WAITING
271
other:
272
hex := hex2nib( c )
273
if hex == -1
274
term.str(@badhex)
275
term.dec(c)
276
state := WAITING
277
else
278
buff[k] := (hex <<4)
' upper 4 bits
279
state := LOWBITS
' Next state
280
LOWBITS:
281
hex := hex2nib(c)
282
if hex == -1
283
term.str(@badhex)
284
term.dec(c)
285
state := WAITING
286
else
287
buff[k++] |= (hex & $0F)
288
state:= HIGHBITS
289
STRSEND:
290
case c
291
' Enter to send
292
CR:
293
i2cObject.writeBytesRaw(@buff, k)
294
state := WAITING
295
' Backspace to delete
296
$08:
297
if k > 1
298
k-299
state := STRSEND
300
' Escape to cancel
301
$1B: state := WAITING
302
' Printable Characters
303
$20..$7F:
304
if k < 40
305
buff[k++] := c
306
else
307
term.str(string("Buffer Overflow - Input Canceled",13))
308
state := WAITING
309
other:
310
term.str(string("Unprintable Character: "))
311
term.tx(c)
312
term.tx(CR)
313
state:= WAITING
314
315
Return True
316
317 PRI hex2nib(c)
318
if c > "`"
319
c -= $20
320
Return lookdown(c : $30..$39, $41..$46 ) - 1
321
322
323 CON
324
WAITING = 0
325
ADDRESS0 = 1
326
ADDRESS1 = 2
327
ADDRESS2 = 3
328
LOWBITS = 4
329
HIGHBITS = 5
110 330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
STRSEND = 6
SENDING = 7
DAT
state
k
nan
buff
byte
byte
byte
byte
0
1
$ff
0[64],0
DAT
badhex
clearline
rotarybuff
msg
byte "Invalid Input",0
byte "
",0
long $12345678[8]
byte " "[32]
,0
'Define some custom characters to
'form the Team Spectrum logo on LCD2
'Characters are 5 wide by 7 high
'So these bits:\
are unused
'
|||
'
vvv
LOGO1
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_01000
byte %000_01000
byte %000_01000
byte %000_01001
byte %000_10110
'
LOGO2
byte %000_00100
byte %000_00100
byte %000_00100
byte %000_00100
byte %000_00100
byte %000_01010
byte %000_01010
byte %000_10001
'
LOGO3
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_00010
byte %000_00010
byte %000_00010
byte %000_10010
byte %000_01101
'
LOGO4
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_00000
byte %000_11111
1.5.3 Front_Panel_Inputs_001.spin
1 {{
2
Front Panel Inputs - UIM Embedded - Team Spectrum
3
George Mason University Senior Design Project 2012
4
5
File:
Input Devices Controller
6
Author:
Jacob Dilles <jdilles@gmu.edu>
7
Descrip: Handles a 4x4 keypad on inputs [7:0],
111 8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
as well as monitoring the other buttons
on the front panel
Call INIT first, which will take 2 COGs.
Then, call getChars, as often as you like. It will copy
any pending input in the 64 byte buffer to your pointer.
It is a valid string, ending in '0', to be sent to the
computer
Idea for keypad reader came from the
4x4KeypadReader v1.0 by Beau Schwabe (2007)
However, his did not work with the hybrid
button/matrix keypad, so I re-wrote it with active
low logic and now it works fine.
Also, since a cog must be dedicated to the rising
edge detector, I have mashed monitoring the other
buttons in here as well. So sorry if it is not an
ideal OO model :/
}}
CON
NumControls = 18
BUF_PTR_MASK = $3F ' 64 byte tx buffer
OBJ
knobs
: "Quadrature_Encoder"
VAR
long kpstack[128], delta
byte i,j, bit
PUB INIT
cognew(EndlessLoop, @kpstack)
{Set up the Rotary Encoder object}
knobs.Start(8, 2, 2, @rotarybuff)
PUB GetChars(loc)
'' Get the current input string waiting to be sent to
'' the computer (copy to buffer)
repeat until j == i
byte[loc++] := buff[j++]
j &= BUF_PTR_MASK
delta := knobs.ReadDelta(0)
repeat while delta > 0
byte[loc++] := "<"
delta -repeat while delta < 0
byte[loc++] := ">"
delta ++
' Read the bottom knob
delta := knobs.ReadDelta(1)
repeat while delta > 0
byte[loc++] := "{"
delta -repeat while delta < 0
byte[loc++] := "}"
delta ++
byte[loc++] := 0
PRI EndlessLoop
'' Endless loop for a new COG
repeat
ReadRows
ReadBtns
CalcChange
' Read the row data from the keypad
' Read the additional buttons
' Rising edge detector
112 81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
PRI ReadBtns
'' This reads the buttons, so that the same rising edge detector can be
'' used with the keypad
keypad <<= 2
keypad |= ina[12..13]
keypad <<= 1
keypad |= ina[23]
PRI ReadRows
'' Keypad read-rows routine
keypad := 0
ReadRow(3)
keypad <<= 4
ReadRow(2)
keypad <<= 4
ReadRow(1)
keypad <<= 4
ReadRow(0)
'Clear 4x4 'keypad' value
'Call routine to read entire ROW
'Shift 'keypad' value left by 4
'Call routine to read entire ROW
'Shift 'keypad' value left by 4
'Call routine to read entire ROW
'Shift 'keypad' value left by 4
'Call routine to read entire ROW
PRI ReadRow(n)
'' Keypad Read a Row routine. Uses
'' having to use pullup resistors
dira[0..7] ~
'
outa[0..7] ~
'
outa[0..7] ~~ '
'
dira[0..7] ~~
'
dira[0..7] ~
'
outa[n] := 0
'
dira[n] := 1
'
dira[n] := 0
'
keypad += ina[4..7]
'
0
1
2
3
the keepers on the IO pins to get around
all pins input
first discharge to low
preset to high
all output, set keepers high
all input, keepers maintain last
Clear one row
Activate output on that row
Deactivate, keeper maintains
Add in result
PRI CalcChange
'' Simple rising edge detector
st1 := st0
st0 := !keypad
kpchange:= st0 & (st0 ^ st1)
' active low
' rising edge
repeat bit from 0 to numcontrols
if (kpchange & 1) == 1
PutChar( kplut[bit] )
kpchange >>= 1
buff[i] := 0 ' signal end of string
PRI PutChar(c)
'' Add a character to the buffer
buff[i] := c
i := (i+1) & BUF_PTR_MASK ' circular buffer
DAT
kplut
byte
buff
byte
keypad
st1
st0
kpchange
rotarybuff
"PYX321A654B987C#0*D"
" "[64],0
long
0 ' holds the keypad stuff
long
0
long
0
long
0
long $12345678[4]
1.5.4 pcFullDuplexSerial.spin
1 ''************************************
2 ''* Full-Duplex Serial Driver v1.1 *
3 ''* (C) 2006 Parallax, Inc.
*
113 4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
''*
*
''*
*
''*
*
''************************************
''*
*
''*
now with 64 byte rx buffers
*
''************************************
VAR
long
cog
'cog flag/id
long
long
long
long
long
long
long
long
long
rx_head
rx_tail
tx_head
tx_tail
rx_pin
tx_pin
rxtx_mode
bit_ticks
buffer_ptr
'9 contiguous longs
byte
byte
rx_buffer[64]
tx_buffer[16]
'transmit and receive buffers
PUB start(rxpin, txpin, mode, baudrate) : okay
'' Start serial driver - starts a cog
'' returns false if no cog available
''
'' mode bit 0 = invert rx
'' mode bit 1 = invert tx
'' mode bit 2 = open-drain/source tx
'' mode bit 3 = ignore tx echo on rx
stop
longfill(@rx_head, 0, 4)
longmove(@rx_pin, @rxpin, 3)
bit_ticks := clkfreq / baudrate
buffer_ptr := @rx_buffer
okay := cog := cognew(@entry, @rx_head) + 1
PUB stop
'' Stop serial driver - frees a cog
if cog
cogstop(cog~ - 1)
longfill(@rx_head, 0, 9)
PUB getCogID : result
return cog -1
PUB rxflush
'' Flush receive buffer
repeat while rxcheck => 0
PUB rxcheck : rxbyte
'' Check if byte received (never waits)
'' returns -1 if no byte received, $00..$FF if byte
rxbyte-if rx_tail <> rx_head
rxbyte := rx_buffer[rx_tail]
rx_tail := (rx_tail + 1) & $3F
PUB rxtime(ms) : rxbyte | t
'' Wait ms milliseconds for a byte to be received
'' returns -1 if no byte received, $00..$FF if byte
t := cnt
repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms
114 77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
PUB rx : rxbyte
'' Receive byte (may wait for byte)
'' returns $00..$FF
repeat while (rxbyte := rxcheck) < 0
PUB tx(txbyte)
'' Send byte (may wait for room in buffer)
repeat until (tx_tail <> (tx_head + 1) & $F)
tx_buffer[tx_head] := txbyte
tx_head := (tx_head + 1) & $F
if rxtx_mode & %1000
rx
PUB str(stringptr)
'' Send string
repeat strsize(stringptr)
tx(byte[stringptr++])
PUB dec(value) | i
'' Print a decimal number
if value < 0
-value
tx("-")
i := 1_000_000_000
repeat 10
if value => i
tx(value / i + "0")
value //= i
result~~
elseif result or i == 1
tx("0")
i /= 10
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
tx((value <-= 1) & 1 + "0")
DAT
'***********************************
'* Assembly language serial driver *
'***********************************
org
'
'
' Entry
'
entry
mov
add
t1,par
t1,#4 << 2
'get structure address
'skip past heads and tails
rdlong
mov
shl
t2,t1
rxmask,#1
rxmask,t2
'get rx_pin
115 150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
urn
178
179
180
181
182
183
184
185
186
187
188
189
190
urn
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
add
rdlong
mov
shl
t1,#4
t2,t1
txmask,#1
txmask,t2
'get tx_pin
add
rdlong
t1,#4
rxtxmode,t1
'get rxtx_mode
add
rdlong
t1,#4
bitticks,t1
'get bit_ticks
add
rdlong
mov
'add
add
t1,#4
rxbuff,t1
txbuff,rxbuff
txbuff,#16
txbuff,#64
'get buffer_ptr
test
test
or
or
rxtxmode,#%100
rxtxmode,#%010
outa,txmask
dira,txmask
mov
txcode,#transmit
'initialize ping-pong multitasking
jmpret
rxcode,txcode
'run a chunk of transmit code, then ret
test
test
jmp
rxtxmode,#%001
rxmask,ina
#receive
mov
mov
shr
add
rxbits,#9
rxcnt,bitticks
rxcnt,#1
rxcnt,cnt
'ready to receive byte
:bit
add
rxcnt,bitticks
'ready next bit period
:wait
jmpret
rxcode,txcode
'run a chuck of transmit code, then ret
mov
sub
cmps
jmp
t1,rxcnt
t1,cnt
t1,#0
#:wait
'check if bit receive period done
test
rcr
djnz
rxmask,ina
rxdata,#1
rxbits,#:bit
shr
and
test
xor
rxdata,#32-9
rxdata,#$FF
rxtxmode,#%001
rxdata,#$FF
rdlong
add
wrbyte
sub
add
'and
and
wrlong
t2,par
'save received byte and inc head
t2,rxbuff
rxdata,t2
t2,rxbuff
t2,#1
t2,#$F
t2,#$3F
' big buffers
t2,par
jmp
#receive
'byte done, receive next byte
jmpret
txcode,rxcode
'run a chunk of receive code, then retu
if_z_ne_c
if_z
'
'
' Receive
'
receive
if_z_eq_c
if_nc
if_nz
'
'
' Transmit
'
transmit
' big RX buffer
wz
wc
wz
wc
'init tx pin according to mode
'wait for start bit on rx pin
wc
wc
'receive bit on rx pin
'justify and trim received byte
wz
'if rx inverted, invert byte
116 rn
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
rn
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
if_z
:bit
if_z_and_c
if_z
if_nz
:wait
if_nc
mov
add
rdlong
add
rdlong
cmp
jmp
t1,par
t1,#2 << 2
t2,t1
t1,#1 << 2
t3,t1
t2,t3
#transmit
add
rdbyte
sub
add
and
wrlong
t3,txbuff
txdata,t3
t3,txbuff
t3,#1
t3,#$0F
t3,t1
'get byte and inc tail
or
shl
or
mov
mov
txdata,#$100
txdata,#2
txdata,#1
txbits,#11
txcnt,cnt
'ready byte to transmit
test
test
xor
shr
muxc
muxnc
add
rxtxmode,#%100
rxtxmode,#%010
txdata,#1
txdata,#1
outa,txmask
dira,txmask
txcnt,bitticks
jmpret
txcode,rxcode
'run a chunk of receive code, then retu
mov
sub
cmps
jmp
t1,txcnt
t1,cnt
t1,#0
#:wait
'check if bit transmit period done
djnz
txbits,#:bit
'another bit to transmit?
'byte done, transmit next byte
jmp
#transmit
'
'
' Uninitialized data
'
t1
t2
t3
res
res
res
1
1
1
rxtxmode
bitticks
res
res
1
1
rxmask
rxbuff
rxdata
rxbits
rxcnt
rxcode
res
res
res
res
res
res
1
1
1
1
1
1
txmask
txbuff
txdata
txbits
txcnt
txcode
res
res
res
res
res
res
1
1
1
1
1
1 'check for head <> tail
wz
wz
wc
'output bit on tx pin according to mode
wc
'ready next cnt
wc
1.5.5 Quadrature_Encoder.spin
1 {{
2 *************************************
117 3 * Quadrature Encoder v1.0
*
4 * Author: Jeff Martin
*
5 * Copyright (c) 2005 Parallax, Inc. *
6 * See end of file for terms of use. *
7 *************************************
8 }}
9
10 VAR
11
byte
Cog
'Cog (ID+1) that is running Update
12
byte
TotDelta
'Number of encoders needing deta value support.
13
long
Pos
'Address of position buffer
14
15
16 PUB Start(StartPin, NumEnc, NumDelta, PosAddr): Pass
17 ''Record configuration, clear all encoder positions and launch a continuous encoderreading cog.
18 ''PARAMETERS: StartPin = (0..63) 1st pin of encoder 1. 2nd pin of encoder 1 is StartPin+1.
19 ''
Additional pins for other encoders are contiguous starting with Star
tPin+2 but MUST NOT cross port boundry (31).
20 ''
NumEnc
= Number of encoders (1..16) to monitor.
21 ''
NumDelta = Number of encoders (0..16) needing delta value support (can be less
than NumEnc).
22 ''
PosAddr = Address of a buffer of longs where each encoder's position (and deta
position, if any) is to be stored.
23 ''RETURNS:
True if successful, False otherwise.
24
25
Pin := StartPin
26
TotEnc := NumEnc
27
TotDelta := NumDelta
28
Pos := PosAddr
29
Stop
30
longfill(Pos, 0, TotEnc+TotDelta)
31
Pass := (Cog := cognew(@Update, Pos) + 1) > 0
32
33
34 PUB Stop
35 ''Stop the encoder-reading cog, if there is one.
36
37
if Cog > 0
38
cogstop(Cog-1)
39
40
41 PUB ReadDelta(EncID): DeltaPos
42 ''Read delta position (relative position value since last time read) of EncID.
43
44
DeltaPos := 0 + -(EncID < TotDelta) * long[Pos][TotEnc+EncID] + (long[Pos][TotEnc+EncID] := long[Pos][EncID])
45
46
47
48 '************************************
49 '* Encoder Reading Assembly Routine *
50 '************************************
51
52 DAT
53 'Read all encoders and update encoder positions in main memory.
54 'See "Theory of Operation," below, for operational explanation.
55 'Cycle Calculation Equation:
56 ' Terms:
SU = :Sample to :Update. UTI = :UpdatePos through :IPos. MMW = Main Memory Wr
ite.
57 '
AMMN = After MMW to :Next. NU = :Next to :UpdatePos. SH = Resync to Hub. NS
= :Next to :Sample.
58 ' Equation: SU + UTI + MMW + (AMMN + NU + UTI + SH + MMW) * (TotEnc-1) + AMMN + NS
59 '
= 92 + 16 + 8 + ( 16 + 4 + 16 + 6 + 8 ) * (TotEnc-1) + 16 + 12
60 '
= 144 + 50*(TotEnc-1)
61
62
org
0
63
64 Update
65
test
muxc
Pin, #$20
:PinSrc, #%1
wc
'Test for upper or lower port
'Adjust :PinSrc instruction f
118 or proper port
66
mov
IPosAddr, #IntPos
osition values
67
movd
:IClear, IPosAddr
ter
68
mov
Idx, TotEnc
69
:IClear
mov
0, #0
70
add
IPosAddr, #1
71
movd
:IClear, IPosAddr
72
djnz
Idx, #:IClear
73
74
mov
St2, ina
pins
75
shr
St2, Pin
76 :Sample
mov
IPosAddr, #IntPos
r addresses
77
movd
:IPos+0, IPosAddr
78
movd
:IPos+1, IPosAddr
79
mov
MPosAddr, PAR
80
mov
St1, St2
bit signed offsets (St1 = B1:A1)
81
mov
T1, St2
1 = B1:A1
82
shl
T1, #1
1 = A1:x
83
:PinSrc
mov
St2, inb
t2 = B2:A2 left shifted by first encoder offset)
84
shr
St2, Pin
t2 = B2:A2)
85
xor
St1, St2
B1^B2:A1^A2
86
xor
T1, St2
A1^B2:x
87
and
T1, BMask
A1^B2:0
88
or
T1, AMask
A1^B2:1
89
mov
T2, St1
B1^B2:A1^A2
90
and
T2, AMask
0:A1^A2
91
and
St1, BMask
B1^B2:0
92
shr
St1, #1
0:B1^B2
93
xor
T2, St1
0:A1^A2^B1^B2
94
mov
St1, T2
0:A1^B2^B1^A2
95
shl
St1, #1
2^B1^A2:0
96
or
St1, T2
2^B1^A2:A1^B2^B1^A2
97
and
St1, T1
2&A1^B2:A1^B2^B1^A2
98
mov
Idx, TotEnc
99 :UpdatePos
ror
St1, #2
31:30
100
mov
Diff, St1
bit signed Diff
101
sar
Diff, #30
102
:IPos
add
0, Diff
e
103
wrlong 0, MPosAddr
emory
104
add
IPosAddr, #1
ddresses
105
movd
:IPos+0, IPosAddr
106
movd
:IPos+1, IPosAddr
107
add
MPosAddr, #4
108 :Next
djnz
Idx, #:UpdatePos
109
jmp
#:Sample
110
'Clear all internal encoder p
'
set starting internal poin
'
'
'
for all encoders...
clear internal memory
increment pointer
'
loop for each encoder
'Take first sample of encoder
'Reset encoder position buffe
'Calc 2'
T
'
T
'
Sample encoders
(S
'
Adj for first encoder
(S
'
St1
=
'
T1
=
'
T1
=
'
T1
=
'
T2
=
'
T2
=
'
St1
=
'
St1
=
'
T2
=
'
St1
=
'
St1
=
A1^B
'
St1
=
A1^B
'
St1
=
A1^B2^B1^A
'For all encoders...
'Rotate current bit pair into
'Convert 2-bit signed to 32'Add to encoder position valu
'Write new position to main m
'Increment encoder position a
'Loop for each encoder
'Loop forever
119 111 'Define Encoder Reading Cog's constants/variables
112
113 AMask
long
$55555555
'A bit mask
114 BMask
long
$AAAAAAAA
'B bit mask
115 MSB
long
$80000000
'MSB mask for current bit pai
r
116
117 Pin
long
0
'First pin connected to first
encoder
118 TotEnc
long
0
'Total number of encoders
119
120 Idx
res
1
'Encoder index
121 St1
res
1
'Previous state
122 St2
res
1
'Current state
123 T1
res
1
'Temp 1
124 T2
res
1
'Temp 2
125 Diff
res
1
'Difference, ie: -1, 0 or +1
126 IPosAddr
res
1
'Address of current encoder p
osition counter (Internal Memory)
127 MPosAddr
res
1
'Address of current encoder p
osition counter (Main Memory)
128 IntPos
res
16
'Internal encoder position co
unter buffer
129
130
131
132 {{
133 **************************
134 * FUNCTIONAL DESCRIPTION *
135 **************************
136
137 Reads 1 to 16 two-bit gray-code quadrature encoders and provides 32bit absolute position values for each and optionally provides delta position support
138 (value since last read) for up to 16 encoders. See "Required Cycles and Maximum RPM" below f
or speed boundary calculations.
139
140 Connect each encoder to two contiguous I/O pins (multiple encoders must be connected to a con
tiguous block of pins). If delta position support is
141 required, those encoders must be at the start of the group, followed by any encoders not requ
iring delta position support.
142
143 To use this object:
144
1) Create a position buffer (array of longs). The position buffer MUST contain NumEnc + Nu
mDelta longs. The first NumEnc longs of the position buffer
145
will always contain readonly, absolute positions for the respective encoders. The remaining NumDelta longs of the positi
on buffer will be "last
146
absolute read" storage for providing delta position support (if used) and should be igno
red (use ReadDelta() method instead).
147
2) Call Start() passing in the starting pin number, number of encoders, number needing delt
a support and the address of the position buffer. Start() will
148
configure and start an encoder reader in a separate cog; which runs continuously until S
top is called.
149
3) Read position buffer (first NumEnc values) to obtain an absolute 32bit position value for each encoder. Each long (32-bit position counter) within
150
the position buffer is updated automatically by the encoder reader cog.
151
4) For any encoders requiring delta position support, call ReadDelta(); you must have first
sized the position buffer and configured Start() appropriately
152
for this feature.
153
154 Example Code:
155
156 OBJ
157
Encoder : "Quadrature Encoder"
158
159 VAR
160
long Pos[3]
'Create buffer for two encoders (plus room for delta
position support of 1st encoder)
161
162 PUB Init
163
Encoder.Start(8, 2, 1, @Pos)
'Start continuous twoencoder reader (encoders connected to pins 8 - 11)
164
120 165 PUB Main
166
repeat
167
<read Pos[0] or Pos[1] here>
'Read each encoder's absolute position
168
<variable> := Encoder.ReadDelta(0)
'Read 1st encoder's delta position (value since last
read)
169
170 ________________________________
171 REQUIRED CYCLES AND MAXIMUM RPM:
172
173 Encoder Reading Cog requires 144 + 50*(TotEnc1) cycles per sample. That is: 144 for 1 encoder, 194 for 2 encoders, 894 for 16 encoders.
174
175 Conservative Maximum RPM of Highest Resolution Encoder = XINFreq * PLLMultiplier / EncReaderC
ogCycles / 2 / MaxEncPulsesPerRevolution * 60
176
177 Example 1: Using a 4 MHz crystal, 8x internal multiplier, 16 encoders where the highest resol
ution encoders is 1024 pulses per revolution:
178
Max RPM = 4,000,000 * 8 / 894 / 2 / 1024 * 60 = 1,048 RPM
179
180 Example 2: Using same example above, but with only 2 encoders of 128 pulses per revolution:
181
Max RPM = 4,000,000 * 8 / 194 / 2 / 128 * 60 = 38,659 RPM
182 }}
183
184
185 {
186 ____________________
187 THEORY OF OPERATION:
188 Column 1 of the following truth table illustrates 2bit, gray code quadrature encoder output (encoder pins A and B) and their possible transitions (a
ssuming
189 we're sampling fast enough). A1 is the previous value of pin A, A2 is the current value of p
in A, etc. '->' means 'transition to'. The four double-step
190 transition possibilities are not shown here because we won't ever see them if we're sampling
fast enough and, secondly, it is impossible to tell direction
191 if a transition is missed anyway.
192
193 Column 2 shows each of the 2bit results of cross XOR'ing the bits in the previous and current values. Because of the encoder
's gray code output, when
194 there is an actual transition, A1^B2 (msb of column 2) yields the direction (0 = clockwise, 1
= counter-clockwise). When A1^B2 is paired with B1^A2, the
195 resulting 2bit value gives more transition detail (00 or 11 if no transition, 01 if clockwise, 10 if counter
-clockwise).
196
197 Columns 3 and 4 show the results of further XORs and one AND operation. The result is a conv
enient set of 2-bit signed values: 0 if no transition, +1 if
198 clockwise, and -1 and if counter-clockwise.
199
200 This object's Update routine performs the sampling (column 1) and logical operations (colum 3
) of up to 16 2-bit pairs in one operation, then adds the
201 resulting offset (-1, 0 or +1) to each position counter, iteratively.
202
203
1
|
2
|
3
|
4
|
5
204 -------------|-------------|----------------------|----------------|----------205
|
| A1^B2^B1^A2&(A1^B2): |
2-bit sign
|
206 B1A1 -> B2A2 | A1^B2:B1^A2 |
A1^B2^B1^A2
| extended value | Diagnosis
207 -------------|-------------|----------------------|----------------|----------208 00 -> 00 |
00
|
00
|
+0
|
No
209 01 -> 01 |
11
|
00
|
+0
| Movement
210 11 -> 11 |
00
|
00
|
+0
|
211 10 -> 10 |
11
|
00
|
+0
|
212 -------------|-------------|----------------------|----------------|----------213 00 -> 01 |
01
|
01
|
+1
| Clockwise
214 01 -> 11 |
01
|
01
|
+1
|
215 11 -> 10 |
01
|
01
|
+1
|
216 10 -> 00 |
01
|
01
|
+1
|
217 -------------|-------------|----------------------|----------------|----------218 00 -> 10 |
10
|
11
|
-1
| Counter219 10 -> 11 |
10
|
11
|
-1
| Clockwise
220 11 -> 01 |
10
|
11
|
-1
|
221 01 -> 00 |
10
|
11
|
-1
|
222 }
121 223
224 {{
225 ┌──────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────┐
226 │
TERMS OF USE: MIT License
│
227 ├──────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────┤
228 │Permission is hereby granted, free of charge, to any person obtaining a copy of this softwar
e and associated documentation
│
229 │files (the "Software"), to deal in the Software without restriction, including without limit
ation the rights to use, copy,
│
230 │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to p
ermit persons to whom the Software│
231 │is furnished to do so, subject to the following conditions:
│
232 │
│
233 │The above copyright notice and this permission notice shall be included in all copies or sub
stantial portions of the Software.│
234 │
│
235 │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDIN
G BUT NOT LIMITED TO THE
│
236 │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO E
VENT SHALL THE AUTHORS OR
│
237 │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE,
│
238 │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
│
239 └──────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────┘
240 }} 1.5.6 web4robot_lcd_001.spin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
'***********************************************
'** Controlls the web4robot I2C LCD
'** Jacob Dilles <jdilles@gmu.edu> 6/8/2012
'** Version 1.00
'***********************************************
CON
lcd2
= $4c << 1 | 0
' 7 bit address
' Initial values
LCD_BRIGHTNESS = 100 ' 0 - 250
LCD_CONTRAST = 80 ' 0 - 100
OBJ
i2cObject
: "basic_i2c_driver"
VAR
byte _contrast
byte _brightness
PUB
Start
'' set initial values
_contrast :=
LCD_CONTRAST
_brightness :=
LCD_BRIGHTNESS
' set initial state (on)
clear
on
'power on
contrast(_contrast)
PUB brightness(br)
'' Set the brightness value 0-250
i2cObject.start
i2cObject.write(lcd2)
122 34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
i2cObject.write($fe)
i2cObject.write($03)
i2cObject.write(br)
i2cObject.stop
PUB contrast(cn)
'' Set the contrast value 0 - 100
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($04)
i2cObject.write(cn)
i2cObject.stop
PUB pos(x, y)
'' Set the cursor position. X = 0..19, Y = 0..3
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($0C)
i2cObject.write(x)
i2cObject.write(y)
i2cObject.stop
PUB line(ln)
'' Move to the start of the given line
pos(0,ln)
PUB home
'' Move the cursor to the home position
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($0D)
i2cObject.stop
PUB off
'' Turn the LCD off (does not affect backlight)
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($0B)
i2cObject.stop
brightness(0)
PUB on
'' Turn the LCD on
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($0A)
i2cObject.stop
brightness(_brightness)
PUB underline(en)
'' Turn on or off the cursor underline
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
if en
i2cObject.write($0E)
else
i2cObject.write($0F)
i2cObject.stop
PUB left
'' Move the cursor left one position
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($10)
i2cObject.stop
123 107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
PUB right
'' Move the cursor right one position
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($11)
i2cObject.stop
PUB space
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($20)
i2cObject.stop
PUB blink(en)
'' Turn on or off the cursor blink
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
if en
i2cObject.write($12)
else
i2cObject.write($13)
i2cObject.stop
PUB clear
'' Move the cursor left one position
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($14)
i2cObject.stop
PUB charmap(charaddr, map)
'' map a custom character
'' charaddr = 0 .. 7, custom character
'' map = a long (8 bytes) with character data
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write($fe)
i2cObject.write($1A)
i2cObject.write(charaddr)
repeat 8
i2cObject.write( byte[map++] )
i2cObject.stop
PUB out(b)
'' write a single byte
i2cObject.start
i2cObject.write(lcd2)
i2cObject.write(b)
i2cObject.stop
PUB str(stringloc)
'' Write an ASC-II string: writeString(@stringloc) or writeString("hi there")
i2cObject.writeString(lcd2, stringloc)
PUB writeBytes(byteloc, n)
i2cObject.writeBytes(lcd2, byteloc, n)
PUB bin(value, nbits)
bin2str(value, @msg, nbits)
writeBytes(@msg, nbits)
PUB hex(value, nchars)
hex2str(value, @msg, nchars)
writeBytes(@msg, nchars)
PRI bin2str(val, strloc,n)
'' Buffer a value as binary
val <<= 32-n
repeat n
byte[strloc++]:=((val <-= 1) & 1 + "0")
124 180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
pri hex2str(value, strloc, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
byte[strloc++] := lookupz((value <-= 4) & $F : "0".."9", "A".."F")
DAT
'------------ LCD comand strings -----------lcd_clear
byte $fe, $14, 0
lcd_pow_on
byte $fe, $0A, 0
lcd_pow_off byte $fe, $0B, 0
lcd_home
byte $fe, $0d, 0
' ----------------- String Buffer
msg
byte "0",$00[64]
' stringbuff
1.6 IPM
1.6.1 IPM VGA Spice Simulation (With Parasitics)
Version 4
SHEET 1 2692 1212
WIRE 160 -16 160 -32
WIRE 352 0 352 -16
WIRE -544 16 -544 -16
WIRE -496 16 -496 0
WIRE 256 80 256 64
WIRE 1568 80 1536 80
WIRE 1680 80 1680 -32
WIRE 1680 80 1632 80
WIRE -544 96 -544 80
WIRE -496 96 -496 80
WIRE -496 96 -544 96
WIRE 16 96 -16 96
WIRE 160 96 160 48
WIRE 160 96 16 96
WIRE 224 96 160 96
WIRE 1680 96 1680 80
WIRE -624 112 -752 112
WIRE -496 112 -496 96
WIRE -496 112 -544 112
WIRE -448 112 -496 112
WIRE 352 112 352 64
WIRE 352 112 288 112
WIRE 736 112 352 112
WIRE 1680 112 1680 96
WIRE 224 128 176 128
WIRE -752 160 -752 112
WIRE -720 160 -752 160
WIRE -496 160 -496 112
WIRE 256 160 256 144
WIRE -752 176 -752 160
WIRE 144 176 144 160
WIRE 560 176 560 160
WIRE 944 176 944 160
WIRE 1584 208 1520 208
WIRE 1680 208 1680 176
WIRE 1680 208 1648 208
WIRE 1680 224 1680 208
WIRE -496 256 -496 240
WIRE -496 256 -576 256
WIRE -432 256 -496 256
WIRE 16 256 16 96
WIRE 16 256 -32 256
WIRE 48 256 16 256
WIRE 144 256 144 240
WIRE 144 256 128 256
125 WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
176 256 144 256
304 256 256 256
352 256 304 256
400 256 352 256
448 256 400 256
464 256 448 256
560 256 560 240
560 256 544 256
608 256 560 256
736 256 736 112
736 256 688 256
784 256 736 256
944 256 944 240
944 256 864 256
1024 256 944 256
1136 256 1104 256
1184 256 1136 256
-752 272 -752 240
-576 272 -576 256
-496 272 -496 256
944 272 944 256
304 288 304 256
352 288 352 256
400 288 400 256
1136 288 1136 256
144 320 144 256
176 320 144 320
256 320 256 256
256 320 240 320
1680 320 1680 304
-576 336 -576 320
16 336 16 256
-496 352 -496 336
448 352 448 256
464 352 448 352
560 352 560 256
560 352 528 352
-576 368 -576 336
352 368 352 352
400 368 400 352
-240 384 -272 384
-144 384 -176 384
1136 400 1136 368
1680 432 1680 400
1680 432 1664 432
1760 432 1680 432
1888 432 1840 432
-656 448 -736 448
-592 448 -656 448
-528 448 -592 448
-448 448 -528 448
-384 448 -448 448
-368 448 -384 448
1680 448 1680 432
16 464 -64 384
16 464 16 416
160 464 16 464
256 464 224 464
-736 480 -736 448
-656 496 -656 448
-384 496 -384 448
-288 496 -288 448
16 496 16 464
16 496 -288 496
-656 512 -656 496
-592 512 -592 448
-528 512 -528 448
-448 512 -448 448
16 512 16 496
1680 544 1680 528
-288 608 -288 592
16 608 16 592
16 608 -288 608
126 WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
WIRE
-736 640 -736 560
-656 640 -656 576
-656 640 -736 640
-592 640 -592 576
-592 640 -656 640
-528 640 -528 576
-528 640 -592 640
-448 640 -448 576
-448 640 -528 640
-384 640 -384 608
-384 640 -448 640
-368 640 -384 640
-288 640 -288 608
1680 640 1680 624
1744 640 1680 640
1840 640 1808 640
-288 656 -288 640
16 656 16 608
80 656 80 592
80 656 16 656
160 656 80 656
256 656 224 656
1680 656 1680 640
1840 688 1840 640
1840 688 1792 688
1840 704 1840 688
16 720 16 656
-240 736 -272 736
-144 736 -176 736
-64 736 16 656
-736 752 -736 720
144 752 144 720
368 752 368 736
416 752 416 720
192 768 176 768
288 768 256 768
464 768 448 768
560 768 528 768
1680 768 1680 736
1728 768 1680 768
1792 768 1792 688
1680 816 1680 768
16 864 16 800
16 864 -16 864
48 864 16 864
144 864 144 816
144 864 128 864
176 864 176 768
176 864 144 864
192 864 176 864
288 864 288 768
288 864 272 864
336 864 336 816
336 864 288 864
368 864 368 816
368 864 336 864
416 864 416 816
416 864 368 864
448 864 448 768
448 864 416 864
464 864 448 864
560 864 560 768
560 864 544 864
624 864 560 864
736 864 736 816
736 864 704 864
784 864 736 864
944 864 944 848
944 864 864 864
1024 864 944 864
1136 864 1104 864
1216 864 1136 864
944 880 944 864
127 WIRE 560 896 560 864
WIRE 1136 896 1136 864
WIRE 944 960 944 944
WIRE 256 976 256 960
WIRE 560 976 560 960
WIRE 224 992 144 992
WIRE 336 1008 288 1008
WIRE 736 1008 736 864
WIRE 736 1008 336 1008
WIRE 1136 1008 1136 976
WIRE 16 1024 16 864
WIRE 16 1024 -16 1024
WIRE 192 1024 16 1024
WIRE 224 1024 192 1024
WIRE 16 1040 16 1024
WIRE 192 1040 192 1024
WIRE 336 1040 336 1008
WIRE 256 1072 256 1040
WIRE 192 1120 192 1104
WIRE 336 1120 336 1104
FLAG 256 160 vee
FLAG 256 64 vcc
FLAG 176 128 vcm1
FLAG 1680 -32 vcc
FLAG 1184 256 op
FLAG 304 368 0
FLAG 1664 432 0
FLAG 1680 816 vee
FLAG 256 960 vee
FLAG 256 1072 vcc
FLAG 144 992 vcm2
FLAG 1216 864 on
FLAG 336 736 0
FLAG -720 160 vcm
FLAG 944 960 0
FLAG 944 160 0
FLAG 256 656 0
FLAG 256 464 0
FLAG 144 720 0
FLAG 144 160 0
FLAG 1840 704 0
FLAG 1536 80 0
FLAG 1520 208 0
FLAG -752 272 0
FLAG 368 736 0
FLAG 352 368 0
FLAG -432 256 vcm2
FLAG -448 112 vcm1
FLAG -496 352 0
FLAG -496 0 0
FLAG 192 1120 0
FLAG 336 1120 0
FLAG 352 -16 0
FLAG 560 160 0
FLAG 560 976 0
FLAG 160 -32 0
FLAG -576 368 0
FLAG -544 -16 0
FLAG 1136 1008 0
FLAG 1136 400 0
FLAG 1888 432 vcm
FLAG -272 736 0
FLAG -272 384 0
FLAG 400 368 0
FLAG 416 720 0
FLAG -736 752 0
SYMBOL current -736 480 R0
WINDOW 123 -100 94 Left 2
WINDOW 39 0 0 Left 2
WINDOW 3 -251 36 Left 2
SYMATTR Value2 AC 1
SYMATTR Value SINE(0 10u 100k)
SYMATTR InstName I1
128 SYMBOL res 272 240 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R1
SYMATTR Value 2.000k
SYMBOL voltage 1680 304 R0
WINDOW 123 0 0 Left 2
WINDOW 39 24 124 Left 2
SYMATTR InstName V1
SYMATTR Value 2.5
SYMATTR SpiceLine Rser=5
SYMBOL res 560 240 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R2
SYMATTR Value 499
SYMBOL res 320 384 R180
WINDOW 0 36 76 Left 2
WINDOW 3 36 40 Left 2
SYMATTR InstName R3
SYMATTR Value {rs}
SYMBOL voltage 1680 432 R0
WINDOW 123 0 0 Left 2
WINDOW 39 24 124 Left 2
SYMATTR InstName V2
SYMATTR Value 2.5
SYMATTR SpiceLine Rser=5
SYMBOL cap 336 288 R0
WINDOW 3 -27 112 Left 2
SYMATTR InstName C1
SYMATTR Value 90.3p
SYMBOL cap 528 336 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C3
SYMATTR Value .5p
SYMBOL res 288 880 M270
WINDOW 0 32 56 VTop 2
WINDOW 3 0 90 VBottom 2
SYMATTR InstName R5
SYMATTR Value 2.000k
SYMBOL res 560 880 M270
WINDOW 0 32 56 VTop 2
WINDOW 3 0 56 VBottom 2
SYMATTR InstName R6
SYMATTR Value 499
SYMBOL res 352 720 M0
WINDOW 0 23 -12 Left 2
WINDOW 3 34 27 Left 2
SYMATTR InstName R7
SYMATTR Value {rs}
SYMBOL res 1120 992 M180
WINDOW 0 36 76 Left 2
WINDOW 3 36 40 Left 2
SYMATTR InstName R8
SYMATTR Value 50
SYMBOL cap 352 816 M180
WINDOW 0 24 56 Left 2
WINDOW 3 -10 118 Left 2
SYMATTR InstName C4
SYMATTR Value 90.3p
SYMBOL cap 256 784 M270
WINDOW 0 32 32 VTop 2
WINDOW 3 0 32 VBottom 2
SYMATTR InstName C5
SYMATTR Value .5p
SYMBOL cap 528 784 M270
WINDOW 0 32 32 VTop 2
WINDOW 3 0 32 VBottom 2
SYMATTR InstName C6
SYMATTR Value .5p
SYMBOL Opamps\\LT1886 256 48 R0
SYMATTR InstName U1
129 SYMBOL Opamps\\LT1886 256 1072 M180
SYMATTR InstName U2
SYMBOL cap -608 512 R0
SYMATTR InstName C7
SYMATTR Value 100p
SYMBOL res 1856 416 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R10
SYMATTR Value 0.129
SYMBOL cap 928 176 R0
SYMATTR InstName C8
SYMATTR Value 1.44p
SYMBOL cap 928 880 R0
SYMATTR InstName C9
SYMATTR Value 2.11p
SYMBOL res -272 432 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R9
SYMATTR Value 2
SYMBOL ind 0 704 R0
SYMATTR InstName L1
SYMATTR Value 48n
SYMBOL ind 0 320 R0
SYMATTR InstName L2
SYMATTR Value 48n
SYMBOL ind 144 240 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L3
SYMATTR Value 15n
SYMBOL ind 144 848 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L4
SYMATTR Value 25.85n
SYMBOL ind -272 624 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L5
SYMATTR Value 0.48u
SYMBOL cap -544 512 R0
SYMATTR InstName C12
SYMATTR Value 168p
SYMBOL cap -464 512 R0
SYMATTR InstName C13
SYMATTR Value 60p
SYMBOL cap 224 448 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C10
SYMATTR Value 2.69p
SYMBOL cap 224 640 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C11
SYMATTR Value 2.69p
SYMBOL cap 128 176 R0
WINDOW 3 -39 16 Left 2
SYMATTR InstName C14
SYMATTR Value .96p
SYMBOL cap 128 752 R0
WINDOW 0 -49 18 Left 2
WINDOW 3 -43 60 Left 2
SYMATTR InstName C15
SYMATTR Value 1.2p
SYMBOL ind 1664 528 R0
WINDOW 3 85 48 Left 2
SYMATTR Value 6.98n
SYMATTR InstName L6
SYMBOL ind 1664 640 R0
SYMATTR InstName L7
130 SYMATTR Value 6.96n
SYMBOL cap 1808 624 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C16
SYMATTR Value 2.2u
SYMBOL cap 1792 752 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C18
SYMATTR Value 2.2u
SYMBOL ind 1664 208 R0
WINDOW 0 -46 80 Left 2
SYMATTR InstName L8
SYMATTR Value 4.23n
SYMBOL ind 1664 80 R0
SYMATTR InstName L9
SYMATTR Value 3.85n
SYMBOL cap 1648 192 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C19
SYMATTR Value 2.2u
SYMBOL cap 1632 64 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C21
SYMATTR Value 2.2u
SYMBOL cap -768 176 R0
WINDOW 0 -56 66 Left 2
SYMATTR InstName C17
SYMATTR Value 1.2p
SYMBOL ind -512 144 R0
SYMATTR InstName L10
SYMATTR Value 5.368n
SYMBOL cap -512 272 R0
SYMATTR InstName C20
SYMATTR Value .385p
SYMBOL cap -512 16 R0
SYMATTR InstName C23
SYMATTR Value .385p
SYMBOL ind -528 96 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L11
SYMATTR Value 4.16n
SYMBOL cap 176 1040 R0
WINDOW 3 -23 59 Left 2
SYMATTR Value .337p
SYMATTR InstName C24
SYMBOL cap 320 1040 R0
SYMATTR InstName C26
SYMATTR Value .337p
SYMBOL ind 720 848 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L12
SYMATTR Value 11.82n
SYMBOL ind 704 240 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L13
SYMATTR Value 22.24n
SYMBOL ind 880 848 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L14
SYMATTR Value 36.94n
SYMBOL ind 880 240 R90
WINDOW 0 5 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName L15
SYMATTR Value 24.04n
131 SYMBOL cap 336 0 R0
SYMATTR InstName C27
SYMATTR Value .337p
SYMBOL cap 544 176 R0
SYMATTR InstName C28
SYMATTR Value 1.34p
SYMBOL cap 544 896 R0
SYMATTR InstName C29
SYMATTR Value .77p
SYMBOL cap 144 -16 R0
SYMATTR InstName C30
SYMATTR Value .337p
SYMBOL cap -592 272 R0
SYMATTR InstName C25
SYMATTR Value .337p
SYMBOL cap -560 16 R0
WINDOW 0 -52 4 Left 2
SYMATTR InstName C31
SYMATTR Value .337p
SYMBOL res 1120 848 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R11
SYMATTR Value 50
SYMBOL res 1120 384 M180
WINDOW 0 36 76 Left 2
WINDOW 3 36 40 Left 2
SYMATTR InstName R12
SYMATTR Value 50
SYMBOL res 1120 240 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R13
SYMATTR Value 50
SYMBOL res -672 480 R0
SYMATTR InstName R4
SYMATTR Value 100k
SYMBOL res -48 720 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R15
SYMATTR Value {Rc}
SYMBOL cap -176 720 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C32
SYMATTR Value {Cc}
SYMBOL res -48 368 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R16
SYMATTR Value {Rc}
SYMBOL cap -176 368 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C33
SYMATTR Value {Cc}
SYMATTR SpiceLine Rser=10m Lser=10p
SYMBOL cap 384 288 R0
SYMATTR InstName C2
SYMATTR Value {Ct}
SYMBOL cap 400 752 R0
SYMATTR InstName C22
SYMATTR Value {Ct}
SYMBOL cap 240 304 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C34
SYMATTR Value .5p
SYMBOL res 64 496 R0
SYMATTR InstName R14
SYMATTR Value 100k
SYMBOL cap -752 656 R0
132 SYMATTR InstName C35
SYMATTR Value 10n
TEXT 960 -72 Left 2 !.tran 1m startup
TEXT -472 -224 Left 2 ;.step param rs list 1e9 15999.998976 31.936128 15.984016 10.659560
7.996002 6.397441 5.331556 4.570123 3.999000 3.554766 3.199360 2.908562 2.666222 2.461160
2.285388 2.133049
TEXT -192 -48 Left 2 ;.param rs 5.39
TEXT -448 712 Left 2 ;rg-58
TEXT -584 688 Left 2 ;rg-58
TEXT -688 672 Left 2 ;pd
TEXT -496 680 Left 2 ;con
TEXT 1808 488 Left 2 ;header
TEXT -568 176 Left 2 ;trace
TEXT 624 192 Left 2 ;trace
TEXT 616 920 Left 2 ;trace
TEXT 280 32 Left 2 ;pad
TEXT 856 208 Left 2 ;trace
TEXT 864 896 Left 2 ;trace
TEXT 104 0 Left 2 ;pad
TEXT -632 304 Left 2 ;pad
TEXT -640 768 Left 2 ;PULSE(0 10u 100n 10n 10n 20n)
TEXT -200 -152 Left 2 !.param Rc 6.8
TEXT -192 -120 Left 2 !.param Cc 20n
TEXT 160 -152 Left 2 ;.step param Cc list 10n 12n 14n 16n 18n 20n
TEXT 176 -184 Left 2 ;.step param Rc list 8 10 12 14 16 18
TEXT 80 224 Left 2 ;trace
TEXT 120 -120 Left 2 !.param Ct 1p
TEXT 496 440 Left 2 ;Fix is to add 2x compensation RCs: Cc=20n and Rc=6.8 from inputs to ground
TEXT 496 480 Left 2 ;This decreases frequency response, and moves the peak to around 200khz (vs
10 MHz)
TEXT 512 512 Left 2 ;but should make us unconditionally stable
TEXT -208 0 Left 2 !.param rs 15
133 

Similar documents