mirror of
https://github.com/wfjm/w11.git
synced 2026-03-27 02:34:25 +00:00
- add sources for C++/Tcl based backend, add directories
- tools/src/... - tools/tcl/... - tools/dox - tools/make - add rlink test system - rtl/sys_gen/tst_rlink/nexys2/...
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# $Id: README.txt 351 2010-12-30 21:50:54Z mueller $
|
||||
# $Id: README.txt 353 2011-01-02 21:02:48Z mueller $
|
||||
|
||||
Release notes for w11a
|
||||
|
||||
|
||||
7
rtl/bplib/nexys2/tb/nexys2_fusp_dummy.vbom
Normal file
7
rtl/bplib/nexys2/tb/nexys2_fusp_dummy.vbom
Normal file
@@ -0,0 +1,7 @@
|
||||
# libs
|
||||
../../../vlib/slvtypes.vhd
|
||||
../nexys2lib.vhd
|
||||
# components
|
||||
../n2_cram_dummy.vbom
|
||||
# design
|
||||
nexys2_fusp_dummy.vhd
|
||||
90
rtl/bplib/nexys2/tb/nexys2_fusp_dummy.vhd
Normal file
90
rtl/bplib/nexys2/tb/nexys2_fusp_dummy.vhd
Normal file
@@ -0,0 +1,90 @@
|
||||
-- $Id: nexys2_fusp_dummy.vhd 338 2010-11-13 22:19:25Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: nexys2_dummy - syn
|
||||
-- Description: nexys2 minimal target (base; serport loopback)
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- To test: tb_nexys2
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 11.4, 12.1; ghdl 0.26-0.29
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-11-13 338 1.0.2 add O_CLKSYS (for DCM derived system clock)
|
||||
-- 2010-11-06 336 1.0.1 rename input pin CLK -> I_CLK50
|
||||
-- 2010-05-28 295 1.0 Initial version (derived from s3board_fusp_dummy)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.nexys2lib.all;
|
||||
|
||||
entity nexys2_fusp_dummy is -- NEXYS 2 dummy (base+fusp; loopback)
|
||||
-- implements nexys2_fusp_aif
|
||||
port (
|
||||
I_CLK50 : in slbit; -- 50 MHz board clock
|
||||
O_CLKSYS : out slbit; -- DCM derived system clock
|
||||
I_RXD : in slbit; -- receive data (board view)
|
||||
O_TXD : out slbit; -- transmit data (board view)
|
||||
I_SWI : in slv8; -- s3 switches
|
||||
I_BTN : in slv4; -- s3 buttons
|
||||
O_LED : out slv8; -- s3 leds
|
||||
O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low)
|
||||
O_SEG_N : out slv8; -- 7 segment disp: segments (act.low)
|
||||
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
|
||||
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
|
||||
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
|
||||
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
|
||||
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
|
||||
O_MEM_CLK : out slbit; -- cram: clock
|
||||
O_MEM_CRE : out slbit; -- cram: command register enable
|
||||
I_MEM_WAIT : in slbit; -- cram: mem wait
|
||||
O_FLA_CE_N : out slbit; -- flash ce.. (act.low)
|
||||
O_MEM_ADDR : out slv23; -- cram: address lines
|
||||
IO_MEM_DATA : inout slv16; -- cram: data lines
|
||||
O_FUSP_RTS_N : out slbit; -- fusp: rs232 rts_n
|
||||
I_FUSP_CTS_N : in slbit; -- fusp: rs232 cts_n
|
||||
I_FUSP_RXD : in slbit; -- fusp: rs232 rx
|
||||
O_FUSP_TXD : out slbit -- fusp: rs232 tx
|
||||
);
|
||||
end nexys2_fusp_dummy;
|
||||
|
||||
architecture syn of nexys2_fusp_dummy is
|
||||
|
||||
begin
|
||||
|
||||
O_CLKSYS <= I_CLK50; -- use 50 MHz clock
|
||||
O_TXD <= I_RXD; -- loop back
|
||||
O_FUSP_TXD <= I_FUSP_RXD;
|
||||
O_FUSP_RTS_N <= I_FUSP_CTS_N;
|
||||
|
||||
CRAM : n2_cram_dummy -- connect CRAM to protection dummy
|
||||
port map (
|
||||
O_MEM_CE_N => O_MEM_CE_N,
|
||||
O_MEM_BE_N => O_MEM_BE_N,
|
||||
O_MEM_WE_N => O_MEM_WE_N,
|
||||
O_MEM_OE_N => O_MEM_OE_N,
|
||||
O_MEM_ADV_N => O_MEM_ADV_N,
|
||||
O_MEM_CLK => O_MEM_CLK,
|
||||
O_MEM_CRE => O_MEM_CRE,
|
||||
I_MEM_WAIT => I_MEM_WAIT,
|
||||
O_FLA_CE_N => O_FLA_CE_N,
|
||||
O_MEM_ADDR => O_MEM_ADDR,
|
||||
IO_MEM_DATA => IO_MEM_DATA
|
||||
);
|
||||
|
||||
end syn;
|
||||
@@ -3,9 +3,9 @@ tb_s3board_dummy_[sft]sim
|
||||
tb_s3board_dummy_ISim
|
||||
tb_s3board_dummy_ISim_[sft]sim
|
||||
tb_s3board_fusp_dummy
|
||||
tb_rriext_fifo_rx
|
||||
tb_rriext_fifo_tx
|
||||
tb_rriext_conf
|
||||
rlink_cext_fifo_rx
|
||||
rlink_cext_fifo_tx
|
||||
rlink_cext_conf
|
||||
tb_s3_sram_memctl
|
||||
tb_s3_sram_memctl_[sft]sim
|
||||
tb_s3_sram_memctl_stim
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# $Id: tbw.dat 290 2010-05-16 08:44:36Z mueller $
|
||||
# $Id: tbw.dat 353 2011-01-02 21:02:48Z mueller $
|
||||
#
|
||||
[tb_s3board_dummy]
|
||||
tb_rriext_fifo_rx = <fifo>
|
||||
tb_rriext_fifo_tx = <fifo>
|
||||
tb_rriext_conf = <null>
|
||||
rlink_cext_fifo_rx = <fifo>
|
||||
rlink_cext_fifo_tx = <fifo>
|
||||
rlink_cext_conf = <null>
|
||||
|
||||
3
rtl/sys_gen/tst_rlink/nexys2/.cvsignore
Normal file
3
rtl/sys_gen/tst_rlink/nexys2/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
_impactbatch.log
|
||||
sys_tst_rlink_n2.ucf
|
||||
*.dep_ucf_cpp
|
||||
32
rtl/sys_gen/tst_rlink/nexys2/Makefile
Normal file
32
rtl/sys_gen/tst_rlink/nexys2/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
# $Id: Makefile 351 2010-12-30 21:50:54Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2010-12-29 351 1.0 Initial version
|
||||
#
|
||||
VBOM_all = $(wildcard *.vbom)
|
||||
BIT_all = $(VBOM_all:.vbom=.bit)
|
||||
#
|
||||
ISE_BOARD = nexys2
|
||||
ISE_PATH = xc3s1200e-fg320-4
|
||||
#
|
||||
.phony : all clean
|
||||
#
|
||||
all : $(BIT_all)
|
||||
#
|
||||
clean : ise_clean
|
||||
rm -f sys_tst_rlink_n2.ucf
|
||||
#
|
||||
sys_tst_rlink_n2.mcs : sys_tst_rlink_n2.bit
|
||||
promgen -w -x xcf04s -p mcs -u 0 sys_tst_rlink_n2
|
||||
mv sys_tst_rlink_n2.prm sys_tst_rlink_n2_prm.log
|
||||
mv sys_tst_rlink_n2.cfi sys_tst_rlink_n2_cfi.log
|
||||
#
|
||||
#----
|
||||
#
|
||||
include $(RETROBASE)/rtl/vlib/Makefile.xflow
|
||||
include $(RETROBASE)/rtl/vlib/Makefile.ghdl
|
||||
#
|
||||
include $(VBOM_all:.vbom=.dep_xst)
|
||||
include $(VBOM_all:.vbom=.dep_ghdl)
|
||||
#
|
||||
49
rtl/sys_gen/tst_rlink/nexys2/sys_conf.vhd
Normal file
49
rtl/sys_gen/tst_rlink/nexys2/sys_conf.vhd
Normal file
@@ -0,0 +1,49 @@
|
||||
-- $Id: sys_conf.vhd 351 2010-12-30 21:50:54Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Package Name: sys_conf
|
||||
-- Description: Definitions for sys_tst_rlink_n2 (for synthesis)
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-29 351 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
|
||||
package sys_conf is
|
||||
|
||||
constant sys_conf_clkfx_divide : positive := 1;
|
||||
constant sys_conf_clkfx_multiply : positive := 1; --
|
||||
|
||||
constant sys_conf_ser2rri_defbaud : integer := 115200; -- default 115k baud
|
||||
|
||||
constant sys_conf_hio_debounce : boolean := true; -- instantiate debouncers
|
||||
|
||||
-- derived constants
|
||||
|
||||
constant sys_conf_clksys : integer :=
|
||||
(50000000/sys_conf_clkfx_divide)*sys_conf_clkfx_multiply;
|
||||
constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000;
|
||||
|
||||
constant sys_conf_ser2rri_cdinit : integer :=
|
||||
(sys_conf_clksys/sys_conf_ser2rri_defbaud)-1;
|
||||
|
||||
end package sys_conf;
|
||||
|
||||
19
rtl/sys_gen/tst_rlink/nexys2/sys_tst_rlink_n2.ucf_cpp
Normal file
19
rtl/sys_gen/tst_rlink/nexys2/sys_tst_rlink_n2.ucf_cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
## $Id: mueller $
|
||||
##
|
||||
## Revision History:
|
||||
## Date Rev Version Comment
|
||||
## 2010-12-29 351 1.0 Initial version
|
||||
##
|
||||
|
||||
NET "I_CLK50" TNM_NET = "I_CLK50";
|
||||
TIMESPEC "TS_I_CLK50" = PERIOD "I_CLK50" 20.0 ns HIGH 50 %;
|
||||
OFFSET = IN 10 ns BEFORE "I_CLK50";
|
||||
OFFSET = OUT 20 ns AFTER "I_CLK50";
|
||||
|
||||
## std board
|
||||
##
|
||||
#include "bplib/nexys2/nexys2_pins.ucf"
|
||||
##
|
||||
## Pmod B0 - RS232
|
||||
##
|
||||
#include "bplib/nexys2/nexys2_pins_pmb0_rs232.ucf"
|
||||
17
rtl/sys_gen/tst_rlink/nexys2/sys_tst_rlink_n2.vbom
Normal file
17
rtl/sys_gen/tst_rlink/nexys2/sys_tst_rlink_n2.vbom
Normal file
@@ -0,0 +1,17 @@
|
||||
# libs
|
||||
../../../vlib/slvtypes.vhd
|
||||
../../../vlib/xlib/xlib.vhd
|
||||
../../../vlib/genlib/genlib.vhd
|
||||
../../../bplib/s3board/s3boardlib.vbom
|
||||
../../../bplib/nexys2/nexys2lib.vhd
|
||||
sys_conf : sys_conf.vhd
|
||||
# components
|
||||
[xst,isim]../../../vlib/xlib/dcm_sp_sfs_unisim.vbom
|
||||
[ghdl]../../../vlib/xlib/dcm_sp_sfs_gsim.vbom
|
||||
../../../vlib/genlib/clkdivce.vbom
|
||||
../../../bplib/s3board/s3_rs232_iob_int_ext.vbom
|
||||
../tst_rlink.vbom
|
||||
../../../bplib/nexys2/n2_cram_dummy.vbom
|
||||
# design
|
||||
sys_tst_rlink_n2.vhd
|
||||
@ucf_cpp: sys_tst_rlink_n2.ucf
|
||||
181
rtl/sys_gen/tst_rlink/nexys2/sys_tst_rlink_n2.vhd
Normal file
181
rtl/sys_gen/tst_rlink/nexys2/sys_tst_rlink_n2.vhd
Normal file
@@ -0,0 +1,181 @@
|
||||
-- $Id: sys_tst_rlink_n2.vhd 375 2011-04-02 07:56:47Z mueller $
|
||||
--
|
||||
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: sys_tst_rlink_n2 - syn
|
||||
-- Description: rlink tester design for nexys2
|
||||
--
|
||||
-- Dependencies: vlib/xlib/dcm_sp_sfs
|
||||
-- vlib/genlib/clkdivce
|
||||
-- bplib/s3board/s3_rs232_iob_int_ext
|
||||
-- vlib/nexys2/n2_cram_dummy
|
||||
--
|
||||
-- Test bench: tb/tb_tst_rlink_n2
|
||||
--
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
--
|
||||
-- Synthesized (xst):
|
||||
-- Date Rev ise Target flop lutl lutm slic t peri
|
||||
-- 2011-04-02 375 12.1 M53d xc3s1200e-4 688 1572 68 994 t 13.8
|
||||
-- 2010-12-29 351 12.1 M53d xc3s1200e-4 604 1298 68 851 t 14.7
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-29 351 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.xlib.all;
|
||||
use work.genlib.all;
|
||||
use work.s3boardlib.all;
|
||||
use work.nexys2lib.all;
|
||||
use work.sys_conf.all;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
entity sys_tst_rlink_n2 is -- top level
|
||||
-- implements nexys2_fusp_aif
|
||||
port (
|
||||
I_CLK50 : in slbit; -- 50 MHz clock
|
||||
O_CLKSYS : out slbit; -- DCM derived system clock
|
||||
I_RXD : in slbit; -- receive data (board view)
|
||||
O_TXD : out slbit; -- transmit data (board view)
|
||||
I_SWI : in slv8; -- s3 switches
|
||||
I_BTN : in slv4; -- s3 buttons
|
||||
O_LED : out slv8; -- s3 leds
|
||||
O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low)
|
||||
O_SEG_N : out slv8; -- 7 segment disp: segments (act.low)
|
||||
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
|
||||
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
|
||||
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
|
||||
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
|
||||
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
|
||||
O_MEM_CLK : out slbit; -- cram: clock
|
||||
O_MEM_CRE : out slbit; -- cram: command register enable
|
||||
I_MEM_WAIT : in slbit; -- cram: mem wait
|
||||
O_FLA_CE_N : out slbit; -- flash ce.. (act.low)
|
||||
O_MEM_ADDR : out slv23; -- cram: address lines
|
||||
IO_MEM_DATA : inout slv16; -- cram: data lines
|
||||
O_FUSP_RTS_N : out slbit; -- fusp: rs232 rts_n
|
||||
I_FUSP_CTS_N : in slbit; -- fusp: rs232 cts_n
|
||||
I_FUSP_RXD : in slbit; -- fusp: rs232 rx
|
||||
O_FUSP_TXD : out slbit -- fusp: rs232 tx
|
||||
);
|
||||
end sys_tst_rlink_n2;
|
||||
|
||||
architecture syn of sys_tst_rlink_n2 is
|
||||
|
||||
signal CLK : slbit := '0';
|
||||
|
||||
signal RXD : slbit := '1';
|
||||
signal TXD : slbit := '0';
|
||||
signal RTS_N : slbit := '0';
|
||||
signal CTS_N : slbit := '0';
|
||||
|
||||
signal SWI : slv8 := (others=>'0');
|
||||
signal BTN : slv4 := (others=>'0');
|
||||
|
||||
signal RESET : slbit := '0';
|
||||
signal CE_USEC : slbit := '0';
|
||||
signal CE_MSEC : slbit := '0';
|
||||
|
||||
begin
|
||||
|
||||
assert (sys_conf_clksys mod 1000000) = 0
|
||||
report "assert sys_conf_clksys on MHz grid"
|
||||
severity failure;
|
||||
|
||||
DCM : dcm_sp_sfs
|
||||
generic map (
|
||||
CLKFX_DIVIDE => sys_conf_clkfx_divide,
|
||||
CLKFX_MULTIPLY => sys_conf_clkfx_multiply,
|
||||
CLKIN_PERIOD => 20.0)
|
||||
port map (
|
||||
CLKIN => I_CLK50,
|
||||
CLKFX => CLK,
|
||||
LOCKED => open
|
||||
);
|
||||
|
||||
O_CLKSYS <= CLK;
|
||||
|
||||
CLKDIV : clkdivce
|
||||
generic map (
|
||||
CDUWIDTH => 7,
|
||||
USECDIV => sys_conf_clksys_mhz,
|
||||
MSECDIV => 1000)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
CE_USEC => CE_USEC,
|
||||
CE_MSEC => CE_MSEC
|
||||
);
|
||||
|
||||
IOB_RS232 : s3_rs232_iob_int_ext
|
||||
port map (
|
||||
CLK => CLK,
|
||||
SEL => SWI(0),
|
||||
RXD => RXD,
|
||||
TXD => TXD,
|
||||
CTS_N => CTS_N,
|
||||
RTS_N => RTS_N,
|
||||
I_RXD0 => I_RXD,
|
||||
O_TXD0 => O_TXD,
|
||||
I_RXD1 => I_FUSP_RXD,
|
||||
O_TXD1 => O_FUSP_TXD,
|
||||
I_CTS1_N => I_FUSP_CTS_N,
|
||||
O_RTS1_N => O_FUSP_RTS_N
|
||||
);
|
||||
|
||||
RLTEST : entity work.tst_rlink
|
||||
generic map (
|
||||
DEBOUNCE => sys_conf_hio_debounce,
|
||||
CDINIT => sys_conf_ser2rri_cdinit)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
CE_USEC => CE_USEC,
|
||||
CE_MSEC => CE_MSEC,
|
||||
RXD => RXD,
|
||||
TXD => TXD,
|
||||
CTS_N => CTS_N,
|
||||
RTS_N => RTS_N,
|
||||
SWI => SWI,
|
||||
BTN => BTN,
|
||||
I_SWI => I_SWI,
|
||||
I_BTN => I_BTN,
|
||||
O_LED => O_LED,
|
||||
O_ANO_N => O_ANO_N,
|
||||
O_SEG_N => O_SEG_N
|
||||
);
|
||||
|
||||
SRAM_PROT : n2_cram_dummy -- connect CRAM to protection dummy
|
||||
port map (
|
||||
O_MEM_CE_N => O_MEM_CE_N,
|
||||
O_MEM_BE_N => O_MEM_BE_N,
|
||||
O_MEM_WE_N => O_MEM_WE_N,
|
||||
O_MEM_OE_N => O_MEM_OE_N,
|
||||
O_MEM_ADV_N => O_MEM_ADV_N,
|
||||
O_MEM_CLK => O_MEM_CLK,
|
||||
O_MEM_CRE => O_MEM_CRE,
|
||||
I_MEM_WAIT => I_MEM_WAIT,
|
||||
O_FLA_CE_N => O_FLA_CE_N,
|
||||
O_MEM_ADDR => O_MEM_ADDR,
|
||||
IO_MEM_DATA => IO_MEM_DATA
|
||||
);
|
||||
|
||||
end syn;
|
||||
7
rtl/sys_gen/tst_rlink/nexys2/tb/.cvsignore
Normal file
7
rtl/sys_gen/tst_rlink/nexys2/tb/.cvsignore
Normal file
@@ -0,0 +1,7 @@
|
||||
tb_tst_rlink_n2
|
||||
tb_tst_rlink_n2_[sft]sim
|
||||
rlink_cext_fifo_rx
|
||||
rlink_cext_fifo_tx
|
||||
rlink_cext_conf
|
||||
sys_tst_rlink_n2.ucf
|
||||
*.dep_ucf_cpp
|
||||
30
rtl/sys_gen/tst_rlink/nexys2/tb/Makefile
Normal file
30
rtl/sys_gen/tst_rlink/nexys2/tb/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
# $Id: Makefile 351 2010-12-30 21:50:54Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2010-12-29 351 1.0 Initial version
|
||||
#
|
||||
EXE_all = tb_tst_rlink_n2
|
||||
#
|
||||
ISE_PATH = xc3s1200e-fg320-4
|
||||
#
|
||||
.phony : all all_ssim all_tsim clean
|
||||
#
|
||||
all : $(EXE_all)
|
||||
all_ssim : $(EXE_all:=_ssim)
|
||||
all_tsim : $(EXE_all:=_tsim)
|
||||
#
|
||||
clean : ise_clean ghdl_clean
|
||||
rm -f sys_tst_rlink_n2.ucf
|
||||
#
|
||||
#-----
|
||||
#
|
||||
include $(RETROBASE)/rtl/vlib/Makefile.ghdl
|
||||
include $(RETROBASE)/rtl/vlib/Makefile.xflow
|
||||
#
|
||||
VBOM_all = $(wildcard *.vbom)
|
||||
#
|
||||
include $(VBOM_all:.vbom=.dep_xst)
|
||||
include $(VBOM_all:.vbom=.dep_ghdl)
|
||||
include $(wildcard *.o.dep_ghdl)
|
||||
#
|
||||
45
rtl/sys_gen/tst_rlink/nexys2/tb/sys_conf_sim.vhd
Normal file
45
rtl/sys_gen/tst_rlink/nexys2/tb/sys_conf_sim.vhd
Normal file
@@ -0,0 +1,45 @@
|
||||
-- $Id: sys_conf_sim.vhd 351 2010-12-30 21:50:54Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Package Name: sys_conf
|
||||
-- Description: Definitions for sys_tst_rlink_n2 (for simulation)
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-29 351 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
|
||||
package sys_conf is
|
||||
|
||||
constant sys_conf_clkfx_divide : positive := 1;
|
||||
constant sys_conf_clkfx_multiply : positive := 1;
|
||||
|
||||
constant sys_conf_ser2rri_cdinit : integer := 1-1; -- 1 cycle/bit in sim
|
||||
|
||||
constant sys_conf_hio_debounce : boolean := false; -- no debouncers
|
||||
|
||||
-- derived constants
|
||||
|
||||
constant sys_conf_clksys : integer :=
|
||||
(50000000/sys_conf_clkfx_divide)*sys_conf_clkfx_multiply;
|
||||
constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000;
|
||||
|
||||
end package sys_conf;
|
||||
1
rtl/sys_gen/tst_rlink/nexys2/tb/sys_tst_rlink_n2.ucf_cpp
Symbolic link
1
rtl/sys_gen/tst_rlink/nexys2/tb/sys_tst_rlink_n2.ucf_cpp
Symbolic link
@@ -0,0 +1 @@
|
||||
../sys_tst_rlink_n2.ucf_cpp
|
||||
7
rtl/sys_gen/tst_rlink/nexys2/tb/tb_tst_rlink_n2.vbom
Normal file
7
rtl/sys_gen/tst_rlink/nexys2/tb/tb_tst_rlink_n2.vbom
Normal file
@@ -0,0 +1,7 @@
|
||||
# configure tb_nexsy2_fusp with sys_tst_rlink_n2 target;
|
||||
# use vhdl configure file (tb_tst_rlink_n2.vhd) to allow
|
||||
# that all configurations will co-exist in work library
|
||||
nexys2_aif : ../sys_tst_rlink_n2.vbom
|
||||
sys_conf = sys_conf_sim.vhd
|
||||
../../../../bplib/nexys2/tb/tb_nexys2_fusp.vbom
|
||||
tb_tst_rlink_n2.vhd
|
||||
39
rtl/sys_gen/tst_rlink/nexys2/tb/tb_tst_rlink_n2.vhd
Normal file
39
rtl/sys_gen/tst_rlink/nexys2/tb/tb_tst_rlink_n2.vhd
Normal file
@@ -0,0 +1,39 @@
|
||||
-- $Id: tb_tst_rlink_n2.vhd 351 2010-12-30 21:50:54Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: tb_tst_rlink
|
||||
-- Description: Configuration for tb_tst_rlink_s2 for tb_nexys2_fusp
|
||||
--
|
||||
-- Dependencies: sys_tst_rlink_n2
|
||||
--
|
||||
-- To test: sys_tst_rlink_n2
|
||||
--
|
||||
-- Verified:
|
||||
-- Date Rev Code ghdl ise Target Comment
|
||||
-- 2010-12-xx xxx - 0.29 12.1 M53d xc3s1200e u:???
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-29 351 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
configuration tb_tst_rlink_n2 of tb_nexys2_fusp is
|
||||
|
||||
for sim
|
||||
for all : nexys2_fusp_aif
|
||||
use entity work.sys_tst_rlink_n2;
|
||||
end for;
|
||||
end for;
|
||||
|
||||
end tb_tst_rlink_n2;
|
||||
@@ -0,0 +1,6 @@
|
||||
# configure for _*sim case
|
||||
# Note: this tb uses sys_tst_rlink_n2.vbom in local directory
|
||||
# (not in .. as usual) to allow a tb specific configure !!!
|
||||
nexys2_aif = sys_tst_rlink_n2_ssim.vhd
|
||||
tb_tst_rlink_n2.vbom
|
||||
@top:tb_tst_rlink_n2
|
||||
6
rtl/sys_gen/tst_rlink/nexys2/tb/tbw.dat
Normal file
6
rtl/sys_gen/tst_rlink/nexys2/tb/tbw.dat
Normal file
@@ -0,0 +1,6 @@
|
||||
# $Id: tbw.dat 351 2010-12-30 21:50:54Z mueller $
|
||||
#
|
||||
[tb_tst_rlink_n2]
|
||||
rlink_cext_fifo_rx = <fifo>
|
||||
rlink_cext_fifo_tx = <fifo>
|
||||
rlink_cext_conf = <null>
|
||||
17
rtl/sys_gen/tst_rlink/tst_rlink.vbom
Normal file
17
rtl/sys_gen/tst_rlink/tst_rlink.vbom
Normal file
@@ -0,0 +1,17 @@
|
||||
# libs
|
||||
../../vlib/slvtypes.vhd
|
||||
../../vlib/rbus/rblib.vhd
|
||||
../../vlib/rbus/rbdlib.vhd
|
||||
../../vlib/rlink/rlinklib.vbom
|
||||
../../bplib/s3board/s3boardlib.vhd
|
||||
# components
|
||||
../../vlib/rlink/rlink_base_serport.vbom
|
||||
../../vlib/rbus/rbd_tester.vbom
|
||||
../../vlib/rbus/rbd_bram.vbom
|
||||
../../vlib/rbus/rbd_rbmon.vbom
|
||||
../../vlib/rbus/rbd_eyemon.vbom
|
||||
../../vlib/rbus/rbd_timer.vbom
|
||||
../../bplib/s3board/s3_humanio_rbus.vbom
|
||||
../../vlib/rbus/rb_sres_or_4.vbom
|
||||
# design
|
||||
tst_rlink.vhd
|
||||
293
rtl/sys_gen/tst_rlink/tst_rlink.vhd
Normal file
293
rtl/sys_gen/tst_rlink/tst_rlink.vhd
Normal file
@@ -0,0 +1,293 @@
|
||||
-- $Id: tst_rlink.vhd 375 2011-04-02 07:56:47Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: tst_rlink - syn
|
||||
-- Description: tester for rlink
|
||||
--
|
||||
-- Dependencies: rlink/rlink_base_serport
|
||||
-- rbus/rbd_tester
|
||||
-- rbus/rbd_bram
|
||||
-- rbus/rbd_rbmon
|
||||
-- rbus/rbd_eyemon
|
||||
-- rbus/rbd_timer
|
||||
-- s3board/s3_humanio_rbus
|
||||
-- rbus/rb_sres_or_4
|
||||
--
|
||||
-- Test bench: nexys2/tb/tb_tst_rlink_n2
|
||||
--
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2011-04-02 375 1.0.1 add rbd_eyemon and two timer
|
||||
-- 2010-12-29 351 1.0 Initial version (inspired by sys_tst_rri)
|
||||
------------------------------------------------------------------------------
|
||||
-- Usage of Nexys 2 Switches, Buttons, LEDs:
|
||||
--
|
||||
-- SWI(0): 0 -> main board RS232 port - implemented in sys_tst_rlink_*
|
||||
-- 1 -> Pmod B/top RS232 port /
|
||||
-- (1:7): no function (only connected to s3_humanio_rbus)
|
||||
--
|
||||
-- LED(0): timer 0 busy
|
||||
-- LED(1): timer 1 busy
|
||||
-- LED(2:7): no function (only connected to s3_humanio_rbus)
|
||||
--
|
||||
-- DSP: RL_SER_MONI.clkdiv (from auto bauder)
|
||||
-- DP(0): RXSD (inverted to signal activity)
|
||||
-- DP(1): RTS_N (shows rx back preasure)
|
||||
-- DP(2): TXSD (inverted to signal activity)
|
||||
-- DP(3): CTS_N (shows tx back preasure)
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.rblib.all;
|
||||
use work.rbdlib.all;
|
||||
use work.rlinklib.all;
|
||||
use work.s3boardlib.all;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
entity tst_rlink is -- tester for rlink
|
||||
generic (
|
||||
DEBOUNCE : boolean := true;
|
||||
CDINIT : natural := 15);
|
||||
port (
|
||||
CLK : in slbit; -- clock
|
||||
RESET : in slbit; -- reset
|
||||
CE_USEC : in slbit; -- usec pulse
|
||||
CE_MSEC : in slbit; -- msec pulse
|
||||
RXD : in slbit; -- receive data (board view)
|
||||
TXD : out slbit; -- transmit data (board view)
|
||||
CTS_N : in slbit; -- rs232 cts_n
|
||||
RTS_N : out slbit; -- rs232 rts_n
|
||||
SWI : out slv8; -- switches (for top cntl)
|
||||
BTN : out slv4; -- buttons (for top cntl)
|
||||
I_SWI : in slv8; -- s3 switches
|
||||
I_BTN : in slv4; -- s3 buttons
|
||||
O_LED : out slv8; -- s3 leds
|
||||
O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low)
|
||||
O_SEG_N : out slv8 -- 7 segment disp: segments (act.low)
|
||||
);
|
||||
end tst_rlink;
|
||||
|
||||
architecture syn of tst_rlink is
|
||||
|
||||
signal RTS_N_L : slbit := '0';
|
||||
signal DSP_DAT : slv16 := (others=>'0');
|
||||
signal DSP_DP : slv4 := (others=>'0');
|
||||
|
||||
signal SWI_L : slv8 := (others=>'0');
|
||||
signal BTN_L : slv4 := (others=>'0');
|
||||
signal LED : slv8 := (others=>'0');
|
||||
|
||||
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
|
||||
signal RB_SRES : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_TEST : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_BRAM : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_MON : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_EMON : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_TIM0 : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_TIM1 : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_HIO : rb_sres_type := rb_sres_init;
|
||||
signal RB_SRES_SUM1 : rb_sres_type := rb_sres_init;
|
||||
|
||||
signal RB_LAM : slv16 := (others=>'0');
|
||||
signal RB_STAT : slv3 := (others=>'0');
|
||||
|
||||
signal RB_LAM_TEST : slv16 := (others=>'0');
|
||||
|
||||
signal TIM0_DONE : slbit := '0';
|
||||
signal TIM0_BUSY : slbit := '0';
|
||||
signal TIM1_DONE : slbit := '0';
|
||||
signal TIM1_BUSY : slbit := '0';
|
||||
|
||||
signal RL_MONI : rl_moni_type := rl_moni_init;
|
||||
signal RL_SER_MONI : rl_ser_moni_type := rl_ser_moni_init;
|
||||
|
||||
constant rbaddr_mon : slv8 := "11111100"; -- 111111xx
|
||||
constant rbaddr_emon : slv8 := "11111000"; -- 111110xx
|
||||
constant rbaddr_bram : slv8 := "11110100"; -- 111101xx
|
||||
constant rbaddr_test : slv8 := "11110000"; -- 111100xx
|
||||
constant rbaddr_tim1 : slv8 := "11100001"; -- 11100001
|
||||
constant rbaddr_tim0 : slv8 := "11100000"; -- 11100000
|
||||
constant rbaddr_hio : slv8 := "11000000"; -- 110000xx
|
||||
|
||||
begin
|
||||
|
||||
RLINK : rlink_base_serport
|
||||
generic map (
|
||||
ATOWIDTH => 6, -- 64 cycles access timeout
|
||||
ITOWIDTH => 6, -- 64 periods max idle timeout
|
||||
CPREF => c_rlink_cpref,
|
||||
IFAWIDTH => 5,
|
||||
OFAWIDTH => 0,
|
||||
ENAPIN_RLMON => sbcntl_sbf_rlmon,
|
||||
ENAPIN_RBMON => sbcntl_sbf_rbmon,
|
||||
RB_ADDR => conv_std_logic_vector(2#11111110#,8),
|
||||
CDWIDTH => 13,
|
||||
CDINIT => CDINIT)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
CE_USEC => CE_USEC,
|
||||
CE_MSEC => CE_MSEC,
|
||||
CE_INT => CE_MSEC,
|
||||
RESET => RESET,
|
||||
RXSD => RXD,
|
||||
TXSD => TXD,
|
||||
CTS_N => CTS_N,
|
||||
RTS_N => RTS_N_L,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES,
|
||||
RB_LAM => RB_LAM,
|
||||
RB_STAT => RB_STAT,
|
||||
RL_MONI => RL_MONI,
|
||||
RL_SER_MONI => RL_SER_MONI
|
||||
);
|
||||
|
||||
RB_LAM(15 downto 2) <= RB_LAM_TEST(15 downto 2);
|
||||
RB_LAM(1) <= TIM1_DONE;
|
||||
RB_LAM(0) <= TIM0_DONE;
|
||||
|
||||
TEST : rbd_tester
|
||||
generic map (
|
||||
RB_ADDR => rbaddr_test)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_TEST,
|
||||
RB_LAM => RB_LAM_TEST,
|
||||
RB_STAT => RB_STAT
|
||||
);
|
||||
|
||||
BRAM : rbd_bram
|
||||
generic map (
|
||||
RB_ADDR => rbaddr_bram)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_BRAM
|
||||
);
|
||||
|
||||
MON : rbd_rbmon
|
||||
generic map (
|
||||
RB_ADDR => rbaddr_mon,
|
||||
AWIDTH => 9)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_MON,
|
||||
RB_SRES_SUM => RB_SRES
|
||||
);
|
||||
|
||||
EMON : rbd_eyemon
|
||||
generic map (
|
||||
RB_ADDR => rbaddr_emon,
|
||||
RDIV => conv_std_logic_vector(0,8))
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_EMON,
|
||||
RXSD => RXD,
|
||||
RXACT => RL_SER_MONI.rxact
|
||||
);
|
||||
|
||||
TIM0 : rbd_timer
|
||||
generic map (
|
||||
RB_ADDR => rbaddr_tim0)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
CE_USEC => CE_USEC,
|
||||
RESET => RESET,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_TIM0,
|
||||
DONE => TIM0_DONE,
|
||||
BUSY => TIM0_BUSY
|
||||
);
|
||||
|
||||
TIM1 : rbd_timer
|
||||
generic map (
|
||||
RB_ADDR => rbaddr_tim1)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
CE_USEC => CE_USEC,
|
||||
RESET => RESET,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_TIM1,
|
||||
DONE => TIM1_DONE,
|
||||
BUSY => TIM1_BUSY
|
||||
);
|
||||
|
||||
HIO : s3_humanio_rbus
|
||||
generic map (
|
||||
DEBOUNCE => DEBOUNCE,
|
||||
RB_ADDR => rbaddr_hio)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
CE_MSEC => CE_MSEC,
|
||||
RB_MREQ => RB_MREQ,
|
||||
RB_SRES => RB_SRES_HIO,
|
||||
SWI => SWI_L,
|
||||
BTN => BTN_L,
|
||||
LED => LED,
|
||||
DSP_DAT => DSP_DAT,
|
||||
DSP_DP => DSP_DP,
|
||||
I_SWI => I_SWI,
|
||||
I_BTN => I_BTN,
|
||||
O_LED => O_LED,
|
||||
O_ANO_N => O_ANO_N,
|
||||
O_SEG_N => O_SEG_N
|
||||
);
|
||||
|
||||
RB_SRES_OR1 : rb_sres_or_4
|
||||
port map (
|
||||
RB_SRES_1 => RB_SRES_TEST,
|
||||
RB_SRES_2 => RB_SRES_BRAM,
|
||||
RB_SRES_3 => RB_SRES_MON,
|
||||
RB_SRES_4 => RB_SRES_HIO,
|
||||
RB_SRES_OR => RB_SRES_SUM1
|
||||
);
|
||||
|
||||
RB_SRES_OR : rb_sres_or_4
|
||||
port map (
|
||||
RB_SRES_1 => RB_SRES_SUM1,
|
||||
RB_SRES_2 => RB_SRES_EMON,
|
||||
RB_SRES_3 => RB_SRES_TIM0,
|
||||
RB_SRES_4 => RB_SRES_TIM1,
|
||||
RB_SRES_OR => RB_SRES
|
||||
);
|
||||
|
||||
DSP_DAT <= RL_SER_MONI.clkdiv;
|
||||
DSP_DP(0) <= RL_SER_MONI.rxact;
|
||||
DSP_DP(1) <= RTS_N_L;
|
||||
DSP_DP(2) <= RL_SER_MONI.txact;
|
||||
DSP_DP(3) <= CTS_N;
|
||||
|
||||
LED(0) <= TIM0_BUSY;
|
||||
LED(1) <= TIM1_BUSY;
|
||||
LED(7) <= RL_SER_MONI.abact;
|
||||
|
||||
RTS_N <= RTS_N_L;
|
||||
SWI <= SWI_L;
|
||||
BTN <= BTN_L;
|
||||
|
||||
end syn;
|
||||
@@ -1,6 +1,6 @@
|
||||
tb_rriext_fifo_rx
|
||||
tb_rriext_fifo_tx
|
||||
tb_rriext_conf
|
||||
rlink_cext_fifo_rx
|
||||
rlink_cext_fifo_tx
|
||||
rlink_cext_conf
|
||||
to_ptp
|
||||
to_lda
|
||||
tmu_ofile
|
||||
|
||||
4
rtl/vlib/memlib/ram_1swsr_wfirst_gen.vbom
Normal file
4
rtl/vlib/memlib/ram_1swsr_wfirst_gen.vbom
Normal file
@@ -0,0 +1,4 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
# design
|
||||
ram_1swsr_wfirst_gen.vhd
|
||||
89
rtl/vlib/memlib/ram_1swsr_wfirst_gen.vhd
Normal file
89
rtl/vlib/memlib/ram_1swsr_wfirst_gen.vhd
Normal file
@@ -0,0 +1,89 @@
|
||||
-- $Id: ram_1swsr_wfirst_gen.vhd 314 2010-07-09 17:38:41Z mueller $
|
||||
--
|
||||
-- Copyright 2006-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: ram_1swsr_rfirst_gen - syn
|
||||
-- Description: Single-Port RAM with with one synchronous read/write port
|
||||
-- and 'read-through' semantics (as block RAM).
|
||||
-- The 'ram_style' attribute is set to 'block', this will
|
||||
-- force in XST a synthesis as block RAM.
|
||||
--
|
||||
-- Notes: For xst 8.1.03i: can be written with a signal or a shared
|
||||
-- variable declared at the architecture level. Use variable
|
||||
-- because this seemed better for simulation. Using a simple
|
||||
-- variable declared at process level leads to an array of
|
||||
-- registers and a big mux.
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Test bench: -
|
||||
-- Target Devices: generic Spartan, Virtex
|
||||
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-06-03 299 1.0.3 use sv_ prefix for shared variables
|
||||
-- 2008-03-08 123 1.0.2 use std_logic_arith, not _unsigned; use unsigned();
|
||||
-- 2008-03-02 122 1.0.1 change generic default for BRAM models
|
||||
-- 2007-06-03 45 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
|
||||
entity ram_1swsr_wfirst_gen is -- RAM, 1 sync r/w ports, write first
|
||||
generic (
|
||||
AWIDTH : positive := 11; -- address port width
|
||||
DWIDTH : positive := 9); -- data port width
|
||||
port(
|
||||
CLK : in slbit; -- clock
|
||||
EN : in slbit; -- enable
|
||||
WE : in slbit; -- write enable
|
||||
ADDR : in slv(AWIDTH-1 downto 0); -- address port
|
||||
DI : in slv(DWIDTH-1 downto 0); -- data in port
|
||||
DO : out slv(DWIDTH-1 downto 0) -- data out port
|
||||
);
|
||||
end ram_1swsr_wfirst_gen;
|
||||
|
||||
|
||||
architecture syn of ram_1swsr_wfirst_gen is
|
||||
|
||||
constant memsize : positive := 2**AWIDTH;
|
||||
constant datzero : slv(DWIDTH-1 downto 0) := (others=>'0');
|
||||
type ram_type is array (0 to memsize-1) of slv(DWIDTH-1 downto 0);
|
||||
shared variable sv_ram : ram_type := (others=>datzero);
|
||||
|
||||
attribute ram_style : string;
|
||||
attribute ram_style of sv_ram : variable is "block";
|
||||
|
||||
signal R_DO : slv(DWIDTH-1 downto 0) := datzero;
|
||||
|
||||
begin
|
||||
|
||||
proc_clk: process (CLK)
|
||||
begin
|
||||
if CLK'event and CLK='1' then
|
||||
if EN = '1' then
|
||||
if WE = '1' then
|
||||
sv_ram(conv_integer(unsigned(ADDR))) := DI;
|
||||
end if;
|
||||
R_DO <= sv_ram(conv_integer(unsigned(ADDR)));
|
||||
end if;
|
||||
end if;
|
||||
end process proc_clk;
|
||||
|
||||
DO <= R_DO;
|
||||
|
||||
end syn;
|
||||
|
||||
7
rtl/vlib/memlib/ram_1swsr_wfirst_gen_unisim.vbom
Normal file
7
rtl/vlib/memlib/ram_1swsr_wfirst_gen_unisim.vbom
Normal file
@@ -0,0 +1,7 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
memlib.vhd
|
||||
# components
|
||||
ram_1swsr_xfirst_gen_unisim.vbom
|
||||
# design
|
||||
ram_1swsr_wfirst_gen_unisim.vhd
|
||||
70
rtl/vlib/memlib/ram_1swsr_wfirst_gen_unisim.vhd
Normal file
70
rtl/vlib/memlib/ram_1swsr_wfirst_gen_unisim.vhd
Normal file
@@ -0,0 +1,70 @@
|
||||
-- $Id: ram_1swsr_wfirst_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $
|
||||
--
|
||||
-- Copyright 2008- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: ram_1swsr_wfirst_gen - syn
|
||||
-- Description: Single-Port RAM with with one synchronous read/write port
|
||||
-- and 'read-through' semantics (as block RAM).
|
||||
-- Direct instantiation of Xilinx UNISIM primitives
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Test bench: -
|
||||
-- Target Devices: Spartan-3, Virtex-2,-4
|
||||
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2008-03-08 123 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.ALL;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.memlib.all;
|
||||
|
||||
entity ram_1swsr_wfirst_gen is -- RAM, 1 sync r/w port, write first
|
||||
generic (
|
||||
AWIDTH : positive := 11; -- address port width
|
||||
DWIDTH : positive := 9); -- data port width
|
||||
port(
|
||||
CLK : in slbit; -- clock
|
||||
EN : in slbit; -- enable
|
||||
WE : in slbit; -- write enable
|
||||
ADDR : in slv(AWIDTH-1 downto 0); -- address
|
||||
DI : in slv(DWIDTH-1 downto 0); -- data in
|
||||
DO : out slv(DWIDTH-1 downto 0) -- data out
|
||||
);
|
||||
end ram_1swsr_wfirst_gen;
|
||||
|
||||
|
||||
architecture syn of ram_1swsr_wfirst_gen is
|
||||
begin
|
||||
|
||||
UMEM: ram_1swsr_xfirst_gen_unisim
|
||||
generic map (
|
||||
AWIDTH => AWIDTH,
|
||||
DWIDTH => DWIDTH,
|
||||
WRITE_MODE => "WRITE_FIRST")
|
||||
port map (
|
||||
CLK => CLK,
|
||||
EN => EN,
|
||||
WE => WE,
|
||||
ADDR => ADDR,
|
||||
DI => DI,
|
||||
DO => DO
|
||||
);
|
||||
|
||||
end syn;
|
||||
5
rtl/vlib/memlib/ram_1swsr_xfirst_gen_unisim.vbom
Normal file
5
rtl/vlib/memlib/ram_1swsr_xfirst_gen_unisim.vbom
Normal file
@@ -0,0 +1,5 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
@lib:unisim
|
||||
# design
|
||||
ram_1swsr_xfirst_gen_unisim.vhd
|
||||
307
rtl/vlib/memlib/ram_1swsr_xfirst_gen_unisim.vhd
Normal file
307
rtl/vlib/memlib/ram_1swsr_xfirst_gen_unisim.vhd
Normal file
@@ -0,0 +1,307 @@
|
||||
-- $Id: ram_1swsr_xfirst_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $
|
||||
--
|
||||
-- Copyright 2008- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: ram_1swsr_xfirst_gen_unisim - syn
|
||||
-- Description: Single-Port RAM with with one synchronous read/write port
|
||||
-- Direct instantiation of Xilinx UNISIM primitives
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Test bench: -
|
||||
-- Target Devices: Spartan-3, Virtex-2,-4
|
||||
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2008-04-13 135 1.0.1 fix range error for AW_14_S1
|
||||
-- 2008-03-08 123 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.ALL;
|
||||
|
||||
use work.slvtypes.all;
|
||||
|
||||
entity ram_1swsr_xfirst_gen_unisim is -- RAM, 1 sync r/w ports
|
||||
generic (
|
||||
AWIDTH : positive := 11; -- address port width
|
||||
DWIDTH : positive := 9; -- data port width
|
||||
WRITE_MODE : string := "READ_FIRST"); -- write mode: (READ|WRITE)_FIRST
|
||||
port(
|
||||
CLK : in slbit; -- clock
|
||||
EN : in slbit; -- enable
|
||||
WE : in slbit; -- write enable
|
||||
ADDR : in slv(AWIDTH-1 downto 0); -- address
|
||||
DI : in slv(DWIDTH-1 downto 0); -- data in
|
||||
DO : out slv(DWIDTH-1 downto 0) -- data out
|
||||
);
|
||||
end ram_1swsr_xfirst_gen_unisim;
|
||||
|
||||
|
||||
architecture syn of ram_1swsr_xfirst_gen_unisim is
|
||||
|
||||
constant ok_mod32 : boolean := (DWIDTH mod 32)=0 and
|
||||
((DWIDTH+35)/36)=((DWIDTH+31)/32);
|
||||
constant ok_mod16 : boolean := (DWIDTH mod 16)=0 and
|
||||
((DWIDTH+17)/18)=((DWIDTH+16)/16);
|
||||
constant ok_mod08 : boolean := (DWIDTH mod 32)=0 and
|
||||
((DWIDTH+8)/9)=((DWIDTH+7)/8);
|
||||
|
||||
begin
|
||||
|
||||
assert AWIDTH>=9 and AWIDTH<=14
|
||||
report "assert(AWIDTH>=9 and AWIDTH<=14): unsupported BRAM from factor"
|
||||
severity failure;
|
||||
|
||||
AW_09_S36: if AWIDTH=9 and not ok_mod32 generate
|
||||
constant dw_mem : positive := ((DWIDTH+35)/36)*36;
|
||||
signal L_DO : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
signal L_DI : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
begin
|
||||
|
||||
L_DI(DI'range) <= DI;
|
||||
|
||||
GL: for i in dw_mem/36-1 downto 0 generate
|
||||
MEM : RAMB16_S36
|
||||
generic map (
|
||||
INIT => O"000000000000",
|
||||
SRVAL => O"000000000000",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => L_DO(36*i+31 downto 36*i),
|
||||
DOP => L_DO(36*i+35 downto 36*i+32),
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => L_DI(36*i+31 downto 36*i),
|
||||
DIP => L_DI(36*i+35 downto 36*i+32),
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
|
||||
DO <= L_DO(DO'range);
|
||||
|
||||
end generate AW_09_S36;
|
||||
|
||||
AW_09_S32: if AWIDTH=9 and ok_mod32 generate
|
||||
GL: for i in DWIDTH/32-1 downto 0 generate
|
||||
MEM : RAMB16_S36
|
||||
generic map (
|
||||
INIT => X"00000000",
|
||||
SRVAL => X"00000000",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => DO(32*i+31 downto 32*i),
|
||||
DOP => open,
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => DI(32*i+31 downto 32*i),
|
||||
DIP => "0000",
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
end generate AW_09_S32;
|
||||
|
||||
AW_10_S18: if AWIDTH=10 and not ok_mod16 generate
|
||||
constant dw_mem : positive := ((DWIDTH+17)/18)*18;
|
||||
signal L_DO : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
signal L_DI : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
begin
|
||||
|
||||
L_DI(DI'range) <= DI;
|
||||
|
||||
GL: for i in dw_mem/18-1 downto 0 generate
|
||||
MEM : RAMB16_S18
|
||||
generic map (
|
||||
INIT => O"000000",
|
||||
SRVAL => O"000000",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => L_DO(18*i+15 downto 18*i),
|
||||
DOP => L_DO(18*i+17 downto 18*i+16),
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => L_DI(18*i+15 downto 18*i),
|
||||
DIP => L_DI(18*i+17 downto 18*i+16),
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
|
||||
DO <= L_DO(DO'range);
|
||||
|
||||
end generate AW_10_S18;
|
||||
|
||||
AW_10_S16: if AWIDTH=10 and ok_mod16 generate
|
||||
GL: for i in DWIDTH/16-1 downto 0 generate
|
||||
MEM : RAMB16_S18
|
||||
generic map (
|
||||
INIT => X"0000",
|
||||
SRVAL => X"0000",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => DO(16*i+15 downto 16*i),
|
||||
DOP => open,
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => DI(16*i+15 downto 16*i),
|
||||
DIP => "00",
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
end generate AW_10_S16;
|
||||
|
||||
AW_11_S9: if AWIDTH=11 and not ok_mod08 generate
|
||||
constant dw_mem : positive := ((DWIDTH+8)/9)*9;
|
||||
signal L_DO : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
signal L_DI : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
begin
|
||||
|
||||
L_DI(DI'range) <= DI;
|
||||
|
||||
GL: for i in dw_mem/9-1 downto 0 generate
|
||||
MEM : RAMB16_S9
|
||||
generic map (
|
||||
INIT => O"000",
|
||||
SRVAL => O"000",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => L_DO(9*i+7 downto 9*i),
|
||||
DOP => L_DO(9*i+8 downto 9*i+8),
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => L_DI(9*i+7 downto 9*i),
|
||||
DIP => L_DI(9*i+8 downto 9*i+8),
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
|
||||
DO <= L_DO(DO'range);
|
||||
|
||||
end generate AW_11_S9;
|
||||
|
||||
AW_11_S8: if AWIDTH=11 and ok_mod08 generate
|
||||
GL: for i in DWIDTH/8-1 downto 0 generate
|
||||
MEM : RAMB16_S9
|
||||
generic map (
|
||||
INIT => X"00",
|
||||
SRVAL => X"00",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => DO(8*i+7 downto 8*i),
|
||||
DOP => open,
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => DI(8*i+7 downto 8*i),
|
||||
DIP => "0",
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
end generate AW_11_S8;
|
||||
|
||||
AW_12_S4: if AWIDTH = 12 generate
|
||||
constant dw_mem : positive := ((DWIDTH+3)/4)*4;
|
||||
signal L_DO : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
signal L_DI : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
begin
|
||||
|
||||
L_DI(DI'range) <= DI;
|
||||
|
||||
GL: for i in dw_mem/4-1 downto 0 generate
|
||||
MEM : RAMB16_S4
|
||||
generic map (
|
||||
INIT => X"0",
|
||||
SRVAL => X"0",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => L_DO(4*i+3 downto 4*i),
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => L_DI(4*i+3 downto 4*i),
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
|
||||
DO <= L_DO(DO'range);
|
||||
|
||||
end generate AW_12_S4;
|
||||
|
||||
AW_13_S2: if AWIDTH = 13 generate
|
||||
constant dw_mem : positive := ((DWIDTH+1)/2)*2;
|
||||
signal L_DO : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
signal L_DI : slv(dw_mem-1 downto 0) := (others=> '0');
|
||||
begin
|
||||
|
||||
L_DI(DI'range) <= DI;
|
||||
|
||||
GL: for i in dw_mem/2-1 downto 0 generate
|
||||
MEM : RAMB16_S2
|
||||
generic map (
|
||||
INIT => "00",
|
||||
SRVAL => "00",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => L_DO(2*i+1 downto 2*i),
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => L_DI(2*i+1 downto 2*i),
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
|
||||
DO <= L_DO(DO'range);
|
||||
|
||||
end generate AW_13_S2;
|
||||
|
||||
AW_14_S1: if AWIDTH = 14 generate
|
||||
GL: for i in DWIDTH-1 downto 0 generate
|
||||
MEM : RAMB16_S1
|
||||
generic map (
|
||||
INIT => "0",
|
||||
SRVAL => "0",
|
||||
WRITE_MODE => WRITE_MODE)
|
||||
port map (
|
||||
DO => DO(i downto i),
|
||||
ADDR => ADDR,
|
||||
CLK => CLK,
|
||||
DI => DI(i downto i),
|
||||
EN => EN,
|
||||
SSR => '0',
|
||||
WE => WE
|
||||
);
|
||||
end generate GL;
|
||||
end generate AW_14_S1;
|
||||
|
||||
|
||||
end syn;
|
||||
|
||||
-- Note: in XST 8.2 the defaults for INIT_(A|B) and SRVAL_(A|B) are
|
||||
-- nonsense: INIT_A : bit_vector := X"000";
|
||||
-- This is a 12 bit value, while a 9 bit one is needed. Thus the
|
||||
-- explicit definition above.
|
||||
4
rtl/vlib/memlib/ram_2swsr_wfirst_gen.vbom
Normal file
4
rtl/vlib/memlib/ram_2swsr_wfirst_gen.vbom
Normal file
@@ -0,0 +1,4 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
# design
|
||||
ram_2swsr_wfirst_gen.vhd
|
||||
101
rtl/vlib/memlib/ram_2swsr_wfirst_gen.vhd
Normal file
101
rtl/vlib/memlib/ram_2swsr_wfirst_gen.vhd
Normal file
@@ -0,0 +1,101 @@
|
||||
-- $Id: ram_2swsr_wfirst_gen.vhd 314 2010-07-09 17:38:41Z mueller $
|
||||
--
|
||||
-- Copyright 2006-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: ram_2swsr_wfirst_gen - syn
|
||||
-- Description: Dual-Port RAM with with two synchronous read/write ports
|
||||
-- and 'read-through' semantics (as block RAM).
|
||||
-- The code is inspired by Xilinx example rams_16.vhd. The
|
||||
-- 'ram_style' attribute is set to 'block', this will
|
||||
-- force in XST a synthesis as block RAM.
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Test bench: -
|
||||
-- Target Devices: generic Spartan, Virtex
|
||||
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-06-03 299 1.0.3 use sv_ prefix for shared variables
|
||||
-- 2008-03-08 123 1.0.2 use std_logic_arith, not _unsigned; use unsigned();
|
||||
-- 2008-03-02 122 1.0.1 change generic default for BRAM models
|
||||
-- 2007-06-03 45 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
|
||||
entity ram_2swsr_wfirst_gen is -- RAM, 2 sync r/w ports, write first
|
||||
generic (
|
||||
AWIDTH : positive := 11; -- address port width
|
||||
DWIDTH : positive := 9); -- data port width
|
||||
port(
|
||||
CLKA : in slbit; -- clock port A
|
||||
CLKB : in slbit; -- clock port B
|
||||
ENA : in slbit; -- enable port A
|
||||
ENB : in slbit; -- enable port B
|
||||
WEA : in slbit; -- write enable port A
|
||||
WEB : in slbit; -- write enable port B
|
||||
ADDRA : in slv(AWIDTH-1 downto 0); -- address port A
|
||||
ADDRB : in slv(AWIDTH-1 downto 0); -- address port B
|
||||
DIA : in slv(DWIDTH-1 downto 0); -- data in port A
|
||||
DIB : in slv(DWIDTH-1 downto 0); -- data in port B
|
||||
DOA : out slv(DWIDTH-1 downto 0); -- data out port A
|
||||
DOB : out slv(DWIDTH-1 downto 0) -- data out port B
|
||||
);
|
||||
end ram_2swsr_wfirst_gen;
|
||||
|
||||
|
||||
architecture syn of ram_2swsr_wfirst_gen is
|
||||
constant memsize : positive := 2**AWIDTH;
|
||||
constant datzero : slv(DWIDTH-1 downto 0) := (others=>'0');
|
||||
type ram_type is array (0 to memsize-1) of slv(DWIDTH-1 downto 0);
|
||||
shared variable sv_ram : ram_type := (others=>datzero);
|
||||
|
||||
attribute ram_style : string;
|
||||
attribute ram_style of sv_ram : variable is "block";
|
||||
|
||||
signal R_DOA : slv(DWIDTH-1 downto 0) := datzero;
|
||||
signal R_DOB : slv(DWIDTH-1 downto 0) := datzero;
|
||||
begin
|
||||
|
||||
proc_clka: process (CLKA)
|
||||
begin
|
||||
if CLKA'event and CLKA='1' then
|
||||
if ENA = '1' then
|
||||
if WEA = '1' then
|
||||
sv_ram(conv_integer(unsigned(ADDRA))) := DIA;
|
||||
end if;
|
||||
R_DOA <= sv_ram(conv_integer(unsigned(ADDRA)));
|
||||
end if;
|
||||
end if;
|
||||
end process proc_clka;
|
||||
|
||||
proc_clkb: process (CLKB)
|
||||
begin
|
||||
if CLKB'event and CLKB='1' then
|
||||
if ENB = '1' then
|
||||
if WEB = '1' then
|
||||
sv_ram(conv_integer(unsigned(ADDRB))) := DIB;
|
||||
end if;
|
||||
R_DOB <= sv_ram(conv_integer(unsigned(ADDRB)));
|
||||
end if;
|
||||
end if;
|
||||
end process proc_clkb;
|
||||
|
||||
DOA <= R_DOA;
|
||||
DOB <= R_DOB;
|
||||
|
||||
end syn;
|
||||
7
rtl/vlib/memlib/ram_2swsr_wfirst_gen_unisim.vbom
Normal file
7
rtl/vlib/memlib/ram_2swsr_wfirst_gen_unisim.vbom
Normal file
@@ -0,0 +1,7 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
memlib.vhd
|
||||
# components
|
||||
ram_2swsr_xfirst_gen_unisim.vbom
|
||||
# design
|
||||
ram_2swsr_wfirst_gen_unisim.vhd
|
||||
83
rtl/vlib/memlib/ram_2swsr_wfirst_gen_unisim.vhd
Normal file
83
rtl/vlib/memlib/ram_2swsr_wfirst_gen_unisim.vhd
Normal file
@@ -0,0 +1,83 @@
|
||||
-- $Id: ram_2swsr_wfirst_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $
|
||||
--
|
||||
-- Copyright 2008- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: ram_2swsr_wfirst_gen - syn
|
||||
-- Description: Dual-Port RAM with with two synchronous read/write ports
|
||||
-- and 'read-through' semantics (as block RAM).
|
||||
-- Direct instantiation of Xilinx UNISIM primitives
|
||||
--
|
||||
-- Dependencies: -
|
||||
-- Test bench: -
|
||||
-- Target Devices: Spartan-3, Virtex-2,-4
|
||||
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2008-03-08 123 1.1 use now ram_2swsr_xfirst_gen_unisim
|
||||
-- 2008-03-02 122 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.ALL;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.memlib.all;
|
||||
|
||||
entity ram_2swsr_wfirst_gen is -- RAM, 2 sync r/w ports, write first
|
||||
generic (
|
||||
AWIDTH : positive := 11; -- address port width
|
||||
DWIDTH : positive := 9); -- data port width
|
||||
port(
|
||||
CLKA : in slbit; -- clock port A
|
||||
CLKB : in slbit; -- clock port B
|
||||
ENA : in slbit; -- enable port A
|
||||
ENB : in slbit; -- enable port B
|
||||
WEA : in slbit; -- write enable port A
|
||||
WEB : in slbit; -- write enable port B
|
||||
ADDRA : in slv(AWIDTH-1 downto 0); -- address port A
|
||||
ADDRB : in slv(AWIDTH-1 downto 0); -- address port B
|
||||
DIA : in slv(DWIDTH-1 downto 0); -- data in port A
|
||||
DIB : in slv(DWIDTH-1 downto 0); -- data in port B
|
||||
DOA : out slv(DWIDTH-1 downto 0); -- data out port A
|
||||
DOB : out slv(DWIDTH-1 downto 0) -- data out port B
|
||||
);
|
||||
end ram_2swsr_wfirst_gen;
|
||||
|
||||
|
||||
architecture syn of ram_2swsr_wfirst_gen is
|
||||
begin
|
||||
|
||||
UMEM: ram_2swsr_xfirst_gen_unisim
|
||||
generic map (
|
||||
AWIDTH => AWIDTH,
|
||||
DWIDTH => DWIDTH,
|
||||
WRITE_MODE => "WRITE_FIRST")
|
||||
port map (
|
||||
CLKA => CLKA,
|
||||
CLKB => CLKB,
|
||||
ENA => ENA,
|
||||
ENB => ENB,
|
||||
WEA => WEA,
|
||||
WEB => WEB,
|
||||
ADDRA => ADDRA,
|
||||
ADDRB => ADDRB,
|
||||
DIA => DIA,
|
||||
DIB => DIB,
|
||||
DOA => DOA,
|
||||
DOB => DOB
|
||||
);
|
||||
|
||||
end syn;
|
||||
7
rtl/vlib/rbus/rb_sres_or_4.vbom
Normal file
7
rtl/vlib/rbus/rb_sres_or_4.vbom
Normal file
@@ -0,0 +1,7 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
rblib.vhd
|
||||
# components
|
||||
[ghdl,isim]rb_sres_or_mon.vbom
|
||||
# design
|
||||
rb_sres_or_4.vhd
|
||||
85
rtl/vlib/rbus/rb_sres_or_4.vhd
Normal file
85
rtl/vlib/rbus/rb_sres_or_4.vhd
Normal file
@@ -0,0 +1,85 @@
|
||||
-- $Id: rb_sres_or_4.vhd 343 2010-12-05 21:24:38Z mueller $
|
||||
--
|
||||
-- Copyright 2008-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: rb_sres_or_4 - syn
|
||||
-- Description: rbus result or, 4 input
|
||||
--
|
||||
-- Dependencies: rb_sres_or_mon [sim only]
|
||||
-- Test bench: -
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4, 12.1; ghdl 0.18-0.29
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-04 343 1.1.1 use now rb_sres_or_mon
|
||||
-- 2010-06-26 309 1.1 add rritb_sres_or_mon
|
||||
-- 2008-08-22 161 1.0.1 renamed rri_rbres_ -> rb_sres_
|
||||
-- 2008-01-20 113 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.rblib.all;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
entity rb_sres_or_4 is -- rbus result or, 4 input
|
||||
port (
|
||||
RB_SRES_1 : in rb_sres_type; -- rb_sres input 1
|
||||
RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2
|
||||
RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3
|
||||
RB_SRES_4 : in rb_sres_type := rb_sres_init; -- rb_sres input 4
|
||||
RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output
|
||||
);
|
||||
end rb_sres_or_4;
|
||||
|
||||
architecture syn of rb_sres_or_4 is
|
||||
|
||||
begin
|
||||
|
||||
proc_comb : process (RB_SRES_1, RB_SRES_2, RB_SRES_3, RB_SRES_4)
|
||||
begin
|
||||
|
||||
RB_SRES_OR.ack <= RB_SRES_1.ack or
|
||||
RB_SRES_2.ack or
|
||||
RB_SRES_3.ack or
|
||||
RB_SRES_4.ack;
|
||||
RB_SRES_OR.busy <= RB_SRES_1.busy or
|
||||
RB_SRES_2.busy or
|
||||
RB_SRES_3.busy or
|
||||
RB_SRES_4.busy;
|
||||
RB_SRES_OR.err <= RB_SRES_1.err or
|
||||
RB_SRES_2.err or
|
||||
RB_SRES_3.err or
|
||||
RB_SRES_4.err;
|
||||
RB_SRES_OR.dout <= RB_SRES_1.dout or
|
||||
RB_SRES_2.dout or
|
||||
RB_SRES_3.dout or
|
||||
RB_SRES_4.dout;
|
||||
|
||||
end process proc_comb;
|
||||
|
||||
-- synthesis translate_off
|
||||
ORMON : rb_sres_or_mon
|
||||
port map (
|
||||
RB_SRES_1 => RB_SRES_1,
|
||||
RB_SRES_2 => RB_SRES_2,
|
||||
RB_SRES_3 => RB_SRES_3,
|
||||
RB_SRES_4 => RB_SRES_4
|
||||
);
|
||||
-- synthesis translate_on
|
||||
|
||||
end syn;
|
||||
9
rtl/vlib/rbus/rbd_bram.vbom
Normal file
9
rtl/vlib/rbus/rbd_bram.vbom
Normal file
@@ -0,0 +1,9 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
../memlib/memlib.vhd
|
||||
rblib.vhd
|
||||
# components
|
||||
[ghdl,isim]../memlib/ram_1swsr_wfirst_gen.vbom
|
||||
[xst]../memlib/ram_1swsr_wfirst_gen_unisim.vbom
|
||||
# design
|
||||
rbd_bram.vhd
|
||||
221
rtl/vlib/rbus/rbd_bram.vhd
Normal file
221
rtl/vlib/rbus/rbd_bram.vhd
Normal file
@@ -0,0 +1,221 @@
|
||||
-- $Id: rbd_bram.vhd 372 2011-03-20 22:48:11Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: rbd_bram - syn
|
||||
-- Description: rbus dev: rbus bram test target
|
||||
--
|
||||
-- Dependencies: memlib/ram_1swsr_wfirst_gen
|
||||
--
|
||||
-- Test bench: rlink/tb/tb_rlink_tba_ttcombo
|
||||
--
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
--
|
||||
-- Synthesized (xst):
|
||||
-- Date Rev ise Target flop lutl lutm slic t peri
|
||||
-- 2010-12-26 349 12.1 M53d xc3s1000-4 23 61 - 34 s 6.3
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-31 352 1.0.2 simplify irb_ack logic
|
||||
-- 2010-12-29 351 1.0.1 default addr 1111001x->1111010x
|
||||
-- 2010-12-26 349 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
--
|
||||
-- rbus registers:
|
||||
--
|
||||
-- Address Bits Name r/w/f Function
|
||||
-- bbbbbbb0 cntl r/w/- Control register
|
||||
-- 15:10 nbusy r/w/- busy cycles
|
||||
-- 9:00 addr r/w/- bram address (will auto-increment)
|
||||
-- bbbbbbb1 15:00 data r/w/- Data register (read/write to bram via addr)
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.memlib.all;
|
||||
use work.rblib.all;
|
||||
|
||||
entity rbd_bram is -- rbus dev: rbus bram test target
|
||||
-- complete rrirp_aif interface
|
||||
generic (
|
||||
RB_ADDR : slv8 := conv_std_logic_vector(2#11110100#,8));
|
||||
port (
|
||||
CLK : in slbit; -- clock
|
||||
RESET : in slbit; -- reset
|
||||
RB_MREQ : in rb_mreq_type; -- rbus: request
|
||||
RB_SRES : out rb_sres_type -- rbus: response
|
||||
);
|
||||
end entity rbd_bram;
|
||||
|
||||
|
||||
architecture syn of rbd_bram is
|
||||
|
||||
constant rbaddr_cntl : slv1 := "0"; -- cntl address offset
|
||||
constant rbaddr_data : slv1 := "1"; -- data address offset
|
||||
|
||||
subtype cntl_rbf_nbusy is integer range 15 downto 10;
|
||||
subtype cntl_rbf_addr is integer range 9 downto 0;
|
||||
|
||||
type regs_type is record -- state registers
|
||||
rbsel : slbit; -- rbus select
|
||||
addr : slv10; -- addr register
|
||||
nbusy : slv6; -- nbusy setting
|
||||
cntbusy : slv6; -- busy timer
|
||||
end record regs_type;
|
||||
|
||||
constant regs_init : regs_type := (
|
||||
'0', -- rbsel
|
||||
(others=>'0'), -- addr
|
||||
(others=>'0'), -- nbusy
|
||||
(others=>'0') -- cntbusy
|
||||
);
|
||||
|
||||
signal R_REGS : regs_type := regs_init;
|
||||
signal N_REGS : regs_type := regs_init;
|
||||
|
||||
signal BRAM_EN : slbit := '0';
|
||||
signal BRAM_WE : slbit := '0';
|
||||
signal BRAM_DO : slv16 := (others=>'0');
|
||||
|
||||
begin
|
||||
|
||||
BRAM : ram_1swsr_wfirst_gen
|
||||
generic map (
|
||||
AWIDTH => 10,
|
||||
DWIDTH => 16)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
EN => BRAM_EN,
|
||||
WE => BRAM_WE,
|
||||
ADDR => R_REGS.addr,
|
||||
DI => RB_MREQ.din,
|
||||
DO => BRAM_DO
|
||||
);
|
||||
|
||||
proc_regs: process (CLK)
|
||||
begin
|
||||
if CLK'event and CLK='1' then
|
||||
if RESET = '1' then
|
||||
R_REGS <= regs_init;
|
||||
else
|
||||
R_REGS <= N_REGS;
|
||||
end if;
|
||||
end if;
|
||||
end process proc_regs;
|
||||
|
||||
proc_next : process (R_REGS, RB_MREQ, BRAM_DO)
|
||||
variable r : regs_type := regs_init;
|
||||
variable n : regs_type := regs_init;
|
||||
variable irb_ack : slbit := '0';
|
||||
variable irb_busy : slbit := '0';
|
||||
variable irb_dout : slv16 := (others=>'0');
|
||||
variable irbena : slbit := '0';
|
||||
variable isbusy : slbit := '0';
|
||||
variable ibramen : slbit := '0';
|
||||
variable ibramwe : slbit := '0';
|
||||
begin
|
||||
|
||||
r := R_REGS;
|
||||
n := R_REGS;
|
||||
|
||||
irb_ack := '0';
|
||||
irb_busy := '0';
|
||||
irb_dout := (others=>'0');
|
||||
|
||||
irbena := RB_MREQ.re or RB_MREQ.we;
|
||||
|
||||
isbusy := '0';
|
||||
if unsigned(r.cntbusy) /= 0 then
|
||||
isbusy := '1';
|
||||
end if;
|
||||
|
||||
ibramen := '0';
|
||||
ibramwe := '0';
|
||||
|
||||
-- rbus address decoder
|
||||
n.rbsel := '0';
|
||||
if RB_MREQ.aval='1' and RB_MREQ.addr(7 downto 1)=RB_ADDR(7 downto 1) then
|
||||
|
||||
n.rbsel := '1';
|
||||
ibramen := '1';
|
||||
|
||||
if irbena = '0' then -- addr valid and selected, but no req
|
||||
n.cntbusy := r.nbusy; -- preset busy timer
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
-- rbus transactions
|
||||
if r.rbsel = '1' then
|
||||
|
||||
if irbena = '1' then -- if request active
|
||||
if unsigned(r.cntbusy) /= 0 then -- if busy timer > 0
|
||||
n.cntbusy := unsigned(r.cntbusy) - 1; -- decrement busy timer
|
||||
end if;
|
||||
end if;
|
||||
|
||||
irb_ack := irbena; -- ack all accesses
|
||||
|
||||
case RB_MREQ.addr(0 downto 0) is
|
||||
|
||||
when rbaddr_cntl =>
|
||||
if RB_MREQ.we = '1' then
|
||||
n.nbusy := RB_MREQ.din(cntl_rbf_nbusy);
|
||||
n.addr := RB_MREQ.din(cntl_rbf_addr);
|
||||
end if;
|
||||
|
||||
when rbaddr_data =>
|
||||
irb_busy := irbena and isbusy;
|
||||
if isbusy = '0' then
|
||||
if RB_MREQ.we = '1' then
|
||||
ibramwe := '1';
|
||||
end if;
|
||||
if irbena = '1' then
|
||||
n.addr := unsigned(r.addr) + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- rbus output driver
|
||||
if r.rbsel = '1' then
|
||||
case RB_MREQ.addr(0 downto 0) is
|
||||
when rbaddr_cntl =>
|
||||
irb_dout(cntl_rbf_nbusy) := r.nbusy;
|
||||
irb_dout(cntl_rbf_addr) := r.addr;
|
||||
when rbaddr_data =>
|
||||
irb_dout := BRAM_DO;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
N_REGS <= n;
|
||||
|
||||
BRAM_EN <= ibramen;
|
||||
BRAM_WE <= ibramwe;
|
||||
|
||||
RB_SRES.dout <= irb_dout;
|
||||
RB_SRES.ack <= irb_ack;
|
||||
RB_SRES.err <= '0';
|
||||
RB_SRES.busy <= irb_busy;
|
||||
|
||||
end process proc_next;
|
||||
|
||||
end syn;
|
||||
9
rtl/vlib/rbus/rbd_eyemon.vbom
Normal file
9
rtl/vlib/rbus/rbd_eyemon.vbom
Normal file
@@ -0,0 +1,9 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
../memlib/memlib.vhd
|
||||
rblib.vhd
|
||||
# components
|
||||
[ghdl,isim]../memlib/ram_2swsr_wfirst_gen.vbom
|
||||
[xst]../memlib/ram_2swsr_wfirst_gen_unisim.vbom
|
||||
# design
|
||||
rbd_eyemon.vhd
|
||||
357
rtl/vlib/rbus/rbd_eyemon.vhd
Normal file
357
rtl/vlib/rbus/rbd_eyemon.vhd
Normal file
@@ -0,0 +1,357 @@
|
||||
-- $Id: rbd_eyemon.vhd 375 2011-04-02 07:56:47Z mueller $
|
||||
--
|
||||
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: rbd_eyemon - syn
|
||||
-- Description: rbus dev: eye monitor for serport's
|
||||
--
|
||||
-- Dependencies: memlib/ram_2swsr_wfirst_gen
|
||||
--
|
||||
-- Test bench: -
|
||||
--
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
--
|
||||
-- Synthesized (xst):
|
||||
-- Date Rev ise Target flop lutl lutm slic t peri
|
||||
-- 2011-04-02 374 12.1 M53d xc3s1000-4 46 154 - 109 s 8.7
|
||||
-- 2010-12-27 349 12.1 M53d xc3s1000-4 45 147 - 106 s 8.9
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2011-04-02 375 1.0.2 handle back-to-back chars properly (in sim..)
|
||||
-- 2010-12-31 352 1.0.1 simplify irb_ack logic
|
||||
-- 2010-12-27 349 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
--
|
||||
-- rbus registers:
|
||||
--
|
||||
-- Address Bits Name r/w/f Function
|
||||
-- bbbbbb00 cntl r/w/- Control register
|
||||
-- 03 ena01 r/w/- track 0->1 rxsd transitions
|
||||
-- 02 ena10 r/w/- track 1->0 rxsd transitions
|
||||
-- 01 clr r/-/f w: writing a 1 starts memory clear
|
||||
-- r: 1 indicates clr in progress (512 cyc)
|
||||
-- 00 go r/w/- enables monitor
|
||||
-- bbbbbb01 7:00 rdiv r/w/- Sample rate divider
|
||||
-- bbbbbb10 addr r/w/- Address register
|
||||
-- 9:01 laddr r/w/ line address
|
||||
-- 00 waddr r/w/ word address
|
||||
-- bbbbbb11 15:00 data r/-/- Data register
|
||||
--
|
||||
-- data format:
|
||||
-- word 1 counter msb's
|
||||
-- word 0 counter lsb's
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.memlib.all;
|
||||
use work.rblib.all;
|
||||
|
||||
entity rbd_eyemon is -- rbus dev: eye monitor for serport's
|
||||
generic (
|
||||
RB_ADDR : slv8 := conv_std_logic_vector(2#11111000#,8);
|
||||
RDIV : slv8 := conv_std_logic_vector(0,8));
|
||||
port (
|
||||
CLK : in slbit; -- clock
|
||||
RESET : in slbit; -- reset
|
||||
RB_MREQ : in rb_mreq_type; -- rbus: request
|
||||
RB_SRES : out rb_sres_type; -- rbus: response
|
||||
RXSD : in slbit; -- rx: serial data
|
||||
RXACT : in slbit -- rx: active (start seen)
|
||||
);
|
||||
end entity rbd_eyemon;
|
||||
|
||||
|
||||
architecture syn of rbd_eyemon is
|
||||
|
||||
constant rbaddr_cntl : slv2 := "00"; -- cntl address offset
|
||||
constant rbaddr_rdiv : slv2 := "01"; -- rdiv address offset
|
||||
constant rbaddr_addr : slv2 := "10"; -- addr address offset
|
||||
constant rbaddr_data : slv2 := "11"; -- data address offset
|
||||
|
||||
constant cntl_rbf_ena01 : integer := 3;
|
||||
constant cntl_rbf_ena10 : integer := 2;
|
||||
constant cntl_rbf_clr : integer := 1;
|
||||
constant cntl_rbf_go : integer := 0;
|
||||
subtype addr_rbf_laddr is integer range 9 downto 1;
|
||||
constant addr_rbf_waddr : integer := 0;
|
||||
|
||||
type state_type is (
|
||||
s_idle, -- s_idle: wait for char or clr
|
||||
s_char, -- s_char: processing a char
|
||||
s_clr -- s_clr: clear memory
|
||||
);
|
||||
|
||||
type regs_type is record -- state registers
|
||||
state : state_type; -- state
|
||||
rbsel : slbit; -- rbus select
|
||||
go : slbit; -- go flag
|
||||
clr : slbit; -- clear pending
|
||||
ena10 : slbit; -- enable 1->0
|
||||
ena01 : slbit; -- enable 0->1
|
||||
rdiv : slv8; -- rate divider
|
||||
laddr : slv9; -- line address
|
||||
waddr : slbit; -- word address
|
||||
laddr_1 : slv9; -- line address last cycle
|
||||
rxsd_1 : slbit; -- rxsd last cycle
|
||||
memwe : slbit; -- write bram (clr or inc)
|
||||
memclr : slbit; -- write zero into bram
|
||||
rdivcnt : slv8; -- rate divider counter
|
||||
end record regs_type;
|
||||
|
||||
constant regs_init : regs_type := (
|
||||
s_idle, -- state
|
||||
'0', -- rbsel
|
||||
'0', -- go (default is off)
|
||||
'0','0','0', -- clr,ena01,ena10
|
||||
(others=>'0'), -- rdiv
|
||||
(others=>'0'), -- laddr
|
||||
'0', -- waddr
|
||||
(others=>'0'), -- laddr_1
|
||||
'0','0','0', -- rxsd_1,memwe,memclr
|
||||
(others=>'0') -- rdivcnt
|
||||
);
|
||||
|
||||
signal R_REGS : regs_type := regs_init;
|
||||
signal N_REGS : regs_type := regs_init;
|
||||
|
||||
signal BRAM_ENA : slbit := '0';
|
||||
signal BRAM_DIA : slv32 := (others=>'0');
|
||||
signal BRAM_DIB : slv32 := (others=>'0');
|
||||
signal BRAM_DOA : slv32 := (others=>'0');
|
||||
|
||||
begin
|
||||
|
||||
BRAM : ram_2swsr_wfirst_gen
|
||||
generic map (
|
||||
AWIDTH => 9,
|
||||
DWIDTH => 32)
|
||||
port map (
|
||||
CLKA => CLK,
|
||||
CLKB => CLK,
|
||||
ENA => BRAM_ENA,
|
||||
ENB => R_REGS.memwe,
|
||||
WEA => '0',
|
||||
WEB => R_REGS.memwe,
|
||||
ADDRA => R_REGS.laddr,
|
||||
ADDRB => R_REGS.laddr_1,
|
||||
DIA => BRAM_DIA,
|
||||
DIB => BRAM_DIB,
|
||||
DOA => BRAM_DOA,
|
||||
DOB => open
|
||||
);
|
||||
|
||||
proc_regs: process (CLK)
|
||||
begin
|
||||
if CLK'event and CLK='1' then
|
||||
if RESET = '1' then
|
||||
R_REGS <= regs_init;
|
||||
else
|
||||
R_REGS <= N_REGS;
|
||||
end if;
|
||||
end if;
|
||||
end process proc_regs;
|
||||
|
||||
proc_next : process (R_REGS, RB_MREQ, RXSD, RXACT, BRAM_DOA)
|
||||
variable r : regs_type := regs_init;
|
||||
variable n : regs_type := regs_init;
|
||||
variable irb_ack : slbit := '0';
|
||||
variable irb_busy : slbit := '0';
|
||||
variable irb_err : slbit := '0';
|
||||
variable irb_dout : slv16 := (others=>'0');
|
||||
variable irbena : slbit := '0';
|
||||
variable ibramen : slbit := '0';
|
||||
variable ibramdi : slv32 := (others=>'0');
|
||||
variable laddr_we : slbit := '0';
|
||||
variable laddr_clr : slbit := '0';
|
||||
variable laddr_inc : slbit := '0';
|
||||
begin
|
||||
|
||||
r := R_REGS;
|
||||
n := R_REGS;
|
||||
|
||||
irb_ack := '0';
|
||||
irb_busy := '0';
|
||||
irb_err := '0';
|
||||
irb_dout := (others=>'0');
|
||||
|
||||
irbena := RB_MREQ.re or RB_MREQ.we;
|
||||
|
||||
ibramen := '0';
|
||||
|
||||
laddr_we := '0';
|
||||
laddr_clr := '0';
|
||||
laddr_inc := '0';
|
||||
|
||||
-- rbus address decoder
|
||||
n.rbsel := '0';
|
||||
if RB_MREQ.aval='1' and RB_MREQ.addr(7 downto 2)=RB_ADDR(7 downto 2) then
|
||||
n.rbsel := '1';
|
||||
ibramen := '1';
|
||||
end if;
|
||||
|
||||
-- rbus transactions
|
||||
if r.rbsel = '1' then
|
||||
|
||||
irb_ack := irbena; -- ack all accesses
|
||||
|
||||
case RB_MREQ.addr(1 downto 0) is
|
||||
|
||||
when rbaddr_cntl =>
|
||||
if RB_MREQ.we = '1' then
|
||||
n.ena01 := RB_MREQ.din(cntl_rbf_ena01);
|
||||
n.ena10 := RB_MREQ.din(cntl_rbf_ena10);
|
||||
if RB_MREQ.din(cntl_rbf_clr) = '1' then
|
||||
n.clr := '1';
|
||||
end if;
|
||||
n.go := RB_MREQ.din(cntl_rbf_go);
|
||||
end if;
|
||||
|
||||
when rbaddr_rdiv =>
|
||||
if RB_MREQ.we = '1' then
|
||||
n.rdiv := RB_MREQ.din(n.rdiv'range);
|
||||
end if;
|
||||
|
||||
when rbaddr_addr =>
|
||||
if RB_MREQ.we = '1' then
|
||||
laddr_we := '1';
|
||||
n.waddr := RB_MREQ.din(addr_rbf_waddr);
|
||||
end if;
|
||||
|
||||
when rbaddr_data =>
|
||||
if RB_MREQ.we='1' then
|
||||
irb_err := '1';
|
||||
end if;
|
||||
if RB_MREQ.re = '1' then
|
||||
if r.go='0' and r.clr='0' and r.state=s_idle then
|
||||
n.waddr := not r.waddr;
|
||||
if r.waddr = '1' then
|
||||
laddr_inc := '1';
|
||||
end if;
|
||||
else
|
||||
irb_err := '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- rbus output driver
|
||||
if r.rbsel = '1' then
|
||||
case RB_MREQ.addr(1 downto 0) is
|
||||
when rbaddr_cntl =>
|
||||
irb_dout(cntl_rbf_ena01) := r.ena01;
|
||||
irb_dout(cntl_rbf_ena10) := r.ena10;
|
||||
irb_dout(cntl_rbf_clr) := r.clr;
|
||||
irb_dout(cntl_rbf_go) := r.go;
|
||||
when rbaddr_rdiv =>
|
||||
irb_dout(r.rdiv'range) := r.rdiv;
|
||||
when rbaddr_addr =>
|
||||
irb_dout(addr_rbf_laddr) := r.laddr;
|
||||
irb_dout(addr_rbf_waddr) := r.waddr;
|
||||
when rbaddr_data =>
|
||||
case r.waddr is
|
||||
when '1' => irb_dout := BRAM_DOA(31 downto 16);
|
||||
when '0' => irb_dout := BRAM_DOA(15 downto 0);
|
||||
when others => null;
|
||||
end case;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- eye monitor
|
||||
n.memwe := '0';
|
||||
n.memclr := '0';
|
||||
|
||||
case r.state is
|
||||
when s_idle => -- s_idle: wait for char or clr ------
|
||||
if r.clr = '1' then
|
||||
laddr_clr := '1';
|
||||
n.state := s_clr;
|
||||
elsif r.go = '1' and RXSD='0' then
|
||||
laddr_clr := '1';
|
||||
n.rdivcnt := r.rdiv;
|
||||
n.state := s_char;
|
||||
end if;
|
||||
|
||||
when s_char => -- s_char: processing a char ---------
|
||||
if RXACT = '0' then -- uart went unactive
|
||||
if RXSD = '1' then -- line idle -> to s_idle
|
||||
n.state := s_idle;
|
||||
else -- already next start bit seen
|
||||
laddr_clr := '1'; -- clear and restart
|
||||
n.rdivcnt := r.rdiv; -- happens only in simulation...
|
||||
end if;
|
||||
else
|
||||
if (r.ena01='1' and r.rxsd_1='0' and RXSD='1') or
|
||||
(r.ena10='1' and r.rxsd_1='1' and RXSD='0') then
|
||||
n.memwe := '1';
|
||||
ibramen := '1';
|
||||
end if;
|
||||
end if;
|
||||
if unsigned(r.rdiv)=0 or unsigned(r.rdivcnt)=0 then
|
||||
n.rdivcnt := r.rdiv;
|
||||
if unsigned(r.laddr) /= (2**r.laddr'length)-1 then
|
||||
laddr_inc := '1';
|
||||
end if;
|
||||
else
|
||||
n.rdivcnt := unsigned(r.rdivcnt) - 1;
|
||||
end if;
|
||||
|
||||
when s_clr => -- s_clr: clear memory ---------------
|
||||
laddr_inc := '1';
|
||||
n.memwe := '1';
|
||||
n.memclr := '1';
|
||||
if unsigned(r.laddr) = (2**r.laddr'length)-1 then
|
||||
n.clr := '0';
|
||||
n.state := s_idle;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
if laddr_we = '1' then
|
||||
n.laddr := RB_MREQ.din(addr_rbf_laddr);
|
||||
elsif laddr_clr = '1' then
|
||||
n.laddr := (others=>'0');
|
||||
elsif laddr_inc = '1' then
|
||||
n.laddr := unsigned(r.laddr) + 1;
|
||||
end if;
|
||||
|
||||
n.laddr_1 := r.laddr;
|
||||
n.rxsd_1 := RXSD;
|
||||
|
||||
ibramdi := (others=>'0');
|
||||
if r.memclr = '0' then
|
||||
ibramdi := unsigned(BRAM_DOA) + 1;
|
||||
end if;
|
||||
|
||||
N_REGS <= n;
|
||||
|
||||
BRAM_ENA <= ibramen;
|
||||
BRAM_DIB <= ibramdi;
|
||||
|
||||
RB_SRES.dout <= irb_dout;
|
||||
RB_SRES.ack <= irb_ack;
|
||||
RB_SRES.err <= irb_err;
|
||||
RB_SRES.busy <= irb_busy;
|
||||
|
||||
end process proc_next;
|
||||
|
||||
end syn;
|
||||
9
rtl/vlib/rbus/rbd_rbmon.vbom
Normal file
9
rtl/vlib/rbus/rbd_rbmon.vbom
Normal file
@@ -0,0 +1,9 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
../memlib/memlib.vhd
|
||||
rblib.vhd
|
||||
# components
|
||||
[ghdl,isim]../memlib/ram_1swsr_wfirst_gen.vbom
|
||||
[xst]../memlib/ram_1swsr_wfirst_gen_unisim.vbom
|
||||
# design
|
||||
rbd_rbmon.vhd
|
||||
414
rtl/vlib/rbus/rbd_rbmon.vhd
Normal file
414
rtl/vlib/rbus/rbd_rbmon.vhd
Normal file
@@ -0,0 +1,414 @@
|
||||
-- $Id: rbd_rbmon.vhd 374 2011-03-27 17:02:47Z mueller $
|
||||
--
|
||||
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: rbd_rbmon - syn
|
||||
-- Description: rbus dev: rbus monitor
|
||||
--
|
||||
-- Dependencies: memlib/ram_1swsr_wfirst_gen
|
||||
--
|
||||
-- Test bench: rlink/tb/tb_rlink_tba_ttcombo
|
||||
--
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
--
|
||||
-- Synthesized (xst):
|
||||
-- Date Rev ise Target flop lutl lutm slic t peri
|
||||
-- 2010-12-27 349 12.1 M53d xc3s1000-4 95 228 - 154 s 10.4
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2011-03-27 374 1.0.2 rename ncyc -> nbusy because it counts busy cycles
|
||||
-- 2010-12-31 352 1.0.1 simplify irb_ack logic
|
||||
-- 2010-12-27 349 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
--
|
||||
-- address layout:
|
||||
-- bbbbbb00 : cntl
|
||||
-- 00 : go/halt (writing 1 clears addr)
|
||||
-- bbbbbb01 : alim: read-write register
|
||||
-- 15:08 : hilim: upper address limit (def: ff)
|
||||
-- 7:00 : lolim: lower address limit (def: 00)
|
||||
-- bbbbbb10 : addr: read-write register
|
||||
-- 15 : wrap: line address wrapped (read-only, cleared on write)
|
||||
-- xx:02 : laddr: line address
|
||||
-- 01:00 : waddr: word address
|
||||
-- bbbbbb11 : data: read-write register
|
||||
--
|
||||
-- data format:
|
||||
-- word 3 15 : ack
|
||||
-- 14 : busy
|
||||
-- 13 : err
|
||||
-- 12 : nak
|
||||
-- 11 : tout
|
||||
-- 09 : init
|
||||
-- 08 : we
|
||||
-- 07:00 : addr
|
||||
-- word 2 data
|
||||
-- word 1 15:00 : delay to prev (lsb's)
|
||||
-- word 0 15:12 : delay to prev (msb's)
|
||||
-- 11:00 : number of busy cycles
|
||||
--
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.memlib.all;
|
||||
use work.rblib.all;
|
||||
|
||||
entity rbd_rbmon is -- rbus dev: rbus monitor
|
||||
generic (
|
||||
RB_ADDR : slv8 := conv_std_logic_vector(2#11111100#,8);
|
||||
AWIDTH : positive := 9);
|
||||
port (
|
||||
CLK : in slbit; -- clock
|
||||
RESET : in slbit; -- reset
|
||||
RB_MREQ : in rb_mreq_type; -- rbus: request
|
||||
RB_SRES : out rb_sres_type; -- rbus: response
|
||||
RB_SRES_SUM : in rb_sres_type -- rbus: response (sum for monitor)
|
||||
);
|
||||
end entity rbd_rbmon;
|
||||
|
||||
|
||||
architecture syn of rbd_rbmon is
|
||||
|
||||
constant rbaddr_cntl : slv2 := "00"; -- cntl address offset
|
||||
constant rbaddr_alim : slv2 := "01"; -- alim address offset
|
||||
constant rbaddr_addr : slv2 := "10"; -- addr address offset
|
||||
constant rbaddr_data : slv2 := "11"; -- data address offset
|
||||
|
||||
constant cntl_rbf_go : integer := 0;
|
||||
subtype alim_rbf_hilim is integer range 15 downto 8;
|
||||
subtype alim_rbf_lolim is integer range 7 downto 0;
|
||||
constant addr_rbf_wrap : integer := 15;
|
||||
subtype addr_rbf_laddr is integer range 2+AWIDTH-1 downto 2;
|
||||
subtype addr_rbf_waddr is integer range 1 downto 0;
|
||||
|
||||
constant dat3_rbf_ack : integer := 15;
|
||||
constant dat3_rbf_busy : integer := 14;
|
||||
constant dat3_rbf_err : integer := 13;
|
||||
constant dat3_rbf_nak : integer := 12;
|
||||
constant dat3_rbf_tout : integer := 11;
|
||||
constant dat3_rbf_init : integer := 9;
|
||||
constant dat3_rbf_we : integer := 8;
|
||||
subtype dat3_rbf_addr is integer range 7 downto 0;
|
||||
subtype dat0_rbf_ndlymsb is integer range 15 downto 12;
|
||||
subtype dat0_rbf_nbusy is integer range 11 downto 0;
|
||||
|
||||
type regs_type is record -- state registers
|
||||
rbsel : slbit; -- rbus select
|
||||
go : slbit; -- go flag
|
||||
hilim : slv8; -- upper address limit
|
||||
lolim : slv8; -- lower address limit
|
||||
wrap : slbit; -- laddr wrap flag
|
||||
laddr : slv(AWIDTH-1 downto 0); -- line address
|
||||
waddr : slv2; -- word address
|
||||
rbtake_1 : slbit; -- rb capture active in last cycle
|
||||
rbaddr : slv8; -- rbus trace: addr
|
||||
rbinit : slbit; -- rbus trace: init
|
||||
rbwe : slbit; -- rbus trace: we
|
||||
rback : slbit; -- rbus trace: ack seen
|
||||
rbbusy : slbit; -- rbus trace: busy seen
|
||||
rberr : slbit; -- rbus trace: err seen
|
||||
rbnak : slbit; -- rbus trace: nak detected
|
||||
rbtout : slbit; -- rbus trace: tout detected
|
||||
rbdata : slv16; -- rbus trace: data
|
||||
rbnbusy : slv12; -- rbus number of busy cycles
|
||||
rbndly : slv20; -- rbus delay to prev. access
|
||||
end record regs_type;
|
||||
|
||||
constant laddrzero : slv(AWIDTH-1 downto 0) := (others=>'0');
|
||||
constant laddrlast : slv(AWIDTH-1 downto 0) := (others=>'1');
|
||||
|
||||
constant regs_init : regs_type := (
|
||||
'0', -- rbsel
|
||||
'0', -- go (default is off)
|
||||
(others=>'1'), -- hilim (def: ff)
|
||||
(others=>'0'), -- lolim (def: 00)
|
||||
'0', -- wrap
|
||||
laddrzero, -- laddr
|
||||
"00", -- waddr
|
||||
'0', -- rbtake_1
|
||||
(others=>'0'), -- rbaddr
|
||||
'0','0','0','0','0', -- rbinit,rbwe,rback,rbbusy,rberr
|
||||
'0','0', -- rbnak,rbtout
|
||||
(others=>'0'), -- rbdata
|
||||
(others=>'0'), -- rbnbusy
|
||||
(others=>'0') -- rbndly
|
||||
);
|
||||
|
||||
constant rbnbusylast : slv12 := (others=>'1');
|
||||
constant rbndlylast : slv20 := (others=>'1');
|
||||
|
||||
signal R_REGS : regs_type := regs_init;
|
||||
signal N_REGS : regs_type := regs_init;
|
||||
|
||||
signal BRAM_EN : slbit := '0';
|
||||
signal BRAM_WE : slbit := '0';
|
||||
signal BRAM0_DI : slv32 := (others=>'0');
|
||||
signal BRAM1_DI : slv32 := (others=>'0');
|
||||
signal BRAM0_DO : slv32 := (others=>'0');
|
||||
signal BRAM1_DO : slv32 := (others=>'0');
|
||||
|
||||
begin
|
||||
|
||||
assert AWIDTH<=13
|
||||
report "assert(AWIDTH<=13): max address width supported"
|
||||
severity failure;
|
||||
|
||||
BRAM1 : ram_1swsr_wfirst_gen
|
||||
generic map (
|
||||
AWIDTH => AWIDTH,
|
||||
DWIDTH => 32)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
EN => BRAM_EN,
|
||||
WE => BRAM_WE,
|
||||
ADDR => R_REGS.laddr,
|
||||
DI => BRAM1_DI,
|
||||
DO => BRAM1_DO
|
||||
);
|
||||
|
||||
BRAM0 : ram_1swsr_wfirst_gen
|
||||
generic map (
|
||||
AWIDTH => AWIDTH,
|
||||
DWIDTH => 32)
|
||||
port map (
|
||||
CLK => CLK,
|
||||
EN => BRAM_EN,
|
||||
WE => BRAM_WE,
|
||||
ADDR => R_REGS.laddr,
|
||||
DI => BRAM0_DI,
|
||||
DO => BRAM0_DO
|
||||
);
|
||||
|
||||
proc_regs: process (CLK)
|
||||
begin
|
||||
if CLK'event and CLK='1' then
|
||||
if RESET = '1' then
|
||||
R_REGS <= regs_init;
|
||||
else
|
||||
R_REGS <= N_REGS;
|
||||
end if;
|
||||
end if;
|
||||
end process proc_regs;
|
||||
|
||||
proc_next : process (R_REGS, RB_MREQ, RB_SRES_SUM, BRAM0_DO, BRAM1_DO)
|
||||
variable r : regs_type := regs_init;
|
||||
variable n : regs_type := regs_init;
|
||||
variable irb_ack : slbit := '0';
|
||||
variable irb_busy : slbit := '0';
|
||||
variable irb_err : slbit := '0';
|
||||
variable irb_dout : slv16 := (others=>'0');
|
||||
variable irbena : slbit := '0';
|
||||
variable ibramen : slbit := '0';
|
||||
variable ibramwe : slbit := '0';
|
||||
variable rbtake : slbit := '0';
|
||||
variable laddr_inc : slbit := '0';
|
||||
variable idat0 : slv16 := (others=>'0');
|
||||
variable idat1 : slv16 := (others=>'0');
|
||||
variable idat2 : slv16 := (others=>'0');
|
||||
variable idat3 : slv16 := (others=>'0');
|
||||
begin
|
||||
|
||||
r := R_REGS;
|
||||
n := R_REGS;
|
||||
|
||||
irb_ack := '0';
|
||||
irb_busy := '0';
|
||||
irb_err := '0';
|
||||
irb_dout := (others=>'0');
|
||||
|
||||
irbena := RB_MREQ.re or RB_MREQ.we;
|
||||
|
||||
ibramen := '0';
|
||||
ibramwe := '0';
|
||||
|
||||
laddr_inc := '0';
|
||||
|
||||
-- rbus address decoder
|
||||
n.rbsel := '0';
|
||||
if RB_MREQ.aval='1' and RB_MREQ.addr(7 downto 2)=RB_ADDR(7 downto 2) then
|
||||
n.rbsel := '1';
|
||||
ibramen := '1';
|
||||
end if;
|
||||
|
||||
-- rbus transactions
|
||||
if r.rbsel = '1' then
|
||||
|
||||
irb_ack := irbena; -- ack all accesses
|
||||
|
||||
case RB_MREQ.addr(1 downto 0) is
|
||||
|
||||
when rbaddr_cntl =>
|
||||
if RB_MREQ.we = '1' then
|
||||
n.go := RB_MREQ.din(cntl_rbf_go);
|
||||
if RB_MREQ.din(cntl_rbf_go)='1' then
|
||||
n.wrap := '0';
|
||||
n.laddr := laddrzero;
|
||||
n.waddr := "00";
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when rbaddr_alim =>
|
||||
if RB_MREQ.we = '1' then
|
||||
n.hilim := RB_MREQ.din(alim_rbf_hilim);
|
||||
n.lolim := RB_MREQ.din(alim_rbf_lolim);
|
||||
end if;
|
||||
|
||||
when rbaddr_addr =>
|
||||
if RB_MREQ.we = '1' then
|
||||
n.go := '0';
|
||||
n.wrap := '0';
|
||||
n.laddr := RB_MREQ.din(addr_rbf_laddr);
|
||||
n.waddr := RB_MREQ.din(addr_rbf_waddr);
|
||||
end if;
|
||||
|
||||
when rbaddr_data =>
|
||||
if r.go='1' or RB_MREQ.we='1' then
|
||||
irb_err := '1';
|
||||
end if;
|
||||
if RB_MREQ.re = '1' then
|
||||
n.waddr := unsigned(r.waddr) + 1;
|
||||
if r.waddr = "11" then
|
||||
laddr_inc := '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- rbus output driver
|
||||
if r.rbsel = '1' then
|
||||
case RB_MREQ.addr(1 downto 0) is
|
||||
when rbaddr_cntl =>
|
||||
irb_dout(cntl_rbf_go) := r.go;
|
||||
when rbaddr_alim =>
|
||||
irb_dout(alim_rbf_hilim) := r.hilim;
|
||||
irb_dout(alim_rbf_lolim) := r.lolim;
|
||||
when rbaddr_addr =>
|
||||
irb_dout(addr_rbf_wrap) := r.wrap;
|
||||
irb_dout(addr_rbf_laddr) := r.laddr;
|
||||
irb_dout(addr_rbf_waddr) := r.waddr;
|
||||
when rbaddr_data =>
|
||||
case r.waddr is
|
||||
when "11" => irb_dout := BRAM1_DO(31 downto 16);
|
||||
when "10" => irb_dout := BRAM1_DO(15 downto 0);
|
||||
when "01" => irb_dout := BRAM0_DO(31 downto 16);
|
||||
when "00" => irb_dout := BRAM0_DO(15 downto 0);
|
||||
when others => null;
|
||||
end case;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- rbus monitor
|
||||
-- a rbus transaction are captured if the address is in alim window
|
||||
-- and the access is not refering to rbd_rbmon itself
|
||||
|
||||
rbtake := '0';
|
||||
if RB_MREQ.aval='1' and irbena='1' then -- aval and (re or we)
|
||||
if unsigned(RB_MREQ.addr)>=unsigned(r.lolim) and -- and in addr window
|
||||
unsigned(RB_MREQ.addr)<=unsigned(r.hilim) and
|
||||
r.rbsel='0' then -- and not self
|
||||
rbtake := '1';
|
||||
end if;
|
||||
end if;
|
||||
if RB_MREQ.init = '1' then -- also take init's
|
||||
rbtake := '1';
|
||||
end if;
|
||||
|
||||
if rbtake = '1' then -- if capture active
|
||||
n.rbaddr := RB_MREQ.addr; -- keep track of some state
|
||||
n.rbinit := RB_MREQ.init;
|
||||
n.rbwe := RB_MREQ.we;
|
||||
if RB_MREQ.init='1' or RB_MREQ.we='1' then -- for write/init of din
|
||||
n.rbdata := RB_MREQ.din;
|
||||
else -- for read of dout
|
||||
n.rbdata := RB_SRES_SUM.dout;
|
||||
end if;
|
||||
|
||||
if r.rbtake_1 = '0' then -- if initial cycle of a transaction
|
||||
n.rback := RB_SRES_SUM.ack;
|
||||
n.rbbusy := RB_SRES_SUM.busy;
|
||||
n.rberr := RB_SRES_SUM.err;
|
||||
n.rbnbusy := (others=>'0');
|
||||
else -- if non-initial cycles
|
||||
if RB_SRES_SUM.err = '1' then -- keep track of err flags
|
||||
n.rberr := '1';
|
||||
end if;
|
||||
if r.rbnbusy /= rbnbusylast then -- and count
|
||||
n.rbnbusy := unsigned(r.rbnbusy) + 1;
|
||||
end if;
|
||||
end if;
|
||||
n.rbnak := not RB_SRES_SUM.ack;
|
||||
n.rbtout := RB_SRES_SUM.busy;
|
||||
|
||||
else -- if capture not active
|
||||
if r.go='1' and r.rbtake_1='1' then -- active and transaction just ended
|
||||
ibramen := '1';
|
||||
ibramwe := '1';
|
||||
laddr_inc := '1';
|
||||
end if;
|
||||
if r.rbtake_1 = '1' then -- rbus transaction just ended
|
||||
n.rbndly := (others=>'0'); -- clear delay counter
|
||||
else -- just idle
|
||||
if r.rbndly /= rbndlylast then -- count cycles
|
||||
n.rbndly := unsigned(r.rbndly) + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if laddr_inc = '1' then
|
||||
n.laddr := unsigned(r.laddr) + 1;
|
||||
if r.go='1' and r.laddr=laddrlast then
|
||||
n.wrap := '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
idat3 := (others=>'0');
|
||||
idat3(dat3_rbf_ack) := r.rback;
|
||||
idat3(dat3_rbf_busy) := r.rbbusy;
|
||||
idat3(dat3_rbf_err) := r.rberr;
|
||||
idat3(dat3_rbf_nak) := r.rbnak;
|
||||
idat3(dat3_rbf_tout) := r.rbtout;
|
||||
idat3(dat3_rbf_init) := r.rbinit;
|
||||
idat3(dat3_rbf_we) := r.rbwe;
|
||||
idat3(dat3_rbf_addr) := r.rbaddr;
|
||||
idat2 := r.rbdata;
|
||||
idat1 := r.rbndly(15 downto 0);
|
||||
idat0(dat0_rbf_ndlymsb) := r.rbndly(19 downto 16);
|
||||
idat0(dat0_rbf_nbusy) := r.rbnbusy;
|
||||
|
||||
n.rbtake_1 := rbtake;
|
||||
|
||||
N_REGS <= n;
|
||||
|
||||
BRAM_EN <= ibramen;
|
||||
BRAM_WE <= ibramwe;
|
||||
|
||||
BRAM1_DI <= idat3 & idat2;
|
||||
BRAM0_DI <= idat1 & idat0;
|
||||
|
||||
RB_SRES.dout <= irb_dout;
|
||||
RB_SRES.ack <= irb_ack;
|
||||
RB_SRES.err <= irb_err;
|
||||
RB_SRES.busy <= irb_busy;
|
||||
|
||||
end process proc_next;
|
||||
|
||||
end syn;
|
||||
@@ -1,4 +1,4 @@
|
||||
-- $Id: rbd_tester.vhd 352 2011-01-02 13:01:37Z mueller $
|
||||
-- $Id: rbd_tester.vhd 369 2011-03-13 22:39:26Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
@@ -42,7 +42,6 @@
|
||||
-- 15 nofifo r/w/- a 1 disables fifo, to test delayed aborts
|
||||
-- 14:12 stat r/w/- echo'ed on RB_STAT
|
||||
-- 11:00 nbusy r/w/- busy cycles (for data and fifo access)
|
||||
-- 00 go r/w/- enables monitor
|
||||
-- bbbbbb01 15:00 data r/w/- Data register (just w/r reg, no function)
|
||||
-- bbbbbb10 15:00 fifo r/w/- Fifo interface register
|
||||
-- bbbbbb11 attn r/w/- Attn/Length register
|
||||
|
||||
6
rtl/vlib/rbus/rbd_timer.vbom
Normal file
6
rtl/vlib/rbus/rbd_timer.vbom
Normal file
@@ -0,0 +1,6 @@
|
||||
# libs
|
||||
../slvtypes.vhd
|
||||
rblib.vhd
|
||||
# components
|
||||
# design
|
||||
rbd_timer.vhd
|
||||
152
rtl/vlib/rbus/rbd_timer.vhd
Normal file
152
rtl/vlib/rbus/rbd_timer.vhd
Normal file
@@ -0,0 +1,152 @@
|
||||
-- $Id: rbd_timer.vhd 351 2010-12-30 21:50:54Z mueller $
|
||||
--
|
||||
-- Copyright 2010- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
--
|
||||
-- This program is free software; you may redistribute and/or modify it under
|
||||
-- the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 2, 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 General Public License
|
||||
-- for complete details.
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
-- Module Name: rbd_timer - syn
|
||||
-- Description: rbus dev: usec precision timer
|
||||
--
|
||||
-- Dependencies: -
|
||||
--
|
||||
-- Test bench: -
|
||||
--
|
||||
-- Target Devices: generic
|
||||
-- Tool versions: xst 12.1; ghdl 0.29
|
||||
--
|
||||
-- Synthesized (xst):
|
||||
-- Date Rev ise Target flop lutl lutm slic t peri
|
||||
-- 2010-12-29 351 12.1 M53d xc3s1000-4 19 63 - 34 s 7.6
|
||||
--
|
||||
-- Revision History:
|
||||
-- Date Rev Version Comment
|
||||
-- 2010-12-29 351 1.0 Initial version
|
||||
------------------------------------------------------------------------------
|
||||
--
|
||||
-- rbus registers:
|
||||
--
|
||||
-- Address Bits Name r/w/f Function
|
||||
-- bbbbbbbb time r/w/- Timer register
|
||||
-- w: if > 0 timer is running
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
use work.slvtypes.all;
|
||||
use work.rblib.all;
|
||||
|
||||
entity rbd_timer is -- rbus dev: usec precision timer
|
||||
generic (
|
||||
RB_ADDR : slv8 := conv_std_logic_vector(2#00000000#,8));
|
||||
port (
|
||||
CLK : in slbit; -- clock
|
||||
CE_USEC : in slbit; -- usec pulse
|
||||
RESET : in slbit; -- reset
|
||||
RB_MREQ : in rb_mreq_type; -- rbus: request
|
||||
RB_SRES : out rb_sres_type; -- rbus: response
|
||||
DONE : out slbit; -- 1 cycle pulse when expired
|
||||
BUSY : out slbit -- timer running
|
||||
);
|
||||
end entity rbd_timer;
|
||||
|
||||
|
||||
architecture syn of rbd_timer is
|
||||
|
||||
type regs_type is record -- state registers
|
||||
rbsel : slbit; -- rbus select
|
||||
timer : slv16; -- timer value
|
||||
timer_act : slbit; -- timer active flag
|
||||
timer_end : slbit; -- timer done flag
|
||||
end record regs_type;
|
||||
|
||||
constant regs_init : regs_type := (
|
||||
'0', -- rbsel
|
||||
(others=>'0'), -- timer
|
||||
'0','0' -- timer_act,timer_end
|
||||
);
|
||||
|
||||
signal R_REGS : regs_type := regs_init;
|
||||
signal N_REGS : regs_type := regs_init;
|
||||
|
||||
begin
|
||||
|
||||
proc_regs: process (CLK)
|
||||
begin
|
||||
if CLK'event and CLK='1' then
|
||||
if RESET = '1' then
|
||||
R_REGS <= regs_init;
|
||||
else
|
||||
R_REGS <= N_REGS;
|
||||
end if;
|
||||
end if;
|
||||
end process proc_regs;
|
||||
|
||||
proc_next : process (R_REGS, CE_USEC, RB_MREQ)
|
||||
variable r : regs_type := regs_init;
|
||||
variable n : regs_type := regs_init;
|
||||
variable irb_ack : slbit := '0';
|
||||
variable irb_dout : slv16 := (others=>'0');
|
||||
begin
|
||||
|
||||
r := R_REGS;
|
||||
n := R_REGS;
|
||||
|
||||
irb_ack := '0';
|
||||
irb_dout := (others=>'0');
|
||||
|
||||
-- rbus address decoder
|
||||
n.rbsel := '0';
|
||||
if RB_MREQ.aval='1' and RB_MREQ.addr=RB_ADDR then
|
||||
n.rbsel := '1';
|
||||
end if;
|
||||
|
||||
-- rbus transactions
|
||||
if r.rbsel = '1' then
|
||||
irb_ack := RB_MREQ.re or RB_MREQ.we;
|
||||
|
||||
if RB_MREQ.we = '1' then
|
||||
n.timer := RB_MREQ.din;
|
||||
n.timer_act := '1';
|
||||
end if;
|
||||
if RB_MREQ.re = '1' then
|
||||
irb_dout := r.timer;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- timer logic
|
||||
-- count down when active and 'on-the-usec'
|
||||
n.timer_end := '0'; -- ensure end is 1 cycle pulse
|
||||
if CE_USEC = '1' then -- if at usec
|
||||
if r.timer_act = '1' then -- if timer active
|
||||
if unsigned(r.timer) = 0 then -- if timer at end
|
||||
n.timer_act := '0'; -- mark unactive
|
||||
n.timer_end := '1'; -- send end marker
|
||||
else -- else: timer not at end
|
||||
n.timer := unsigned(r.timer) - 1; -- decrement
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
N_REGS <= n;
|
||||
|
||||
RB_SRES.dout <= irb_dout;
|
||||
RB_SRES.ack <= irb_ack;
|
||||
RB_SRES.err <= '0';
|
||||
RB_SRES.busy <= '0';
|
||||
|
||||
DONE <= r.timer_end;
|
||||
BUSY <= r.timer_act;
|
||||
|
||||
end process proc_next;
|
||||
|
||||
end syn;
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: rlink_cext.c 351 2010-12-30 21:50:54Z mueller $
|
||||
/* $Id: rlink_cext.c 366 2011-03-05 14:55:15Z mueller $
|
||||
*
|
||||
* Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
*
|
||||
@@ -13,6 +13,7 @@
|
||||
*
|
||||
* Revision History:
|
||||
* Date Rev Vers Comment
|
||||
* 2011-03-05 366 1.3.1 add RLINK_CEXT_TRACE=2 trace level
|
||||
* 2010-12-29 351 1.3 rename cext_rriext -> rlink_cext; rename functions
|
||||
* cext_* -> rlink_cext_* and fifo file names
|
||||
* tb_cext_* -> rlink_cext_*
|
||||
@@ -78,6 +79,12 @@ static void rlink_cext_doread()
|
||||
char buf[1];
|
||||
ssize_t nbyte;
|
||||
nbyte = read(fd_rx, buf, 1);
|
||||
if (io_trace > 1) {
|
||||
printf("rlink_cext-I: read rc=%d", nbyte);
|
||||
if (nbyte < 0) printf(" errno=%d %s", errno, strerror(errno));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (nbyte < 0) {
|
||||
qr_err = errno;
|
||||
} else if (nbyte == 0) {
|
||||
@@ -128,8 +135,15 @@ int rlink_cext_getbyte(int clk)
|
||||
|
||||
io_trace = 0;
|
||||
env_val = getenv("RLINK_CEXT_TRACE");
|
||||
if (env_val && strcmp(env_val, "1") == 0) {
|
||||
io_trace = 1;
|
||||
if (env_val) {
|
||||
printf("rlink_cext-I: seen RLINK_CEXT_TRACE=%s\n", env_val);
|
||||
if (strcmp(env_val, "1") == 0) {
|
||||
printf("rlink_cext-I: set trace level to 1\n");
|
||||
io_trace = 1;
|
||||
} else if (strcmp(env_val, "2") == 0) {
|
||||
printf("rlink_cext-I: set trace level to 2\n");
|
||||
io_trace = 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -208,6 +222,11 @@ int rlink_cext_putbyte(int dat)
|
||||
|
||||
buf[0] = (unsigned char) dat;
|
||||
nbyte = write(fd_tx, buf, 1);
|
||||
if (io_trace > 1) {
|
||||
printf("rlink_cext-I: write rc=%d", nbyte);
|
||||
if (nbyte < 0) printf(" errno=%d %s", errno, strerror(errno));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (nbyte < 0) {
|
||||
perror("rlink_cext-E: write error on rlink_cext_fifo_tx");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id: pi_rri 351 2010-12-30 21:50:54Z mueller $
|
||||
# $Id: pi_rri 374 2011-03-27 17:02:47Z mueller $
|
||||
#
|
||||
# Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
#
|
||||
@@ -6455,7 +6455,7 @@ sub term_open { # term fifo: open handler
|
||||
my $newtios = new POSIX::Termios;
|
||||
$newtios->getattr($fd) || die "getattr failed: $!"; ## hack for cygwin !!
|
||||
|
||||
my $c_iflag = &POSIX::BRKINT; # ignore parity errors
|
||||
my $c_iflag = &POSIX::BRKINT; # ignore parity errors (??? WRONG??)
|
||||
my $c_oflag = 0;
|
||||
my $c_cflag = &POSIX::CS8 | # 8 bit chars
|
||||
&POSIX::CSTOPB | # 2 stop bits
|
||||
@@ -6532,30 +6532,30 @@ sub term_tios_print {
|
||||
|
||||
printf "iflag = %8.8x:", $iflag;
|
||||
print " BRKINT" if $iflag & &POSIX::BRKINT;
|
||||
print " ICRNL " if $iflag & &POSIX::ICRNL;
|
||||
print " ICRNL " if $iflag & &POSIX::ICRNL;
|
||||
print " IGNBRK" if $iflag & &POSIX::IGNBRK;
|
||||
print " IGNCR " if $iflag & &POSIX::IGNCR;
|
||||
print " IGNCR " if $iflag & &POSIX::IGNCR;
|
||||
print " IGNPAR" if $iflag & &POSIX::IGNPAR;
|
||||
print " INLCR " if $iflag & &POSIX::INLCR;
|
||||
print " INPCK " if $iflag & &POSIX::INPCK;
|
||||
print " INLCR " if $iflag & &POSIX::INLCR;
|
||||
print " INPCK " if $iflag & &POSIX::INPCK;
|
||||
print " ISTRIP" if $iflag & &POSIX::ISTRIP;
|
||||
print " IXOFF " if $iflag & &POSIX::IXOFF;
|
||||
print " IXON " if $iflag & &POSIX::IXON;
|
||||
print " IXOFF " if $iflag & &POSIX::IXOFF;
|
||||
print " IXON " if $iflag & &POSIX::IXON;
|
||||
print " PARMRK" if $iflag & &POSIX::PARMRK;
|
||||
print "\n";
|
||||
printf "oflag = %8.8x:", $oflag;
|
||||
print " OPOST " if $oflag & &POSIX::OPOST;
|
||||
print " OPOST " if $oflag & &POSIX::OPOST;
|
||||
print "\n";
|
||||
|
||||
printf "cflag = %8.8x:", $cflag;
|
||||
print " CLOCAL" if $cflag & &POSIX::CLOCAL;
|
||||
print " CREAD " if $cflag & &POSIX::CREAD;
|
||||
print " CREAD " if $cflag & &POSIX::CREAD;
|
||||
print " CS5 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS5;
|
||||
print " CS6 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS6;
|
||||
print " CS7 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS7;
|
||||
print " CS8 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS8;
|
||||
print " CSTOPB" if $cflag & &POSIX::CSTOPB;
|
||||
print " HUPCL " if $cflag & &POSIX::HUPCL;
|
||||
print " HUPCL " if $cflag & &POSIX::HUPCL;
|
||||
print " PARENB" if $cflag & &POSIX::PARENB;
|
||||
print " PARODD" if $cflag & &POSIX::PARODD;
|
||||
|
||||
@@ -6563,7 +6563,7 @@ sub term_tios_print {
|
||||
&POSIX::B150 | &POSIX::B200 | &POSIX::B300 | &POSIX::B600 |
|
||||
&POSIX::B1200 | &POSIX::B1800 | &POSIX::B2400 | &POSIX::B4800 |
|
||||
&POSIX::B9600 | &POSIX::B19200 | &POSIX::B38400;
|
||||
print " B0 " if ($cflag & $sbits) == &POSIX::B0;
|
||||
print " B0 " if ($cflag & $sbits) == &POSIX::B0;
|
||||
print " B50 " if ($cflag & $sbits) == &POSIX::B50;
|
||||
print " B75 " if ($cflag & $sbits) == &POSIX::B75;
|
||||
print " B110 " if ($cflag & $sbits) == &POSIX::B110;
|
||||
@@ -6582,13 +6582,13 @@ sub term_tios_print {
|
||||
print "\n";
|
||||
|
||||
printf "lflag = %8.8x:", $lflag;
|
||||
print " ECHO " if $lflag & &POSIX::ECHO;
|
||||
print " ECHOE " if $lflag & &POSIX::ECHOE;
|
||||
print " ECHOK " if $lflag & &POSIX::ECHOK;
|
||||
print " ECHO " if $lflag & &POSIX::ECHO;
|
||||
print " ECHOE " if $lflag & &POSIX::ECHOE;
|
||||
print " ECHOK " if $lflag & &POSIX::ECHOK;
|
||||
print " ECHONL" if $lflag & &POSIX::ECHONL;
|
||||
print " ICANON" if $lflag & &POSIX::ICANON;
|
||||
print " IEXTEN" if $lflag & &POSIX::IEXTEN;
|
||||
print " ISIG " if $lflag & &POSIX::ISIG;
|
||||
print " ISIG " if $lflag & &POSIX::ISIG;
|
||||
print " NOFLSH" if $lflag & &POSIX::NOFLSH;
|
||||
print " TOSTOP" if $lflag & &POSIX::TOSTOP;
|
||||
print "\n";
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#!/bin/sh
|
||||
# $Id: rm_dep 284 2010-04-26 20:55:13Z mueller $
|
||||
# $Id: rm_dep 354 2011-01-09 22:38:53Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-01-09 354 1.1.1 add *.dep for cpp depends
|
||||
# 2010-04-26 284 1.1 add xargs -r to prevent rm errors on empty lists
|
||||
# 2010-04-24 282 1.0 Initial version
|
||||
#
|
||||
for ftype in dep_ghdl dep_isim dep_xst dep_ucf_cpp
|
||||
for ftype in dep dep_ghdl dep_isim dep_xst dep_ucf_cpp
|
||||
do
|
||||
echo "---------- remove *.$ftype ----------------------------------------"
|
||||
find -name "*.$ftype" | xargs --no-run-if-empty rm -v
|
||||
|
||||
204
tools/bin/ti_rri
Executable file
204
tools/bin/ti_rri
Executable file
@@ -0,0 +1,204 @@
|
||||
#! /usr/bin/env tclsh
|
||||
# -*- tcl -*-
|
||||
# $Id: ti_rri 375 2011-04-02 07:56:47Z mueller $
|
||||
#
|
||||
# Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
#
|
||||
# This program is free software; you may redistribute and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation, either version 2, 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 General Public License
|
||||
# for complete details.
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-04-02 376 1.0 Initial version
|
||||
# 2011-03-19 371 0.1 First draft
|
||||
#
|
||||
#
|
||||
# --fifo[=name,keep]
|
||||
# --term[=???] ; not yet implemented...
|
||||
# --run=command
|
||||
# --log=filename ; default "-"
|
||||
# --logl=n ; default 2
|
||||
# --dmpl=n ; default 0
|
||||
# --tiol=n ; default 0
|
||||
# --int
|
||||
# --help
|
||||
# --
|
||||
# tcl cmds
|
||||
# @...tcl
|
||||
#
|
||||
|
||||
array set opts {
|
||||
fifo 0
|
||||
fifo_ ""
|
||||
term 0
|
||||
term_ ""
|
||||
run_ ""
|
||||
log_ "-"
|
||||
logl_ 2
|
||||
dmpl_ 0
|
||||
tiol_ 0
|
||||
int 0
|
||||
help 0
|
||||
}
|
||||
|
||||
set clist {}
|
||||
set optsendseen 0
|
||||
|
||||
foreach arg $argv {
|
||||
if { $optsendseen } {
|
||||
lappend clist $arg
|
||||
continue
|
||||
}
|
||||
switch -regexp -- $arg {
|
||||
^--?fifo=?.*$ { set opts(fifo) 1; regexp -- {=(.*)} $arg dummy opts(fifo_) }
|
||||
^--?term=?.*$ { set opts(term) 1; regexp -- {=(.*)} $arg dummy opts(term_) }
|
||||
^--?run=.+$ { regexp -- {=(.*)} $arg dummy opts(run_) }
|
||||
^--?log=.+$ { regexp -- {=(.*)} $arg dummy opts(log_) }
|
||||
^--?logl=.+$ { regexp -- {=(.*)} $arg dummy opts(logl_) }
|
||||
^--?dmpl=.+$ { regexp -- {=(.*)} $arg dummy opts(dmpl_) }
|
||||
^--?tiol=.+$ { regexp -- {=(.*)} $arg dummy opts(tiol_) }
|
||||
^--?int$ { set opts(int) 1 }
|
||||
^--?help$ { set opts(help) 1 }
|
||||
^--$ { set optsendseen 1 }
|
||||
^--.+$ { puts "-E: bad option $arg, see --help for proper usage"
|
||||
return 1
|
||||
}
|
||||
default { lappend clist $arg }
|
||||
}
|
||||
}
|
||||
|
||||
if { $opts(help) } {
|
||||
puts "usage: ti_rri"
|
||||
return 0
|
||||
}
|
||||
|
||||
if { $opts(fifo) && $opts(term) } {
|
||||
puts "-E: both --fifo and --term given, only one allowed"
|
||||
return 1
|
||||
}
|
||||
|
||||
lappend auto_path [file join $env(RETROBASE) tools tcl]
|
||||
lappend auto_path [file join $env(RETROBASE) tools lib]
|
||||
|
||||
package require rlink
|
||||
package require rutiltpp
|
||||
package require rlinktpp
|
||||
|
||||
rlinkconnect rlc
|
||||
|
||||
# setup logging
|
||||
if { $opts(log_) ne "-" } {
|
||||
rlc config -logfile $opts(log_)
|
||||
}
|
||||
rlc config -logprintlevel $opts(logl_)
|
||||
rlc config -logdumplevel $opts(dmpl_)
|
||||
rlc config -logtracelevel $opts(tiol_)
|
||||
|
||||
# first start, if specified with -run, the test bench
|
||||
set runpid {}
|
||||
if { $opts(run_) ne "" } {
|
||||
if { [catch {eval "exec $opts(run_) &" } runpid] } {
|
||||
puts "-E: failed to execute \"$opts(run_)\" with error message\n $runpid"
|
||||
puts "aborting..."
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
# than open the rlink connection
|
||||
# handle --fifo
|
||||
if { $opts(fifo) } {
|
||||
set nlist [split $opts(fifo_) ","]
|
||||
set path [lindex $nlist 0]
|
||||
set keep [lindex $nlist 1]
|
||||
if {$path eq ""} {set path "rlink_cext_fifo"}
|
||||
set url "fifo:$path"
|
||||
if {$keep ne ""} {append url "?keep"}
|
||||
rlc open $url
|
||||
}
|
||||
|
||||
# handle --term
|
||||
if { $opts(term) } {
|
||||
set nlist [split $opts(term_) ","]
|
||||
set dev [lindex $nlist 0]
|
||||
set baud [lindex $nlist 1]
|
||||
set brk [lindex $nlist 2]
|
||||
if {$dev eq ""} {set dev "/dev/ttyS0"}
|
||||
if {$baud eq ""} {set baud "115k"}
|
||||
set url "term:$dev?baud=$baud"
|
||||
if {$brk ne ""} {append url ";break"}
|
||||
rlc open $url
|
||||
}
|
||||
|
||||
# setup simulation mode default
|
||||
set rlink::sim_mode [rlink::isfifo]
|
||||
|
||||
foreach cmd $clist {
|
||||
# handle @filename commands
|
||||
if { [regexp {^@(.+)} $cmd dummy filename] } {
|
||||
# handle @file.tcl --> source tcl file
|
||||
if { [regexp {\.tcl$} $filename] } {
|
||||
if { [catch {source $filename} errmsg] } {
|
||||
puts "-E: failed to source file \"$filename\" with error message:"
|
||||
if {[info exists errorInfo]} {puts $errorInfo} else {puts $errmsg}
|
||||
puts "aborting..."
|
||||
break
|
||||
}
|
||||
# handle @file.dat ect --> not yet supported
|
||||
} else {
|
||||
puts "-E: only tcl supported but $filename found"
|
||||
puts "aborting..."
|
||||
break
|
||||
}
|
||||
|
||||
# handle normal tcl commands --> eval them
|
||||
} else {
|
||||
if { [catch {eval $cmd} errmsg] } {
|
||||
puts "-E: eval of \"$cmd\" failed with error message:"
|
||||
if {[info exists errorInfo]} {puts $errorInfo} else {puts $errmsg}
|
||||
puts "aborting..."
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# if tclsh runs a script given on the command line or is invoked
|
||||
# like here via a shebang the tcl_interactive is always set to 0
|
||||
# so we have to check whether stdin/stdout is a terminal and set
|
||||
# tcl_interactive accordingly
|
||||
|
||||
# FIXME_code: fstat not available (grr...), currently just assume istty
|
||||
set tcl_interactive 1
|
||||
|
||||
if { $opts(int) || [llength $clist] == 0 } {
|
||||
if {$tcl_interactive} {
|
||||
package require tclreadline
|
||||
namespace eval tclreadline {
|
||||
proc prompt1 {} {
|
||||
set version [info tclversion]
|
||||
return "ti_rri > "
|
||||
}
|
||||
}
|
||||
::tclreadline::Loop
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# now close rlink connection
|
||||
#
|
||||
if { $opts(fifo) || $opts(term) } {
|
||||
rlc close
|
||||
}
|
||||
|
||||
# FIXME_code: should sync here with -run process run-down
|
||||
# but no wait available in tcl (grr...)
|
||||
if { $runpid } {
|
||||
after 100; # currently just wait 100ms
|
||||
}
|
||||
|
||||
return 0
|
||||
283
tools/dox/w11.Doxyfile
Normal file
283
tools/dox/w11.Doxyfile
Normal file
@@ -0,0 +1,283 @@
|
||||
# $Id: $
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-01-09 354 1.0 Initial version
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# Doxyfile 1.7.3
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = w11
|
||||
PROJECT_NUMBER = 0.53
|
||||
PROJECT_BRIEF = "Backend server for Rlink and w11"
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY = $(HOME)/tmp/w11
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH = $(RETROBASE)/tools/src
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING = ipp=C++
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
SYMBOL_CACHE_SIZE = 0
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = $(RETROBASE)/tools/src
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.cpp *.hpp *.ipp *.dox
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS = */.svn* */tests/*
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = YES
|
||||
USE_INLINE_TREES = YES
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
SEARCHENGINE = YES
|
||||
SERVER_BASED_SEARCH = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
53
tools/make/generic_cpp.mk
Normal file
53
tools/make/generic_cpp.mk
Normal file
@@ -0,0 +1,53 @@
|
||||
# $Id: generic_cpp.mk 355 2011-01-15 09:06:23Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-01-09 354 1.0 Initial version (from wrepo/make/generic_cxx.mk)
|
||||
#---
|
||||
#
|
||||
# Compile options
|
||||
#
|
||||
# -- handle C
|
||||
# -O optimize
|
||||
# -fPIC position independent code
|
||||
# -Wall all warnings
|
||||
#
|
||||
# -g request debugging info
|
||||
#
|
||||
ifdef CCCOMMAND
|
||||
CC = $(CCCOMMAND)
|
||||
endif
|
||||
ifndef CCOPTFLAGS
|
||||
CCOPTFLAGS = -O
|
||||
endif
|
||||
#
|
||||
CC = gcc
|
||||
CFLAGS = -Wall $(CCOPTFLAGS) $(INCLFLAGS)
|
||||
#
|
||||
# -- handle C++
|
||||
#
|
||||
# -O optimize
|
||||
# -fPIC position independent code
|
||||
# -Wall all warnings
|
||||
#
|
||||
# -g request debugging info
|
||||
#
|
||||
ifdef CXXCOMMAND
|
||||
CXX = $(CXXCOMMAND)
|
||||
endif
|
||||
#
|
||||
ifndef CXXOPTFLAGS
|
||||
CXXOPTFLAGS = -O2
|
||||
endif
|
||||
#
|
||||
CXXFLAGS = -Wall -std=c++0x $(CXXOPTFLAGS) $(INCLFLAGS)
|
||||
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
|
||||
#
|
||||
LINK.o = $(CXX) $(CXXOPTFLAGS) $(LDOPTFLAGS) $(LDFLAGS) $(TARGET_ARCH)
|
||||
LDFLAGS = -g
|
||||
#
|
||||
# Compile rule
|
||||
#
|
||||
%.o: %.cpp
|
||||
$(COMPILE.cc) $< $(OUTPUT_OPTION)
|
||||
#
|
||||
18
tools/make/generic_dep.mk
Normal file
18
tools/make/generic_dep.mk
Normal file
@@ -0,0 +1,18 @@
|
||||
# $Id: generic_dep.mk 354 2011-01-09 22:38:53Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-01-09 354 1.0 Initial version (from wrepo/make/generic_dep.mk)
|
||||
#---
|
||||
#
|
||||
# Dependency generation rules
|
||||
#
|
||||
%.dep: %.c
|
||||
@ echo "$(CC) -MM $< | sed ... > $@"
|
||||
@ $(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $(CFLAGS) $< \
|
||||
| sed '\''s/\($*\.o\)[ :]*/\1 $@ : /g'\'' > $@'
|
||||
%.dep: %.cpp
|
||||
@ echo "$(CXX) -MM $< | sed ... > $@"
|
||||
@ $(SHELL) -ec '$(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $< \
|
||||
| sed '\''s/\($*\.o\)[ :]*/\1 $@ : /g'\'' > $@'
|
||||
#
|
||||
43
tools/make/generic_so.mk
Normal file
43
tools/make/generic_so.mk
Normal file
@@ -0,0 +1,43 @@
|
||||
# $Id: generic_so.mk 354 2011-01-09 22:38:53Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-01-09 354 1.0 Initial version (from wrepo/make/generic_so.mk)
|
||||
#---
|
||||
#
|
||||
# Build a sharable library and an archive
|
||||
#
|
||||
# Before including, defined the following variables:
|
||||
# SOPATH relative directory path of the library (def: $RETROBASE/tools/lib)
|
||||
# SONAME name of the library
|
||||
# SOMAJV major version number
|
||||
# SOMINV minor version number
|
||||
#
|
||||
ifndef SOPATH
|
||||
SOPATH = $(RETROBASE)/tools/lib
|
||||
endif
|
||||
#
|
||||
SOFILE = lib$(SONAME).so
|
||||
SOFILEV = lib$(SONAME).so.$(SOMAJV)
|
||||
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV)
|
||||
AFILE = lib$(SONAME).a
|
||||
#
|
||||
.PHONY : libs
|
||||
libs : $(SOPATH)/$(AFILE) $(SOPATH)/$(SOFILEVV)
|
||||
#
|
||||
# Build the sharable library
|
||||
#
|
||||
$(SOPATH)/$(SOFILEVV) : $(OBJ_all)
|
||||
if [ ! -d $(SOPATH) ]; then mkdir $(SOPATH); fi
|
||||
$(CXX) -shared -Wl,-soname,$(SOFILEV) -o $(SOPATH)/$(SOFILEVV) \
|
||||
$(OBJ_all) $(LDLIBS)
|
||||
(cd $(SOPATH); rm -f $(SOFILE) $(SOFILEV))
|
||||
(cd $(SOPATH); ln -s $(SOFILEVV) $(SOFILEV))
|
||||
(cd $(SOPATH); ln -s $(SOFILEV) $(SOFILE))
|
||||
#
|
||||
# Build an archive
|
||||
#
|
||||
$(SOPATH)/$(AFILE) : $(OBJ_all)
|
||||
if [ ! -d $(SOPATH) ]; then mkdir $(SOPATH); fi
|
||||
ar -scruv $(SOPATH)/$(AFILE) $?
|
||||
#
|
||||
51
tools/src/Makefile
Normal file
51
tools/src/Makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
# $Id: Makefile 372 2011-03-20 22:48:11Z mueller $
|
||||
#
|
||||
# Top level makefile, using the recipe found in
|
||||
# http://www.lackof.org/taggart/hacking/make-example/
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-03-20 372 1.1.1 renamed ..tcl -> ..tpp
|
||||
# 2011-03-14 370 1.1.0 rename librtoolstcl -> librtcltools
|
||||
# 2011-02-13 361 1.1 add realclean rule; add dirs and dependencies
|
||||
# 2011-01-30 357 1.0 Initial version
|
||||
#
|
||||
DIRS = librtools
|
||||
DIRS += librlink
|
||||
DIRS += librtcltools
|
||||
DIRS += librutiltpp
|
||||
DIRS += librlinktpp
|
||||
#
|
||||
BUILDDIRS = $(DIRS:%=build-%)
|
||||
CLEANDIRS = $(DIRS:%=clean-%)
|
||||
REALCDIRS = $(DIRS:%=realc-%)
|
||||
#
|
||||
.PHONY: all clean realclean
|
||||
.PHONY: $(DIRS)
|
||||
.PHONY: $(BUILDDIRS)
|
||||
.PHONY: $(CLEANDIRS)
|
||||
.PHONY: $(REALCDIRS)
|
||||
#
|
||||
# build 'all' rule
|
||||
#
|
||||
all: $(BUILDDIRS)
|
||||
#
|
||||
build-librlink : build-librtools
|
||||
build-librtcltools : build-librtools
|
||||
build-librutiltpp : build-librtcltools
|
||||
build-librlinktpp : build-librlink build-librtcltools
|
||||
#
|
||||
$(BUILDDIRS):
|
||||
$(MAKE) -C $(@:build-%=%)
|
||||
#
|
||||
# clean rule
|
||||
#
|
||||
clean: $(CLEANDIRS)
|
||||
$(CLEANDIRS):
|
||||
$(MAKE) -C $(@:clean-%=%) clean
|
||||
#
|
||||
# realclean rule
|
||||
#
|
||||
realclean: $(REALCDIRS)
|
||||
$(REALCDIRS):
|
||||
$(MAKE) -C $(@:realc-%=%) realclean
|
||||
1
tools/src/librlink/.cvsignore
Normal file
1
tools/src/librlink/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
*.dep
|
||||
57
tools/src/librlink/Makefile
Normal file
57
tools/src/librlink/Makefile
Normal file
@@ -0,0 +1,57 @@
|
||||
# $Id: $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-01-09 354 1.0 Initial version (adopted from CTB...)
|
||||
#---
|
||||
#
|
||||
# Name of the sharable library
|
||||
#
|
||||
SONAME = rlink
|
||||
SOMAJV = 1
|
||||
SOMINV = 0
|
||||
#
|
||||
# Compile and Link search paths
|
||||
#
|
||||
INCLFLAGS = -I${RETROBASE}/tools/src
|
||||
LDLIBS = -L${RETROBASE}/tools/lib -lrtools
|
||||
#
|
||||
# Object files to be included
|
||||
#
|
||||
OBJ_all = RlinkAddrMap.o \
|
||||
RlinkCommand.o RlinkCommandExpect.o RlinkCommandList.o \
|
||||
RlinkConnect.o \
|
||||
RlinkCrc8.o RlinkPacketBuf.o \
|
||||
RlinkPort.o RlinkPortFactory.o RlinkPortFifo.o RlinkPortTerm.o
|
||||
#
|
||||
DEP_all = $(OBJ_all:.o=.dep)
|
||||
#
|
||||
#- generic part ----------------------------------------------------------------
|
||||
#
|
||||
SOFILE = lib$(SONAME).so
|
||||
SOFILEV = lib$(SONAME).so.$(SOMAJV)
|
||||
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV)
|
||||
#
|
||||
include $(RETROBASE)/tools/make/generic_cpp.mk
|
||||
include $(RETROBASE)/tools/make/generic_dep.mk
|
||||
include $(RETROBASE)/tools/make/generic_so.mk
|
||||
#
|
||||
# The magic autodependcy include
|
||||
#
|
||||
include $(DEP_all)
|
||||
#
|
||||
# cleanup phonies:
|
||||
#
|
||||
.PHONY : clean cleandep realclean
|
||||
clean :
|
||||
@ rm -f $(OBJ_all)
|
||||
@ echo "Object files removed"
|
||||
#
|
||||
cleandep :
|
||||
@ rm -f $(DEP_all)
|
||||
@ echo "Dependency files removed"
|
||||
#
|
||||
realclean : clean cleandep
|
||||
@ rm -f $(SOPATH)/lib$(SONAME).a $(SOPATH)/lib$(SONAME).so*
|
||||
@ echo "Libraries removed"
|
||||
#
|
||||
189
tools/src/librlink/RlinkAddrMap.cpp
Normal file
189
tools/src/librlink/RlinkAddrMap.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
// $Id: RlinkAddrMap.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-06 367 1.0 Initial version
|
||||
// 2011-03-05 366 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkAddrMap.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of class RlinkAddrMap.
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "RlinkAddrMap.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkAddrMap
|
||||
\brief FIXME_text
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkAddrMap::RlinkAddrMap()
|
||||
: fNameMap(),
|
||||
fAddrMap(),
|
||||
fMaxLength(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkAddrMap::~RlinkAddrMap()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkAddrMap::Clear()
|
||||
{
|
||||
fNameMap.clear();
|
||||
fAddrMap.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkAddrMap::Insert(const std::string& name, uint16_t addr)
|
||||
{
|
||||
if (fNameMap.find(name) != fNameMap.end()) return false;
|
||||
if (fAddrMap.find(addr) != fAddrMap.end()) return false;
|
||||
|
||||
fNameMap.insert(nmap_val_t(name, addr));
|
||||
fAddrMap.insert(amap_val_t(addr, name));
|
||||
fMaxLength = max(fMaxLength, name.length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkAddrMap::Erase(const std::string& name)
|
||||
{
|
||||
nmap_cit_t it = fNameMap.find(name);
|
||||
if (it == fNameMap.end()) return false;
|
||||
|
||||
fMaxLength = 0; // force recalculate
|
||||
if (fNameMap.erase(name) == 0)
|
||||
throw logic_error("RlinkAddrMap::Erase: fNameMap erase failed");
|
||||
if (fAddrMap.erase(it->second) == 0)
|
||||
throw logic_error("RlinkAddrMap::Erase: fAddrMap erase failed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkAddrMap::Erase(uint16_t addr)
|
||||
{
|
||||
amap_cit_t it = fAddrMap.find(addr);
|
||||
if (it == fAddrMap.end()) return false;
|
||||
|
||||
fMaxLength = 0; // force recalculate
|
||||
if (fAddrMap.erase(addr) == 0)
|
||||
throw logic_error("RlinkAddrMap::Erase: fAddrMap erase failed");
|
||||
if (fNameMap.erase(it->second) == 0)
|
||||
throw logic_error("RlinkAddrMap::Erase: fNameMap erase failed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkAddrMap::Find(const std::string& name, uint16_t& addr) const
|
||||
{
|
||||
nmap_cit_t it = fNameMap.find(name);
|
||||
if (it == fNameMap.end()) return false;
|
||||
|
||||
addr = it->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkAddrMap::Find(uint16_t addr, std::string& name) const
|
||||
{
|
||||
amap_cit_t it = fAddrMap.find(addr);
|
||||
if (it == fAddrMap.end()) return false;
|
||||
|
||||
name = it->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkAddrMap::MaxNameLength() const
|
||||
{
|
||||
if (fMaxLength == 0) {
|
||||
for (amap_cit_t it=fAddrMap.begin(); it!=fAddrMap.end(); it++) {
|
||||
fMaxLength = max(fMaxLength, (it->second).length());
|
||||
}
|
||||
}
|
||||
return fMaxLength;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkAddrMap::Print(std::ostream& os, int ind) const
|
||||
{
|
||||
size_t maxlen = max(6u, MaxNameLength());
|
||||
|
||||
RosFill bl(ind);
|
||||
for (amap_cit_t it=fAddrMap.begin(); it!=fAddrMap.end(); it++) {
|
||||
os << bl << RosPrintf((it->second).c_str(), "-s",maxlen)
|
||||
<< " : " << RosPrintf(it->first, "$x0", 4)
|
||||
<< " " << RosPrintf(it->first, "o0", 6) << endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkAddrMap::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkAddrMap @ " << this << endl;
|
||||
Print(os,ind+2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkAddrMap_NoInline))
|
||||
#define inline
|
||||
#include "RlinkAddrMap.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
80
tools/src/librlink/RlinkAddrMap.hpp
Normal file
80
tools/src/librlink/RlinkAddrMap.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// $Id: RlinkAddrMap.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-05 366 1.0 Initial version
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkAddrMap.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class \c RlinkAddrMap.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkAddrMap
|
||||
#define included_Retro_RlinkAddrMap 1
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkAddrMap {
|
||||
public:
|
||||
typedef std::map<std::string, uint16_t> nmap_t;
|
||||
typedef nmap_t::iterator nmap_it_t;
|
||||
typedef nmap_t::const_iterator nmap_cit_t;
|
||||
typedef nmap_t::value_type nmap_val_t;
|
||||
typedef std::map<uint16_t, std::string> amap_t;
|
||||
typedef amap_t::iterator amap_it_t;
|
||||
typedef amap_t::const_iterator amap_cit_t;
|
||||
typedef amap_t::value_type amap_val_t;
|
||||
|
||||
RlinkAddrMap();
|
||||
~RlinkAddrMap();
|
||||
|
||||
void Clear();
|
||||
|
||||
bool Insert(const std::string& name, uint16_t addr);
|
||||
bool Erase(const std::string& name);
|
||||
bool Erase(uint16_t addr);
|
||||
|
||||
bool Find(const std::string& name, uint16_t& addr) const;
|
||||
bool Find(uint16_t addr, std::string& name) const;
|
||||
|
||||
const nmap_t& Nmap() const;
|
||||
const amap_t& Amap() const;
|
||||
|
||||
size_t MaxNameLength() const;
|
||||
|
||||
void Print(std::ostream& os, int ind=0) const;
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
protected:
|
||||
nmap_t fNameMap; //!< name->addr map
|
||||
amap_t fAddrMap; //!< addr->name map
|
||||
mutable size_t fMaxLength; //!< max name length
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkAddrMap_NoInline))
|
||||
#include "RlinkAddrMap.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
44
tools/src/librlink/RlinkAddrMap.ipp
Normal file
44
tools/src/librlink/RlinkAddrMap.ipp
Normal file
@@ -0,0 +1,44 @@
|
||||
// $Id: RlinkAddrMap.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-05 366 1.0 Initial version
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkAddrMap.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of class RlinkAddrMap.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const RlinkAddrMap::nmap_t& RlinkAddrMap::Nmap() const
|
||||
{
|
||||
return fNameMap;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const RlinkAddrMap::amap_t& RlinkAddrMap::Amap() const
|
||||
{
|
||||
return fAddrMap;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
497
tools/src/librlink/RlinkCommand.cpp
Normal file
497
tools/src/librlink/RlinkCommand.cpp
Normal file
@@ -0,0 +1,497 @@
|
||||
// $Id: RlinkCommand.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommand.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of class RlinkCommand.
|
||||
*/
|
||||
|
||||
// debug
|
||||
#include <iostream>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "RlinkCommand.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librtools/RosPrintBvi.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkCommand
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
// constants definitions
|
||||
|
||||
const uint8_t RlinkCommand::kCmdRreg;
|
||||
const uint8_t RlinkCommand::kCmdRblk;
|
||||
const uint8_t RlinkCommand::kCmdWreg;
|
||||
const uint8_t RlinkCommand::kCmdWblk;
|
||||
const uint8_t RlinkCommand::kCmdStat;
|
||||
const uint8_t RlinkCommand::kCmdAttn;
|
||||
const uint8_t RlinkCommand::kCmdInit;
|
||||
|
||||
const uint32_t RlinkCommand::kFlagInit;
|
||||
const uint32_t RlinkCommand::kFlagSend;
|
||||
const uint32_t RlinkCommand::kFlagDone;
|
||||
const uint32_t RlinkCommand::kFlagPktBeg;
|
||||
const uint32_t RlinkCommand::kFlagPktEnd;
|
||||
const uint32_t RlinkCommand::kFlagRecov;
|
||||
const uint32_t RlinkCommand::kFlagResend;
|
||||
const uint32_t RlinkCommand::kFlagErrNak;
|
||||
const uint32_t RlinkCommand::kFlagErrMiss;
|
||||
const uint32_t RlinkCommand::kFlagErrCmd;
|
||||
const uint32_t RlinkCommand::kFlagErrCrc;
|
||||
const uint32_t RlinkCommand::kFlagChkStat;
|
||||
const uint32_t RlinkCommand::kFlagChkData;
|
||||
const uint32_t RlinkCommand::kFlagVol;
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkCommand::RlinkCommand()
|
||||
: fRequest(0),
|
||||
fAddress(0),
|
||||
fData(0),
|
||||
fBlock(),
|
||||
fpBlockExt(0),
|
||||
fBlockExtSize(0),
|
||||
fStatRequest(0),
|
||||
fStatus(0),
|
||||
fFlags(0),
|
||||
fRcvSize(0),
|
||||
fpExpect(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Copy constructor
|
||||
|
||||
RlinkCommand::RlinkCommand(const RlinkCommand& rhs)
|
||||
: fRequest(rhs.fRequest),
|
||||
fAddress(rhs.fAddress),
|
||||
fData(rhs.fData),
|
||||
fBlock(rhs.fBlock),
|
||||
fpBlockExt(rhs.fpBlockExt),
|
||||
fBlockExtSize(rhs.fBlockExtSize),
|
||||
fStatRequest(rhs.fStatRequest),
|
||||
fStatus(rhs.fStatus),
|
||||
fFlags(rhs.fFlags),
|
||||
fRcvSize(rhs.fRcvSize),
|
||||
fpExpect(rhs.fpExpect ? new RlinkCommandExpect(*rhs.fpExpect) : 0)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkCommand::~RlinkCommand()
|
||||
{
|
||||
delete fpExpect; // expect object owned by command
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::CmdRblk(uint16_t addr, size_t size)
|
||||
{
|
||||
SetCommand(kCmdRblk, addr);
|
||||
SetBlockRead(size);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::CmdRblk(uint16_t addr, uint16_t* pblock, size_t size)
|
||||
{
|
||||
SetCommand(kCmdRblk, addr);
|
||||
SetBlockExt(pblock, size);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::CmdWblk(uint16_t addr, const std::vector<uint16_t>& block)
|
||||
{
|
||||
SetCommand(kCmdWblk, addr);
|
||||
SetBlockWrite(block);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::CmdWblk(uint16_t addr, const uint16_t* pblock, size_t size)
|
||||
{
|
||||
SetCommand(kCmdWblk, addr);
|
||||
SetBlockExt(const_cast<uint16_t*>(pblock), size);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::SetCommand(uint8_t cmd, uint16_t addr, uint16_t data)
|
||||
{
|
||||
if (cmd > kCmdInit)
|
||||
throw invalid_argument("RlinkCommand::SetCommand: invalid cmd");
|
||||
if (addr > 0xff)
|
||||
throw invalid_argument("RlinkCommand::SetCommand: invalid addr");
|
||||
fRequest = cmd;
|
||||
fAddress = addr;
|
||||
fData = data;
|
||||
fpBlockExt = 0;
|
||||
fBlockExtSize = 0;
|
||||
fStatus = 0;
|
||||
fFlags = kFlagInit;
|
||||
fRcvSize = 0;
|
||||
delete fpExpect;
|
||||
fpExpect = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::SetAddress(uint16_t addr)
|
||||
{
|
||||
if (addr > 0xff)
|
||||
throw invalid_argument("RlinkCommand::SetAddress: invalid addr");
|
||||
fAddress = addr;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::SetBlockWrite(const std::vector<uint16_t>& block)
|
||||
{
|
||||
if (block.size() == 0 || block.size() > 256)
|
||||
throw invalid_argument("RlinkCommand::SetBlockWrite: invalid block size");
|
||||
fBlock = block;
|
||||
fpBlockExt = 0;
|
||||
fBlockExtSize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::SetBlockRead(size_t size)
|
||||
{
|
||||
if (size == 0 || size > 256)
|
||||
throw invalid_argument("RlinkCommand::SetBlockRead: invalid block size");
|
||||
fBlock.clear();
|
||||
fBlock.resize(size);
|
||||
fpBlockExt = 0;
|
||||
fBlockExtSize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::SetBlockExt(uint16_t* pblock, size_t size)
|
||||
{
|
||||
if (pblock == 0)
|
||||
throw invalid_argument("RlinkCommand::SetBlockExt: pblock is null");
|
||||
if (size == 0 || size > 256)
|
||||
throw invalid_argument("RlinkCommand::SetBlockExt: invalid block size");
|
||||
fpBlockExt = pblock;
|
||||
fBlockExtSize = size;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::SetExpect(RlinkCommandExpect* pexp)
|
||||
{
|
||||
delete fpExpect;
|
||||
fpExpect = pexp;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::Print(std::ostream& os, const RlinkAddrMap* pamap,
|
||||
size_t abase, size_t dbase, size_t sbase) const
|
||||
{
|
||||
uint8_t ccode = Command();
|
||||
|
||||
// separator + command mnemonic, code and flags
|
||||
// separator: ++ first in packet
|
||||
// -- non-first in packet
|
||||
// -= non-first in packet (marked volatile)
|
||||
const char* sep = "??";
|
||||
if (TestFlagAny(kFlagPktBeg)) {
|
||||
sep = "++";
|
||||
} else {
|
||||
sep = TestFlagAny(kFlagVol) ? "-=" : "--";
|
||||
}
|
||||
|
||||
os << sep << " " << CommandName(ccode)
|
||||
<< " (" << RosPrintBvi(Request(), 8)
|
||||
<< "," << RosPrintBvi(fFlags, 16, 20)
|
||||
<< ")";
|
||||
|
||||
// address field
|
||||
if (ccode==kCmdRreg || ccode==kCmdRblk ||
|
||||
ccode==kCmdWreg || ccode==kCmdWblk ||
|
||||
ccode==kCmdInit) {
|
||||
os << " a=" << RosPrintBvi(fAddress, abase);
|
||||
if (pamap) {
|
||||
string name;
|
||||
if (!pamap->Find(fAddress, name)) name.clear();
|
||||
os << "(" << name << RosFill(pamap->MaxNameLength()-name.length()) << ")";
|
||||
}
|
||||
}
|
||||
|
||||
// data field (scalar)
|
||||
if (ccode== kCmdRreg || ccode==kCmdWreg ||
|
||||
ccode== kCmdStat || ccode==kCmdAttn ||
|
||||
ccode== kCmdInit) {
|
||||
os << " d=" << RosPrintBvi(fData, dbase);
|
||||
|
||||
if (fpExpect &&
|
||||
(ccode==kCmdRreg || ccode==kCmdStat || ccode==kCmdAttn)) {
|
||||
if (TestFlagAny(kFlagChkData)) {
|
||||
os << "#";
|
||||
os << " D=" << RosPrintBvi(fpExpect->DataValue(), dbase);
|
||||
if (fpExpect->DataMask() != 0x0000) {
|
||||
os << "," << RosPrintBvi(fpExpect->DataMask(), dbase);
|
||||
}
|
||||
} else if (fpExpect->DataIsChecked()) {
|
||||
os << "!";
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (ccode== kCmdRblk || ccode==kCmdWblk) {
|
||||
os << " n=" << RosPrintf(BlockSize(), "d", 3);
|
||||
}
|
||||
|
||||
// ccmd field
|
||||
if (ccode == kCmdStat) {
|
||||
os << " c=" << RosPrintBvi(fStatRequest, 8);
|
||||
}
|
||||
|
||||
// status field
|
||||
os << " s=" << RosPrintBvi(fStatus, sbase);
|
||||
if (fpExpect) {
|
||||
if (TestFlagAny(kFlagChkStat)) {
|
||||
os << "#";
|
||||
os << " S=" << RosPrintBvi(fpExpect->StatusValue(), sbase);
|
||||
if (fpExpect->StatusMask() != 0x00) {
|
||||
os << "," << RosPrintBvi(fpExpect->StatusMask(), sbase);
|
||||
}
|
||||
} else if (fpExpect->StatusIsChecked()) {
|
||||
os << "!";
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
|
||||
if (TestFlagAny(kFlagDone)) {
|
||||
if (TestFlagAny(kFlagChkStat|kFlagChkData)) {
|
||||
os << " FAIL: "
|
||||
<< Rtools::Flags2String(fFlags&(kFlagChkStat|kFlagChkData),
|
||||
FlagNames(),',');
|
||||
} else {
|
||||
os << " OK";
|
||||
}
|
||||
if (TestFlagAny(kFlagRecov|kFlagResend)) os << " WARN: retried";
|
||||
} else if (TestFlagAny(kFlagSend)) {
|
||||
os << " FAIL: "
|
||||
<< Rtools::Flags2String(fFlags&(kFlagErrNak|kFlagErrMiss|
|
||||
kFlagErrCmd|kFlagErrCrc),
|
||||
FlagNames(),',');
|
||||
} else {
|
||||
os << " PEND";
|
||||
}
|
||||
|
||||
// handle data part of rblk and wblk commands
|
||||
size_t dwidth = (dbase==2) ? 16 : ((dbase==8) ? 6 : 4);
|
||||
|
||||
if (ccode==kCmdRblk) {
|
||||
bool dcheck = (fpExpect && fpExpect->BlockValue().size() > 0);
|
||||
size_t ncol = (80-4-5)/(dwidth+2);
|
||||
|
||||
size_t size = BlockSize();
|
||||
const uint16_t* pdat = BlockPointer();
|
||||
|
||||
for (size_t i=0; i<size; i++) {
|
||||
if (i%ncol == 0) os << "\n " << RosPrintf(i,"d",3) << ": ";
|
||||
os << RosPrintBvi(pdat[i], dbase);
|
||||
if (dcheck) {
|
||||
if (!fpExpect->BlockCheck(i, pdat[i])) {
|
||||
os << "#";
|
||||
} else {
|
||||
os << (fpExpect->BlockIsChecked(i) ? "!" : "-");
|
||||
}
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
os << " ";
|
||||
}
|
||||
|
||||
if (dcheck && TestFlagAny(kFlagChkData)) {
|
||||
const vector<uint16_t>& evalvec = fpExpect->BlockValue();
|
||||
const vector<uint16_t>& emskvec = fpExpect->BlockMask();
|
||||
for (size_t i=0; i<size; i++) {
|
||||
if (!fpExpect->BlockCheck(i, pdat[i])) {
|
||||
os << "\n FAIL d[" << RosPrintf(i,"d",3) << "]: "
|
||||
<< RosPrintBvi(pdat[i], dbase) << "#"
|
||||
<< " D=" << RosPrintBvi(evalvec[i], dbase);
|
||||
if (i < emskvec.size() && emskvec[i]!=0x0000) {
|
||||
os << "," << RosPrintBvi(emskvec[i], dbase);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ccode==kCmdWblk) {
|
||||
const uint16_t* pdat = BlockPointer();
|
||||
size_t size = BlockSize();
|
||||
size_t ncol = (80-4-5)/(dwidth+2);
|
||||
for (size_t i=0; i<size; i++) {
|
||||
if (i%ncol == 0) os << "\n " << RosPrintf(i,"d",3) << ": ";
|
||||
os << RosPrintBvi(pdat[i], dbase) << " ";
|
||||
}
|
||||
}
|
||||
|
||||
os << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommand::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkCommand @ " << this << endl;
|
||||
|
||||
os << bl << " fRequest: " << RosPrintBvi(fRequest,8)
|
||||
<< " seq:" << RosPrintf(SeqNumber(),"d",2)
|
||||
<< " cmd:" << RosPrintf(Command(),"d",1)
|
||||
<< " " << CommandName(Command()) << endl;
|
||||
os << bl << " fAddress: " << RosPrintBvi(fAddress,0) << endl;
|
||||
os << bl << " fData: " << RosPrintBvi(fData,0) << endl;
|
||||
os << bl << " fBlock.size: " << RosPrintf(fBlock.size(),"d",3) << endl;
|
||||
os << bl << " fpBlockExt: " << fpBlockExt << endl;
|
||||
os << bl << " fBlockExtSize: " << RosPrintf(fBlockExtSize,"d",3) << endl;
|
||||
os << bl << " fStatRequest: " << RosPrintBvi(fStatRequest,0) << endl;
|
||||
os << bl << " fStatus: " << RosPrintBvi(fStatus,0) << endl;
|
||||
os << bl << " fFlags: " << RosPrintBvi(fFlags,16,24)
|
||||
<< " " << Rtools::Flags2String(fFlags, FlagNames()) << endl;
|
||||
os << bl << " fRcvSize: " << RosPrintf(fRcvSize,"d",4) << endl;
|
||||
if (BlockSize() > 0) {
|
||||
size_t ncol = max(1, (80-ind-4-5)/(4+1));
|
||||
os << bl << " block data:";
|
||||
for (size_t i=0; i<BlockSize(); i++) {
|
||||
if (i%ncol == 0) os << "\n" << bl << " " << RosPrintf(i,"d",3) << ": ";
|
||||
os << RosPrintBvi(BlockPointer()[i],16) << " ";
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
if (fpExpect) fpExpect->Dump(os, ind+2, "fpExpect: ");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
const char* RlinkCommand::CommandName(uint8_t cmd)
|
||||
{
|
||||
static const char* cmdname[8] = {"rreg","rblk","wreg","wblk",
|
||||
"stat","attn","init","????"};
|
||||
|
||||
return cmdname[cmd&0x7];
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
const Retro::RflagName* RlinkCommand::FlagNames()
|
||||
{
|
||||
// use msb first order, will also be printing order
|
||||
static Retro::RflagName fnam[] = {
|
||||
{kFlagChkData, "ChkData"},
|
||||
{kFlagChkStat, "ChkStat"},
|
||||
{kFlagErrCrc, "ErrCrc"},
|
||||
{kFlagErrCmd, "ErrCmd"},
|
||||
{kFlagErrMiss, "ErrMiss"},
|
||||
{kFlagErrNak, "ErrNak"},
|
||||
{kFlagResend, "Resend"},
|
||||
{kFlagRecov, "Recov"},
|
||||
{kFlagPktEnd, "PktEnd"},
|
||||
{kFlagPktBeg, "PktBeg"},
|
||||
{kFlagDone, "Done"},
|
||||
{kFlagSend, "Send"},
|
||||
{kFlagInit, "Init"},
|
||||
{0u, ""}
|
||||
};
|
||||
return fnam;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RlinkCommand& RlinkCommand::operator=(const RlinkCommand& rhs)
|
||||
{
|
||||
if (&rhs == this) return *this;
|
||||
fRequest = rhs.fRequest;
|
||||
fAddress = rhs.fAddress;
|
||||
fData = rhs.fData;
|
||||
fBlock = rhs.fBlock;
|
||||
fpBlockExt = rhs.fpBlockExt;
|
||||
fBlockExtSize = rhs.fBlockExtSize;
|
||||
fStatRequest = rhs.fStatRequest;
|
||||
fStatus = rhs.fStatus;
|
||||
fFlags = rhs.fFlags;
|
||||
fRcvSize = rhs.fRcvSize;
|
||||
delete fpExpect;
|
||||
fpExpect = rhs.fpExpect ? new RlinkCommandExpect(*rhs.fpExpect) : 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkCommand_NoInline))
|
||||
#define inline
|
||||
#include "RlinkCommand.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
153
tools/src/librlink/RlinkCommand.hpp
Normal file
153
tools/src/librlink/RlinkCommand.hpp
Normal file
@@ -0,0 +1,153 @@
|
||||
// $Id: RlinkCommand.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-09 354 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommand.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkCommand.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkCommand
|
||||
#define included_Retro_RlinkCommand 1
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
#include "RlinkCommandExpect.hpp"
|
||||
#include "RlinkAddrMap.hpp"
|
||||
#include "librtools/Rtools.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkCommand {
|
||||
public:
|
||||
RlinkCommand();
|
||||
RlinkCommand(const RlinkCommand& rhs);
|
||||
~RlinkCommand();
|
||||
|
||||
void CmdRreg(uint16_t addr);
|
||||
void CmdRblk(uint16_t addr, size_t size);
|
||||
void CmdRblk(uint16_t addr, uint16_t* pblock, size_t size);
|
||||
void CmdWreg(uint16_t addr, uint16_t data);
|
||||
void CmdWblk(uint16_t addr, const std::vector<uint16_t>& block);
|
||||
void CmdWblk(uint16_t addr, const uint16_t* pblock, size_t size);
|
||||
void CmdStat();
|
||||
void CmdAttn();
|
||||
void CmdInit(uint16_t addr, uint16_t data);
|
||||
|
||||
void SetCommand(uint8_t cmd, uint16_t addr=0, uint16_t data=0);
|
||||
void SetSeqNumber(uint8_t snum);
|
||||
void SetAddress(uint16_t addr);
|
||||
void SetData(uint16_t data);
|
||||
void SetBlockWrite(const std::vector<uint16_t>& block);
|
||||
void SetBlockRead(size_t size) ;
|
||||
void SetBlockExt(uint16_t* pblock, size_t size);
|
||||
void SetStatRequest(uint8_t ccmd);
|
||||
void SetStatus(uint8_t stat);
|
||||
void SetFlagBit(uint32_t mask);
|
||||
void ClearFlagBit(uint32_t mask);
|
||||
void SetRcvSize(size_t rsize);
|
||||
void SetExpect(RlinkCommandExpect* pexp);
|
||||
|
||||
uint8_t Request() const;
|
||||
uint8_t Command() const;
|
||||
uint8_t SeqNumber() const;
|
||||
uint16_t Address() const;
|
||||
uint16_t Data() const;
|
||||
const std::vector<uint16_t>& Block() const;
|
||||
bool IsBlockExt() const;
|
||||
uint16_t* BlockPointer();
|
||||
const uint16_t* BlockPointer() const;
|
||||
size_t BlockSize() const;
|
||||
uint8_t StatRequest() const;
|
||||
uint8_t Status() const;
|
||||
uint32_t Flags() const;
|
||||
bool TestFlagAny(uint32_t mask) const;
|
||||
bool TestFlagAll(uint32_t mask) const;
|
||||
size_t RcvSize() const;
|
||||
RlinkCommandExpect* Expect() const;
|
||||
|
||||
void Print(std::ostream& os, const RlinkAddrMap* pamap=0,
|
||||
size_t abase=16, size_t dbase=16,
|
||||
size_t sbase=16) const;
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
static const char* CommandName(uint8_t cmd);
|
||||
static const RflagName* FlagNames();
|
||||
|
||||
RlinkCommand& operator=(const RlinkCommand& rhs);
|
||||
|
||||
// some constants
|
||||
static const uint8_t kCmdRreg = 0; //!< command code read register
|
||||
static const uint8_t kCmdRblk = 1; //!< command code read block
|
||||
static const uint8_t kCmdWreg = 2; //!< command code write register
|
||||
static const uint8_t kCmdWblk = 3; //!< command code write block
|
||||
static const uint8_t kCmdStat = 4; //!< command code get status
|
||||
static const uint8_t kCmdAttn = 5; //!< command code get attention
|
||||
static const uint8_t kCmdInit = 6; //!< command code send initialize
|
||||
|
||||
static const uint32_t kFlagInit = 1u<<0; //!< cmd,addr,data setup
|
||||
static const uint32_t kFlagSend = 1u<<1; //!< command send
|
||||
static const uint32_t kFlagDone = 1u<<2; //!< command done
|
||||
|
||||
static const uint32_t kFlagPktBeg = 1u<<4; //!< command first in packet
|
||||
static const uint32_t kFlagPktEnd = 1u<<5; //!< command last in packet
|
||||
static const uint32_t kFlagRecov = 1u<<6; //!< command stat recovered
|
||||
static const uint32_t kFlagResend = 1u<<7; //!< command resend recovered
|
||||
|
||||
static const uint32_t kFlagErrNak = 1u<<8; //!< error: nak abort
|
||||
static const uint32_t kFlagErrMiss= 1u<<9; //!< error: missing data
|
||||
static const uint32_t kFlagErrCmd = 1u<<10; //!< error: cmd or nblk check
|
||||
static const uint32_t kFlagErrCrc = 1u<<11; //!< error: crc check
|
||||
|
||||
static const uint32_t kFlagChkStat= 1u<<12; //!< stat expect check failed
|
||||
static const uint32_t kFlagChkData= 1u<<13; //!< data expect check failed
|
||||
|
||||
static const uint32_t kFlagVol = 1<<16; //!< volatile
|
||||
|
||||
protected:
|
||||
void SetCmdSimple(uint8_t cmd, uint16_t addr, uint16_t data);
|
||||
|
||||
protected:
|
||||
uint8_t fRequest; //!< rlink request (cmd+seqnum)
|
||||
uint16_t fAddress; //!< rbus address
|
||||
uint16_t fData; //!< data
|
||||
std::vector<uint16_t> fBlock; //!< data vector for blk commands
|
||||
uint16_t* fpBlockExt; //!< external data for blk commands
|
||||
size_t fBlockExtSize; //!< transfer size if data external
|
||||
uint8_t fStatRequest; //!< stat command ccmd return field
|
||||
uint8_t fStatus; //!< rlink command status
|
||||
uint32_t fFlags; //!< state bits
|
||||
size_t fRcvSize; //!< receive size for command
|
||||
RlinkCommandExpect* fpExpect; //!< pointer to expect container
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RlinkCommand& obj);
|
||||
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkCommand_NoInline))
|
||||
#include "RlinkCommand.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
286
tools/src/librlink/RlinkCommand.ipp
Normal file
286
tools/src/librlink/RlinkCommand.ipp
Normal file
@@ -0,0 +1,286 @@
|
||||
// $Id: RlinkCommand.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommand.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of class RlinkCommand.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::CmdRreg(uint16_t addr)
|
||||
{
|
||||
SetCommand(kCmdRreg, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::CmdWreg(uint16_t addr, uint16_t data)
|
||||
{
|
||||
SetCommand(kCmdWreg, addr, data);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::CmdStat()
|
||||
{
|
||||
SetCommand(kCmdStat);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::CmdAttn()
|
||||
{
|
||||
SetCommand(kCmdAttn);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::CmdInit(uint16_t addr, uint16_t data)
|
||||
{
|
||||
SetCommand(kCmdInit, addr, data);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::SetSeqNumber(uint8_t snum)
|
||||
{
|
||||
fRequest = (snum<<3) | (fRequest&0x07);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::SetData(uint16_t data)
|
||||
{
|
||||
fData = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::SetStatRequest(uint8_t ccmd)
|
||||
{
|
||||
fStatRequest = ccmd;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::SetStatus(uint8_t stat)
|
||||
{
|
||||
fStatus = stat;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::SetFlagBit(uint32_t mask)
|
||||
{
|
||||
fFlags |= mask;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::ClearFlagBit(uint32_t mask)
|
||||
{
|
||||
fFlags &= ~mask;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommand::SetRcvSize(size_t rsize)
|
||||
{
|
||||
fRcvSize = rsize;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommand::Request() const
|
||||
{
|
||||
return fRequest;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommand::Command() const
|
||||
{
|
||||
return fRequest & 0x07;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommand::SeqNumber() const
|
||||
{
|
||||
return fRequest>>3;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint16_t RlinkCommand::Address() const
|
||||
{
|
||||
return fAddress;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint16_t RlinkCommand::Data() const
|
||||
{
|
||||
return fData;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline const std::vector<uint16_t>& RlinkCommand::Block() const
|
||||
{
|
||||
return fBlock;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommand::IsBlockExt() const
|
||||
{
|
||||
return fpBlockExt != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint16_t* RlinkCommand::BlockPointer()
|
||||
{
|
||||
return IsBlockExt() ? fpBlockExt : (fBlock.size() ? &fBlock[0] : 0);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline const uint16_t* RlinkCommand::BlockPointer() const
|
||||
{
|
||||
return IsBlockExt() ? fpBlockExt : (fBlock.size() ? &fBlock[0] : 0);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline size_t RlinkCommand::BlockSize() const
|
||||
{
|
||||
return IsBlockExt() ? fBlockExtSize : fBlock.size();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommand::StatRequest() const
|
||||
{
|
||||
return fStatRequest;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommand::Status() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint32_t RlinkCommand::Flags() const
|
||||
{
|
||||
return fFlags;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommand::TestFlagAny(uint32_t mask) const
|
||||
{
|
||||
return (fFlags & mask) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommand::TestFlagAll(uint32_t mask) const
|
||||
{
|
||||
return (fFlags & mask) == fFlags;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline size_t RlinkCommand::RcvSize() const
|
||||
{
|
||||
return fRcvSize;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline RlinkCommandExpect* RlinkCommand::Expect() const
|
||||
{
|
||||
return fpExpect;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
/*!
|
||||
\relates RlinkCommand
|
||||
\brief ostream insertion operator.
|
||||
*/
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const RlinkCommand& obj)
|
||||
{
|
||||
obj.Print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
195
tools/src/librlink/RlinkCommandExpect.cpp
Normal file
195
tools/src/librlink/RlinkCommandExpect.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
// $Id: RlinkCommandExpect.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-12 368 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommandExpect.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of class RlinkCommandExpect.
|
||||
*/
|
||||
|
||||
// debug
|
||||
#include <iostream>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "RlinkCommandExpect.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librtools/RosPrintBvi.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkCommandExpect
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkCommandExpect::RlinkCommandExpect()
|
||||
: fStatusVal(0),
|
||||
fStatusMsk(0xff),
|
||||
fDataVal(0),
|
||||
fDataMsk(0xffff),
|
||||
fBlockVal(),
|
||||
fBlockMsk()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RlinkCommandExpect::RlinkCommandExpect(uint8_t stat, uint8_t statmsk)
|
||||
: fStatusVal(stat),
|
||||
fStatusMsk(statmsk),
|
||||
fDataVal(0),
|
||||
fDataMsk(0xffff),
|
||||
fBlockVal(),
|
||||
fBlockMsk()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RlinkCommandExpect::RlinkCommandExpect(uint8_t stat, uint8_t statmsk,
|
||||
uint16_t data, uint16_t datamsk)
|
||||
: fStatusVal(stat),
|
||||
fStatusMsk(statmsk),
|
||||
fDataVal(data),
|
||||
fDataMsk(datamsk),
|
||||
fBlockVal(),
|
||||
fBlockMsk()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RlinkCommandExpect::RlinkCommandExpect(uint8_t stat, uint8_t statmsk,
|
||||
const std::vector<uint16_t>& block)
|
||||
: fStatusVal(stat),
|
||||
fStatusMsk(statmsk),
|
||||
fDataVal(0),
|
||||
fDataMsk(0xffff),
|
||||
fBlockVal(block),
|
||||
fBlockMsk()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RlinkCommandExpect::RlinkCommandExpect(uint8_t stat, uint8_t statmsk,
|
||||
const std::vector<uint16_t>& block,
|
||||
const std::vector<uint16_t>& blockmsk)
|
||||
: fStatusVal(stat),
|
||||
fStatusMsk(statmsk),
|
||||
fDataVal(0),
|
||||
fDataMsk(0xffff),
|
||||
fBlockVal(block),
|
||||
fBlockMsk(blockmsk)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkCommandExpect::~RlinkCommandExpect()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkCommandExpect::BlockCheck(size_t ind, uint16_t val) const
|
||||
{
|
||||
if (ind >= fBlockVal.size()) return true;
|
||||
uint16_t eval = fBlockVal[ind];
|
||||
uint16_t emsk = (ind < fBlockMsk.size()) ? fBlockMsk[ind] : 0x0000;
|
||||
return (val|emsk) == (eval|emsk);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandExpect::BlockCheck(const uint16_t* pval, size_t size) const
|
||||
{
|
||||
size_t nerr = 0;
|
||||
for (size_t i=0; i<size; i++) {
|
||||
if (i >= fBlockVal.size()) break;
|
||||
uint16_t eval = fBlockVal[i];
|
||||
uint16_t emsk = (i < fBlockMsk.size()) ? fBlockMsk[i] : 0x0000;
|
||||
if ((pval[i]|emsk) != (eval|emsk)) nerr += 1;
|
||||
}
|
||||
|
||||
return nerr;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkCommandExpect::BlockIsChecked(size_t ind) const
|
||||
{
|
||||
if (ind >= fBlockVal.size()) return false;
|
||||
if (ind >= fBlockMsk.size()) return true;
|
||||
return fBlockMsk[ind] != 0xffff;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommandExpect::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkCommandExpect @ " << this << endl;
|
||||
|
||||
os << bl << " fStatusVal: " << RosPrintBvi(fStatusVal,0) << endl;
|
||||
os << bl << " fStatusMsk: " << RosPrintBvi(fStatusMsk,0) << endl;
|
||||
os << bl << " fDataVal: " << RosPrintBvi(fDataVal,0) << endl;
|
||||
os << bl << " fDataMsk: " << RosPrintBvi(fDataMsk,0) << endl;
|
||||
os << bl << " fBlockVal.size: " << RosPrintf(fBlockVal.size(),"d",3) << endl;
|
||||
os << bl << " fBlockMsk.size: " << RosPrintf(fBlockMsk.size(),"d",3) << endl;
|
||||
if (fBlockVal.size() > 0) {
|
||||
os << bl << " fBlockVal & Msk data: ";
|
||||
size_t width = (fBlockMsk.size()>0) ? 9 : 4;
|
||||
size_t ncol = max(1u, (80-ind-4-5)/(width+1));
|
||||
for (size_t i=0; i< fBlockVal.size(); i++) {
|
||||
if (i%ncol == 0) os << "\n" << bl << " " << RosPrintf(i,"d",3) << ": ";
|
||||
|
||||
os << RosPrintBvi(fBlockVal[i],16);
|
||||
if (fBlockMsk.size()>0) {
|
||||
if (i<fBlockMsk.size() && fBlockMsk[i]!=0x0000) {
|
||||
os << "," << RosPrintBvi(fBlockMsk[i],16);
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
os << " ";
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkCommandExpect_NoInline))
|
||||
#define inline
|
||||
#include "RlinkCommandExpect.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
89
tools/src/librlink/RlinkCommandExpect.hpp
Normal file
89
tools/src/librlink/RlinkCommandExpect.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// $Id: RlinkCommandExpect.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-12 368 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommandExpect.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkCommandExpect.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkCommandExpect
|
||||
#define included_Retro_RlinkCommandExpect 1
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkCommandExpect {
|
||||
public:
|
||||
|
||||
RlinkCommandExpect();
|
||||
explicit RlinkCommandExpect(uint8_t stat, uint8_t statmsk=0);
|
||||
RlinkCommandExpect(uint8_t stat, uint8_t statmsk,
|
||||
uint16_t data, uint16_t datamsk=0);
|
||||
RlinkCommandExpect(uint8_t stat, uint8_t statmsk,
|
||||
const std::vector<uint16_t>& block);
|
||||
RlinkCommandExpect(uint8_t stat, uint8_t statmsk,
|
||||
const std::vector<uint16_t>& block,
|
||||
const std::vector<uint16_t>& blockmsk);
|
||||
~RlinkCommandExpect();
|
||||
|
||||
void SetStatus(uint8_t stat, uint8_t statmsk=0);
|
||||
void SetData(uint16_t data, uint16_t datamsk=0);
|
||||
void SetBlock(const std::vector<uint16_t>& block);
|
||||
void SetBlock(const std::vector<uint16_t>& block,
|
||||
const std::vector<uint16_t>& blockmsk);
|
||||
|
||||
uint8_t StatusValue() const;
|
||||
uint8_t StatusMask() const;
|
||||
uint16_t DataValue() const;
|
||||
uint16_t DataMask() const;
|
||||
const std::vector<uint16_t>& BlockValue() const;
|
||||
const std::vector<uint16_t>& BlockMask() const;
|
||||
|
||||
bool StatusCheck(uint8_t val) const;
|
||||
bool DataCheck(uint16_t val) const;
|
||||
bool BlockCheck(size_t ind, uint16_t val) const;
|
||||
size_t BlockCheck(const uint16_t* pval, size_t size) const;
|
||||
|
||||
bool StatusIsChecked() const;
|
||||
bool DataIsChecked() const;
|
||||
bool BlockIsChecked(size_t ind) const;
|
||||
|
||||
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
protected:
|
||||
uint8_t fStatusVal; //!< status value
|
||||
uint8_t fStatusMsk; //!< status mask
|
||||
uint16_t fDataVal; //!< data value
|
||||
uint16_t fDataMsk; //!< data mask
|
||||
std::vector<uint16_t> fBlockVal; //!< block value
|
||||
std::vector<uint16_t> fBlockMsk; //!< block mask
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkCommandExpect_NoInline))
|
||||
#include "RlinkCommandExpect.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
150
tools/src/librlink/RlinkCommandExpect.ipp
Normal file
150
tools/src/librlink/RlinkCommandExpect.ipp
Normal file
@@ -0,0 +1,150 @@
|
||||
// $Id: RlinkCommandExpect.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-12 368 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommandExpect.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of class RlinkCommandExpect.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommandExpect::SetStatus(uint8_t stat, uint8_t statmsk)
|
||||
{
|
||||
fStatusVal = stat;
|
||||
fStatusMsk = statmsk;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommandExpect::SetData(uint16_t data, uint16_t datamsk)
|
||||
{
|
||||
fDataVal = data;
|
||||
fDataMsk = datamsk;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommandExpect::SetBlock(const std::vector<uint16_t>& block)
|
||||
{
|
||||
fBlockVal = block;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline void RlinkCommandExpect::SetBlock(
|
||||
const std::vector<uint16_t>& block,
|
||||
const std::vector<uint16_t>& blockmsk)
|
||||
{
|
||||
fBlockVal = block;
|
||||
fBlockMsk = blockmsk;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommandExpect::StatusValue() const
|
||||
{
|
||||
return fStatusVal;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint8_t RlinkCommandExpect::StatusMask() const
|
||||
{
|
||||
return fStatusMsk;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint16_t RlinkCommandExpect::DataValue() const
|
||||
{
|
||||
return fDataVal;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline uint16_t RlinkCommandExpect::DataMask() const
|
||||
{
|
||||
return fDataMsk;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline const std::vector<uint16_t>& RlinkCommandExpect::BlockValue() const
|
||||
{
|
||||
return fBlockVal;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline const std::vector<uint16_t>& RlinkCommandExpect::BlockMask() const
|
||||
{
|
||||
return fBlockMsk;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommandExpect::StatusCheck(uint8_t val) const
|
||||
{
|
||||
return (val|fStatusMsk) == (fStatusVal|fStatusMsk);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommandExpect::DataCheck(uint16_t val) const
|
||||
{
|
||||
return (val|fDataMsk) == (fDataVal|fDataMsk);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommandExpect::StatusIsChecked() const
|
||||
{
|
||||
return fStatusMsk != 0xff;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline bool RlinkCommandExpect::DataIsChecked() const
|
||||
{
|
||||
return fDataMsk != 0xffff;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
284
tools/src/librlink/RlinkCommandList.cpp
Normal file
284
tools/src/librlink/RlinkCommandList.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
// $Id: RlinkCommandList.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-05 366 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommandList.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of class RlinkCommandList.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "RlinkCommandList.hpp"
|
||||
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librtools/RosFill.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkCommandList
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkCommandList::RlinkCommandList()
|
||||
: fList()
|
||||
{
|
||||
fList.reserve(16); // should prevent most re-alloc's
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Copy constructor
|
||||
|
||||
RlinkCommandList::RlinkCommandList(const RlinkCommandList& rhs)
|
||||
: fList()
|
||||
{
|
||||
operator=(rhs);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkCommandList::~RlinkCommandList()
|
||||
{
|
||||
for (size_t i=0; i<fList.size(); i++) delete fList[i];
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddCommand(RlinkCommand* cmd)
|
||||
{
|
||||
size_t ind = fList.size();
|
||||
fList.push_back(cmd);
|
||||
return ind;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddCommand(const RlinkCommand& cmd)
|
||||
{
|
||||
return AddCommand(new RlinkCommand(cmd));
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddCommand(const RlinkCommandList& clist)
|
||||
{
|
||||
size_t ind = fList.size();
|
||||
for (size_t i=0; i<clist.Size(); i++) {
|
||||
AddCommand(new RlinkCommand(clist[i]));
|
||||
}
|
||||
return ind;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddRreg(uint16_t addr)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdRreg(addr);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddRblk(uint16_t addr, size_t size)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdRblk(addr, size);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddRblk(uint16_t addr, uint16_t* block, size_t size)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdRblk(addr, block, size);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddWreg(uint16_t addr, uint16_t data)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdWreg(addr, data);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddWblk(uint16_t addr, std::vector<uint16_t> block)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdWblk(addr, block);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddWblk(uint16_t addr, const uint16_t* block,
|
||||
size_t size)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdWblk(addr, block, size);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddStat()
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdStat();
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddAttn()
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdAttn();
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
size_t RlinkCommandList::AddInit(uint16_t addr, uint16_t data)
|
||||
{
|
||||
RlinkCommand* pcmd = new RlinkCommand();
|
||||
pcmd->CmdInit(addr, data);
|
||||
return AddCommand(pcmd);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommandList::LastVolatile()
|
||||
{
|
||||
if (fList.size() == 0)
|
||||
throw out_of_range("RlinkCommandList::LastExpect: list empty");
|
||||
fList[fList.size()-1]->SetFlagBit(RlinkCommand::kFlagVol);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommandList::LastExpect(RlinkCommandExpect* exp)
|
||||
{
|
||||
if (fList.size() == 0)
|
||||
throw out_of_range("RlinkCommandList::LastExpect: list empty");
|
||||
fList[fList.size()-1]->SetExpect(exp);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommandList::Clear()
|
||||
{
|
||||
|
||||
fList.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommandList::Print(std::ostream& os, const RlinkAddrMap* pamap,
|
||||
size_t abase, size_t dbase, size_t sbase) const
|
||||
{
|
||||
for (size_t i=0; i<fList.size(); i++) {
|
||||
fList[i]->Print(os, pamap, abase, dbase, sbase);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkCommandList::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkCommandList @ " << this << endl;
|
||||
|
||||
for (size_t i=0; i<Size(); i++) {
|
||||
string pref("fList[");
|
||||
pref << RosPrintf(i) << RosPrintf("]: ");
|
||||
fList[i]->Dump(os, ind+2, pref.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RlinkCommandList&
|
||||
Retro::RlinkCommandList::operator=( const RlinkCommandList& rhs)
|
||||
{
|
||||
if (&rhs == this) return *this;
|
||||
for (size_t i=0; i<fList.size(); i++) delete fList[i];
|
||||
fList.clear();
|
||||
for (size_t i=0; i<rhs.Size(); i++) AddCommand(rhs[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
Retro::RlinkCommand& Retro::RlinkCommandList::operator[](size_t ind)
|
||||
{
|
||||
return *fList.at(ind);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
const Retro::RlinkCommand& Retro::RlinkCommandList::operator[](size_t ind) const
|
||||
{
|
||||
return *fList.at(ind);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkCommandList_NoInline))
|
||||
#define inline
|
||||
#include "RlinkCommandList.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
89
tools/src/librlink/RlinkCommandList.hpp
Normal file
89
tools/src/librlink/RlinkCommandList.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// $Id: RlinkCommandList.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-05 366 1.0 Initial version
|
||||
// 2011-01-09 354 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommandList.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkCommandList.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkCommandList
|
||||
#define included_Retro_RlinkCommandList 1
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include "RlinkCommandExpect.hpp"
|
||||
#include "RlinkCommand.hpp"
|
||||
#include "RlinkAddrMap.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkCommandList {
|
||||
public:
|
||||
|
||||
RlinkCommandList();
|
||||
RlinkCommandList(const RlinkCommandList&);
|
||||
~RlinkCommandList();
|
||||
|
||||
size_t AddCommand(RlinkCommand* cmd);
|
||||
size_t AddCommand(const RlinkCommand& cmd);
|
||||
size_t AddCommand(const RlinkCommandList& clist);
|
||||
size_t AddRreg(uint16_t addr);
|
||||
size_t AddRblk(uint16_t addr, size_t size);
|
||||
size_t AddRblk(uint16_t addr, uint16_t* block, size_t size);
|
||||
size_t AddWreg(uint16_t addr, uint16_t data);
|
||||
size_t AddWblk(uint16_t addr, std::vector<uint16_t> block);
|
||||
size_t AddWblk(uint16_t addr, const uint16_t* block, size_t size);
|
||||
size_t AddStat();
|
||||
size_t AddAttn();
|
||||
size_t AddInit(uint16_t addr, uint16_t data);
|
||||
|
||||
void LastVolatile();
|
||||
void LastExpect(RlinkCommandExpect* exp);
|
||||
|
||||
void Clear();
|
||||
size_t Size() const;
|
||||
|
||||
void Print(std::ostream& os, const RlinkAddrMap* pamap=0,
|
||||
size_t abase=16, size_t dbase=16,
|
||||
size_t sbase=16) const;
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
RlinkCommandList& operator=(const RlinkCommandList& rhs);
|
||||
|
||||
RlinkCommand& operator[](size_t ind);
|
||||
const RlinkCommand& operator[](size_t ind) const;
|
||||
|
||||
protected:
|
||||
std::vector<RlinkCommand*> fList; //!< vector of commands
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RlinkCommandList& obj);
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkCommandList_NoInline))
|
||||
#include "RlinkCommandList.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
50
tools/src/librlink/RlinkCommandList.ipp
Normal file
50
tools/src/librlink/RlinkCommandList.ipp
Normal file
@@ -0,0 +1,50 @@
|
||||
// $Id: RlinkCommandList.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-05 366 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCommandList.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of class RlinkCommandList.
|
||||
*/
|
||||
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
inline size_t RlinkCommandList::Size() const
|
||||
{
|
||||
return fList.size();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
/*!
|
||||
\relates RlinkCommandList
|
||||
\brief ostream insertion operator.
|
||||
*/
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const RlinkCommandList& obj)
|
||||
{
|
||||
obj.Print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
504
tools/src/librlink/RlinkConnect.cpp
Normal file
504
tools/src/librlink/RlinkConnect.cpp
Normal file
@@ -0,0 +1,504 @@
|
||||
// $Id: RlinkConnect.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-04-02 375 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkConnect.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of RlinkConnect.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "RlinkConnect.hpp"
|
||||
#include "RlinkPortFactory.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librtools/RosPrintBvi.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkConnect
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkConnect::RlinkConnect()
|
||||
: fpPort(0),
|
||||
fTxPkt(),
|
||||
fRxPkt(),
|
||||
fAddrMap(),
|
||||
fStats(),
|
||||
fLogOpts(),
|
||||
fLogFile(&cout)
|
||||
{
|
||||
for (size_t i=0; i<8; i++) fSeqNumber[i] = 0;
|
||||
|
||||
fStats.Define(kStatNExec, "NExec", "Exec() calls");
|
||||
fStats.Define(kStatNSplitVol, "NSplitVol", "clist splits: Volatile");
|
||||
fStats.Define(kStatNExecPart, "NExecPart", "ExecPart() calls");
|
||||
fStats.Define(kStatNCmd, "NCmd", "commands executed");
|
||||
fStats.Define(kStatNRreg, "NRreg", "rreg commands");
|
||||
fStats.Define(kStatNRblk, "NRblk", "rblk commands");
|
||||
fStats.Define(kStatNWreg, "NWreg", "wreg commands");
|
||||
fStats.Define(kStatNWblk, "NWblk", "wblk commands");
|
||||
fStats.Define(kStatNStat, "NStat", "stat commands");
|
||||
fStats.Define(kStatNAttn, "NAttn", "attn commands");
|
||||
fStats.Define(kStatNInit, "NInit", "init commands");
|
||||
fStats.Define(kStatNRblkWord, "NRblkWord", "words rcvd with rblk");
|
||||
fStats.Define(kStatNWblkWord, "NWblkWord", "words send with wblk");
|
||||
fStats.Define(kStatNTxPktByt, "NTxPktByt", "Tx packet bytes send");
|
||||
fStats.Define(kStatNTxEsc, "NTxEsc", "Tx escapes");
|
||||
fStats.Define(kStatNRxPktByt, "NRxPktByt", "Rx packet bytes rcvd");
|
||||
fStats.Define(kStatNRxEsc, "NRxEsc", "Rx escapes");
|
||||
fStats.Define(kStatNRxAttn, "NRxAttn", "Rx ATTN commas seen");
|
||||
fStats.Define(kStatNRxIdle, "NRxIdle", "Rx IDLE commas seen");
|
||||
fStats.Define(kStatNRxDrop, "NRxDrop", "Rx bytes droped");
|
||||
fStats.Define(kStatNExpData, "NExpData", "Expect() for data defined");
|
||||
fStats.Define(kStatNExpStat, "NExpStat", "Expect() for stat defined");
|
||||
fStats.Define(kStatNChkData, "NChkData", "expect data failed");
|
||||
fStats.Define(kStatNChkStat, "NChkStat", "expect stat failed");
|
||||
fStats.Define(kStatNSndOob, "NSndOob", "SndOob() calls");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkConnect::~RlinkConnect()
|
||||
{
|
||||
delete fpPort;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkConnect::Open(const std::string& name, RerrMsg& emsg)
|
||||
{
|
||||
if (fpPort) Close();
|
||||
|
||||
fpPort = RlinkPortFactory::Open(name, emsg);
|
||||
if (!fpPort) return false;
|
||||
|
||||
fpPort->SetLogFile(&fLogFile);
|
||||
fpPort->SetTraceLevel(fLogOpts.tracelevel);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkConnect::Close()
|
||||
{
|
||||
if (!fpPort)
|
||||
throw logic_error("RlinkConnect::PortClose(): no port connected");
|
||||
|
||||
if (fpPort->UrlFindOpt("keep")) {
|
||||
RerrMsg emsg;
|
||||
fTxPkt.SndKeep(fpPort, emsg);
|
||||
}
|
||||
|
||||
delete fpPort;
|
||||
fpPort = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkConnect::Exec(RlinkCommandList& clist, RerrMsg& emsg)
|
||||
{
|
||||
if (clist.Size() == 0)
|
||||
throw invalid_argument("RlinkConnect::Exec(): clist empty");
|
||||
if (! IsOpen())
|
||||
throw logic_error("RlinkConnect::Exec(): port not open");
|
||||
|
||||
fStats.Inc(kStatNExec);
|
||||
|
||||
size_t ibeg = 0;
|
||||
size_t size = clist.Size();
|
||||
|
||||
for (size_t i=0; i<size; i++) {
|
||||
RlinkCommand& cmd = clist[i];
|
||||
if (!cmd.TestFlagAny(RlinkCommand::kFlagInit))
|
||||
throw invalid_argument("RlinkConnect::Exec(): command not initialized");
|
||||
if (cmd.Command() > RlinkCommand::kCmdInit)
|
||||
throw invalid_argument("RlinkConnect::Exec(): invalid command code");
|
||||
cmd.ClearFlagBit(RlinkCommand::kFlagSend | RlinkCommand::kFlagDone |
|
||||
RlinkCommand::kFlagPktBeg | RlinkCommand::kFlagPktEnd |
|
||||
RlinkCommand::kFlagRecov | RlinkCommand::kFlagResend |
|
||||
RlinkCommand::kFlagErrNak | RlinkCommand::kFlagErrMiss |
|
||||
RlinkCommand::kFlagErrCmd | RlinkCommand::kFlagErrCrc);
|
||||
}
|
||||
|
||||
while (ibeg < size) {
|
||||
size_t iend = ibeg;
|
||||
for (size_t i=ibeg; i<size; i++) {
|
||||
iend = i;
|
||||
if (clist[i].TestFlagAll(RlinkCommand::kFlagVol)) {
|
||||
fStats.Inc(kStatNSplitVol);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool rc = ExecPart(clist, ibeg, iend, emsg);
|
||||
if (!rc) return rc;
|
||||
ibeg = iend+1;
|
||||
}
|
||||
|
||||
bool checkseen = false;
|
||||
bool errorseen = false;
|
||||
|
||||
for (size_t i=0; i<size; i++) {
|
||||
RlinkCommand& cmd = clist[i];
|
||||
|
||||
checkseen |= cmd.TestFlagAny(RlinkCommand::kFlagChkStat |
|
||||
RlinkCommand::kFlagChkData);
|
||||
errorseen |= cmd.TestFlagAny(RlinkCommand::kFlagErrNak |
|
||||
RlinkCommand::kFlagErrMiss |
|
||||
RlinkCommand::kFlagErrCmd |
|
||||
RlinkCommand::kFlagErrCrc);
|
||||
}
|
||||
|
||||
size_t loglevel = 3;
|
||||
if (checkseen) loglevel = 2;
|
||||
if (errorseen) loglevel = 1;
|
||||
if (loglevel <= fLogOpts.printlevel)
|
||||
clist.Print(fLogFile(), &AddrMap(), fLogOpts.baseaddr, fLogOpts.basedata,
|
||||
fLogOpts.basestat);
|
||||
if (loglevel <= fLogOpts.dumplevel)
|
||||
clist.Dump(fLogFile(), 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkConnect::ExecPart(RlinkCommandList& clist, size_t ibeg, size_t iend,
|
||||
RerrMsg& emsg)
|
||||
{
|
||||
if (ibeg<0 || ibeg>iend || iend>=clist.Size())
|
||||
throw invalid_argument("RlinkConnect::ExecPart(): ibeg or iend invalid");
|
||||
if (!IsOpen())
|
||||
throw logic_error("RlinkConnect::ExecPart(): port not open");
|
||||
|
||||
fStats.Inc(kStatNExecPart);
|
||||
|
||||
size_t nrcvtot = 0;
|
||||
fTxPkt.Init();
|
||||
|
||||
for (size_t i=ibeg; i<=iend; i++) {
|
||||
RlinkCommand& cmd = clist[i];
|
||||
uint8_t ccode = cmd.Command();
|
||||
size_t ndata = cmd.BlockSize();
|
||||
uint16_t* pdata = cmd.BlockPointer();
|
||||
|
||||
fStats.Inc(kStatNCmd);
|
||||
|
||||
cmd.SetSeqNumber(fSeqNumber[ccode]++);
|
||||
cmd.ClearFlagBit(RlinkCommand::kFlagPktBeg | RlinkCommand::kFlagPktEnd);
|
||||
|
||||
fTxPkt.PutWithCrc(cmd.Request());
|
||||
|
||||
switch(ccode) {
|
||||
case RlinkCommand::kCmdRreg:
|
||||
fStats.Inc(kStatNRreg);
|
||||
cmd.SetRcvSize(1+2+1+1); // rcv: cmd+data+stat+crc
|
||||
fTxPkt.PutWithCrc((uint8_t)cmd.Address());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdRblk:
|
||||
fStats.Inc(kStatNRblk);
|
||||
fStats.Inc(kStatNRblkWord, (double) ndata);
|
||||
cmd.SetRcvSize(1+1+2*ndata+1+1); // rcv: cmd+nblk+n*data+stat+crc
|
||||
fTxPkt.PutWithCrc((uint8_t)cmd.Address());
|
||||
fTxPkt.PutWithCrc((uint8_t)(ndata-1));
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdWreg:
|
||||
fStats.Inc(kStatNWreg);
|
||||
cmd.SetRcvSize(1+1+1); // rcv: cmd+stat+crc
|
||||
fTxPkt.PutWithCrc((uint8_t)cmd.Address());
|
||||
fTxPkt.PutWithCrc(cmd.Data());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdWblk:
|
||||
fStats.Inc(kStatNWblk);
|
||||
fStats.Inc(kStatNWblkWord, (double) ndata);
|
||||
cmd.SetRcvSize(1+1+1); // rcv: cmd+stat+crc
|
||||
fTxPkt.PutWithCrc((uint8_t)cmd.Address());
|
||||
fTxPkt.PutWithCrc((uint8_t)(ndata-1));
|
||||
fTxPkt.PutCrc();
|
||||
for (size_t j=0; j<ndata; j++) fTxPkt.PutWithCrc(*pdata++);
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdStat:
|
||||
fStats.Inc(kStatNStat);
|
||||
cmd.SetRcvSize(1+1+2+1+1); // rcv: cmd+ccmd+data+stat+crc
|
||||
break;
|
||||
case RlinkCommand::kCmdAttn:
|
||||
fStats.Inc(kStatNAttn);
|
||||
cmd.SetRcvSize(1+2+1+1); // rcv: cmd+data+stat+crc
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdInit:
|
||||
fStats.Inc(kStatNInit);
|
||||
cmd.SetRcvSize(1+1+1); // rcv: cmd+stat+crc
|
||||
fTxPkt.PutWithCrc((uint8_t)cmd.Address());
|
||||
fTxPkt.PutWithCrc(cmd.Data());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw logic_error("RlinkConnect::Exec(): invalid command");
|
||||
}
|
||||
|
||||
fTxPkt.PutCrc();
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagSend);
|
||||
nrcvtot += cmd.RcvSize();
|
||||
}
|
||||
|
||||
clist[ibeg].SetFlagBit(RlinkCommand::kFlagPktBeg);
|
||||
clist[iend].SetFlagBit(RlinkCommand::kFlagPktEnd);
|
||||
|
||||
// FIXME_code: handle send fail properly;
|
||||
if (!fTxPkt.SndPacket(fpPort, emsg)) return false;
|
||||
fStats.Inc(kStatNTxPktByt, double(fTxPkt.PktSize()));
|
||||
fStats.Inc(kStatNTxEsc , double(fTxPkt.Nesc()));
|
||||
|
||||
fRxPkt.Init();
|
||||
// FIXME_code: handle timeout properly; parametrize timeout
|
||||
if (!fRxPkt.RcvPacket(fpPort, nrcvtot, 1.0, emsg)) return false;
|
||||
fStats.Inc(kStatNRxPktByt, double(fRxPkt.PktSize()));
|
||||
fStats.Inc(kStatNRxEsc , double(fRxPkt.Nesc()));
|
||||
fStats.Inc(kStatNRxAttn , double(fRxPkt.Nattn()));
|
||||
fStats.Inc(kStatNRxIdle , double(fRxPkt.Nidle()));
|
||||
fStats.Inc(kStatNRxDrop , double(fRxPkt.Ndrop()));
|
||||
|
||||
size_t ncmd = 0;
|
||||
|
||||
for (size_t i=ibeg; i<=iend; i++) {
|
||||
RlinkCommand& cmd = clist[i];
|
||||
uint8_t ccode = cmd.Command();
|
||||
size_t ndata = cmd.BlockSize();
|
||||
uint16_t* pdata = cmd.BlockPointer();
|
||||
|
||||
if (!fRxPkt.CheckSize(cmd.RcvSize())) { // not enough data for cmd
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrMiss);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fRxPkt.Get8WithCrc() != cmd.Request()) { // command mismatch
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrCmd);
|
||||
break;
|
||||
}
|
||||
|
||||
// check length mismatch in rblk here (simpler than multi-level break)
|
||||
if (ccode == RlinkCommand::kCmdRblk) {
|
||||
if (fRxPkt.Get8WithCrc() != (uint8_t)(ndata-1)) { // length mismatch
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrCmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(ccode) {
|
||||
case RlinkCommand::kCmdRreg:
|
||||
cmd.SetData(fRxPkt.Get16WithCrc());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdRblk:
|
||||
// length was consumed and tested already before switch()..
|
||||
for (size_t j=0; j<ndata; j++) *pdata++ = fRxPkt.Get16WithCrc();
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdWreg:
|
||||
case RlinkCommand::kCmdWblk:
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdStat:
|
||||
cmd.SetStatRequest(fRxPkt.Get8WithCrc());
|
||||
cmd.SetData(fRxPkt.Get16WithCrc());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdAttn:
|
||||
cmd.SetData(fRxPkt.Get16WithCrc());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdInit:
|
||||
break;
|
||||
}
|
||||
|
||||
cmd.SetStatus(fRxPkt.Get8WithCrc());
|
||||
if (!fRxPkt.CheckCrc()) { // crc mismatch
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrCrc);
|
||||
//fStats.Inc(kStatNRxCcrc);
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME_code: proper wblk dcrc handling...
|
||||
if (ccode == RlinkCommand::kCmdWblk) {
|
||||
// FIXME_code: check for dcrc flag...
|
||||
if (false) {
|
||||
//fStats.Inc(kStatNRxDcrc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagDone);
|
||||
ncmd += 1;
|
||||
|
||||
if (cmd.Expect()) {
|
||||
RlinkCommandExpect& expect = *cmd.Expect();
|
||||
if (expect.DataIsChecked() ||
|
||||
expect.BlockValue().size()>0) fStats.Inc(kStatNExpData);
|
||||
if (expect.StatusIsChecked()) fStats.Inc(kStatNExpStat);
|
||||
|
||||
if (ccode==RlinkCommand::kCmdRreg || ccode==RlinkCommand::kCmdStat ||
|
||||
ccode==RlinkCommand::kCmdAttn) {
|
||||
if (!expect.DataCheck(cmd.Data())) {
|
||||
fStats.Inc(kStatNChkData);
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagChkData);
|
||||
}
|
||||
} else if (ccode==RlinkCommand::kCmdRblk) {
|
||||
size_t nerr = expect.BlockCheck(cmd.BlockPointer(), cmd.BlockSize());
|
||||
if (nerr != 0) {
|
||||
fStats.Inc(kStatNChkData);
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagChkData);
|
||||
}
|
||||
}
|
||||
if (!expect.StatusCheck(cmd.Status())) {
|
||||
fStats.Inc(kStatNChkStat);
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagChkStat);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// FIXME_code: add proper error handling...
|
||||
if (ncmd != iend-ibeg+1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
double RlinkConnect::WaitAttn(double timeout, RerrMsg& emsg)
|
||||
{
|
||||
double rval = fRxPkt.WaitAttn(fpPort, timeout, emsg);
|
||||
fStats.Inc(kStatNRxAttn , double(fRxPkt.Nattn()));
|
||||
fStats.Inc(kStatNRxIdle , double(fRxPkt.Nidle()));
|
||||
fStats.Inc(kStatNRxDrop , double(fRxPkt.Ndrop()));
|
||||
return rval;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkConnect::SndOob(uint16_t addr, uint16_t data, RerrMsg& emsg)
|
||||
{
|
||||
fStats.Inc(kStatNSndOob);
|
||||
return fTxPkt.SndOob(fpPort, addr, data, emsg);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkConnect::LogOpen(const std::string& name)
|
||||
{
|
||||
if (!fLogFile.Open(name)) {
|
||||
fLogFile.UseStream(&cout);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkConnect::LogUseStream(std::ostream* pstr)
|
||||
{
|
||||
fLogFile.UseStream(pstr);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkConnect::SetLogOpts(const LogOpts& opts)
|
||||
{
|
||||
if (opts.baseaddr!=2 && opts.baseaddr!=8 && opts.baseaddr!=16)
|
||||
throw invalid_argument("RlinkConnect::SetLogOpts(): baseaddr != 2,8,16");
|
||||
if (opts.basedata!=2 && opts.basedata!=8 && opts.basedata!=16)
|
||||
throw invalid_argument("RlinkConnect::SetLogOpts(): basedata != 2,8,16");
|
||||
if (opts.basestat!=2 && opts.basestat!=8 && opts.basestat!=16)
|
||||
throw invalid_argument("RlinkConnect::SetLogOpts(): basestat != 2,8,16");
|
||||
|
||||
fLogOpts = opts;
|
||||
if (fpPort) fpPort->SetTraceLevel(opts.tracelevel);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkConnect::Print(std::ostream& os) const
|
||||
{
|
||||
os << "RlinkConnect::Print(std::ostream& os)" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkConnect::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkConnect @ " << this << endl;
|
||||
|
||||
if (fpPort) {
|
||||
fpPort->Dump(os, ind+2, "fpPort: ");
|
||||
} else {
|
||||
os << bl << " fpPort: " << fpPort << endl;
|
||||
}
|
||||
|
||||
os << bl << " fSeqNumber: ";
|
||||
for (size_t i=0; i<8; i++) os << RosPrintBvi(fSeqNumber[i],16) << " ";
|
||||
os << endl;
|
||||
|
||||
fTxPkt.Dump(os, ind+2, "fTxPkt: ");
|
||||
fRxPkt.Dump(os, ind+2, "fRxPkt: ");
|
||||
fAddrMap.Dump(os, ind+2, "fAddrMap: ");
|
||||
fStats.Dump(os, ind+2, "fStats: ");
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkConnect_NoInline))
|
||||
#define inline
|
||||
#include "RlinkConnect.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
147
tools/src/librlink/RlinkConnect.hpp
Normal file
147
tools/src/librlink/RlinkConnect.hpp
Normal file
@@ -0,0 +1,147 @@
|
||||
// $Id: RlinkConnect.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-04-02 375 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkConnect.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class \c RlinkConnect.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkConnect
|
||||
#define included_Retro_RlinkConnect 1
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
#include "librtools/RerrMsg.hpp"
|
||||
#include "librtools/Rstats.hpp"
|
||||
#include "librtools/RlogFile.hpp"
|
||||
|
||||
#include "RlinkPort.hpp"
|
||||
#include "RlinkCommandList.hpp"
|
||||
#include "RlinkPacketBuf.hpp"
|
||||
#include "RlinkAddrMap.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkConnect {
|
||||
public:
|
||||
struct LogOpts {
|
||||
size_t baseaddr;
|
||||
size_t basedata;
|
||||
size_t basestat;
|
||||
size_t printlevel; // 0=off,1=err,2=chk,3=all
|
||||
size_t dumplevel; // 0=off,1=err,2=chk,3=all
|
||||
size_t tracelevel; // 0=off,1=buf,2=char
|
||||
|
||||
LogOpts()
|
||||
: baseaddr(16), basedata(16), basestat(16),
|
||||
printlevel(0), dumplevel(0), tracelevel(0)
|
||||
{}
|
||||
};
|
||||
|
||||
RlinkConnect();
|
||||
~RlinkConnect();
|
||||
|
||||
bool Open(const std::string& name, RerrMsg& emsg);
|
||||
void Close();
|
||||
bool IsOpen() const;
|
||||
RlinkPort* Port() const;
|
||||
|
||||
bool Exec(RlinkCommandList& clist, RerrMsg& emsg);
|
||||
bool ExecPart(RlinkCommandList& clist, size_t ibeg, size_t iend,
|
||||
RerrMsg& emsg);
|
||||
|
||||
double WaitAttn(double timeout, RerrMsg& emsg);
|
||||
bool SndOob(uint16_t addr, uint16_t data, RerrMsg& emsg);
|
||||
|
||||
bool AddrMapInsert(const std::string& name, uint16_t addr);
|
||||
bool AddrMapErase(const std::string& name);
|
||||
bool AddrMapErase(uint16_t addr);
|
||||
void AddrMapClear();
|
||||
|
||||
const RlinkAddrMap& AddrMap() const;
|
||||
const Rstats& Stats() const;
|
||||
|
||||
bool LogOpen(const std::string& name);
|
||||
void LogUseStream(std::ostream* pstr);
|
||||
void SetLogOpts(const LogOpts& opts);
|
||||
const LogOpts& GetLogOpts() const;
|
||||
RlogFile& LogFile() const;
|
||||
|
||||
void Print(std::ostream& os) const;
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
|
||||
// statistics counter indices
|
||||
enum stats {
|
||||
kStatNExec = 0,
|
||||
kStatNSplitVol,
|
||||
kStatNExecPart,
|
||||
kStatNCmd,
|
||||
kStatNRreg,
|
||||
kStatNRblk,
|
||||
kStatNWreg,
|
||||
kStatNWblk,
|
||||
kStatNStat,
|
||||
kStatNAttn,
|
||||
kStatNInit,
|
||||
kStatNRblkWord,
|
||||
kStatNWblkWord,
|
||||
kStatNTxPktByt,
|
||||
kStatNTxEsc,
|
||||
kStatNRxPktByt,
|
||||
kStatNRxEsc,
|
||||
kStatNRxAttn,
|
||||
kStatNRxIdle,
|
||||
kStatNRxDrop,
|
||||
kStatNExpData,
|
||||
kStatNExpStat,
|
||||
kStatNChkData,
|
||||
kStatNChkStat,
|
||||
kStatNSndOob,
|
||||
kDimStat
|
||||
};
|
||||
|
||||
protected:
|
||||
RlinkPort* fpPort; //!< ptr to port
|
||||
uint8_t fSeqNumber[8]; //!< command sequence number
|
||||
RlinkPacketBuf fTxPkt; //!< transmit packet buffer
|
||||
RlinkPacketBuf fRxPkt; //!< receive packet buffer
|
||||
RlinkAddrMap fAddrMap; //!< name<->address mapping
|
||||
Rstats fStats; //!< statistics
|
||||
LogOpts fLogOpts; //!< log options
|
||||
RlogFile fLogFile; //!< connection log file
|
||||
|
||||
// RlinkConnect is not copyable and assignable
|
||||
private:
|
||||
RlinkConnect(const RlinkConnect& rhs);
|
||||
RlinkConnect& operator=(const RlinkConnect& rhs);
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkConnect_NoInline))
|
||||
#include "RlinkConnect.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
110
tools/src/librlink/RlinkConnect.ipp
Normal file
110
tools/src/librlink/RlinkConnect.ipp
Normal file
@@ -0,0 +1,110 @@
|
||||
// $Id: RlinkConnect.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-04-02 375 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkConnect.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of RlinkConnect.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkConnect::IsOpen() const
|
||||
{
|
||||
return fpPort && fpPort->IsOpen();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline RlinkPort* RlinkConnect::Port() const
|
||||
{
|
||||
return fpPort;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkConnect::AddrMapInsert(const std::string& name, uint16_t addr)
|
||||
{
|
||||
return fAddrMap.Insert(name, addr);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkConnect::AddrMapErase(const std::string& name)
|
||||
{
|
||||
return fAddrMap.Erase(name);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkConnect::AddrMapErase(uint16_t addr)
|
||||
{
|
||||
return fAddrMap.Erase(addr);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkConnect::AddrMapClear()
|
||||
{
|
||||
return fAddrMap.Clear();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const RlinkAddrMap& RlinkConnect::AddrMap() const
|
||||
{
|
||||
return fAddrMap;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const Rstats& RlinkConnect::Stats() const
|
||||
{
|
||||
return fStats;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const RlinkConnect::LogOpts& RlinkConnect::GetLogOpts() const
|
||||
{
|
||||
return fLogOpts;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline RlogFile& RlinkConnect::LogFile() const
|
||||
{
|
||||
return (RlogFile&)fLogFile;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Retro
|
||||
81
tools/src/librlink/RlinkCrc8.cpp
Normal file
81
tools/src/librlink/RlinkCrc8.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// $Id: RlinkCrc8.cpp 365 2011-02-28 07:28:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-02-27 365 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCrc8.cpp 365 2011-02-28 07:28:26Z mueller $
|
||||
\brief Implemenation of class RlinkCrc8.
|
||||
*/
|
||||
|
||||
#include "RlinkCrc8.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkCrc8
|
||||
\brief FIXME_text
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
// from gen_crc8_tbl
|
||||
|
||||
const uint8_t RlinkCrc8::fCrc8Table[256] =
|
||||
{
|
||||
0, 29, 58, 39, 116, 105, 78, 83,
|
||||
232, 245, 210, 207, 156, 129, 166, 187,
|
||||
205, 208, 247, 234, 185, 164, 131, 158,
|
||||
37, 56, 31, 2, 81, 76, 107, 118,
|
||||
135, 154, 189, 160, 243, 238, 201, 212,
|
||||
111, 114, 85, 72, 27, 6, 33, 60,
|
||||
74, 87, 112, 109, 62, 35, 4, 25,
|
||||
162, 191, 152, 133, 214, 203, 236, 241,
|
||||
19, 14, 41, 52, 103, 122, 93, 64,
|
||||
251, 230, 193, 220, 143, 146, 181, 168,
|
||||
222, 195, 228, 249, 170, 183, 144, 141,
|
||||
54, 43, 12, 17, 66, 95, 120, 101,
|
||||
148, 137, 174, 179, 224, 253, 218, 199,
|
||||
124, 97, 70, 91, 8, 21, 50, 47,
|
||||
89, 68, 99, 126, 45, 48, 23, 10,
|
||||
177, 172, 139, 150, 197, 216, 255, 226,
|
||||
38, 59, 28, 1, 82, 79, 104, 117,
|
||||
206, 211, 244, 233, 186, 167, 128, 157,
|
||||
235, 246, 209, 204, 159, 130, 165, 184,
|
||||
3, 30, 57, 36, 119, 106, 77, 80,
|
||||
161, 188, 155, 134, 213, 200, 239, 242,
|
||||
73, 84, 115, 110, 61, 32, 7, 26,
|
||||
108, 113, 86, 75, 24, 5, 34, 63,
|
||||
132, 153, 190, 163, 240, 237, 202, 215,
|
||||
53, 40, 15, 18, 65, 92, 123, 102,
|
||||
221, 192, 231, 250, 169, 180, 147, 142,
|
||||
248, 229, 194, 223, 140, 145, 182, 171,
|
||||
16, 13, 42, 55, 100, 121, 94, 67,
|
||||
178, 175, 136, 149, 198, 219, 252, 225,
|
||||
90, 71, 96, 125, 46, 51, 20, 9,
|
||||
127, 98, 69, 88, 11, 22, 49, 44,
|
||||
151, 138, 173, 176, 227, 254, 217, 196
|
||||
};
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkCrc8_NoInline))
|
||||
#define inline
|
||||
#include "RlinkCrc8.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
56
tools/src/librlink/RlinkCrc8.hpp
Normal file
56
tools/src/librlink/RlinkCrc8.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// $Id: RlinkCrc8.hpp 365 2011-02-28 07:28:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-02-27 365 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCrc8.hpp 365 2011-02-28 07:28:26Z mueller $
|
||||
\brief Declaration of class \c RlinkCrc8.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkCrc8
|
||||
#define included_Retro_RlinkCrc8 1
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkCrc8 {
|
||||
public:
|
||||
RlinkCrc8();
|
||||
~RlinkCrc8();
|
||||
|
||||
void Clear();
|
||||
void AddData(uint8_t data);
|
||||
uint8_t Crc() const;
|
||||
|
||||
protected:
|
||||
|
||||
uint8_t fCrc; //!< current crc value
|
||||
static const uint8_t fCrc8Table[256]; // doxed in cpp
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkCrc8_NoInline))
|
||||
#include "RlinkCrc8.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
68
tools/src/librlink/RlinkCrc8.ipp
Normal file
68
tools/src/librlink/RlinkCrc8.ipp
Normal file
@@ -0,0 +1,68 @@
|
||||
// $Id: RlinkCrc8.ipp 365 2011-02-28 07:28:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-02-27 365 1.0 Initial version
|
||||
// 2011-01-15 355 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkCrc8.ipp 365 2011-02-28 07:28:26Z mueller $
|
||||
\brief Implemenation (inline) of class RlinkCrc8.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
inline RlinkCrc8::RlinkCrc8()
|
||||
: fCrc(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
inline RlinkCrc8::~RlinkCrc8()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkCrc8::Clear()
|
||||
{
|
||||
fCrc = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkCrc8::AddData(uint8_t data)
|
||||
{
|
||||
fCrc = fCrc8Table[fCrc ^ data];
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline uint8_t RlinkCrc8::Crc() const
|
||||
{
|
||||
return fCrc;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
371
tools/src/librlink/RlinkPacketBuf.cpp
Normal file
371
tools/src/librlink/RlinkPacketBuf.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
// $Id: RlinkPacketBuf.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-04-02 375 1.0 Initial version
|
||||
// 2011-03-05 366 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPacketBuf.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of class RlinkPacketBuf.
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
// debug
|
||||
#include <iostream>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "RlinkPacketBuf.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librtools/RosPrintBvi.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkPacketBuf
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
// constants definitions
|
||||
|
||||
const uint32_t RlinkPacketBuf::kFlagSopSeen;
|
||||
const uint32_t RlinkPacketBuf::kFlagEopSeen;
|
||||
const uint32_t RlinkPacketBuf::kFlagNakSeen;
|
||||
const uint32_t RlinkPacketBuf::kFlagAttnSeen;
|
||||
const uint32_t RlinkPacketBuf::kFlagTout;
|
||||
const uint32_t RlinkPacketBuf::kFlagDatDrop;
|
||||
const uint32_t RlinkPacketBuf::kFlagDatMiss;
|
||||
|
||||
const uint8_t RlinkPacketBuf::kCPREF;
|
||||
const uint8_t RlinkPacketBuf::kNCOMM;
|
||||
const uint8_t RlinkPacketBuf::kCommaIdle;
|
||||
const uint8_t RlinkPacketBuf::kCommaSop;
|
||||
const uint8_t RlinkPacketBuf::kCommaEop;
|
||||
const uint8_t RlinkPacketBuf::kCommaNak;
|
||||
const uint8_t RlinkPacketBuf::kCommaAttn;
|
||||
const uint8_t RlinkPacketBuf::kSymEsc;
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkPacketBuf::RlinkPacketBuf()
|
||||
: fPktBuf(),
|
||||
fRawBuf(),
|
||||
fRawBufSize(0),
|
||||
fCrc(),
|
||||
fFlags(0),
|
||||
fNdone(0),
|
||||
fNesc(0),
|
||||
fNattn(0),
|
||||
fNidle(0),
|
||||
fNdrop(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkPacketBuf::~RlinkPacketBuf()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkPacketBuf::Init()
|
||||
{
|
||||
fPktBuf.clear();
|
||||
fRawBufSize = 0;
|
||||
fCrc.Clear();
|
||||
fFlags = 0;
|
||||
fNdone = 0;
|
||||
fNesc = 0;
|
||||
fNattn = 0;
|
||||
fNidle = 0;
|
||||
fNdrop = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPacketBuf::SndPacket(RlinkPort* port, RerrMsg& emsg)
|
||||
{
|
||||
fRawBuf.reserve(2*fPktBuf.size()+2); // max. size of raw data
|
||||
fRawBuf.clear();
|
||||
|
||||
fRawBuf.push_back(kCommaSop);
|
||||
|
||||
size_t ni = fPktBuf.size();
|
||||
uint8_t* pi = fPktBuf.data();
|
||||
for (size_t i=0; i<ni; i++) {
|
||||
uint8_t c = *pi++;
|
||||
if (c == kSymEsc || (c >= kCPREF && c <= kCPREF+kNCOMM)) {
|
||||
fRawBuf.push_back(kSymEsc);
|
||||
fRawBuf.push_back(((~kCPREF) & 0xf0) | (c & 0x0f));
|
||||
fNesc += 1;
|
||||
} else {
|
||||
fRawBuf.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
fRawBuf.push_back(kCommaEop);
|
||||
|
||||
return SndRaw(port, emsg);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPacketBuf::RcvPacket(RlinkPort* port, size_t nrcv, float timeout,
|
||||
RerrMsg& emsg)
|
||||
{
|
||||
fPktBuf.clear();
|
||||
|
||||
bool escseen = false; // in esc
|
||||
bool sopseen = false; // sop seen
|
||||
bool eopseen = false; // eop seen
|
||||
bool nakseen = false; // nak seen
|
||||
|
||||
while (!(eopseen|nakseen)) { // try till eop or nak received
|
||||
size_t nread = nrcv - fPktBuf.size();
|
||||
// FIXME_code: if the 'enough data' handling below correct ?
|
||||
if (nread < 0) return true;
|
||||
if (!sopseen) nread += 1;
|
||||
if (!eopseen) nread += 1;
|
||||
|
||||
size_t sizeold = fRawBufSize;
|
||||
int irc = RcvRaw(port, nread, timeout, emsg);
|
||||
|
||||
if (irc <= 0) {
|
||||
if (irc == RlinkPort::kTout) {
|
||||
SetFlagBit(kFlagTout);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* pi = fRawBuf.data()+sizeold;
|
||||
for (int i=0; i<irc; i++) {
|
||||
uint8_t c = *pi++;
|
||||
if (escseen) {
|
||||
escseen = false;
|
||||
if (sopseen && !(nakseen || eopseen)) {
|
||||
fPktBuf.push_back((kCPREF & 0xf0) | (c & 0x0f));
|
||||
}
|
||||
} else if (c == kCommaSop) {
|
||||
if (!eopseen) {
|
||||
SetFlagBit(kFlagSopSeen);
|
||||
sopseen = true;
|
||||
} else {
|
||||
// FIXME_code: handle multiple sop
|
||||
}
|
||||
} else if (c == kCommaEop) {
|
||||
SetFlagBit(kFlagEopSeen);
|
||||
eopseen = true;
|
||||
} else if (c == kCommaNak) {
|
||||
SetFlagBit(kFlagNakSeen);
|
||||
nakseen = true;
|
||||
} else if (c == kCommaAttn) {
|
||||
SetFlagBit(kFlagAttnSeen);
|
||||
fNattn += 1;
|
||||
} else if (c == kCommaIdle) {
|
||||
fNidle += 1;
|
||||
} else if (c == kSymEsc) {
|
||||
fNesc += 1;
|
||||
escseen = true;
|
||||
} else {
|
||||
if (sopseen && !(nakseen || eopseen)) {
|
||||
fPktBuf.push_back(c);
|
||||
} else {
|
||||
fNdrop += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
double RlinkPacketBuf::WaitAttn(RlinkPort* port, double timeout, RerrMsg& emsg)
|
||||
{
|
||||
if (timeout <= 0.)
|
||||
throw invalid_argument("RlinkPacketBuf::WaitAttn(): timeout <= 0.");
|
||||
|
||||
struct timeval tval;
|
||||
gettimeofday(&tval, 0);
|
||||
double tbeg = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
|
||||
double trest = timeout;
|
||||
|
||||
Init();
|
||||
|
||||
while (trest > 0.) {
|
||||
size_t sizeold = fRawBufSize;
|
||||
int irc = RcvRaw(port, 1, trest, emsg);
|
||||
|
||||
if (irc <= 0) {
|
||||
if (irc == RlinkPort::kTout) {
|
||||
SetFlagBit(kFlagTout);
|
||||
return -1.;
|
||||
} else {
|
||||
return -2.;
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&tval, 0);
|
||||
double tend = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
|
||||
trest -= (tend-tbeg);
|
||||
|
||||
uint8_t c = fRawBuf[sizeold];
|
||||
|
||||
if (c == kCommaAttn) {
|
||||
fNattn += 1;
|
||||
SetFlagBit(kFlagAttnSeen);
|
||||
break;
|
||||
} else if (c == kCommaIdle) {
|
||||
fNidle += 1;
|
||||
} else {
|
||||
fNdrop += 1;
|
||||
}
|
||||
|
||||
tbeg = tend;
|
||||
}
|
||||
|
||||
return timeout - trest;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPacketBuf::SndOob(RlinkPort* port, uint16_t addr, uint16_t data,
|
||||
RerrMsg& emsg)
|
||||
{
|
||||
Init();
|
||||
|
||||
fRawBuf.clear();
|
||||
fRawBuf.push_back(kSymEsc); // ESC
|
||||
fRawBuf.push_back(kSymEsc); // ESC
|
||||
fRawBuf.push_back((uint8_t)addr); // ADDR
|
||||
fRawBuf.push_back((uint8_t)(data & 0x00ff)); // DL
|
||||
fRawBuf.push_back((uint8_t)((data>>8) & 0x00ff)); // DH
|
||||
|
||||
return SndRaw(port, emsg);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPacketBuf::SndKeep(RlinkPort* port, RerrMsg& emsg)
|
||||
{
|
||||
Init();
|
||||
|
||||
fRawBuf.clear();
|
||||
fRawBuf.push_back(kSymEsc); // ESC
|
||||
fRawBuf.push_back(kSymEsc); // ESC
|
||||
|
||||
return SndRaw(port, emsg);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkPacketBuf::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkPacketBuf @ " << this << endl;
|
||||
os << bl << " fCrc: " << RosPrintBvi(fCrc.Crc(), 0) << endl;
|
||||
os << bl << " fFlags: " << RosPrintBvi(fFlags, 0) << endl;
|
||||
os << bl << " fNdone: " << RosPrintf(fNdone,"d",4) << endl;
|
||||
os << bl << " fNesc: " << RosPrintf(fNesc,"d",4) << endl;
|
||||
os << bl << " fNattn: " << RosPrintf(fNattn,"d",4) << endl;
|
||||
os << bl << " fNidle: " << RosPrintf(fNidle,"d",4) << endl;
|
||||
os << bl << " fNdrop: " << RosPrintf(fNdrop,"d",4) << endl;
|
||||
|
||||
os << bl << " fPktBuf(size): " << RosPrintf(fPktBuf.size(),"d",4);
|
||||
size_t ncol = max(1, (80-ind-4-6)/(2+1));
|
||||
for (size_t i=0; i< fPktBuf.size(); i++) {
|
||||
if (i%ncol == 0) os << "\n" << bl << " " << RosPrintf(i,"d",4) << ": ";
|
||||
os << RosPrintBvi(fPktBuf[i],16) << " ";
|
||||
}
|
||||
os << endl;
|
||||
|
||||
os << bl << " fRawBuf(size): " << RosPrintf(fRawBufSize,"d",4);
|
||||
for (size_t i=0; i< fRawBufSize; i++) {
|
||||
if (i%ncol == 0) os << "\n" << bl << " " << RosPrintf(i,"d",4) << ": ";
|
||||
os << RosPrintBvi(fRawBuf[i],16) << " ";
|
||||
}
|
||||
os << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPacketBuf::SndRaw(RlinkPort* port, RerrMsg& emsg)
|
||||
{
|
||||
if (port==0 || !port->IsOpen())
|
||||
throw logic_error("RlinkPacketBuf::SndRaw(): port not open");
|
||||
|
||||
fRawBufSize = fRawBuf.size();
|
||||
int irc = port->Write(fRawBuf.data(), fRawBuf.size(), emsg);
|
||||
if (irc < 0) return false;
|
||||
if ((size_t)irc != fRawBuf.size()) {
|
||||
emsg.Init("RlinkPacketBuf::SndRaw()", "failed to write all data");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RlinkPacketBuf::RcvRaw(RlinkPort* port, size_t size, float timeout,
|
||||
RerrMsg& emsg)
|
||||
{
|
||||
if (port==0 || !port->IsOpen())
|
||||
throw logic_error("RlinkPacketBuf::RcvRaw(): port not open");
|
||||
|
||||
if (fRawBuf.size() < fRawBufSize+size) fRawBuf.resize(fRawBufSize+size);
|
||||
int irc = port->Read(fRawBuf.data()+fRawBufSize, size, timeout, emsg);
|
||||
if (irc == RlinkPort::kEof) {
|
||||
emsg.Init("RlinkPacketBuf::RcvRaw()", "eof on read");
|
||||
}
|
||||
|
||||
if (irc > 0) {
|
||||
fRawBufSize += irc;
|
||||
}
|
||||
|
||||
return irc;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkPacketBuf_NoInline))
|
||||
#define inline
|
||||
#include "RlinkPacketBuf.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
122
tools/src/librlink/RlinkPacketBuf.hpp
Normal file
122
tools/src/librlink/RlinkPacketBuf.hpp
Normal file
@@ -0,0 +1,122 @@
|
||||
// $Id: RlinkPacketBuf.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-04-02 375 1.0 Initial version
|
||||
// 2011-03-05 366 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPacketBuf.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkPacketBuf.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkPacketBuf
|
||||
#define included_Retro_RlinkPacketBuf 1
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "RlinkPort.hpp"
|
||||
#include "RlinkCrc8.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkPacketBuf {
|
||||
public:
|
||||
|
||||
RlinkPacketBuf();
|
||||
~RlinkPacketBuf();
|
||||
|
||||
void Init();
|
||||
|
||||
void PutWithCrc(uint8_t data);
|
||||
void PutWithCrc(uint16_t data);
|
||||
void PutCrc();
|
||||
|
||||
bool SndPacket(RlinkPort* port, RerrMsg& emsg);
|
||||
bool RcvPacket(RlinkPort* port, size_t nrcv, float timeout,
|
||||
RerrMsg& emsg);
|
||||
|
||||
double WaitAttn(RlinkPort* port, double timeout, RerrMsg& emsg);
|
||||
bool SndOob(RlinkPort* port, uint16_t addr, uint16_t data,
|
||||
RerrMsg& emsg);
|
||||
bool SndKeep(RlinkPort* port, RerrMsg& emsg);
|
||||
|
||||
bool CheckSize(size_t nbyte) const;
|
||||
uint8_t Get8WithCrc();
|
||||
uint16_t Get16WithCrc();
|
||||
bool CheckCrc();
|
||||
|
||||
size_t PktSize() const;
|
||||
size_t RawSize() const;
|
||||
|
||||
uint32_t Flags() const;
|
||||
bool TestFlag(uint32_t mask) const;
|
||||
size_t Nesc() const;
|
||||
size_t Nattn() const;
|
||||
size_t Nidle() const;
|
||||
size_t Ndrop() const;
|
||||
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
// flag bits
|
||||
static const uint32_t kFlagSopSeen = 1<<0; //!< sop was seen
|
||||
static const uint32_t kFlagEopSeen = 1<<1; //!< eop was seen
|
||||
static const uint32_t kFlagNakSeen = 1<<2; //!< nak was seen
|
||||
static const uint32_t kFlagAttnSeen = 1<<3; //!< attn was seen
|
||||
static const uint32_t kFlagTout = 1<<16; //!< timeout on read
|
||||
static const uint32_t kFlagDatDrop = 1<<17; //!< data before sop dropped
|
||||
static const uint32_t kFlagDatMiss = 1<<18; //!< eop before expected data
|
||||
|
||||
// some constants
|
||||
static const uint8_t kCPREF = 0x80; //!< VHDL def for comma prefix
|
||||
static const uint8_t kNCOMM = 0x04; //!< VHDL def for number of commas
|
||||
static const uint8_t kCommaIdle = kCPREF+0; //!< IDLE comma
|
||||
static const uint8_t kCommaSop = kCPREF+1; //!< SOP comma
|
||||
static const uint8_t kCommaEop = kCPREF+2; //!< EOP comma
|
||||
static const uint8_t kCommaNak = kCPREF+3; //!< NAK comma
|
||||
static const uint8_t kCommaAttn = kCPREF+4; //!< ATTN comma
|
||||
static const uint8_t kSymEsc = kCPREF+0x0f; //!< ESC symbol
|
||||
|
||||
protected:
|
||||
bool SndRaw(RlinkPort* port, RerrMsg& emsg);
|
||||
int RcvRaw(RlinkPort* port, size_t size, float timeout,
|
||||
RerrMsg& emsg);
|
||||
|
||||
void SetFlagBit(uint32_t mask);
|
||||
void ClearFlagBit(uint32_t mask);
|
||||
|
||||
protected:
|
||||
std::vector<uint8_t> fPktBuf; //!< packet buffer
|
||||
std::vector<uint8_t> fRawBuf; //!< raw data buffer
|
||||
size_t fRawBufSize; //!< # of valid bytes in RawBuf
|
||||
RlinkCrc8 fCrc; //!< crc accumulator
|
||||
uint32_t fFlags; //!< request/response flags
|
||||
size_t fNdone; //!< number of input bytes processed
|
||||
size_t fNesc; //!< number of escapes handled
|
||||
size_t fNattn; //!< number of ATTN commas seen
|
||||
size_t fNidle; //!< number of IDLE commas seen
|
||||
size_t fNdrop; //!< number of dropped input bytes
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkPacketBuf_NoInline))
|
||||
#include "RlinkPacketBuf.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
179
tools/src/librlink/RlinkPacketBuf.ipp
Normal file
179
tools/src/librlink/RlinkPacketBuf.ipp
Normal file
@@ -0,0 +1,179 @@
|
||||
// $Id: RlinkPacketBuf.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-04-02 375 1.0 Initial version
|
||||
// 2011-03-05 366 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPacketBuf.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of class RlinkPacketBuf.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPacketBuf::PutWithCrc(uint8_t data)
|
||||
{
|
||||
fPktBuf.push_back(data);
|
||||
fCrc.AddData(data);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPacketBuf::PutWithCrc(uint16_t data)
|
||||
{
|
||||
PutWithCrc((uint8_t)( data & 0xff)); // lsb first
|
||||
PutWithCrc((uint8_t)((data>>8) & 0xff));
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPacketBuf::PutCrc()
|
||||
{
|
||||
fPktBuf.push_back(fCrc.Crc());
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkPacketBuf::CheckSize(size_t nbyte) const
|
||||
{
|
||||
return fPktBuf.size()-fNdone >= nbyte;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline uint8_t RlinkPacketBuf::Get8WithCrc()
|
||||
{
|
||||
uint8_t data = fPktBuf[fNdone++];
|
||||
fCrc.AddData(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline uint16_t RlinkPacketBuf::Get16WithCrc()
|
||||
{
|
||||
uint8_t datl = fPktBuf[fNdone++];
|
||||
uint8_t dath = fPktBuf[fNdone++];
|
||||
fCrc.AddData(datl);
|
||||
fCrc.AddData(dath);
|
||||
return (uint16_t)datl | ((uint16_t)dath << 8);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkPacketBuf::CheckCrc()
|
||||
{
|
||||
uint8_t data = fPktBuf[fNdone++];
|
||||
return data == fCrc.Crc();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPacketBuf::PktSize() const
|
||||
{
|
||||
return fPktBuf.size();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPacketBuf::RawSize() const
|
||||
{
|
||||
return fRawBuf.size();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPacketBuf::SetFlagBit(uint32_t mask)
|
||||
{
|
||||
fFlags |= mask;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline uint32_t RlinkPacketBuf::Flags() const
|
||||
{
|
||||
return fFlags;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkPacketBuf::TestFlag(uint32_t mask) const
|
||||
{
|
||||
return (fFlags & mask) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPacketBuf::Nesc() const
|
||||
{
|
||||
return fNesc;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPacketBuf::Nattn() const
|
||||
{
|
||||
return fNattn;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPacketBuf::Nidle() const
|
||||
{
|
||||
return fNidle;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPacketBuf::Ndrop() const
|
||||
{
|
||||
return fNdrop;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPacketBuf::ClearFlagBit(uint32_t mask)
|
||||
{
|
||||
fFlags &= ~mask;
|
||||
return;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
366
tools/src/librlink/RlinkPort.cpp
Normal file
366
tools/src/librlink/RlinkPort.cpp
Normal file
@@ -0,0 +1,366 @@
|
||||
// $Id: RlinkPort.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 375 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPort.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of RlinkPort.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include "RlinkPort.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librtools/RosPrintBvi.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkPort
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkPort::RlinkPort()
|
||||
: fIsOpen(false),
|
||||
fUrl(),
|
||||
fScheme(),
|
||||
fPath(),
|
||||
fOptMap(),
|
||||
fFdRead(-1),
|
||||
fFdWrite(-1),
|
||||
fpLogFile(0),
|
||||
fTraceLevel(0),
|
||||
fStats()
|
||||
{
|
||||
fStats.Define(kStatNPortWrite, "NPortWrite", "Port::Write() calls");
|
||||
fStats.Define(kStatNPortRead, "NPortRead", "Port::Read() calls");
|
||||
fStats.Define(kStatNPortTxByt, "NPortTxByt", "Port Tx raw bytes send");
|
||||
fStats.Define(kStatNPortRxByt, "NPortRxByt", "Port Rx raw bytes rcvd");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkPort::~RlinkPort()
|
||||
{
|
||||
if (IsOpen()) RlinkPort::Close();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkPort::Close()
|
||||
{
|
||||
if (! IsOpen())
|
||||
throw logic_error("RlinkPort::Close(): port not open");
|
||||
|
||||
close(fFdRead);
|
||||
if (fFdWrite != fFdRead) close(fFdWrite);
|
||||
|
||||
fFdRead = -1;
|
||||
fFdWrite = -1;
|
||||
fIsOpen = false;
|
||||
fUrl.clear();
|
||||
fScheme.clear();
|
||||
fPath.clear();
|
||||
fOptMap.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RlinkPort::Read(uint8_t* buf, size_t size, double timeout, RerrMsg& emsg)
|
||||
{
|
||||
if (!IsOpen())
|
||||
throw logic_error("RlinkPort::Read(): port not open");
|
||||
if (buf == 0)
|
||||
throw invalid_argument("RlinkPort::Read(): buf==NULL");
|
||||
if (size == 0)
|
||||
throw invalid_argument("RlinkPort::Read(): size==0");
|
||||
|
||||
fStats.Inc(kStatNPortRead);
|
||||
|
||||
bool rdpoll = PollRead(timeout);
|
||||
if (!rdpoll) return kTout;
|
||||
|
||||
int irc = -1;
|
||||
while (irc < 0) {
|
||||
irc = read(fFdRead, (void*) buf, size);
|
||||
if (irc < 0 && errno != EINTR) {
|
||||
emsg.InitErrno("RlinkPort::Read()", "read() failed : ", errno);
|
||||
if (fpLogFile && fTraceLevel>0) (*fpLogFile)('E') << emsg << endl;
|
||||
return kErr;
|
||||
}
|
||||
}
|
||||
|
||||
if (fpLogFile && fTraceLevel>0) {
|
||||
ostream& os = (*fpLogFile)();
|
||||
(*fpLogFile)('I') << "port read nchar=" << RosPrintf(irc,"d",4);
|
||||
if (fTraceLevel>1) {
|
||||
size_t ncol = (80-5-6)/(2+1);
|
||||
for (int i=0; i<irc; i++) {
|
||||
if ((i%ncol)==0) os << "\n " << RosPrintf(i,"d",4) << ": ";
|
||||
os << RosPrintBvi(buf[i],16) << " ";
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
|
||||
fStats.Inc(kStatNPortRxByt, double(irc));
|
||||
|
||||
return irc;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RlinkPort::Write(const uint8_t* buf, size_t size, RerrMsg& emsg)
|
||||
{
|
||||
if (!IsOpen())
|
||||
throw logic_error("RlinkPort::Write(): port not open");
|
||||
if (buf == 0)
|
||||
throw invalid_argument("RlinkPort::Write(): buf==NULL");
|
||||
if (size == 0)
|
||||
throw invalid_argument("RlinkPort::Write(): size==0");
|
||||
|
||||
fStats.Inc(kStatNPortWrite);
|
||||
|
||||
if (fpLogFile && fTraceLevel>0) {
|
||||
ostream& os = (*fpLogFile)();
|
||||
(*fpLogFile)('I') << "port write nchar=" << RosPrintf(size,"d",4);
|
||||
if (fTraceLevel>1) {
|
||||
size_t ncol = (80-5-6)/(2+1);
|
||||
for (size_t i=0; i<size; i++) {
|
||||
if ((i%ncol)==0) os << "\n " << RosPrintf(i,"d",4) << ": ";
|
||||
os << RosPrintBvi(buf[i],16) << " ";
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
|
||||
size_t ndone = 0;
|
||||
while (ndone < size) {
|
||||
int irc = -1;
|
||||
while (irc < 0) {
|
||||
irc = write(fFdWrite, (void*) (buf+ndone), size-ndone);
|
||||
if (irc < 0 && errno != EINTR) {
|
||||
emsg.InitErrno("RlinkPort::Write()", "write() failed : ", errno);
|
||||
if (fpLogFile && fTraceLevel>0) (*fpLogFile)('E') << emsg << endl;
|
||||
return kErr;
|
||||
}
|
||||
}
|
||||
// FIXME_code: handle eof ??
|
||||
ndone += irc;
|
||||
}
|
||||
|
||||
fStats.Inc(kStatNPortTxByt, double(ndone));
|
||||
|
||||
return ndone;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPort::PollRead(double timeout)
|
||||
{
|
||||
if (! IsOpen())
|
||||
throw logic_error("RlinkPort::PollRead(): port not open");
|
||||
if (timeout < 0.)
|
||||
throw invalid_argument("RlinkPort::PollRead(): timeout < 0");
|
||||
|
||||
int ito = 1000.*timeout + 0.1;
|
||||
|
||||
struct pollfd fds[1] = {{fFdRead, // fd
|
||||
POLLIN, // events
|
||||
0}}; // revents
|
||||
|
||||
|
||||
int irc = -1;
|
||||
while (irc < 0) {
|
||||
irc = poll(fds, 1, ito);
|
||||
if (irc < 0 && errno != EINTR)
|
||||
throw logic_error("RlinkPort::PollRead(): poll failed: rc<0");
|
||||
}
|
||||
|
||||
if (irc == 0) return false;
|
||||
|
||||
if (fds[0].revents == POLLERR)
|
||||
throw logic_error("RlinkPort::PollRead(): poll failed: POLLERR");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPort::UrlFindOpt(const std::string& name) const
|
||||
{
|
||||
omap_cit_t it = fOptMap.find(name);
|
||||
if (it == fOptMap.end()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPort::UrlFindOpt(const std::string& name, std::string& value) const
|
||||
{
|
||||
omap_cit_t it = fOptMap.find(name);
|
||||
if (it == fOptMap.end()) return false;
|
||||
|
||||
value = it->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RlinkPort::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkPort @ " << this << endl;
|
||||
|
||||
os << bl << " fIsOpen: " << (int)fIsOpen << endl;
|
||||
os << bl << " fUrl: " << fUrl << endl;
|
||||
os << bl << " fScheme: " << fScheme << endl;
|
||||
os << bl << " fPath: " << fPath << endl;
|
||||
os << bl << " fOptMap: " << endl;
|
||||
for (omap_cit_t it=fOptMap.begin(); it!=fOptMap.end(); it++) {
|
||||
os << bl << " " << RosPrintf((it->first).c_str(), "-s",8)
|
||||
<< " : " << it->second << endl;
|
||||
}
|
||||
os << bl << " fFdRead: " << fFdRead << endl;
|
||||
os << bl << " fFdWrite: " << fFdWrite << endl;
|
||||
fStats.Dump(os, ind+2, "fStats: ");
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPort::ParseUrl(const std::string& url, const std::string& optlist,
|
||||
RerrMsg& emsg)
|
||||
{
|
||||
fUrl.clear();
|
||||
fScheme.clear();
|
||||
fPath.clear();
|
||||
fOptMap.clear();
|
||||
|
||||
size_t pdel = url.find_first_of(':');
|
||||
if (pdel == string::npos) {
|
||||
emsg.Init("RlinkPort::ParseUrl()",
|
||||
string("no scheme specified in url \"") + url + string("\""));
|
||||
return false;
|
||||
}
|
||||
|
||||
fUrl = url;
|
||||
fScheme = url.substr(0, pdel);
|
||||
|
||||
size_t odel = url.find_first_of('?', pdel);
|
||||
if (odel == string::npos) { // no options
|
||||
if (url.length() > pdel+1) fPath = url.substr(pdel+1);
|
||||
|
||||
} else { // options to process
|
||||
fPath = url.substr(pdel+1,odel-(pdel+1));
|
||||
string key;
|
||||
string val;
|
||||
bool hasval = false;
|
||||
|
||||
for (size_t i=odel+1; i<url.length(); i++) {
|
||||
char c = url[i];
|
||||
if (c == ';') {
|
||||
if (!AddOpt(key, val, hasval, optlist, emsg)) return false;
|
||||
key.clear();
|
||||
val.clear();
|
||||
hasval = false;
|
||||
} else {
|
||||
if (!hasval) {
|
||||
if (c == '=') {
|
||||
hasval = true;
|
||||
} else
|
||||
key.push_back(c);
|
||||
} else {
|
||||
if (c == '\\') {
|
||||
if (i+1 >= url.length()) {
|
||||
emsg.Init("RlinkPort::ParseUrl()",
|
||||
string("invalid trailing \\ in url \"") + url +
|
||||
string("\""));
|
||||
return false;
|
||||
}
|
||||
i += 1;
|
||||
switch (url[i]) {
|
||||
case '\\' : c = '\\'; break;
|
||||
case ';' : c = ';'; break;
|
||||
default : emsg.Init("RlinkPort::ParseUrl()",
|
||||
string("invalid \\ escape in url \"") +
|
||||
url + string("\""));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
val.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key.length() || hasval) {
|
||||
if (!AddOpt(key, val, hasval, optlist, emsg)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RlinkPort::AddOpt(const std::string& key, const std::string& val,
|
||||
bool hasval, const std::string& optlist, RerrMsg& emsg)
|
||||
{
|
||||
string lkey = "|";
|
||||
lkey += key;
|
||||
if (hasval) lkey += "=";
|
||||
lkey += "|";
|
||||
if (optlist.find(lkey) == string::npos) {
|
||||
emsg.Init("RlinkPort::AddOpt()",
|
||||
string("invalid field name \"") + lkey + string("\""));
|
||||
}
|
||||
|
||||
fOptMap.insert(omap_val_t(key, hasval ? val : "1"));
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkPort_NoInline))
|
||||
#define inline
|
||||
#include "RlinkPort.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
123
tools/src/librlink/RlinkPort.hpp
Normal file
123
tools/src/librlink/RlinkPort.hpp
Normal file
@@ -0,0 +1,123 @@
|
||||
// $Id: RlinkPort.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 375 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPort.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkPort.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkPort
|
||||
#define included_Retro_RlinkPort 1
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "librtools/RerrMsg.hpp"
|
||||
#include "librtools/RlogFile.hpp"
|
||||
#include "librtools/Rstats.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkPort {
|
||||
public:
|
||||
typedef std::map<std::string, std::string> omap_t;
|
||||
typedef omap_t::iterator omap_it_t;
|
||||
typedef omap_t::const_iterator omap_cit_t;
|
||||
typedef omap_t::value_type omap_val_t;
|
||||
|
||||
RlinkPort();
|
||||
virtual ~RlinkPort();
|
||||
|
||||
virtual bool Open(const std::string& url, RerrMsg& emsg) = 0;
|
||||
virtual void Close();
|
||||
|
||||
virtual int Read(uint8_t* buf, size_t size, double timeout,
|
||||
RerrMsg& emsg);
|
||||
virtual int Write(const uint8_t* buf, size_t size, RerrMsg& emsg);
|
||||
virtual bool PollRead(double timeout);
|
||||
|
||||
bool IsOpen() const;
|
||||
const std::string& Url() const;
|
||||
const std::string& UrlScheme() const;
|
||||
const std::string& UrlPath() const;
|
||||
const omap_t& UrlOpts() const;
|
||||
bool UrlFindOpt(const std::string& name) const;
|
||||
bool UrlFindOpt(const std::string& name,
|
||||
std::string& value) const;
|
||||
|
||||
int FdRead() const;
|
||||
int FdWrite() const;
|
||||
|
||||
void SetLogFile(RlogFile* log);
|
||||
void SetTraceLevel(size_t level);
|
||||
size_t TraceLevel() const;
|
||||
|
||||
const Rstats& Stats() const;
|
||||
|
||||
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
// some constants
|
||||
static const int kEof = 0;
|
||||
static const int kTout = -1;
|
||||
static const int kErr = -2;
|
||||
|
||||
// statistics counter indices
|
||||
enum stats {
|
||||
kStatNPortWrite = 0,
|
||||
kStatNPortRead,
|
||||
kStatNPortTxByt,
|
||||
kStatNPortRxByt,
|
||||
kDimStat
|
||||
};
|
||||
|
||||
protected:
|
||||
bool ParseUrl(const std::string& url, const std::string& optlist,
|
||||
RerrMsg& emsg);
|
||||
bool AddOpt(const std::string& key, const std::string& val,
|
||||
bool hasval, const std::string& optlist,
|
||||
RerrMsg& emsg);
|
||||
|
||||
protected:
|
||||
bool fIsOpen; //!< is open flag
|
||||
std::string fUrl; //!< full url given with open
|
||||
std::string fScheme; //!< url scheme part
|
||||
std::string fPath; //!< url path part
|
||||
omap_t fOptMap; //!< option map
|
||||
int fFdRead; //!< fd for read
|
||||
int fFdWrite; //!< fd for write
|
||||
RlogFile* fpLogFile; //!< ptr to log file dsc
|
||||
size_t fTraceLevel; //!< trace level
|
||||
Rstats fStats; //!< statistics
|
||||
|
||||
// RlinkPort is not copyable and assignable
|
||||
private:
|
||||
RlinkPort(const RlinkPort& rhs);
|
||||
RlinkPort& operator=(const RlinkPort& rhs);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkPort_NoInline))
|
||||
#include "RlinkPort.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
119
tools/src/librlink/RlinkPort.ipp
Normal file
119
tools/src/librlink/RlinkPort.ipp
Normal file
@@ -0,0 +1,119 @@
|
||||
// $Id: RlinkPort.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 375 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPort.ipp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation (inline) of RlinkPort.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkPort::IsOpen() const
|
||||
{
|
||||
return fIsOpen;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const std::string& RlinkPort::Url() const
|
||||
{
|
||||
return fUrl;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const std::string& RlinkPort::UrlScheme() const
|
||||
{
|
||||
return fScheme;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const std::string& RlinkPort::UrlPath() const
|
||||
{
|
||||
return fPath;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const RlinkPort::omap_t& RlinkPort::UrlOpts() const
|
||||
{
|
||||
return fOptMap;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline int RlinkPort::FdRead() const
|
||||
{
|
||||
return fFdRead;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline int RlinkPort::FdWrite() const
|
||||
{
|
||||
return fFdWrite;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPort::SetLogFile(RlogFile* log)
|
||||
{
|
||||
fpLogFile = log;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RlinkPort::SetTraceLevel(size_t level)
|
||||
{
|
||||
fTraceLevel = level;
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RlinkPort::TraceLevel() const
|
||||
{
|
||||
return fTraceLevel;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const Rstats& RlinkPort::Stats() const
|
||||
{
|
||||
return fStats;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
81
tools/src/librlink/RlinkPortFactory.cpp
Normal file
81
tools/src/librlink/RlinkPortFactory.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// $Id: RlinkPortFactory.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPortFactory.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of RlinkPortFactory.
|
||||
*/
|
||||
|
||||
#include "RlinkPortFactory.hpp"
|
||||
#include "RlinkPortFifo.hpp"
|
||||
#include "RlinkPortTerm.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkPortFactory
|
||||
\brief FIXME_text
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
RlinkPort* Retro::RlinkPortFactory::New(const std::string& url, RerrMsg& emsg)
|
||||
{
|
||||
size_t dpos = url.find_first_of(':');
|
||||
if (dpos == string::npos) {
|
||||
emsg.Init("RlinkPortFactory::New()",
|
||||
string("no scheme specified in url \"" + url + string("\"")));
|
||||
return 0;
|
||||
}
|
||||
|
||||
string scheme = url.substr(0,dpos); // get scheme without ':' delim
|
||||
|
||||
if (scheme == "fifo") {
|
||||
return new RlinkPortFifo();
|
||||
} else if (scheme == "term") {
|
||||
return new RlinkPortTerm();
|
||||
}
|
||||
|
||||
emsg.Init("RlinkPortFactory::New()", string("unknown scheme: ") + scheme);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
RlinkPort* RlinkPortFactory::Open(const std::string& url, RerrMsg& emsg)
|
||||
{
|
||||
RlinkPort* pport = New(url, emsg);
|
||||
if (pport == 0) return 0;
|
||||
|
||||
if (pport->Open(url, emsg)) return pport;
|
||||
delete pport;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkPortFactory_NoInline))
|
||||
#define inline
|
||||
//#include "RlinkPortFactory.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
47
tools/src/librlink/RlinkPortFactory.hpp
Normal file
47
tools/src/librlink/RlinkPortFactory.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// $Id: RlinkPortFactory.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPortFactory.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkPortFactory.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkPortFactory
|
||||
#define included_Retro_RlinkPortFactory 1
|
||||
|
||||
#include "librtools/RerrMsg.hpp"
|
||||
#include "RlinkPort.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkPortFactory {
|
||||
public:
|
||||
static RlinkPort* New(const std::string& url, RerrMsg& emsg);
|
||||
static RlinkPort* Open(const std::string& url, RerrMsg& emsg);
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
//#if !(defined(Retro_NoInline) || defined(Retro_RlinkPortFactory_NoInline))
|
||||
//#include "RlinkPortFactory.ipp"
|
||||
//#endif
|
||||
|
||||
#endif
|
||||
124
tools/src/librlink/RlinkPortFifo.cpp
Normal file
124
tools/src/librlink/RlinkPortFifo.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// $Id: RlinkPortFifo.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPortFifo.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of RlinkPortFifo.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "RlinkPortFifo.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkPortFifo
|
||||
\brief FIXME_text
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkPortFifo::RlinkPortFifo()
|
||||
: RlinkPort()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkPortFifo::~RlinkPortFifo()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
bool RlinkPortFifo::Open(const std::string& url, RerrMsg& emsg)
|
||||
{
|
||||
if (IsOpen()) Close();
|
||||
|
||||
if (!ParseUrl(url, "|keep|", emsg)) return false;
|
||||
|
||||
// Note: _rx fifo must be opened before the _tx fifo, otherwise the test
|
||||
// bench might close with EOF on read prematurely (is a race condition).
|
||||
|
||||
fFdWrite = OpenFifo(UrlPath() + "_rx", true, emsg);
|
||||
if (fFdWrite < 0) return false;
|
||||
|
||||
fFdRead = OpenFifo(UrlPath() + "_tx", false, emsg);
|
||||
if (fFdRead < 0) {
|
||||
close(fFdWrite);
|
||||
fFdWrite = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
fIsOpen = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
int RlinkPortFifo::OpenFifo(const std::string& name, bool snd, RerrMsg& emsg)
|
||||
{
|
||||
struct stat stat_fifo;
|
||||
|
||||
int irc;
|
||||
|
||||
irc = stat(name.c_str(), &stat_fifo);
|
||||
if (irc == 0) {
|
||||
if ((stat_fifo.st_mode & S_IFIFO) == 0) {
|
||||
emsg.Init("RlinkPortFifo::OpenFiFo()",
|
||||
string("\"") + name + string("\" exists but is not a pipe"));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
mode_t mode = S_IRUSR | S_IWUSR; // user read and write allowed
|
||||
irc = mkfifo(name.c_str(), mode);
|
||||
if (irc != 0) {
|
||||
emsg.InitErrno("RlinkPortFifo::OpenFifo()",
|
||||
string("mkfifo() for \"") + name + string("\" failed: "),
|
||||
errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
irc = open(name.c_str(), snd ? O_WRONLY : O_RDONLY);
|
||||
if (irc < 0) {
|
||||
emsg.InitErrno("RlinkPortFifo::OpenFifo()",
|
||||
string("open() for \"") + name + string("\" failed: "),
|
||||
errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return irc;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkPortFifo_NoInline))
|
||||
#define inline
|
||||
//#include "RlinkPortFifo.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
53
tools/src/librlink/RlinkPortFifo.hpp
Normal file
53
tools/src/librlink/RlinkPortFifo.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// $Id: RlinkPortFifo.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-01-15 356 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPortFifo.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkPortFifo.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkPortFifo
|
||||
#define included_Retro_RlinkPortFifo 1
|
||||
|
||||
#include "RlinkPort.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkPortFifo : public RlinkPort {
|
||||
public:
|
||||
|
||||
RlinkPortFifo();
|
||||
virtual ~RlinkPortFifo();
|
||||
|
||||
virtual bool Open(const std::string& url, RerrMsg& emsg);
|
||||
|
||||
private:
|
||||
int OpenFifo(const std::string&, bool snd, RerrMsg& emsg);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkPortFifo_NoInline))
|
||||
//#include "RlinkPortFifo.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
297
tools/src/librlink/RlinkPortTerm.cpp
Normal file
297
tools/src/librlink/RlinkPortTerm.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
// $Id: RlinkPortTerm.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPortTerm.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of RlinkPortTerm.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "RlinkPortTerm.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RlinkPortTerm
|
||||
\brief FIXME_text
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RlinkPortTerm::RlinkPortTerm()
|
||||
: RlinkPort()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RlinkPortTerm::~RlinkPortTerm()
|
||||
{
|
||||
if (IsOpen()) RlinkPortTerm::Close();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg)
|
||||
{
|
||||
if (IsOpen()) Close();
|
||||
|
||||
if (!ParseUrl(url, "|baud=|break|", emsg)) return false;
|
||||
|
||||
speed_t speed = B115200;
|
||||
string baud;
|
||||
if (UrlFindOpt("baud", baud)) {
|
||||
speed = B0;
|
||||
if (baud=="9600") speed = B9600;
|
||||
if (baud=="19200" || baud=="19k") speed = B19200;
|
||||
if (baud=="38400" || baud=="38k") speed = B38400;
|
||||
if (baud=="57600" || baud=="57k") speed = B57600;
|
||||
if (baud=="115200" || baud=="115k") speed = B115200;
|
||||
if (baud=="230400" || baud=="230k") speed = B230400;
|
||||
if (baud=="460800" || baud=="460k") speed = B460800;
|
||||
if (baud=="500000" || baud=="500k") speed = B500000;
|
||||
if (baud=="921600" || baud=="921k") speed = B921600;
|
||||
if (baud=="1000000" || baud=="1M") speed = B1000000;
|
||||
if (baud=="2000000" || baud=="2M") speed = B2000000;
|
||||
if (baud=="3000000" || baud=="3M") speed = B3000000;
|
||||
if (speed == B0) {
|
||||
emsg.Init("RlinkPortTerm::Open()",
|
||||
string("invalid baud rate \"") + baud + string("\" specified"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int fd;
|
||||
|
||||
fd = open(fPath.c_str(), O_RDWR|O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
emsg.InitErrno("RlinkPortTerm::Open()",
|
||||
string("open() for \"") + fPath + string("\" failed: "),
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isatty(fd)) {
|
||||
emsg.Init("RlinkPortTerm::Open()",
|
||||
string("isatty() check for \"") + fPath +
|
||||
string("\" failed: not a TTY"));
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tcgetattr(fd, &fTiosOld) != 0) {
|
||||
emsg.InitErrno("RlinkPortTerm::Open()",
|
||||
string("tcgetattr() for \"") + fPath + string("\" failed: "),
|
||||
errno);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fTiosNew = fTiosOld;
|
||||
|
||||
fTiosNew.c_iflag = IGNBRK | // ignore breaks on input
|
||||
IGNPAR; // ignore parity errors
|
||||
fTiosNew.c_oflag = 0;
|
||||
fTiosNew.c_cflag = CS8 | // 8 bit chars
|
||||
CSTOPB | // 2 stop bits
|
||||
CREAD | // enable receiver
|
||||
CLOCAL | // ignore modem control
|
||||
CRTSCTS; // enable hardware flow control
|
||||
fTiosNew.c_lflag = 0;
|
||||
|
||||
if (cfsetspeed(&fTiosNew, speed) != 0) {
|
||||
emsg.InitErrno("RlinkPortTerm::Open()",
|
||||
string("cfsetspeed() for \"") + baud + string("\" failed: "),
|
||||
errno);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fTiosNew.c_cc[VEOF] = 0; // undef
|
||||
fTiosNew.c_cc[VEOL] = 0; // undef
|
||||
fTiosNew.c_cc[VERASE] = 0; // undef
|
||||
fTiosNew.c_cc[VINTR] = 0; // undef
|
||||
fTiosNew.c_cc[VKILL] = 0; // undef
|
||||
fTiosNew.c_cc[VQUIT] = 0; // undef
|
||||
fTiosNew.c_cc[VSUSP] = 0; // undef
|
||||
fTiosNew.c_cc[VSTART] = 0; // undef
|
||||
fTiosNew.c_cc[VSTOP] = 0; // undef
|
||||
fTiosNew.c_cc[VMIN] = 1; // wait for 1 char
|
||||
fTiosNew.c_cc[VTIME] = 0; //
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, &fTiosNew) != 0) {
|
||||
emsg.InitErrno("RlinkPortTerm::Open()",
|
||||
string("tcsetattr() for \"") + fPath + string("\" failed: "),
|
||||
errno);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
fFdWrite = fd;
|
||||
fFdRead = fd;
|
||||
fIsOpen = true;
|
||||
|
||||
if (UrlFindOpt("break")) {
|
||||
if (tcsendbreak(fd, 0) != 0) {
|
||||
emsg.InitErrno("RlinkPortTerm::Open()",
|
||||
string("tcsendbreak() for \"") + fPath +
|
||||
string("\" failed: "), errno);
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
uint8_t buf[1];
|
||||
buf[0] = 0x80;
|
||||
if (Write(buf, 1, emsg) != 1) {
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
void RlinkPortTerm::Close()
|
||||
{
|
||||
if (fIsOpen) {
|
||||
if (fFdWrite >= 0) {
|
||||
tcflush(fFdWrite, TCIOFLUSH);
|
||||
tcsetattr(fFdWrite, TCSANOW, &fTiosOld);
|
||||
}
|
||||
RlinkPort::Close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
void RlinkPortTerm::Dump(std::ostream& os, int ind, const char* text) const
|
||||
{
|
||||
RosFill bl(ind);
|
||||
os << bl << (text?text:"--") << "RlinkPortTerm @ " << this << endl;
|
||||
DumpTios(os, ind, "fTiosOld", fTiosOld);
|
||||
DumpTios(os, ind, "fTiosNew", fTiosNew);
|
||||
RlinkPort::Dump(os, ind+2, "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_text
|
||||
|
||||
void RlinkPortTerm::DumpTios(std::ostream& os, int ind, const std::string& name,
|
||||
const struct termios& tios) const
|
||||
{
|
||||
RosFill bl(ind+2);
|
||||
os << bl << name << ":" << endl;
|
||||
os << bl << " c_iflag : " << RosPrintf(tios.c_iflag,"x0",8);
|
||||
if (tios.c_iflag & BRKINT) os << " BRKINT";
|
||||
if (tios.c_iflag & ICRNL) os << " ICRNL ";
|
||||
if (tios.c_iflag & IGNBRK) os << " IGNBRK";
|
||||
if (tios.c_iflag & IGNCR) os << " IGNCR ";
|
||||
if (tios.c_iflag & IGNPAR) os << " IGNPAR";
|
||||
if (tios.c_iflag & INLCR) os << " INLCR ";
|
||||
if (tios.c_iflag & INPCK) os << " INPCK ";
|
||||
if (tios.c_iflag & ISTRIP) os << " ISTRIP";
|
||||
if (tios.c_iflag & IXOFF) os << " IXOFF ";
|
||||
if (tios.c_iflag & IXON) os << " IXON ";
|
||||
if (tios.c_iflag & PARMRK) os << " PARMRK";
|
||||
os << endl;
|
||||
|
||||
os << bl << " c_oflag : " << RosPrintf(tios.c_oflag,"x0",8);
|
||||
if (tios.c_oflag & OPOST) os << " OPOST ";
|
||||
os << endl;
|
||||
|
||||
os << bl << " c_cflag : " << RosPrintf(tios.c_cflag,"x0",8);
|
||||
if (tios.c_cflag & CLOCAL) os << " CLOCAL";
|
||||
if (tios.c_cflag & CREAD) os << " CREAD ";
|
||||
if ((tios.c_cflag & CSIZE) == CS5) os << " CS5 ";
|
||||
if ((tios.c_cflag & CSIZE) == CS6) os << " CS6 ";
|
||||
if ((tios.c_cflag & CSIZE) == CS7) os << " CS7 ";
|
||||
if ((tios.c_cflag & CSIZE) == CS8) os << " CS8 ";
|
||||
if (tios.c_cflag & CSTOPB) os << " CSTOPB";
|
||||
if (tios.c_cflag & HUPCL) os << " HUPCL ";
|
||||
if (tios.c_cflag & PARENB) os << " PARENB";
|
||||
if (tios.c_cflag & PARODD) os << " PARODD";
|
||||
speed_t speed = cfgetispeed(&tios);
|
||||
int baud = 0;
|
||||
if (speed == B9600) baud = 9600;
|
||||
if (speed == B19200) baud = 19200;
|
||||
if (speed == B38400) baud = 38400;
|
||||
if (speed == B57600) baud = 57600;
|
||||
if (speed == B115200) baud = 115200;
|
||||
if (speed == B230400) baud = 230400;
|
||||
if (speed == B460800) baud = 460800;
|
||||
if (speed == B500000) baud = 500000;
|
||||
if (speed == B921600) baud = 921600;
|
||||
if (speed == B1000000) baud = 1000000;
|
||||
if (speed == B2000000) baud = 2000000;
|
||||
if (speed == B3000000) baud = 3000000;
|
||||
os << " speed: " << RosPrintf(baud, "d", 7);
|
||||
os << endl;
|
||||
|
||||
os << bl << " c_lflag : " << RosPrintf(tios.c_lflag,"x0",8);
|
||||
if (tios.c_lflag & ECHO) os << " ECHO ";
|
||||
if (tios.c_lflag & ECHOE) os << " ECHOE ";
|
||||
if (tios.c_lflag & ECHOK) os << " ECHOK ";
|
||||
if (tios.c_lflag & ECHONL) os << " ECHONL";
|
||||
if (tios.c_lflag & ICANON) os << " ICANON";
|
||||
if (tios.c_lflag & IEXTEN) os << " IEXTEN";
|
||||
if (tios.c_lflag & ISIG) os << " ISIG ";
|
||||
if (tios.c_lflag & NOFLSH) os << " NOFLSH";
|
||||
if (tios.c_lflag & TOSTOP) os << " TOSTOP";
|
||||
os << endl;
|
||||
|
||||
os << bl << " c_cc : " << endl;
|
||||
os << bl << " [VEOF] : " << RosPrintf(tios.c_cc[VEOF],"o",3);
|
||||
os << " [VEOL] : " << RosPrintf(tios.c_cc[VEOL],"o",3);
|
||||
os << " [VERASE]: " << RosPrintf(tios.c_cc[VERASE],"o",3);
|
||||
os << " [VINTR] : " << RosPrintf(tios.c_cc[VINTR],"o",3) << endl;
|
||||
os << bl << " [VKILL] : " << RosPrintf(tios.c_cc[VKILL],"o",3);
|
||||
os << " [VQUIT] : " << RosPrintf(tios.c_cc[VQUIT],"o",3);
|
||||
os << " [VSUSP] : " << RosPrintf(tios.c_cc[VSUSP],"o",3);
|
||||
os << " [VSTART]: " << RosPrintf(tios.c_cc[VSTART],"o",3) << endl;
|
||||
os << bl << " [VSTOP] : " << RosPrintf(tios.c_cc[VSTOP],"o",3);
|
||||
os << " [VMIN] : " << RosPrintf(tios.c_cc[VMIN],"o",3);
|
||||
os << " [VTIME] : " << RosPrintf(tios.c_cc[VTIME],"o",3) << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RlinkPortTerm_NoInline))
|
||||
#define inline
|
||||
//#include "RlinkPortTerm.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
61
tools/src/librlink/RlinkPortTerm.hpp
Normal file
61
tools/src/librlink/RlinkPortTerm.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// $Id: RlinkPortTerm.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RlinkPortTerm.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RlinkPortTerm.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RlinkPortTerm
|
||||
#define included_Retro_RlinkPortTerm 1
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#include "RlinkPort.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RlinkPortTerm : public RlinkPort {
|
||||
public:
|
||||
|
||||
RlinkPortTerm();
|
||||
virtual ~RlinkPortTerm();
|
||||
|
||||
virtual bool Open(const std::string& url, RerrMsg& emsg);
|
||||
virtual void Close();
|
||||
|
||||
virtual void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
||||
|
||||
protected:
|
||||
void DumpTios(std::ostream& os, int ind, const std::string& name,
|
||||
const struct termios& tios) const;
|
||||
|
||||
protected:
|
||||
struct termios fTiosOld;
|
||||
struct termios fTiosNew;
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RlinkPortTerm_NoInline))
|
||||
//#include "RlinkPortTerm.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1
tools/src/librlinktpp/.cvsignore
Normal file
1
tools/src/librlinktpp/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
*.dep
|
||||
54
tools/src/librlinktpp/Makefile
Normal file
54
tools/src/librlinktpp/Makefile
Normal file
@@ -0,0 +1,54 @@
|
||||
# $Id: Makefile 372 2011-03-20 22:48:11Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-03-20 372 1.0.1 renamed ..tcl -> ..tpp
|
||||
# 2011-02-12 360 1.0 Initial version
|
||||
#---
|
||||
#
|
||||
# Name of the sharable library
|
||||
#
|
||||
SONAME = rlinktpp
|
||||
SOMAJV = 1
|
||||
SOMINV = 0
|
||||
#
|
||||
# Compile and Link search paths
|
||||
#
|
||||
INCLFLAGS = -I/usr/include/tcl8.4 -I${RETROBASE}/tools/src
|
||||
LDLIBS = -L${RETROBASE}/tools/lib -lrtools -lrtcltools -lrlink
|
||||
#
|
||||
# Object files to be included
|
||||
#
|
||||
OBJ_all = Rlinktpp_Init.o RtclRlinkConnect.o
|
||||
#
|
||||
DEP_all = $(OBJ_all:.o=.dep)
|
||||
#
|
||||
#- generic part ----------------------------------------------------------------
|
||||
#
|
||||
SOFILE = lib$(SONAME).so
|
||||
SOFILEV = lib$(SONAME).so.$(SOMAJV)
|
||||
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV)
|
||||
#
|
||||
include $(RETROBASE)/tools/make/generic_cpp.mk
|
||||
include $(RETROBASE)/tools/make/generic_dep.mk
|
||||
include $(RETROBASE)/tools/make/generic_so.mk
|
||||
#
|
||||
# The magic autodependcy include
|
||||
#
|
||||
include $(DEP_all)
|
||||
#
|
||||
# cleanup phonies:
|
||||
#
|
||||
.PHONY : clean cleandep realclean
|
||||
clean :
|
||||
@ rm -f $(OBJ_all)
|
||||
@ echo "Object files removed"
|
||||
#
|
||||
cleandep :
|
||||
@ rm -f $(DEP_all)
|
||||
@ echo "Dependency files removed"
|
||||
#
|
||||
realclean : clean cleandep
|
||||
@ rm -f $(SOPATH)/lib$(SONAME).a $(SOPATH)/lib$(SONAME).so*
|
||||
@ echo "Libraries removed"
|
||||
#
|
||||
62
tools/src/librlinktpp/Rlinktpp_Init.cpp
Normal file
62
tools/src/librlinktpp/Rlinktpp_Init.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// $Id: Rlinktpp_Init.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-20 372 1.0.2 renamed ..tcl -> ..tpp
|
||||
// 2011-03-19 371 1.0.1 moved Bvi into librtoolstcl
|
||||
// 2011-02-11 360 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rlinktpp_Init.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of Rlinktpp_Init .
|
||||
*/
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "librtcltools/RtclClassOwned.hpp"
|
||||
#include "RtclRlinkConnect.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
extern "C" int Rlinktpp_Init(Tcl_Interp* interp)
|
||||
{
|
||||
int irc;
|
||||
|
||||
// use stubs
|
||||
const char* vers = Tcl_InitStubs(interp, TCL_VERSION, 0);
|
||||
if (vers == NULL) return TCL_ERROR;
|
||||
|
||||
// declare package name and version
|
||||
irc = Tcl_PkgProvide(interp, "rlinktpp", "1.0.0");
|
||||
if (irc != TCL_OK) return irc;
|
||||
|
||||
try {
|
||||
// register class commands
|
||||
RtclClassOwned<RtclRlinkConnect>::CreateClass(interp, "rlinkconnect",
|
||||
"RlinkConnect");
|
||||
return TCL_OK;
|
||||
|
||||
} catch (exception& e) {
|
||||
Tcl_AppendResult(interp, "-E: exception caught in Rlinktpp_Init: \"",
|
||||
e.what(), "\"", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
833
tools/src/librlinktpp/RtclRlinkConnect.cpp
Normal file
833
tools/src/librlinktpp/RtclRlinkConnect.cpp
Normal file
@@ -0,0 +1,833 @@
|
||||
// $Id: RtclRlinkConnect.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-02-11 360 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclRlinkConnect.cpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Implemenation of class RtclRlinkConnect.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include "librtcltools/Rtcl.hpp"
|
||||
#include "librtcltools/RtclOPtr.hpp"
|
||||
#include "librtcltools/RtclNameSet.hpp"
|
||||
#include "librtcltools/RtclStats.hpp"
|
||||
#include "librtools/RmethDsc.hpp"
|
||||
#include "librtools/RosPrintf.hpp"
|
||||
#include "librlink/RlinkCommandList.hpp"
|
||||
#include "RtclRlinkConnect.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RtclRlinkConnect
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RtclRlinkConnect::RtclRlinkConnect(Tcl_Interp* interp, const char* name)
|
||||
: RtclProxyOwned<RlinkConnect>("RlinkConnect", interp, name,
|
||||
new RlinkConnect()),
|
||||
fErrCnt(0),
|
||||
fLogFileName("-")
|
||||
{
|
||||
typedef RmethDsc<RtclRlinkConnect, RtclArgs> mdsc_t;
|
||||
AddMeth("open", new mdsc_t(this, &RtclRlinkConnect::M_open));
|
||||
AddMeth("close", new mdsc_t(this, &RtclRlinkConnect::M_close));
|
||||
AddMeth("exec", new mdsc_t(this, &RtclRlinkConnect::M_exec));
|
||||
AddMeth("amap", new mdsc_t(this, &RtclRlinkConnect::M_amap));
|
||||
AddMeth("errcnt", new mdsc_t(this, &RtclRlinkConnect::M_errcnt));
|
||||
AddMeth("wtlam", new mdsc_t(this, &RtclRlinkConnect::M_wtlam));
|
||||
AddMeth("oob", new mdsc_t(this, &RtclRlinkConnect::M_oob));
|
||||
AddMeth("stats", new mdsc_t(this, &RtclRlinkConnect::M_stats));
|
||||
AddMeth("log", new mdsc_t(this, &RtclRlinkConnect::M_log));
|
||||
AddMeth("print", new mdsc_t(this, &RtclRlinkConnect::M_print));
|
||||
AddMeth("dump", new mdsc_t(this, &RtclRlinkConnect::M_dump));
|
||||
AddMeth("config", new mdsc_t(this, &RtclRlinkConnect::M_config));
|
||||
AddMeth("$default", new mdsc_t(this, &RtclRlinkConnect::M_default));
|
||||
|
||||
for (size_t i=0; i<8; i++) {
|
||||
fCmdnameObj[i] = Tcl_NewStringObj(RlinkCommand::CommandName(i), -1);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RtclRlinkConnect::~RtclRlinkConnect()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_open(RtclArgs& args)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!args.GetArg("?path", path)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
RerrMsg emsg;
|
||||
if (args.NOptMiss() == 0) { // open path
|
||||
if (!Obj().Open(path, emsg)) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
}
|
||||
} else { // open
|
||||
string name = Obj().IsOpen() ? Obj().Port()->Url() : string();
|
||||
args.SetResult(name);
|
||||
}
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_close(RtclArgs& args)
|
||||
{
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
if (!Obj().IsOpen()) {
|
||||
args.AppendResult("-E: port not open", NULL);
|
||||
return kERR;
|
||||
}
|
||||
Obj().Close();
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_exec(RtclArgs& args)
|
||||
{
|
||||
static RtclNameSet optset("-rreg|-rblk|-wreg|-wblk|-stat|-attn|-init|"
|
||||
"-edata|-estat|-estatdef|"
|
||||
"-volatile|-print|-dump|-rlist");
|
||||
|
||||
Tcl_Interp* interp = args.Interp();
|
||||
|
||||
RlinkCommandList clist;
|
||||
string opt;
|
||||
uint16_t addr;
|
||||
|
||||
vector<string> vardata;
|
||||
vector<string> varstat;
|
||||
string varprint;
|
||||
string vardump;
|
||||
string varlist;
|
||||
|
||||
uint8_t estatdef_val = 0x00;
|
||||
uint8_t estatdef_msk = 0xff;
|
||||
|
||||
while (args.NextOpt(opt, optset)) {
|
||||
|
||||
size_t lsize = clist.Size();
|
||||
if (opt == "-rreg") { // -rreg addr ?varData ?varStat ---
|
||||
if (!GetAddr(args, Obj(), addr)) return kERR;
|
||||
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddRreg(addr);
|
||||
|
||||
} else if (opt == "-rblk") { // -rblk addr size ?varData ?varStat
|
||||
int32_t bsize;
|
||||
if (!GetAddr(args, Obj(), addr)) return kERR;
|
||||
if (!args.GetArg("bsize", bsize, 1, 256)) return kERR;
|
||||
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddRblk(addr, (size_t) bsize);
|
||||
|
||||
} else if (opt == "-wreg") { // -wreg addr data ?varStat -------
|
||||
uint16_t data;
|
||||
if (!GetAddr(args, Obj(), addr)) return kERR;
|
||||
if (!args.GetArg("data", data)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddWreg(addr, data);
|
||||
|
||||
} else if (opt == "-wblk") { // -wblk addr block ?varStat ------
|
||||
vector<uint16_t> block;
|
||||
if (!GetAddr(args, Obj(), addr)) return kERR;
|
||||
if (!args.GetArg("data", block, 1, 256)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddWblk(addr, block);
|
||||
|
||||
} else if (opt == "-stat") { // -stat varData ?varStat ---------
|
||||
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddStat();
|
||||
|
||||
} else if (opt == "-attn") { // -attn varData ?varStat ---------
|
||||
if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddAttn();
|
||||
|
||||
} else if (opt == "-init") { // -init addr data ?varStat -------
|
||||
uint16_t data;
|
||||
if (!GetAddr(args, Obj(), addr)) return kERR;
|
||||
if (!args.GetArg("data", data)) return kERR;
|
||||
if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
|
||||
clist.AddInit(addr, data);
|
||||
|
||||
} else if (opt == "-edata") { // -edata data ?mask --------------
|
||||
if (!ClistNonEmpty(args, clist)) return kERR;
|
||||
if (clist[lsize-1].Expect()==0) {
|
||||
clist.LastExpect(new RlinkCommandExpect());
|
||||
}
|
||||
if (clist[lsize-1].Command() == RlinkCommand::kCmdRblk) {
|
||||
vector<uint16_t> data;
|
||||
vector<uint16_t> mask;
|
||||
size_t bsize = clist[lsize-1].BlockSize();
|
||||
if (!args.GetArg("data", data, 0, bsize)) return kERR;
|
||||
if (!args.GetArg("??mask", mask, 0, bsize)) return kERR;
|
||||
clist[lsize-1].Expect()->SetBlock(data, mask);
|
||||
} else {
|
||||
uint16_t data=0;
|
||||
uint16_t mask=0;
|
||||
if (!args.GetArg("data", data)) return kERR;
|
||||
if (!args.GetArg("??mask", mask)) return kERR;
|
||||
clist[lsize-1].Expect()->SetData(data, mask);
|
||||
}
|
||||
|
||||
} else if (opt == "-estat") { // -estat ?stat ?mask -------------
|
||||
if (!ClistNonEmpty(args, clist)) return kERR;
|
||||
uint8_t stat=0;
|
||||
uint8_t mask=0;
|
||||
if (!args.GetArg("??stat", stat)) return kERR;
|
||||
if (!args.GetArg("??mask", mask)) return kERR;
|
||||
if (args.NOptMiss() == 2) mask = 0xff;
|
||||
if (clist[lsize-1].Expect()==0) {
|
||||
clist.LastExpect(new RlinkCommandExpect());
|
||||
}
|
||||
clist[lsize-1].Expect()->SetStatus(stat, mask);
|
||||
|
||||
} else if (opt == "-estatdef") { // -estatdef ?stat ?mask -----------
|
||||
uint8_t stat=0;
|
||||
uint8_t mask=0;
|
||||
if (!args.GetArg("??stat", stat)) return kERR;
|
||||
if (!args.GetArg("??mask", mask)) return kERR;
|
||||
if (args.NOptMiss() == 2) mask = 0xff;
|
||||
estatdef_val = stat;
|
||||
estatdef_msk = mask;
|
||||
|
||||
} else if (opt == "-volatile") { // -volatile ----------------------
|
||||
if (!ClistNonEmpty(args, clist)) return kERR;
|
||||
clist.LastVolatile();
|
||||
|
||||
} else if (opt == "-print") { // -print ?varRes -----------------
|
||||
varprint = "-";
|
||||
if (!args.GetArg("??varRes", varprint)) return kERR;
|
||||
} else if (opt == "-dump") { // -dump ?varRes ------------------
|
||||
vardump = "-";
|
||||
if (!args.GetArg("??varRes", vardump)) return kERR;
|
||||
} else if (opt == "-rlist") { // -rlist ?varRes -----------------
|
||||
varlist = "-";
|
||||
if (!args.GetArg("??varRes", varlist)) return kERR;
|
||||
}
|
||||
|
||||
if (lsize != clist.Size()) { // cmd added to clist (ind=lsize!)
|
||||
if (estatdef_msk != 0xff) { // estatdef defined
|
||||
if (clist[lsize].Expect()==0) {
|
||||
clist.LastExpect(new RlinkCommandExpect());
|
||||
}
|
||||
clist[lsize].Expect()->SetStatus(estatdef_val, estatdef_msk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nact = 0;
|
||||
if (varprint == "-") nact += 1;
|
||||
if (vardump == "-") nact += 1;
|
||||
if (varlist == "-") nact += 1;
|
||||
if (nact > 1) {
|
||||
args.AppendResult("-E: more that one of -print,-dump,-list without ",
|
||||
"target variable found", NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
RerrMsg emsg;
|
||||
|
||||
if (!Obj().Exec(clist, emsg)) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
}
|
||||
|
||||
for (size_t icmd=0; icmd<clist.Size(); icmd++) {
|
||||
RlinkCommand& cmd = clist[icmd];
|
||||
|
||||
if (cmd.TestFlagAny(RlinkCommand::kFlagChkStat)) fErrCnt += 1;
|
||||
if (cmd.TestFlagAny(RlinkCommand::kFlagChkData)) fErrCnt += 1;
|
||||
|
||||
if (icmd<vardata.size() && !vardata[icmd].empty()) {
|
||||
RtclOPtr pres;
|
||||
vector<uint16_t> retstat;
|
||||
RtclOPtr pele;
|
||||
switch (cmd.Command()) {
|
||||
case RlinkCommand::kCmdRreg:
|
||||
case RlinkCommand::kCmdAttn:
|
||||
pres = Tcl_NewIntObj((int)cmd.Data());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdRblk:
|
||||
pres = Rtcl::NewListIntObj(cmd.Block());
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdStat:
|
||||
retstat.resize(2);
|
||||
retstat[0] = cmd.StatRequest();
|
||||
retstat[1] = cmd.Data();
|
||||
pres = Rtcl::NewListIntObj(retstat);
|
||||
break;
|
||||
}
|
||||
if(!Rtcl::SetVar(interp, vardata[icmd], pres)) return kERR;
|
||||
}
|
||||
|
||||
if (icmd<varstat.size() && !varstat[icmd].empty()) {
|
||||
RtclOPtr pres = Tcl_NewIntObj((int)cmd.Status());
|
||||
if (!Rtcl::SetVar(interp, varstat[icmd], pres)) return kERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!varprint.empty()) {
|
||||
ostringstream sos;
|
||||
const RlinkConnect::LogOpts& logopts = Obj().GetLogOpts();
|
||||
clist.Print(sos, &Obj().AddrMap(), logopts.baseaddr, logopts.basedata,
|
||||
logopts.basestat);
|
||||
RtclOPtr pobj = Rtcl::NewLinesObj(sos);
|
||||
if (!Rtcl::SetVarOrResult(args.Interp(), varprint, pobj)) return kERR;
|
||||
}
|
||||
|
||||
if (!vardump.empty()) {
|
||||
ostringstream sos;
|
||||
clist.Dump(sos, 0);
|
||||
RtclOPtr pobj = Rtcl::NewLinesObj(sos);
|
||||
if (!Rtcl::SetVarOrResult(args.Interp(), vardump, pobj)) return kERR;
|
||||
}
|
||||
|
||||
if (!varlist.empty()) {
|
||||
RtclOPtr prlist = Tcl_NewListObj(0, NULL);
|
||||
for (size_t icmd=0; icmd<clist.Size(); icmd++) {
|
||||
RlinkCommand& cmd(clist[icmd]);
|
||||
|
||||
RtclOPtr pres = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(NULL, pres, fCmdnameObj[cmd.Command()]);
|
||||
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Request()));
|
||||
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Flags()));
|
||||
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Status()));
|
||||
|
||||
switch (cmd.Command()) {
|
||||
case RlinkCommand::kCmdRreg:
|
||||
case RlinkCommand::kCmdAttn:
|
||||
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Data()));
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdRblk:
|
||||
Tcl_ListObjAppendElement(NULL, pres,
|
||||
Rtcl::NewListIntObj(cmd.Block()));
|
||||
break;
|
||||
|
||||
case RlinkCommand::kCmdStat:
|
||||
Tcl_ListObjAppendElement(NULL, pres,
|
||||
Tcl_NewIntObj((int)cmd.StatRequest()));
|
||||
Tcl_ListObjAppendElement(NULL, pres, Tcl_NewIntObj((int)cmd.Data()));
|
||||
break;
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, prlist, pres);
|
||||
}
|
||||
if (!Rtcl::SetVarOrResult(args.Interp(), varlist, prlist)) return kERR;
|
||||
}
|
||||
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_amap(RtclArgs& args)
|
||||
{
|
||||
static RtclNameSet optset("-name|-testname|-testaddr|-insert|-erase|"
|
||||
"-clear|-print");
|
||||
|
||||
const RlinkAddrMap& addrmap = Obj().AddrMap();
|
||||
|
||||
string opt;
|
||||
string name;
|
||||
uint16_t addr=0;
|
||||
|
||||
if (args.NextOpt(opt, optset)) {
|
||||
if (opt == "-name") { // amap -name addr
|
||||
if (!args.GetArg("addr", addr, 0x00ff)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
string tstname;
|
||||
if(addrmap.Find(addr, tstname)) {
|
||||
args.SetResult(tstname);
|
||||
} else {
|
||||
args.AppendResult("-E: address \"", args.PeekArgString(-1),
|
||||
"\" not mapped", NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
} else if (opt == "-testname") { // amap -testname name
|
||||
if (!args.GetArg("name", name)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
uint16_t tstaddr;
|
||||
args.SetResult(int(addrmap.Find(name, tstaddr)));
|
||||
|
||||
} else if (opt == "-testaddr") { // amap -testaddr addr
|
||||
if (!args.GetArg("addr", addr, 0x00ff)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
string tstname;
|
||||
args.SetResult(int(addrmap.Find(addr, tstname)));
|
||||
|
||||
} else if (opt == "-insert") { // amap -insert name addr
|
||||
uint16_t tstaddr;
|
||||
string tstname;
|
||||
int tstint;
|
||||
if (!args.GetArg("name", name)) return kERR;
|
||||
// enforce that the name is not a valid representation of an int
|
||||
if (Tcl_GetIntFromObj(NULL, args[args.NDone()-1], &tstint) == kOK) {
|
||||
args.AppendResult("-E: name should not look like an int but \"",
|
||||
name.c_str(), "\" does", NULL);
|
||||
return kERR;
|
||||
}
|
||||
if (!args.GetArg("addr", addr, 0x00ff)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
if (addrmap.Find(name, tstaddr)) {
|
||||
args.AppendResult("-E: mapping already defined for \"", name.c_str(),
|
||||
"\"", NULL);
|
||||
return kERR;
|
||||
}
|
||||
if (addrmap.Find(addr, tstname)) {
|
||||
args.AppendResult("-E: mapping already defined for address \"",
|
||||
args.PeekArgString(-1), "\"", NULL);
|
||||
return kERR;
|
||||
}
|
||||
Obj().AddrMapInsert(name, addr);
|
||||
|
||||
} else if (opt == "-erase") { // amap -erase name
|
||||
if (!args.GetArg("name", name)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
if (!Obj().AddrMapErase(name)) {
|
||||
args.AppendResult("-E: no mapping defined for \"", name.c_str(),
|
||||
"\"", NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
} else if (opt == "-clear") { // amap -clear
|
||||
if (!args.AllDone()) return kERR;
|
||||
Obj().AddrMapClear();
|
||||
|
||||
} else if (opt == "-print") { // amap -print
|
||||
if (!args.AllDone()) return kERR;
|
||||
ostringstream sos;
|
||||
addrmap.Print(sos);
|
||||
args.AppendResultLines(sos);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!args.OptValid()) return kERR;
|
||||
if (!args.GetArg("?name", name)) return kERR;
|
||||
if (args.NOptMiss()==0) { // amap name
|
||||
uint16_t tstaddr;
|
||||
if(addrmap.Find(name, tstaddr)) {
|
||||
args.SetResult(int(tstaddr));
|
||||
} else {
|
||||
args.AppendResult("-E: no mapping defined for \"", name.c_str(),
|
||||
"\"", NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
} else { // amap
|
||||
RtclOPtr plist = Tcl_NewListObj(0, NULL);
|
||||
const RlinkAddrMap::amap_t amap = addrmap.Amap();
|
||||
for (RlinkAddrMap::amap_cit_t it=amap.begin(); it!=amap.end(); it++) {
|
||||
Tcl_Obj* tpair[2];
|
||||
tpair[0] = Tcl_NewIntObj(it->first);
|
||||
tpair[1] = Tcl_NewStringObj((it->second).c_str(),(it->second).length());
|
||||
Tcl_ListObjAppendElement(NULL, plist, Tcl_NewListObj(2, tpair));
|
||||
}
|
||||
args.SetResult(plist);
|
||||
}
|
||||
}
|
||||
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_errcnt(RtclArgs& args)
|
||||
{
|
||||
static RtclNameSet optset("-clear");
|
||||
string opt;
|
||||
bool fclear = false;
|
||||
|
||||
while (args.NextOpt(opt, optset)) {
|
||||
if (opt == "-clear") fclear = true;
|
||||
}
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
args.SetResult(int(fErrCnt));
|
||||
if (fclear) fErrCnt = 0;
|
||||
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_wtlam(RtclArgs& args)
|
||||
{
|
||||
double tout;
|
||||
if (!args.GetArg("tout", tout, 0.001)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
RerrMsg emsg;
|
||||
double twait = Obj().WaitAttn(tout, emsg);
|
||||
|
||||
if (twait == -2.) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
} else if (twait == -1.) {
|
||||
if (Obj().GetLogOpts().printlevel >= 2) {
|
||||
Obj().LogFile()() << "-- wtlam to=" << RosPrintf(tout, "f", 0,3)
|
||||
<< " FAIL timeout" << endl;
|
||||
fErrCnt += 1;
|
||||
args.SetResult(tout);
|
||||
return kOK;
|
||||
}
|
||||
}
|
||||
|
||||
if (Obj().GetLogOpts().printlevel >= 1) {
|
||||
Obj().LogFile()() << "-- wtlam to=" << RosPrintf(tout, "f", 0,3)
|
||||
<< " T=" << RosPrintf(twait, "f", 0,3)
|
||||
<< " OK" << endl;
|
||||
}
|
||||
|
||||
args.SetResult(twait);
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_oob(RtclArgs& args)
|
||||
{
|
||||
static RtclNameSet optset("-rlmon|-rbmon|-sbcntl|-sbdata");
|
||||
|
||||
string opt;
|
||||
uint16_t addr;
|
||||
uint16_t data;
|
||||
RerrMsg emsg;
|
||||
|
||||
if (args.NextOpt(opt, optset)) {
|
||||
if (opt == "-rlmon") { // oob -rlmon (0|1)
|
||||
if (!args.GetArg("val", data, 1)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
addr = 15; // rlmon on bit 15
|
||||
if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
}
|
||||
|
||||
} else if (opt == "-rbmon") { // oob -rbmon (0|1)
|
||||
if (!args.GetArg("val", data, 1)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
addr = 14; // rbmon on bit 14
|
||||
if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
}
|
||||
|
||||
} else if (opt == "-sbcntl") { // oob -sbcntl bit (0|1)
|
||||
if (!args.GetArg("bit", addr, 15)) return kERR;
|
||||
if (!args.GetArg("val", data, 1)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
if (!Obj().SndOob(0x00, (addr<<8)+data, emsg)) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
}
|
||||
|
||||
} else if (opt == "-sbdata") { // oob -sbdata addr val
|
||||
if (!args.GetArg("bit", addr, 0x0ff)) return kERR;
|
||||
if (!args.GetArg("val", data)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
if (!Obj().SndOob(addr, data, emsg)) {
|
||||
args.AppendResult(emsg.Message());
|
||||
return kERR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args.AppendResult("-E: missing option, one of "
|
||||
"-rlmon,-rbmon,-sbcntl,-sbdata",
|
||||
NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_stats(RtclArgs& args)
|
||||
{
|
||||
RtclStats::Context cntx;
|
||||
if (!RtclStats::GetArgs(args, cntx)) return kERR;
|
||||
if (!RtclStats::Exec(args, cntx, Obj().Stats())) return kERR;
|
||||
if (Obj().Port()) {
|
||||
if (!RtclStats::Exec(args, cntx, Obj().Port()->Stats())) return kERR;
|
||||
}
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_log(RtclArgs& args)
|
||||
{
|
||||
string msg;
|
||||
if (!args.GetArg("msg", msg)) return kERR;
|
||||
if (!args.AllDone()) return kERR;
|
||||
if (Obj().GetLogOpts().printlevel != 0 ||
|
||||
Obj().GetLogOpts().dumplevel != 0 ||
|
||||
Obj().GetLogOpts().tracelevel != 0) {
|
||||
Obj().LogFile()() << "# " << msg << endl;
|
||||
}
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_print(RtclArgs& args)
|
||||
{
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
ostringstream sos;
|
||||
Obj().Print(sos);
|
||||
args.SetResult(sos);
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_dump(RtclArgs& args)
|
||||
{
|
||||
if (!args.AllDone()) return kERR;
|
||||
|
||||
ostringstream sos;
|
||||
Obj().Dump(sos, 0);
|
||||
args.SetResult(sos);
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_config(RtclArgs& args)
|
||||
{
|
||||
static RtclNameSet optset("-baseaddr|-basedata|-basestat|"
|
||||
"-logfile|-logprintlevel|-logdumplevel|"
|
||||
"-logtracelevel");
|
||||
|
||||
RlinkConnect::LogOpts logopts = Obj().GetLogOpts();
|
||||
|
||||
if (args.NDone() == (size_t)args.Objc()) {
|
||||
ostringstream sos;
|
||||
sos << "-baseaddr " << RosPrintf(logopts.baseaddr, "d")
|
||||
<< " -basedata " << RosPrintf(logopts.basedata, "d")
|
||||
<< " -basestat " << RosPrintf(logopts.basestat, "d")
|
||||
<< " -logfile {" << fLogFileName << "}"
|
||||
<< " -logprintlevel " << RosPrintf(logopts.printlevel, "d")
|
||||
<< " -logdumplevel " << RosPrintf(logopts.dumplevel, "d")
|
||||
<< " -logtracelevel " << RosPrintf(logopts.tracelevel, "d");
|
||||
args.AppendResult(sos);
|
||||
return kOK;
|
||||
}
|
||||
|
||||
string opt;
|
||||
while (args.NextOpt(opt, optset)) {
|
||||
if (opt == "-baseaddr") { // -baseaddr ?base -----------------
|
||||
if (!ConfigBase(args, logopts.baseaddr)) return kERR;
|
||||
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts);
|
||||
|
||||
} else if (opt == "-basedata") { // -basedata ?base -----------------
|
||||
if (!ConfigBase(args, logopts.basedata)) return kERR;
|
||||
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts);
|
||||
|
||||
} else if (opt == "-basestat") { // -basestat ?base -----------------
|
||||
if (!ConfigBase(args, logopts.basestat)) return kERR;
|
||||
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts);
|
||||
|
||||
} else if (opt == "-logfile") { // -logfile ?name ------------------
|
||||
if (!args.Config("??name", fLogFileName)) return false;
|
||||
if (args.NOptMiss() == 0) { // new filename ?
|
||||
if (fLogFileName == "-") {
|
||||
Obj().LogUseStream(&cout);
|
||||
} else {
|
||||
if (!Obj().LogOpen(fLogFileName)) {
|
||||
args.AppendResult("-E: open failed for \"",
|
||||
fLogFileName.c_str(), "\", using stdout", NULL);
|
||||
Obj().LogUseStream(&cout);
|
||||
fLogFileName = "-";
|
||||
return kERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (opt == "-logprintlevel") { // -logprintlevel ?loglevel --------
|
||||
if (!args.Config("??loglevel", logopts.printlevel, 3)) return false;
|
||||
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts);
|
||||
|
||||
} else if (opt == "-logdumplevel") { // -logdumplevel ?loglevel ---------
|
||||
if (!args.Config("??loglevel", logopts.dumplevel, 3)) return false;
|
||||
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts);
|
||||
|
||||
} else if (opt == "-logtracelevel") { // -logtracelevel ?loglevel --------
|
||||
if (!args.Config("??loglevel", logopts.tracelevel, 3)) return false;
|
||||
if (args.NOptMiss() == 0) Obj().SetLogOpts(logopts);
|
||||
}
|
||||
}
|
||||
|
||||
if (!args.AllDone()) return kERR;
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclRlinkConnect::M_default(RtclArgs& args)
|
||||
{
|
||||
if (!args.AllDone()) return kERR;
|
||||
ostringstream sos;
|
||||
const RlinkConnect::LogOpts& logopts = Obj().GetLogOpts();
|
||||
|
||||
sos << "print base: " << "addr " << RosPrintf(logopts.baseaddr, "d", 2)
|
||||
<< " data " << RosPrintf(logopts.basedata, "d", 2)
|
||||
<< " stat " << RosPrintf(logopts.basestat, "d", 2) << endl;
|
||||
sos << "logfile: " << fLogFileName
|
||||
<< " printlevel " << logopts.printlevel
|
||||
<< " dumplevel " << logopts.dumplevel;
|
||||
|
||||
args.AppendResultLines(sos);
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclRlinkConnect::GetAddr(RtclArgs& args, RlinkConnect& conn,
|
||||
uint16_t& addr)
|
||||
{
|
||||
Tcl_Obj* pobj=0;
|
||||
if (!args.GetArg("addr", pobj)) return kERR;
|
||||
|
||||
int tstint;
|
||||
// if a number is given..
|
||||
if (Tcl_GetIntFromObj(NULL, pobj, &tstint) == kOK) {
|
||||
if (tstint >= 0 && tstint <= 0x00ff) {
|
||||
addr = (uint16_t)tstint;
|
||||
} else {
|
||||
args.AppendResult("-E: value \"", Tcl_GetString(pobj),
|
||||
"\" for \"addr\" out of range 0...0x00ff", NULL);
|
||||
return false;
|
||||
}
|
||||
// if a name is given
|
||||
} else {
|
||||
string name(Tcl_GetString(pobj));
|
||||
uint16_t tstaddr;
|
||||
if (Obj().AddrMap().Find(name, tstaddr)) {
|
||||
addr = tstaddr;
|
||||
} else {
|
||||
args.AppendResult("-E: no address mapping known for \"",
|
||||
Tcl_GetString(pobj), "\"", NULL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclRlinkConnect::GetVarName(RtclArgs& args, const char* argname,
|
||||
size_t nind,
|
||||
std::vector<std::string>& varname)
|
||||
{
|
||||
while (varname.size() < nind+1) varname.push_back(string());
|
||||
string name;
|
||||
if (!args.GetArg(argname, name)) return false;
|
||||
if (name.length()) { // if variable defined
|
||||
char c = name[0];
|
||||
if (isdigit(c) || c=='+' || c=='-' ) { // check for mistaken number
|
||||
args.AppendResult("-E: invalid variable name \"", name.c_str(),
|
||||
"\": looks like a number", NULL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
varname[nind] = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclRlinkConnect::ConfigBase(RtclArgs& args, size_t& base)
|
||||
{
|
||||
size_t tmp = base;
|
||||
if (!args.Config("??base", tmp, 16, 2)) return false;
|
||||
if (tmp != base && tmp != 2 && tmp !=8 && tmp != 16) {
|
||||
args.AppendResult("-E: base must be 2, 8, or 16, found \"",
|
||||
args.PeekArgString(-1), "\"", NULL);
|
||||
}
|
||||
base = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclRlinkConnect::ClistNonEmpty(RtclArgs& args,
|
||||
const RlinkCommandList& clist)
|
||||
{
|
||||
if (clist.Size() == 0) {
|
||||
args.AppendResult("-E: -volatile not allowed on empty command list", NULL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RtclRlinkConnect_NoInline))
|
||||
#define inline
|
||||
//#include "RtclRlinkConnect.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
78
tools/src/librlinktpp/RtclRlinkConnect.hpp
Normal file
78
tools/src/librlinktpp/RtclRlinkConnect.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// $Id: RtclRlinkConnect.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-27 374 1.0 Initial version
|
||||
// 2011-02-11 360 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclRlinkConnect.hpp 375 2011-04-02 07:56:47Z mueller $
|
||||
\brief Declaration of class RtclRlinkConnect.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RtclRlinkConnect
|
||||
#define included_Retro_RtclRlinkConnect 1
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "librtcltools/RtclOPtr.hpp"
|
||||
#include "librtcltools/RtclProxyOwned.hpp"
|
||||
|
||||
#include "librlink/RlinkConnect.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RtclRlinkConnect : public RtclProxyOwned<RlinkConnect> {
|
||||
public:
|
||||
RtclRlinkConnect(Tcl_Interp* interp, const char* name);
|
||||
~RtclRlinkConnect();
|
||||
|
||||
protected:
|
||||
int M_open(RtclArgs& args);
|
||||
int M_close(RtclArgs& args);
|
||||
int M_exec(RtclArgs& args);
|
||||
int M_amap(RtclArgs& args);
|
||||
int M_errcnt(RtclArgs& args);
|
||||
int M_wtlam(RtclArgs& args);
|
||||
int M_oob(RtclArgs& args);
|
||||
int M_stats(RtclArgs& args);
|
||||
int M_log(RtclArgs& args);
|
||||
int M_print(RtclArgs& args);
|
||||
int M_dump(RtclArgs& args);
|
||||
int M_config(RtclArgs& args);
|
||||
int M_default(RtclArgs& args);
|
||||
|
||||
bool GetAddr(RtclArgs& args, RlinkConnect& conn, uint16_t& addr);
|
||||
bool GetVarName(RtclArgs& args, const char* argname,
|
||||
size_t nind, std::vector<std::string>& varname);
|
||||
bool ConfigBase(RtclArgs& args, size_t& base);
|
||||
bool ClistNonEmpty(RtclArgs& args,
|
||||
const RlinkCommandList& clist);
|
||||
|
||||
protected:
|
||||
RtclOPtr fCmdnameObj[8];
|
||||
size_t fErrCnt;
|
||||
std::string fLogFileName;
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RtclRlinkConnect_NoInline))
|
||||
//#include "RtclRlinkConnect.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1
tools/src/librtcltools/.cvsignore
Normal file
1
tools/src/librtcltools/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
*.dep
|
||||
54
tools/src/librtcltools/Makefile
Normal file
54
tools/src/librtcltools/Makefile
Normal file
@@ -0,0 +1,54 @@
|
||||
# $Id: Makefile 370 2011-03-14 18:33:43Z mueller $
|
||||
#
|
||||
# Revision History:
|
||||
# Date Rev Version Comment
|
||||
# 2011-02-11 360 1.0 Initial version
|
||||
#---
|
||||
#
|
||||
# Name of the sharable library
|
||||
#
|
||||
SONAME = rtcltools
|
||||
SOMAJV = 1
|
||||
SOMINV = 0
|
||||
#
|
||||
# Compile and Link search paths
|
||||
#
|
||||
INCLFLAGS = -I/usr/include/tcl8.4 -I${RETROBASE}/tools/src
|
||||
LDLIBS = -L${RETROBASE}/tools/lib -lrtools
|
||||
#
|
||||
# Object files to be included
|
||||
#
|
||||
OBJ_all = Rtcl.o RtclArgs.o RtclClassBase.o RtclContext.o \
|
||||
RtclNameSet.o RtclProxyBase.o RtclStats.o
|
||||
#
|
||||
DEP_all = $(OBJ_all:.o=.dep)
|
||||
#
|
||||
#- generic part ----------------------------------------------------------------
|
||||
#
|
||||
SOFILE = lib$(SONAME).so
|
||||
SOFILEV = lib$(SONAME).so.$(SOMAJV)
|
||||
SOFILEVV = lib$(SONAME).so.$(SOMAJV).$(SOMINV)
|
||||
#
|
||||
include $(RETROBASE)/tools/make/generic_cpp.mk
|
||||
include $(RETROBASE)/tools/make/generic_dep.mk
|
||||
include $(RETROBASE)/tools/make/generic_so.mk
|
||||
#
|
||||
# The magic autodependcy include
|
||||
#
|
||||
include $(DEP_all)
|
||||
#
|
||||
# cleanup phonies:
|
||||
#
|
||||
.PHONY : clean cleandep realclean
|
||||
clean :
|
||||
@ rm -f $(OBJ_all)
|
||||
@ echo "Object files removed"
|
||||
#
|
||||
cleandep :
|
||||
@ rm -f $(DEP_all)
|
||||
@ echo "Dependency files removed"
|
||||
#
|
||||
realclean : clean cleandep
|
||||
@ rm -f $(SOPATH)/lib$(SONAME).a $(SOPATH)/lib$(SONAME).so*
|
||||
@ echo "Libraries removed"
|
||||
#
|
||||
152
tools/src/librtcltools/Rtcl.cpp
Normal file
152
tools/src/librtcltools/Rtcl.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
// $Id: Rtcl.cpp 369 2011-03-13 22:39:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-13 369 1.0.2 add NewListIntObj(vector<uint8_t>)
|
||||
// 2011-03-05 366 1.0.1 add AppendResultNewLines()
|
||||
// 2011-02-26 364 1.0 Initial version
|
||||
// 2011-02-13 361 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rtcl.cpp 369 2011-03-13 22:39:26Z mueller $
|
||||
\brief Implemenation of Rtcl.
|
||||
*/
|
||||
|
||||
#include "Rtcl.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::Rtcl
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
Tcl_Obj* Rtcl::NewLinesObj(const std::string& str)
|
||||
{
|
||||
const char* data = str.data();
|
||||
int size = str.length();
|
||||
if (size>0 && data[size-1]=='\n') size -= 1;
|
||||
return Tcl_NewStringObj(data, size);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
Tcl_Obj* Rtcl::NewListIntObj(const std::vector<uint8_t>& vec)
|
||||
{
|
||||
if (vec.size() == 0) return Tcl_NewListObj(0, NULL);
|
||||
|
||||
vector<Tcl_Obj*> vobj;
|
||||
vobj.reserve(vec.size());
|
||||
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
vobj.push_back(Tcl_NewIntObj((int)vec[i]));
|
||||
}
|
||||
return Tcl_NewListObj(vobj.size(), vobj.data());
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
Tcl_Obj* Rtcl::NewListIntObj(const std::vector<uint16_t>& vec)
|
||||
{
|
||||
if (vec.size() == 0) return Tcl_NewListObj(0, NULL);
|
||||
|
||||
vector<Tcl_Obj*> vobj;
|
||||
vobj.reserve(vec.size());
|
||||
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
vobj.push_back(Tcl_NewIntObj((int)vec[i]));
|
||||
}
|
||||
return Tcl_NewListObj(vobj.size(), vobj.data());
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool Rtcl::SetVar(Tcl_Interp* interp, const std::string& varname, Tcl_Obj* pobj)
|
||||
{
|
||||
Tcl_Obj* pret = 0;
|
||||
|
||||
size_t pos_pbeg = varname.find_first_of('(');
|
||||
size_t pos_pend = varname.find_first_of(')');
|
||||
if (pos_pbeg != string::npos || pos_pend != string::npos) {
|
||||
if (pos_pbeg == string::npos || pos_pbeg == 0 ||
|
||||
pos_pend == string::npos || pos_pend != varname.length()-1 ||
|
||||
pos_pend-pos_pbeg <= 1) {
|
||||
Tcl_AppendResult(interp, "illformed array name \"", varname.c_str(),
|
||||
"\"", NULL);
|
||||
return false;
|
||||
}
|
||||
string arrname(varname.substr(0,pos_pbeg));
|
||||
string elename(varname.substr(pos_pbeg+1, pos_pend-pos_pbeg-1));
|
||||
|
||||
pret = Tcl_SetVar2Ex(interp, arrname.c_str(), elename.c_str(), pobj,
|
||||
TCL_LEAVE_ERR_MSG);
|
||||
} else {
|
||||
pret = Tcl_SetVar2Ex(interp, varname.c_str(), NULL, pobj,
|
||||
TCL_LEAVE_ERR_MSG);
|
||||
}
|
||||
|
||||
return pret!=0;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool Rtcl::SetVarOrResult(Tcl_Interp* interp, const std::string& varname,
|
||||
Tcl_Obj* pobj)
|
||||
{
|
||||
if (varname != "-") {
|
||||
return SetVar(interp, varname, pobj);
|
||||
}
|
||||
Tcl_SetObjResult(interp, pobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void Rtcl::AppendResultNewLines(Tcl_Interp* interp)
|
||||
{
|
||||
// check whether ObjResult is non-empty, in that case add an '\n'
|
||||
// that allows to append output from multiple AppendResultLines properly
|
||||
const char* res = Tcl_GetStringResult(interp);
|
||||
if (res && res[0]) {
|
||||
Tcl_AppendResult(interp, "\n", NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void Rtcl::SetResult(Tcl_Interp* interp, const std::string& str)
|
||||
{
|
||||
Tcl_SetObjResult(interp, NewLinesObj(str));
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_Rtcl_NoInline))
|
||||
#define inline
|
||||
#include "Rtcl.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
65
tools/src/librtcltools/Rtcl.hpp
Normal file
65
tools/src/librtcltools/Rtcl.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// $Id: Rtcl.hpp 369 2011-03-13 22:39:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-13 369 1.0.3 add NewListIntObj(vector<uint8_t>)
|
||||
// 2011-03-12 368 1.0.2 use namespace Rtcl
|
||||
// 2011-03-05 366 1.0.1 add AppendResultNewLines()
|
||||
// 2011-02-26 364 1.0 Initial version
|
||||
// 2011-02-18 362 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rtcl.hpp 369 2011-03-13 22:39:26Z mueller $
|
||||
\brief Declaration of class Rtcl.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_Rtcl
|
||||
#define included_Retro_Rtcl 1
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace Retro {
|
||||
|
||||
namespace Rtcl {
|
||||
Tcl_Obj* NewLinesObj(const std::string& str);
|
||||
Tcl_Obj* NewLinesObj(std::ostringstream& sos);
|
||||
|
||||
Tcl_Obj* NewListIntObj(const std::vector<uint8_t>& vec);
|
||||
Tcl_Obj* NewListIntObj(const std::vector<uint16_t>& vec);
|
||||
|
||||
bool SetVar(Tcl_Interp* interp,
|
||||
const std::string& varname, Tcl_Obj* pobj);
|
||||
bool SetVarOrResult(Tcl_Interp* interp,
|
||||
const std::string& varname, Tcl_Obj* pobj);
|
||||
|
||||
void AppendResultNewLines(Tcl_Interp* interp);
|
||||
|
||||
void SetResult(Tcl_Interp* interp, const std::string& str);
|
||||
void SetResult(Tcl_Interp* interp, std::ostringstream& sos);
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_Rtcl_NoInline))
|
||||
#include "Rtcl.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
tools/src/librtcltools/Rtcl.ipp
Normal file
47
tools/src/librtcltools/Rtcl.ipp
Normal file
@@ -0,0 +1,47 @@
|
||||
// $Id: Rtcl.ipp 365 2011-02-28 07:28:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-02-26 364 1.0 Initial version
|
||||
// 2011-02-18 362 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: Rtcl.ipp 365 2011-02-28 07:28:26Z mueller $
|
||||
\brief Implemenation (inline) of Rtcl.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline Tcl_Obj* Rtcl::NewLinesObj(std::ostringstream& sos)
|
||||
{
|
||||
return NewLinesObj(sos.str());
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void Rtcl::SetResult(Tcl_Interp* interp, std::ostringstream& sos)
|
||||
{
|
||||
SetResult(interp, sos.str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Retro
|
||||
547
tools/src/librtcltools/RtclArgs.cpp
Normal file
547
tools/src/librtcltools/RtclArgs.cpp
Normal file
@@ -0,0 +1,547 @@
|
||||
// $Id: RtclArgs.cpp 374 2011-03-27 17:02:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-26 373 1.0.4 add GetArg(float/double)
|
||||
// 2011-03-13 369 1.0.3 add GetArg(vector<unit8_t>); NextOpt clear NOptMiss
|
||||
// 2011-03-06 367 1.0.2 add Config() methods;
|
||||
// 2011-03-05 366 1.0.1 fObjc,fNDone now size_t; add NDone(), SetResult();
|
||||
// add GetArg(Tcl_Obj), PeekArgString();
|
||||
// 2011-02-26 364 1.0 Initial version
|
||||
// 2011-02-11 360 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclArgs.cpp 374 2011-03-27 17:02:47Z mueller $
|
||||
\brief Implemenation of RtclArgs.
|
||||
*/
|
||||
|
||||
//debug
|
||||
#include <iostream>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "RtclArgs.hpp"
|
||||
#include "Rtcl.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RtclArgs
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RtclArgs::RtclArgs()
|
||||
: fpInterp(0),
|
||||
fObjc(0),
|
||||
fObjv(0),
|
||||
fNDone(0),
|
||||
fNOptMiss(0),
|
||||
fNConfigRead(0),
|
||||
fOptErr(false),
|
||||
fArgErr(false)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RtclArgs::RtclArgs(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[],
|
||||
size_t nskip)
|
||||
: fpInterp(interp),
|
||||
fObjc((size_t)objc),
|
||||
fObjv(objv),
|
||||
fNDone((nskip<=(size_t)objc) ? nskip : (size_t)objc),
|
||||
fNOptMiss(0),
|
||||
fNConfigRead(0),
|
||||
fOptErr(false),
|
||||
fArgErr(false)
|
||||
{
|
||||
if (objc < 0)
|
||||
throw invalid_argument("RtclArgs::ctor: objc must be >= 0");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RtclArgs::RtclArgs(const RtclArgs& rhs)
|
||||
: fpInterp(rhs.fpInterp),
|
||||
fObjc(rhs.fObjc),
|
||||
fObjv(rhs.fObjv),
|
||||
fNDone(rhs.fNDone),
|
||||
fNOptMiss(rhs.fNOptMiss),
|
||||
fOptErr(rhs.fOptErr),
|
||||
fArgErr(rhs.fArgErr)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RtclArgs::~RtclArgs()
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
Tcl_Obj* RtclArgs::Objv(size_t ind) const
|
||||
{
|
||||
if (ind >= (size_t)fObjc)
|
||||
throw out_of_range("RtclArgs::Objv: index out-of-range");
|
||||
return fObjv[ind];
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, Tcl_Obj*& pval)
|
||||
{
|
||||
Tcl_Obj* pobj;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
pval = pobj;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, const char*& val)
|
||||
{
|
||||
Tcl_Obj* pobj;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
val = Tcl_GetString(pobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, std::string& val)
|
||||
{
|
||||
Tcl_Obj* pobj;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
val = Tcl_GetString(pobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, int8_t& val, int8_t min, int8_t max)
|
||||
{
|
||||
int32_t val32 = (int32_t)val;
|
||||
bool ret = GetArg(name, val32, (int32_t)min, (int32_t)max);
|
||||
val = (int8_t) val32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, uint8_t& val, uint8_t max, uint8_t min)
|
||||
{
|
||||
uint32_t val32 = (uint32_t)val;
|
||||
bool ret = GetArg(name, val32, (uint32_t)max, (uint32_t)min);
|
||||
val = (uint8_t) val32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, int16_t& val, int16_t min, int16_t max)
|
||||
{
|
||||
int32_t val32 = (int32_t)val;
|
||||
bool ret = GetArg(name, val32, (int32_t)min, (int32_t)max);
|
||||
val = (int16_t) val32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, uint16_t& val, uint16_t max,
|
||||
uint16_t min)
|
||||
{
|
||||
uint32_t val32 = (uint32_t)val;
|
||||
bool ret = GetArg(name, val32, (uint32_t)max, (uint32_t)min);
|
||||
val = (uint16_t) val32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, int32_t& val, int32_t min, int32_t max)
|
||||
{
|
||||
Tcl_Obj* pobj;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
int objval;
|
||||
if (Tcl_GetIntFromObj(fpInterp, pobj, &objval) != TCL_OK) return false;
|
||||
if (objval < min || objval > max) {
|
||||
ostringstream sos;
|
||||
sos << "-E: value '" << objval << "' for '" << name << "' out of range "
|
||||
<< min << "..." << max;
|
||||
AppendResult(sos);
|
||||
return false;
|
||||
}
|
||||
val = (int32_t) objval;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, uint32_t& val, uint32_t max,
|
||||
uint32_t min)
|
||||
{
|
||||
Tcl_Obj* pobj;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
int objval;
|
||||
if (Tcl_GetIntFromObj(fpInterp, pobj, &objval) != TCL_OK) return false;
|
||||
unsigned int objuval = objval;
|
||||
if (objuval < min || objuval > max) {
|
||||
ostringstream sos;
|
||||
sos << "-E: value '" << objuval << "' for '" << name << "' out of range "
|
||||
<< min << "..." << max;
|
||||
AppendResult(sos);
|
||||
return false;
|
||||
}
|
||||
val = (uint32_t) objval;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, float& val, float min, float max)
|
||||
{
|
||||
double vald = (double)val;
|
||||
bool ret = GetArg(name, vald, (double)max, (double)min);
|
||||
val = (float) vald;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, double& val, double min, double max)
|
||||
{
|
||||
Tcl_Obj* pobj;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
double objval;
|
||||
if (Tcl_GetDoubleFromObj(fpInterp, pobj, &objval) != TCL_OK) return false;
|
||||
if (objval < min || objval > max) {
|
||||
ostringstream sos;
|
||||
sos << "-E: value '" << objval << "' for '" << name << "' out of range "
|
||||
<< min << "..." << max;
|
||||
AppendResult(sos);
|
||||
return false;
|
||||
}
|
||||
val = objval;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, std::vector<uint8_t>& val,
|
||||
size_t lmin, size_t lmax)
|
||||
{
|
||||
int objc = 0;
|
||||
Tcl_Obj** objv = 0;
|
||||
if (!NextArgList(name, objc, objv, lmin, lmax)) return false;
|
||||
if (objv==0) return true;
|
||||
|
||||
val.clear();
|
||||
val.reserve(objc);
|
||||
|
||||
for (int i=0; i<objc; i++) {
|
||||
int ival;
|
||||
if (Tcl_GetIntFromObj(fpInterp, objv[i], &ival) != TCL_OK) return false;
|
||||
int ivalmsb = ival>>8;
|
||||
if (ivalmsb != 0 && ivalmsb != -1) {
|
||||
ostringstream sos;
|
||||
sos << "-E: list element '" << Tcl_GetString(objv[i])
|
||||
<< "' for '" << name
|
||||
<< "' out of range " << "0...0xff";
|
||||
AppendResult(sos);
|
||||
return false;
|
||||
}
|
||||
val.push_back((uint8_t)ival);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::GetArg(const char* name, std::vector<uint16_t>& val,
|
||||
size_t lmin, size_t lmax)
|
||||
{
|
||||
int objc = 0;
|
||||
Tcl_Obj** objv = 0;
|
||||
if (!NextArgList(name, objc, objv, lmin, lmax)) return false;
|
||||
if (objv==0) return true;
|
||||
|
||||
val.clear();
|
||||
val.reserve(objc);
|
||||
|
||||
for (int i=0; i<objc; i++) {
|
||||
int ival;
|
||||
if (Tcl_GetIntFromObj(fpInterp, objv[i], &ival) != TCL_OK) return false;
|
||||
int ivalmsb = ival>>16;
|
||||
if (ivalmsb != 0 && ivalmsb != -1) {
|
||||
ostringstream sos;
|
||||
sos << "-E: list element '" << Tcl_GetString(objv[i])
|
||||
<< "' for '" << name
|
||||
<< "' out of range " << "0...0xffff";
|
||||
AppendResult(sos);
|
||||
return false;
|
||||
}
|
||||
val.push_back((uint16_t)ival);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::Config(const char* name, std::string& val)
|
||||
{
|
||||
ConfigNameCheck(name);
|
||||
string tmp = val;
|
||||
if (!GetArg(name, tmp)) return false;
|
||||
if (fNOptMiss == 0) { // config write
|
||||
val = tmp;
|
||||
} else { // config read
|
||||
if (!ConfigReadCheck()) return false;
|
||||
SetResult(Tcl_NewStringObj(val.data(), val.length()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::Config(const char* name, uint32_t& val, uint32_t max,
|
||||
uint32_t min)
|
||||
{
|
||||
ConfigNameCheck(name);
|
||||
uint32_t tmp = val;
|
||||
if (!GetArg(name, tmp, max, min)) return false;
|
||||
if (fNOptMiss == 0) { // config write
|
||||
val = tmp;
|
||||
} else { // config read
|
||||
if (!ConfigReadCheck()) return false;
|
||||
SetResult(Tcl_NewIntObj((int)val));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::NextOpt(std::string& val)
|
||||
{
|
||||
fNOptMiss = 0;
|
||||
val.clear();
|
||||
fOptErr = false;
|
||||
|
||||
if (fNDone == fObjc) return false;
|
||||
|
||||
const char* str = PeekArgString(0);
|
||||
|
||||
if (str[0]=='-' && str[1] && !isdigit(str[1])) {
|
||||
fNDone += 1;
|
||||
// '--' seen (eat it, and say no Opt's found)
|
||||
if (str[1]=='-' && str[2]==0) {
|
||||
return false;
|
||||
}
|
||||
val = str;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::NextOpt(std::string& val, RtclNameSet& optset)
|
||||
{
|
||||
val.clear();
|
||||
string opt;
|
||||
if (!NextOpt(opt) || opt.empty()) return false;
|
||||
|
||||
fOptErr = !optset.Check(fpInterp, val, opt);
|
||||
return !fOptErr;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::AllDone()
|
||||
{
|
||||
if (fArgErr || fOptErr) return false;
|
||||
if (fNDone < fObjc) {
|
||||
AppendResult("-E: superfluous arguments, first one \"",
|
||||
Tcl_GetString(fObjv[fNDone]), "\"", NULL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
const char* RtclArgs::PeekArgString(int rind) const
|
||||
{
|
||||
int ind = fNDone + rind;
|
||||
if (ind < 0 || ind >= (int)fObjc) return "";
|
||||
return Tcl_GetString(fObjv[ind]);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclArgs::AppendResult(const char* str, ...)
|
||||
{
|
||||
Tcl_AppendResult(fpInterp, str, NULL);
|
||||
va_list ap;
|
||||
va_start (ap, str);
|
||||
Tcl_AppendResultVA(fpInterp, ap);
|
||||
va_end (ap);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclArgs::AppendResultLines(const std::string& str)
|
||||
{
|
||||
Rtcl::AppendResultNewLines(fpInterp);
|
||||
|
||||
if (str.length()>0 && str[str.length()-1]=='\n') {
|
||||
Tcl_AppendResult(fpInterp, str.substr(0,str.length()-1).c_str(), NULL);
|
||||
} else {
|
||||
Tcl_AppendResult(fpInterp, str.c_str(), NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::NextArg(const char* name, Tcl_Obj*& pobj)
|
||||
{
|
||||
pobj = 0;
|
||||
|
||||
bool isopt = name[0] == '?';
|
||||
bool isoptopt = isopt && (name[1] == '?');
|
||||
|
||||
if (!isopt) fNOptMiss = 0;
|
||||
|
||||
if (fNDone == fObjc) {
|
||||
if (!isopt) {
|
||||
AppendResult("-E: required argument \"", name, "\" missing", NULL);
|
||||
fArgErr = true;
|
||||
return false;
|
||||
}
|
||||
fNOptMiss += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// if %% arg peek in next arg and check that it's not an option
|
||||
if (isoptopt) {
|
||||
const char* nval = Tcl_GetString(fObjv[fNDone]);
|
||||
if (nval[0]=='-' && nval[1] && isalpha(nval[1])) {
|
||||
fNOptMiss += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pobj = fObjv[fNDone++];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::NextArgList(const char* name, int& objc, Tcl_Obj**& objv,
|
||||
size_t lmin, size_t lmax)
|
||||
{
|
||||
objc = 0;
|
||||
objv = 0;
|
||||
Tcl_Obj* pobj = 0;
|
||||
if (!NextArg(name, pobj)) return false;
|
||||
if (pobj==0) return true;
|
||||
|
||||
if (Tcl_ListObjGetElements(fpInterp, pobj, &objc, &objv) != TCL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((size_t)objc < lmin || (size_t)objc > lmax) {
|
||||
ostringstream sos;
|
||||
sos << "-E: list length '" << objc << "' for '" << name << "' out of range "
|
||||
<< lmin << "..." << lmax;
|
||||
AppendResult(sos);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclArgs::ConfigNameCheck(const char* name)
|
||||
{
|
||||
if (name==0 || name[0]!='?' || name[1]!='?')
|
||||
throw invalid_argument("RtclArgs::Config(): name must start with ??");
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
bool RtclArgs::ConfigReadCheck()
|
||||
{
|
||||
if (fNConfigRead != 0) {
|
||||
SetResult(Tcl_NewObj());
|
||||
AppendResult("-E: only one config read allowed per command, \"",
|
||||
PeekArgString(-1), "\" is second", NULL);
|
||||
return false;
|
||||
}
|
||||
fNConfigRead += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RtclArgs_NoInline))
|
||||
#define inline
|
||||
#include "RtclArgs.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
151
tools/src/librtcltools/RtclArgs.hpp
Normal file
151
tools/src/librtcltools/RtclArgs.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
// $Id: RtclArgs.hpp 373 2011-03-26 08:54:27Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-26 373 1.0.4 add GetArg(flt/dbl), SetResult(str,sos,int,dbl)
|
||||
// 2011-03-13 369 1.0.3 add GetArg(vector<unit8_t>)
|
||||
// 2011-03-06 367 1.0.2 add min to GetArg(unsigned); add Config() methods;
|
||||
// 2011-03-05 366 1.0.1 fObjc,fNDone now size_t; add NDone(), NOptMiss();
|
||||
// add SetResult(), GetArg(Tcl_Obj), PeekArgString();
|
||||
// 2011-02-26 364 1.0 Initial version
|
||||
// 2011-02-06 359 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclArgs.hpp 373 2011-03-26 08:54:27Z mueller $
|
||||
\brief Declaration of class RtclArgs.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RtclArgs
|
||||
#define included_Retro_RtclArgs 1
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
#include "RtclNameSet.hpp"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RtclArgs {
|
||||
public:
|
||||
|
||||
const static int8_t int8_min = 0xff;
|
||||
const static int8_t int8_max = 0x7f;
|
||||
const static uint8_t uint8_max = 0xff;
|
||||
const static int16_t int16_min = 0xffff;
|
||||
const static int16_t int16_max = 0x7fff;
|
||||
const static uint16_t uint16_max = 0xffff;
|
||||
const static int32_t int32_min = 0xffffffff;
|
||||
const static int32_t int32_max = 0x7fffffff;
|
||||
const static uint32_t uint32_max = 0xffffffff;
|
||||
|
||||
RtclArgs();
|
||||
RtclArgs(Tcl_Interp* interp, int objc,
|
||||
Tcl_Obj* const objv[], size_t nskip=1);
|
||||
RtclArgs(const RtclArgs& rhs);
|
||||
~RtclArgs();
|
||||
|
||||
Tcl_Interp* Interp() const;
|
||||
int Objc() const;
|
||||
Tcl_Obj* Objv(size_t ind) const;
|
||||
|
||||
bool GetArg(const char* name, Tcl_Obj*& pval);
|
||||
|
||||
bool GetArg(const char* name, const char*& val);
|
||||
bool GetArg(const char* name, std::string& val);
|
||||
|
||||
bool GetArg(const char* name, int8_t& val,
|
||||
int8_t min=int8_min, int8_t max=int8_max);
|
||||
bool GetArg(const char* name, uint8_t& val,
|
||||
uint8_t max=uint8_max, uint8_t min=0);
|
||||
bool GetArg(const char* name, int16_t& val,
|
||||
int16_t min=int16_min, int16_t max=int16_max);
|
||||
bool GetArg(const char* name, uint16_t& val,
|
||||
uint16_t max=uint16_max, uint16_t min=0);
|
||||
bool GetArg(const char* name, int32_t& val,
|
||||
int32_t min=int32_min, int32_t max=int32_max);
|
||||
bool GetArg(const char* name, uint32_t& val,
|
||||
uint32_t max=uint32_max, uint32_t min=0);
|
||||
|
||||
bool GetArg(const char* name, float& val,
|
||||
float min=-1.e30, float max=+1.e30);
|
||||
bool GetArg(const char* name, double& val,
|
||||
double min=-1.e30, double max=+1.e30);
|
||||
|
||||
bool GetArg(const char* name, std::vector<uint8_t>& val,
|
||||
size_t lmin=0, size_t lmax=uint32_max);
|
||||
bool GetArg(const char* name, std::vector<uint16_t>& val,
|
||||
size_t lmin=0, size_t lmax=uint32_max);
|
||||
|
||||
bool Config(const char* name, std::string& val);
|
||||
bool Config(const char* name, uint32_t& val,
|
||||
uint32_t max=uint32_max, uint32_t min=0);
|
||||
|
||||
bool NextOpt(std::string& val);
|
||||
bool NextOpt(std::string& val, RtclNameSet& optset);
|
||||
bool OptValid() const;
|
||||
|
||||
bool AllDone();
|
||||
size_t NDone() const;
|
||||
size_t NOptMiss() const;
|
||||
|
||||
const char* PeekArgString(int rind) const;
|
||||
|
||||
void SetResult(const std::string& str);
|
||||
void SetResult(std::ostringstream& sos);
|
||||
void SetResult(int val);
|
||||
void SetResult(double val);
|
||||
void SetResult(Tcl_Obj* pobj);
|
||||
|
||||
void AppendResult(const char* str, ...);
|
||||
void AppendResult(const std::string& str);
|
||||
void AppendResult(std::ostringstream& sos);
|
||||
void AppendResultLines(const std::string& str);
|
||||
void AppendResultLines(std::ostringstream& sos);
|
||||
|
||||
Tcl_Obj* operator[](size_t ind) const;
|
||||
|
||||
protected:
|
||||
bool NextArg(const char* name, Tcl_Obj*& pobj);
|
||||
bool NextArgList(const char* name, int& objc,
|
||||
Tcl_Obj**& objv, size_t lmin=0,
|
||||
size_t lmax=uint32_max);
|
||||
void ConfigNameCheck(const char* name);
|
||||
bool ConfigReadCheck();
|
||||
|
||||
protected:
|
||||
Tcl_Interp* fpInterp; //!< pointer to tcl interpreter
|
||||
size_t fObjc; //!< original args count
|
||||
Tcl_Obj* const * fObjv; //!< original args vector
|
||||
size_t fNDone; //!< number of processed args
|
||||
size_t fNOptMiss; //!< number of missed optional args
|
||||
size_t fNConfigRead; //!< number of read mode config's
|
||||
bool fOptErr; //!< option processing error flag
|
||||
bool fArgErr; //!< argument processing error flag
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RtclArgs_NoInline))
|
||||
#include "RtclArgs.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
153
tools/src/librtcltools/RtclArgs.ipp
Normal file
153
tools/src/librtcltools/RtclArgs.ipp
Normal file
@@ -0,0 +1,153 @@
|
||||
// $Id: RtclArgs.ipp 373 2011-03-26 08:54:27Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-26 373 1.0.2 add SetResult(string)
|
||||
// 2011-03-05 366 1.0.1 add NDone(), NOptMiss(), SetResult();
|
||||
// 2011-02-26 364 1.0 Initial version
|
||||
// 2011-02-18 362 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclArgs.ipp 373 2011-03-26 08:54:27Z mueller $
|
||||
\brief Implemenation (inline) of RtclArgs.
|
||||
*/
|
||||
|
||||
#include "Rtcl.hpp"
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline Tcl_Interp* RtclArgs::Interp() const
|
||||
{
|
||||
return fpInterp;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline int RtclArgs::Objc() const
|
||||
{
|
||||
return fObjc;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RtclArgs::OptValid() const
|
||||
{
|
||||
return !fOptErr;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RtclArgs::NDone() const
|
||||
{
|
||||
return fNDone;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline size_t RtclArgs::NOptMiss() const
|
||||
{
|
||||
return fNOptMiss;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::SetResult(const std::string& str)
|
||||
{
|
||||
Rtcl::SetResult(fpInterp, str);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::SetResult(std::ostringstream& sos)
|
||||
{
|
||||
Rtcl::SetResult(fpInterp, sos);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::SetResult(int val)
|
||||
{
|
||||
Tcl_SetObjResult(fpInterp, Tcl_NewIntObj(val));
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::SetResult(double val)
|
||||
{
|
||||
Tcl_SetObjResult(fpInterp, Tcl_NewDoubleObj(val));
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::SetResult(Tcl_Obj* pobj)
|
||||
{
|
||||
Tcl_SetObjResult(fpInterp, pobj);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::AppendResult(const std::string& str)
|
||||
{
|
||||
Tcl_AppendResult(fpInterp, str.c_str(), NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::AppendResult(std::ostringstream& sos)
|
||||
{
|
||||
AppendResult(sos.str());
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclArgs::AppendResultLines(std::ostringstream& sos)
|
||||
{
|
||||
AppendResultLines(sos.str());
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline Tcl_Obj* RtclArgs::operator[](size_t ind) const
|
||||
{
|
||||
return fObjv[ind];
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
188
tools/src/librtcltools/RtclClassBase.cpp
Normal file
188
tools/src/librtcltools/RtclClassBase.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
// $Id: RtclClassBase.cpp 374 2011-03-27 17:02:47Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-03-05 366 1.0.1 use AppendResultNewLines() in exception catcher
|
||||
// 2011-02-20 363 1.0 Initial version
|
||||
// 2011-02-11 360 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclClassBase.cpp 374 2011-03-27 17:02:47Z mueller $
|
||||
\brief Implemenation of RtclClassBase.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "RtclClassBase.hpp"
|
||||
#include "RtclContext.hpp"
|
||||
#include "RtclOPtr.hpp"
|
||||
#include "Rtcl.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Retro;
|
||||
|
||||
/*!
|
||||
\class Retro::RtclClassBase
|
||||
\brief FIXME_docs
|
||||
*/
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
RtclClassBase::RtclClassBase(const std::string& type)
|
||||
: fType(type),
|
||||
fInterp(0)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Destructor
|
||||
|
||||
RtclClassBase::~RtclClassBase()
|
||||
{
|
||||
if (fInterp) RtclContext::Find(fInterp).UnRegisterClass(this);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclClassBase::CreateClassCmd(Tcl_Interp* interp, const char* name)
|
||||
{
|
||||
fInterp = interp;
|
||||
fCmdToken =
|
||||
Tcl_CreateObjCommand(interp, name, ThunkTclClassCmd, (ClientData) this,
|
||||
(Tcl_CmdDeleteProc *) ThunkTclCmdDeleteProc);
|
||||
RtclContext::Find(interp).RegisterClass(this);
|
||||
Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) this);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline int RtclClassBase::TclClassCmd(Tcl_Interp* interp, int objc,
|
||||
Tcl_Obj* const objv[])
|
||||
{
|
||||
if (objc == 1) {
|
||||
return ClassCmdList(interp);
|
||||
}
|
||||
|
||||
const char* name = Tcl_GetString(objv[1]);
|
||||
if (objc == 3 && strcmp(Tcl_GetString(objv[2]), "-delete")==0) {
|
||||
return ClassCmdDelete(interp, name);
|
||||
}
|
||||
|
||||
return ClassCmdCreate(interp, objc, objv);
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline int RtclClassBase::ClassCmdList(Tcl_Interp* interp)
|
||||
{
|
||||
std::vector<RtclProxyBase*> list;
|
||||
RtclContext::Find(interp).ListProxy(list, Type());
|
||||
RtclOPtr rlist(Tcl_NewListObj(0, NULL));
|
||||
|
||||
for (size_t i=0; i<list.size(); i++) {
|
||||
const char* cmdname = Tcl_GetCommandName(interp, list[i]->Token());
|
||||
RtclOPtr rval(Tcl_NewStringObj(cmdname, -1));
|
||||
if (Tcl_ListObjAppendElement(interp, rlist, rval) != kOK) return kERR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, rlist);
|
||||
|
||||
return kOK;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline int RtclClassBase::ClassCmdDelete(Tcl_Interp* interp, const char* name)
|
||||
{
|
||||
Tcl_CmdInfo cinfo;
|
||||
if (Tcl_GetCommandInfo(interp, name, &cinfo) == 0) {
|
||||
Tcl_AppendResult(interp, "-E: unknown command name \"", name, "\"", NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
RtclContext& cntx = RtclContext::Find(interp);
|
||||
if (!cntx.CheckProxy((RtclProxyBase*) cinfo.objClientData)) {
|
||||
Tcl_AppendResult(interp, "-E: command \"", name, "\" is not a RtclProxy",
|
||||
NULL);
|
||||
return kERR;
|
||||
}
|
||||
if (!cntx.CheckProxy((RtclProxyBase*) cinfo.objClientData, Type())) {
|
||||
Tcl_AppendResult(interp, "-E: command \"", name,
|
||||
"\" is not a RtclProxy of type \"",
|
||||
Type().c_str(), "\"", NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
int irc = Tcl_DeleteCommand(interp, name);
|
||||
if (irc != kOK) Tcl_AppendResult(interp, "-E: failed to delete \"", name,
|
||||
"\"", NULL);
|
||||
return irc;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
int RtclClassBase::ThunkTclClassCmd(ClientData cdata, Tcl_Interp* interp,
|
||||
int objc, Tcl_Obj* const objv[])
|
||||
{
|
||||
if (!cdata) {
|
||||
Tcl_AppendResult(interp, "-E: BUG! ThunkTclClassCmd called with cdata == 0",
|
||||
NULL);
|
||||
return kERR;
|
||||
}
|
||||
|
||||
try {
|
||||
return ((RtclClassBase*) cdata)->TclClassCmd(interp, objc, objv);
|
||||
} catch (exception& e) {
|
||||
Rtcl::AppendResultNewLines(interp);
|
||||
Tcl_AppendResult(interp, "-E: exception caught in ThunkTclClassCmd: \"",
|
||||
e.what(), "\"", NULL);
|
||||
}
|
||||
return kERR;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclClassBase::ThunkTclCmdDeleteProc(ClientData cdata)
|
||||
{
|
||||
Tcl_DeleteExitHandler((Tcl_ExitProc*) ThunkTclExitProc, cdata);
|
||||
delete ((RtclClassBase*) cdata);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtclClassBase::ThunkTclExitProc(ClientData cdata)
|
||||
{
|
||||
delete ((RtclClassBase*) cdata);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
#if (defined(Retro_NoInline) || defined(Retro_RtclClassBase_NoInline))
|
||||
#define inline
|
||||
#include "RtclClassBase.ipp"
|
||||
#undef inline
|
||||
#endif
|
||||
82
tools/src/librtcltools/RtclClassBase.hpp
Normal file
82
tools/src/librtcltools/RtclClassBase.hpp
Normal file
@@ -0,0 +1,82 @@
|
||||
// $Id: RtclClassBase.hpp 365 2011-02-28 07:28:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-02-20 363 1.0 Initial version
|
||||
// 2011-02-11 360 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclClassBase.hpp 365 2011-02-28 07:28:26Z mueller $
|
||||
\brief Declaration of class RtclClassBase.
|
||||
*/
|
||||
|
||||
#ifndef included_Retro_RtclClassBase
|
||||
#define included_Retro_RtclClassBase 1
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
namespace Retro {
|
||||
|
||||
class RtclClassBase {
|
||||
public:
|
||||
static const int kOK = TCL_OK;
|
||||
static const int kERR = TCL_ERROR;
|
||||
|
||||
explicit RtclClassBase(const std::string& type = std::string());
|
||||
virtual ~RtclClassBase();
|
||||
|
||||
const std::string& Type() const;
|
||||
Tcl_Command Token() const;
|
||||
|
||||
protected:
|
||||
void SetType(const std::string& type);
|
||||
|
||||
void CreateClassCmd(Tcl_Interp* interp, const char* name);
|
||||
|
||||
virtual int TclClassCmd(Tcl_Interp* interp, int objc,
|
||||
Tcl_Obj* const objv[]);
|
||||
|
||||
virtual int ClassCmdList(Tcl_Interp* interp);
|
||||
virtual int ClassCmdDelete(Tcl_Interp* interp, const char* name);
|
||||
virtual int ClassCmdCreate(Tcl_Interp* interp, int objc,
|
||||
Tcl_Obj* const objv[]) = 0;
|
||||
|
||||
static int ThunkTclClassCmd(ClientData cdata, Tcl_Interp* interp,
|
||||
int objc, Tcl_Obj* const objv[]);
|
||||
|
||||
static void ThunkTclCmdDeleteProc(ClientData cdata);
|
||||
static void ThunkTclExitProc(ClientData cdata);
|
||||
|
||||
protected:
|
||||
std::string fType; //!< classed type name
|
||||
Tcl_Interp* fInterp; //!< tcl interpreter
|
||||
Tcl_Command fCmdToken; //!< cmd token for class command
|
||||
|
||||
// RtclClassBase is not copy or assignable
|
||||
private:
|
||||
RtclClassBase(const RtclClassBase& rhs);
|
||||
RtclClassBase& operator=(const RtclClassBase& rhs);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
#if !(defined(Retro_NoInline) || defined(Retro_RtclClassBase_NoInline))
|
||||
#include "RtclClassBase.ipp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
54
tools/src/librtcltools/RtclClassBase.ipp
Normal file
54
tools/src/librtcltools/RtclClassBase.ipp
Normal file
@@ -0,0 +1,54 @@
|
||||
// $Id: RtclClassBase.ipp 365 2011-02-28 07:28:26Z mueller $
|
||||
//
|
||||
// Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 2, 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 General Public License
|
||||
// for complete details.
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2011-02-20 363 1.0 Initial version
|
||||
// 2011-02-18 362 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtclClassBase.ipp 365 2011-02-28 07:28:26Z mueller $
|
||||
\brief Implemenation (inline) of RtclClassBase.
|
||||
*/
|
||||
|
||||
// all method definitions in namespace Retro (avoid using in includes...)
|
||||
namespace Retro {
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline const std::string& RtclClassBase::Type() const
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline Tcl_Command RtclClassBase::Token() const
|
||||
{
|
||||
return fCmdToken;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline void RtclClassBase::SetType(const std::string& type)
|
||||
{
|
||||
fType = type;
|
||||
return;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user