Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Hardware V4
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
11
Issues
11
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Hardware V4
Commits
fa9f41e6
Commit
fa9f41e6
authored
Sep 14, 2021
by
Maciej Lipinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sources
parent
4499a1cb
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
353 additions
and
0 deletions
+353
-0
spll_dbg_proxy
FCWR_tests/sw/tools/spll_proxy/spll_dbg_proxy
+0
-0
spll_dbg_proxy.c
FCWR_tests/sw/tools/spll_proxy/spll_dbg_proxy.c
+353
-0
No files found.
FCWR_tests/sw/tools/spll_proxy/spll_dbg_proxy
deleted
100755 → 0
View file @
4499a1cb
File deleted
FCWR_tests/sw/tools/spll_proxy/spll_dbg_proxy.c
0 → 100644
View file @
fa9f41e6
/* SoftPLL debug proxy
Reads out the debug FIFO datastream from the SoftPLL and proxies it
via TCP connection to the application running on an outside host, where
the can be plotted, analyzed, etc.
The debug stream contains run-time signals coming in/out the SoftPLL
- for example, the phase/frequency errors on each channel, DAC drive
values, phase tags.
Todo: poll the hardware FIFO through a driver with interrupt support
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fpga_io.h>
#include <softpll-regs.h> //TODO:check
// #include <libwr/switch_hw.h> //ML: compied shw_fpga_mmap_init() function, and copied:
#include <sys/mman.h>
#include <inttypes.h>
#include <fcntl.h>
#include <poll.h>
/* TCP Port to listen on */
#define MY_PORT 12345
/* Size of the software FIFO ring buffer */
#define RING_BUFFER_ENTRIES 1048576
#define ENTRIES_PER_PACKET 128
__attribute__
((
packed
))
struct
fifo_entry
{
uint32_t
value
;
uint16_t
seq_id
;
};
/*
Simple ring buffer implementation. WARNING: NOT thread-safe
*/
struct
ring_buffer
{
void
*
base
;
int
entry_size
,
num_entries
;
int
wr_ptr
,
rd_ptr
,
count
;
};
int
rbuf_init
(
struct
ring_buffer
*
rbuf
,
int
num_entries
,
int
entry_size
)
{
rbuf
->
base
=
malloc
(
num_entries
*
entry_size
);
if
(
!
rbuf
->
base
)
return
-
1
;
rbuf
->
entry_size
=
entry_size
;
rbuf
->
num_entries
=
num_entries
;
rbuf
->
wr_ptr
=
0
;
rbuf
->
rd_ptr
=
0
;
rbuf
->
count
=
0
;
return
0
;
}
void
rbuf_push
(
struct
ring_buffer
*
rbuf
,
void
*
what
)
{
if
(
rbuf
->
count
>=
rbuf
->
num_entries
-
1
)
/* buffer full */
return
;
rbuf
->
count
++
;
memcpy
(
rbuf
->
base
+
rbuf
->
wr_ptr
*
rbuf
->
entry_size
,
what
,
rbuf
->
entry_size
);
rbuf
->
wr_ptr
++
;
if
(
rbuf
->
wr_ptr
==
rbuf
->
num_entries
)
rbuf
->
wr_ptr
=
0
;
}
int
rbuf_pop
(
struct
ring_buffer
*
rbuf
,
void
*
dst
)
{
if
(
!
rbuf
->
count
)
/* buffer empty */
return
0
;
rbuf
->
count
--
;
memcpy
(
dst
,
rbuf
->
base
+
rbuf
->
rd_ptr
*
rbuf
->
entry_size
,
rbuf
->
entry_size
);
rbuf
->
rd_ptr
++
;
if
(
rbuf
->
rd_ptr
==
rbuf
->
num_entries
)
rbuf
->
rd_ptr
=
0
;
return
1
;
}
void
rbuf_release
(
struct
ring_buffer
*
rbuf
)
{
free
(
rbuf
->
base
);
}
#define SMC_CS0_BASE 0x00A1000000 //base in US+
#define SMC_CS0_SIZE 0x200000
#define SPLL_BASE 0x20200
struct
ring_buffer
spll_trace
;
static
struct
SPLL_WB
*
_spll_regs
=
(
struct
SPLL_WB
*
)
SPLL_BASE
;
#define REG(x) ((uint32_t)(&_spll_regs->x))
void
poll_spll_fifo
(
int
purge
)
{
while
(
1
)
{
/* Move the following lines (and the ring buffering code) to the driver.
for the SPLL: IRQ = 3 (asserted when FIFO != empty)
base : check DFR_HOST register in softpll_regs.h
device: /dev/spfifoX
parameters: base_addr, num_regs (r0, r1), irq
ioctls:
*/
uint32_t
csr
=
_fpga_readl
(
REG
(
DFR_HOST_CSR
));
struct
fifo_entry
ent
;
// fprintf(stderr,"CSR %x\n", csr);
if
(
csr
&
SPLL_DFR_HOST_CSR_EMPTY
)
break
;
else
if
((
csr
&
SPLL_DFR_HOST_CSR_FULL
)
&&
!
purge
)
{
fprintf
(
stderr
,
"FIFO OVERFLOW!
\n
"
);
}
ent
.
value
=
_fpga_readl
(
REG
(
DFR_HOST_R0
));
ent
.
seq_id
=
_fpga_readl
(
REG
(
DFR_HOST_R1
))
&
0xffff
;
// fprintf(stderr, "v: %x\n", ent.value);
if
(
!
purge
)
rbuf_push
(
&
spll_trace
,
(
void
*
)
&
ent
);
}
}
static
int
proxy_done
=
0
;
void
sighandler
(
int
sig
)
{
if
(
sig
==
SIGPIPE
)
{
fprintf
(
stderr
,
"Connection broken. Killing proxy
\n
"
);
proxy_done
=
1
;
}
}
void
proxy_stuff
(
int
fd
)
{
poll_spll_fifo
(
1
);
/* purge it! */
if
(
rbuf_init
(
&
spll_trace
,
RING_BUFFER_ENTRIES
,
sizeof
(
struct
fifo_entry
))
<
0
)
{
perror
(
"rbuf_init()"
);
return
;
}
fprintf
(
stderr
,
"Connection accepted [record size %d].
\n
"
,
sizeof
(
struct
fifo_entry
));
proxy_done
=
0
;
for
(;;)
{
poll_spll_fifo
(
0
);
while
(
spll_trace
.
count
>
ENTRIES_PER_PACKET
)
{
struct
fifo_entry
tx_buf
[
ENTRIES_PER_PACKET
];
int
i
;
/* fixme: make endian-independent */
for
(
i
=
0
;
i
<
ENTRIES_PER_PACKET
;
i
++
)
rbuf_pop
(
&
spll_trace
,
&
tx_buf
[
i
]);
if
(
proxy_done
)
{
rbuf_release
(
&
spll_trace
);
return
;
}
if
(
send
(
fd
,
tx_buf
,
sizeof
(
tx_buf
),
0
)
<=
0
)
{
fprintf
(
stderr
,
"Connection closed.
\n
"
);
rbuf_release
(
&
spll_trace
);
return
;
}
}
// fprintf(stderr,"Count :%d\n", spll_trace.count);
usleep
(
10000
);
}
}
volatile
uint8_t
*
_fpga_base_virt
;
int
shw_fpga_mmap_init
()
{
int
fd
;
fprintf
(
stderr
,
"Initializing FPGA memory mapping.
\n
"
);
fd
=
open
(
"/dev/mem"
,
O_RDWR
|
O_SYNC
);
if
(
fd
<
0
)
{
perror
(
"/dev/mem"
);
return
-
1
;
}
_fpga_base_virt
=
mmap
(
NULL
,
SMC_CS0_SIZE
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
SMC_CS0_BASE
);
close
(
fd
);
if
(
_fpga_base_virt
==
MAP_FAILED
)
{
perror
(
"mmap()"
);
return
-
1
;
}
fprintf
(
stderr
,
"FPGA virtual base = %p
\n
"
,
_fpga_base_virt
);
return
0
;
}
void
test
(
void
)
{
uint32_t
data
=
0
;
fprintf
(
stderr
,
"Test: 0xCAFE reg read:.
\n
"
);
data
=
_fpga_readl
(
0x20134
);
fprintf
(
stderr
,
"Data 0x%x
\n
"
,
data
);
}
void
print_stuff
(
int
fd
)
{
poll_spll_fifo
(
1
);
/* purge it! */
if
(
rbuf_init
(
&
spll_trace
,
RING_BUFFER_ENTRIES
,
sizeof
(
struct
fifo_entry
))
<
0
)
{
perror
(
"rbuf_init()"
);
return
;
}
fprintf
(
stderr
,
"Connection accepted [record size %d].
\n
"
,
sizeof
(
struct
fifo_entry
));
proxy_done
=
0
;
for
(;;)
{
poll_spll_fifo
(
0
);
while
(
spll_trace
.
count
>
ENTRIES_PER_PACKET
)
{
struct
fifo_entry
tx_buf
[
ENTRIES_PER_PACKET
];
int
i
;
/* fixme: make endian-independent */
for
(
i
=
0
;
i
<
ENTRIES_PER_PACKET
;
i
++
)
{
rbuf_pop
(
&
spll_trace
,
&
tx_buf
[
i
]);
fprintf
(
stderr
,
"tx_buf[%d]=0x%x
\n
"
,
i
,
tx_buf
[
i
]);
}
if
(
proxy_done
)
{
rbuf_release
(
&
spll_trace
);
return
;
}
// if(send(fd, tx_buf, sizeof(tx_buf), 0) <= 0)
// {
// fprintf(stderr,"Connection closed.\n");
// rbuf_release(&spll_trace);
// return;
// }
}
// fprintf(stderr,"Count :%d\n", spll_trace.count);
usleep
(
10000
);
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
sock_fd
;
struct
sockaddr_in
sin
;
shw_fpga_mmap_init
();
test
();
// print_stuff(0);
// exit;
if
((
sock_fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
))
<
0
)
{
perror
(
"socket()"
);
return
-
1
;
}
int
yes
=
1
;
if
(
setsockopt
(
sock_fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
yes
,
sizeof
(
yes
))
<
0
)
{
perror
(
"setsockopt()"
);
return
-
1
;
}
sin
.
sin_family
=
AF_INET
;
/* Internet address family */
sin
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
/* Any incoming interface */
sin
.
sin_port
=
htons
(
MY_PORT
);
if
(
bind
(
sock_fd
,
(
struct
sockaddr
*
)
&
sin
,
sizeof
(
sin
))
<
0
)
{
perror
(
"bind()"
);
return
-
1
;
}
if
(
listen
(
sock_fd
,
1
)
<
0
)
{
perror
(
"listen()"
);
return
-
1
;
}
for
(;;)
{
struct
sockaddr_in
client_addr
;
socklen_t
client_len
=
sizeof
(
client_addr
);
int
client_fd
;
if
((
client_fd
=
accept
(
sock_fd
,
(
struct
sockaddr
*
)
&
client_addr
,
&
client_len
))
>
0
)
proxy_stuff
(
client_fd
);
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment