Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
H
HDL
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
RTSD
HDL
Commits
117b30be
Commit
117b30be
authored
Jul 27, 2017
by
Pieter Donker
Browse files
Options
Downloads
Patches
Plain Diff
Task #893: add args_documentation new draft
parent
7d1d6883
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
tools/oneclick/prestudy/YAML/args_documentation.py
+143
-248
143 additions, 248 deletions
tools/oneclick/prestudy/YAML/args_documentation.py
tools/oneclick/prestudy/YAML/peripherals/bf.peripheral.yaml
+6
-6
6 additions, 6 deletions
tools/oneclick/prestudy/YAML/peripherals/bf.peripheral.yaml
with
149 additions
and
254 deletions
tools/oneclick/prestudy/YAML/args_documentation.py
+
143
−
248
View file @
117b30be
...
@@ -36,7 +36,8 @@ import traceback
...
@@ -36,7 +36,8 @@ import traceback
import
yaml
import
yaml
import
time
import
time
from
subprocess
import
CalledProcessError
from
subprocess
import
CalledProcessError
from
pylatex
import
Document
,
Section
,
Subsection
,
Command
,
Package
,
Tabular
,
MultiColumn
,
MultiRow
,
SmallText
,
LargeText
from
pylatex
import
Document
,
Section
,
Subsection
,
Subsubsection
,
Command
,
Package
,
Tabular
,
MultiColumn
,
MultiRow
,
NewLine
from
pylatex
import
SmallText
,
MediumText
,
LargeText
,
HugeText
from
pylatex.utils
import
italic
,
bold
,
NoEscape
,
verbatim
,
escape_latex
from
pylatex.utils
import
italic
,
bold
,
NoEscape
,
verbatim
,
escape_latex
from
py_args_lib
import
*
from
py_args_lib
import
*
...
@@ -46,272 +47,166 @@ import common as cm
...
@@ -46,272 +47,166 @@ import common as cm
def
main
():
def
main
():
try
:
try
:
for
systemname
in
args
.
system
:
for
systemname
in
args
.
system
:
try
:
doc
=
SystemDocumentation
(
systemname
)
system_filename
=
"
./systems/{}.system.yaml
"
.
format
(
systemname
)
doc
.
fill
()
config
=
yaml
.
load
(
open
(
system_filename
,
"
r
"
))
doc
.
make_pdf
()
name
=
config
[
'
system_name
'
]
del
doc
documentation
=
Documentation
(
name
)
time
.
sleep
(
0.5
)
system
=
System
(
system_filename
)
documentation
.
add
(
config
[
'
system_name
'
],
system
)
documentation
.
generate_pdf
()
del
documentation
del
system
time
.
sleep
(
1.0
)
except
CalledProcessError
:
pass
for
peripheralname
in
args
.
peripheral
:
for
peripheralname
in
args
.
peripheral
:
try
:
doc
=
PeripheralDocumentation
(
peripheralname
)
peripheral_filename
=
"
./peripherals/{}.peripheral.yaml
"
.
format
(
peripheralname
)
doc
.
fill
()
logger
.
info
(
"
Load peripheral(s) from
'
%s
'"
,
peripheral_filename
)
doc
.
make_pdf
()
config
=
yaml
.
load
(
open
(
peripheral_filename
,
"
r
"
))
del
doc
name
=
config
[
'
hdl_library_name
'
]
time
.
sleep
(
0.5
)
for
peripheral_config
in
config
[
'
peripherals
'
]:
peripheral
=
Peripheral
(
peripheral_config
)
logger
.
info
(
"
read peripheral
'
%s
'"
%
peripheral
.
component_name
())
peripheral
.
eval_peripheral
()
documentation
=
Documentation
(
name
)
peripheral
.
eval_peripheral
()
documentation
.
add
(
config
[
'
hdl_library_name
'
],
peripheral
)
documentation
.
generate_pdf
()
del
documentation
del
system
time
.
sleep
(
1.0
)
except
CalledProcessError
:
pass
except
IOError
:
except
IOError
:
logger
.
error
(
"
config file
'
{}
'
does not exist
"
.
format
(
filename
))
logger
.
error
(
"
config file
'
{}
'
does not exist
"
.
format
(
filename
))
class
Documentation
(
object
):
"""
make documentation for system or peripheral(s)
class
SystemDocumentation
(
object
):
"""
def
__init__
(
self
,
systemname
):
def
__init__
(
self
,
document_name
):
self
.
systemname
=
systemname
self
.
root_dir
=
os
.
path
.
expandvars
(
'
$RADIOHDL/tools/oneclick/prestudy/YAML
'
)
self
.
system_filename
=
"
./systems/{}.system.yaml
"
.
format
(
systemname
)
self
.
document_name
=
document_name
self
.
config
=
yaml
.
load
(
open
(
self
.
system_filename
,
"
r
"
))
self
.
config
=
{}
geometry_options
=
{
"
tmargin
"
:
"
1cm
"
,
"
lmargin
"
:
"
2.5cm
"
}
geometry_options
=
{
"
tmargin
"
:
"
1cm
"
,
"
lmargin
"
:
"
2.5cm
"
}
self
.
doc
=
Document
(
geometry_options
=
geometry_options
)
self
.
doc
=
Document
(
geometry_options
=
geometry_options
)
#doc.packages.append(Package(u'listings'))
self
.
doc
.
preamble
.
append
(
Command
(
'
title
'
,
'
ARGS Documentation for {}
'
.
format
(
self
.
systemname
)))
#doc.append(NoEscape(r'\lstset{columns=flexible}'))
self
.
doc
.
preamble
.
append
(
Command
(
'
author
'
,
'
oneclick-args-documentation-script
'
))
#doc.append(NoEscape(r'\lstset{keepspaces=true}'))
self
.
doc
.
preamble
.
append
(
Command
(
'
date
'
,
NoEscape
(
r
'
\today
'
)))
#doc.append(NoEscape(r'\lstset{basicstyle=\ttfamily\color{blue}}'))
self
.
doc
.
append
(
NoEscape
(
r
'
\maketitle
'
))
self
.
add_title
()
def
generate_pdf
(
self
):
#self.doc = Documentation(self.config['system_name'])
self
.
doc
.
generate_pdf
(
'
{}
'
.
format
(
self
.
document_name
),
clean_tex
=
True
)
self
.
system
=
System
(
self
.
system_filename
)
#self.doc.generate_tex()
def
add_title
(
self
):
"""
add title to document
"""
self
.
doc
.
preamble
.
append
(
Command
(
'
title
'
,
'
MM Documentation for {}
'
.
format
(
self
.
document_name
)))
def
__del__
(
self
):
self
.
doc
.
preamble
.
append
(
Command
(
'
author
'
,
'
oneclick-mm-documentation-script
'
))
del
self
.
doc
self
.
doc
.
preamble
.
append
(
Command
(
'
date
'
,
NoEscape
(
r
'
\today
'
)))
del
self
.
system
time
.
sleep
(
0.5
)
def
fill
(
self
):
with
self
.
doc
.
create
(
Section
(
"
{} system.
"
.
format
(
self
.
config
[
'
system_name
'
]))):
self
.
doc
.
append
(
self
.
system
.
system_description
)
self
.
doc
.
append
(
NoEscape
(
r
'
\maketitle
'
))
with
self
.
doc
.
create
(
Section
(
"
Peripherals.
"
)):
added_instances
=
[]
for
peri_name
,
peri_class
in
sorted
(
self
.
system
.
peripherals
.
items
()):
if
peri_class
.
name
()
in
added_instances
:
continue
added_instances
.
append
(
peri_class
.
name
())
def
add
(
self
,
header
,
data
):
with
self
.
doc
.
create
(
Section
(
peri_class
.
name
(),
numbering
=
True
)):
"""
add section (data) to the document with header as section name
"""
self
.
doc
.
append
(
peri_class
.
get_kv
(
'
peripheral_description
'
).
replace
(
'"'
,
''
))
if
isinstance
(
data
,
str
):
self
.
doc
.
append
(
NewLine
())
self
.
add_text
(
header
,
data
)
elif
isinstance
(
data
,
dict
):
self
.
add_dict
(
header
,
data
)
elif
isinstance
(
data
,
Peripheral
):
self
.
add_peripheral
(
header
,
data
)
elif
isinstance
(
data
,
System
):
self
.
add_system
(
header
,
data
)
else
:
pass
def
add_text
(
self
,
header
,
text
):
#self.doc.append(MediumText(bold("slave ports.")))
"""
add text to the document
"""
self
.
add_section
(
header
,
text
)
def
add_dict
(
self
,
header
,
data
):
for
val_info
,
val_type
in
((
peri_class
.
registers
,
'
Registers
'
),
"""
add a dict to the document
"""
(
peri_class
.
rams
,
'
Rams
'
),
for
key
,
val
in
data
.
items
():
(
peri_class
.
fifos
,
'
Fifos
'
)):
self
.
add
(
key
,
val
)
def
add_peripheral
(
self
,
header
,
data
):
if
len
(
val_info
)
==
0
:
"""
add a peripheral to the document
"""
continue
self
.
add_section
(
data
.
name
(),
data
.
get_description
()
)
def
add_system
(
self
,
header
,
data
):
#self.doc.add(text=val_type, size="medium")
"""
add a system to the document
"""
self
.
doc
.
append
(
Command
(
'
begin
'
,
'
huge
'
))
self
.
doc
.
append
(
NoEscape
(
"
{} description.
"
.
format
(
header
)))
self
.
doc
.
append
(
Command
(
'
end
'
,
'
huge
'
))
self
.
add
(
""
,
data
.
system_description
)
added_val_types
=
[]
for
key
,
val
in
sorted
(
val_info
.
items
()):
if
val
.
name
()
in
added_val_types
:
continue
added_val_types
.
append
(
val
.
name
())
with
self
.
doc
.
create
(
Subsection
(
"
{} slave.
"
.
format
(
val
.
name
().
lower
()),
numbering
=
True
)):
if
val
.
get_kv
(
'
slave_description
'
)
is
not
None
:
self
.
doc
.
append
(
val
.
get_kv
(
'
slave_description
'
).
replace
(
'"'
,
''
))
added_fields
=
[]
for
field_key
,
field_val
in
sorted
(
val
.
fields
.
items
()):
real_name
=
field_val
.
name
().
strip
().
split
(
'
.
'
)[
0
]
if
real_name
in
added_fields
:
continue
added_fields
.
append
(
real_name
)
with
self
.
doc
.
create
(
Subsubsection
(
"
{} field.
"
.
format
(
"
{}
"
.
format
(
real_name
)),
numbering
=
True
)):
self
.
doc
.
append
(
field_val
.
get_kv
(
'
field_description
'
).
replace
(
'"'
,
''
)
)
#self.doc.append(NewLine())
self
.
doc
.
append
(
Command
(
'
begin
'
,
'
huge
'
))
def
make_pdf
(
self
):
self
.
doc
.
append
(
NoEscape
(
"
Peripherals.
"
))
try
:
self
.
doc
.
append
(
Command
(
'
end
'
,
'
huge
'
))
self
.
doc
.
generate_pdf
(
'
{}
'
.
format
(
self
.
systemname
),
clean_tex
=
True
)
time
.
sleep
(
0.5
)
except
CalledProcessError
:
pass
class
PeripheralDocumentation
(
object
):
def
__init__
(
self
,
peripheralname
):
self
.
peripheralname
=
peripheralname
self
.
peripheral_filename
=
"
./peripherals/{}.peripheral.yaml
"
.
format
(
peripheralname
)
self
.
config
=
yaml
.
load
(
open
(
self
.
peripheral_filename
,
"
r
"
))
geometry_options
=
{
"
tmargin
"
:
"
1cm
"
,
"
lmargin
"
:
"
2.5cm
"
}
self
.
doc
=
Document
(
geometry_options
=
geometry_options
)
self
.
doc
.
preamble
.
append
(
Command
(
'
title
'
,
'
ARGS Documentation for {}
'
.
format
(
self
.
peripheralname
)))
self
.
doc
.
preamble
.
append
(
Command
(
'
author
'
,
'
oneclick-args-documentation-script
'
))
self
.
doc
.
preamble
.
append
(
Command
(
'
date
'
,
NoEscape
(
r
'
\today
'
)))
self
.
doc
.
append
(
NoEscape
(
r
'
\maketitle
'
))
def
fill
(
self
):
with
self
.
doc
.
create
(
Section
(
"
{} library.
"
.
format
(
self
.
config
[
'
hdl_library_name
'
]))):
self
.
doc
.
append
(
self
.
config
[
'
hdl_library_description
'
])
with
self
.
doc
.
create
(
Section
(
"
Peripherals.
"
)):
added_instances
=
[]
added_instances
=
[]
for
key
,
val
in
sorted
(
data
.
peripherals
.
items
()):
for
peri_info
in
self
.
config
[
'
peripherals
'
]:
if
val
.
name
()
in
added_instances
:
peri_class
=
Peripheral
(
peri_info
)
if
peri_class
.
name
()
in
added_instances
:
continue
added_instances
.
append
(
peri_class
.
name
())
with
self
.
doc
.
create
(
Section
(
peri_class
.
name
(),
numbering
=
True
)):
self
.
doc
.
append
(
peri_class
.
get_kv
(
'
peripheral_description
'
).
replace
(
'"'
,
''
))
self
.
doc
.
append
(
NewLine
())
#self.doc.append(MediumText(bold("slave ports.")))
for
val_info
,
val_type
in
((
peri_class
.
registers
,
'
Registers
'
),
(
peri_class
.
rams
,
'
Rams
'
),
(
peri_class
.
fifos
,
'
Fifos
'
)):
if
len
(
val_info
)
==
0
:
continue
continue
added_instances
.
append
(
val
.
name
())
_header
=
val
.
name
().
strip
()
#self.doc.add(text=val_type, size="medium")
_text
=
val
.
get_kv
(
'
peripheral_description
'
)
self
.
add
(
_header
,
_text
)
added_val_types
=
[]
for
key
,
val
in
sorted
(
val_info
.
items
()):
def
add_section
(
self
,
heading
=
''
,
text
=
''
):
if
val
.
name
()
in
added_val_types
:
with
self
.
doc
.
create
(
Section
(
'
%s
'
%
heading
))
as
sec
:
lines
=
text
.
splitlines
(
True
)
n_lines
=
len
(
lines
)
block_data
=
[]
line_nr
=
0
while
line_nr
<
n_lines
:
if
lines
[
line_nr
].
startswith
(
'
+--
'
):
block_data
=
[]
block_data
.
append
(
lines
[
line_nr
])
line_nr
+=
1
while
line_nr
<
n_lines
:
block_data
.
append
(
lines
[
line_nr
])
if
lines
[
line_nr
].
startswith
(
'
+--
'
):
logger
.
debug
(
"
append table
"
)
self
.
add_table
(
sec
,
block_data
)
line_nr
+=
1
break
line_nr
+=
1
elif
lines
[
line_nr
].
startswith
(
'
A|
'
):
block_data
=
[]
block_data
.
append
(
lines
[
line_nr
][
2
:])
line_nr
+=
1
while
line_nr
<
n_lines
:
block_data
.
append
(
lines
[
line_nr
][
2
:])
if
not
lines
[
line_nr
].
startswith
(
'
A|
'
):
logger
.
debug
(
"
append AscciiArt
"
)
self
.
add_ascii_art
(
sec
,
block_data
)
break
line_nr
+=
1
else
:
self
.
add_line
(
sec
,
lines
[
line_nr
])
line_nr
+=
1
return
def
add_line
(
self
,
doc
,
line
,
add
=
True
):
n_spaces
=
0
_line
=
[]
text
=
[]
line
=
line
.
strip
()
#print('3 ', line)
for
ch_nr
,
ch
in
enumerate
(
line
):
if
ch
==
'
'
:
n_spaces
+=
1
else
:
if
n_spaces
==
1
:
text
.
append
(
'
'
)
elif
n_spaces
:
if
text
:
_line
.
append
(
'
%s
'
%
''
.
join
(
text
))
text
=
[]
_line
.
append
(
NoEscape
(
r
'
\hspace{%fcm}
'
%
(
n_spaces
*
0.184
)))
n_spaces
=
0
text
.
append
(
ch
)
if
text
:
_line
.
append
(
'
%s
'
%
''
.
join
(
text
))
#_line.append('\n')
if
add
:
for
i
in
_line
:
doc
.
append
(
i
)
return
return
_line
def
add_ascii_art
(
self
,
doc
,
data
):
doc
.
append
(
Command
(
'
begin
'
,
'
small
'
))
doc
.
append
(
Command
(
'
begin
'
,
'
verbatim
'
))
doc
.
append
(
NoEscape
(
''
.
join
(
data
)))
doc
.
append
(
Command
(
'
end
'
,
'
verbatim
'
))
doc
.
append
(
Command
(
'
end
'
,
'
small
'
))
def
add_table
(
self
,
doc
,
data
):
table
=
None
table_column_pos
=
[]
table_n_columns
=
0
# get vertical line positions of second line
pos
=
0
while
pos
>=
0
:
pos
=
data
[
1
].
find
(
'
|
'
,
pos
)
if
pos
>
-
1
:
table_column_pos
.
append
(
pos
)
pos
+=
1
# make table
table_n_columns
=
len
(
table_column_pos
)
-
1
#table = Tabular('c'.join('|'*len(table_column_pos)))
tabular
=
[
'
|
'
]
p1
=
table_column_pos
[
0
]
for
p2
in
table_column_pos
[
1
:]:
cols
=
p2
-
p1
tabular
.
append
(
'
p{%fcm}|
'
%
(
cols
*
0.16
))
p1
=
p2
table
=
Tabular
(
''
.
join
(
tabular
))
#table.add_hline()
for
line_nr
,
line
in
enumerate
(
data
):
logger
.
debug
(
"
%s, %d
"
,
line
,
len
(
line
))
if
line
.
startswith
(
'
+---
'
):
# or line.startswith('|---'):
table
.
add_hline
()
continue
continue
if
line
.
startswith
(
'
|---
'
):
added_val_types
.
append
(
val
.
name
())
with
self
.
doc
.
create
(
Subsection
(
"
{} slave.
"
.
format
(
val
.
name
().
lower
()),
numbering
=
True
)):
if
val
.
get_kv
(
'
slave_description
'
)
is
not
None
:
self
.
doc
.
append
(
val
.
get_kv
(
'
slave_description
'
).
replace
(
'"'
,
''
))
added_fields
=
[]
for
field_key
,
field_val
in
sorted
(
val
.
fields
.
items
()):
real_name
=
field_val
.
name
().
strip
().
split
(
'
.
'
)[
0
]
if
real_name
in
added_fields
:
continue
continue
added_fields
.
append
(
real_name
)
with
self
.
doc
.
create
(
Subsubsection
(
"
{} field.
"
.
format
(
"
{}
"
.
format
(
real_name
)),
numbering
=
True
)):
self
.
doc
.
append
(
field_val
.
get_kv
(
'
field_description
'
).
replace
(
'"'
,
''
)
)
#self.doc.append(NewLine())
def
make_pdf
(
self
):
try
:
self
.
doc
.
generate_pdf
(
'
{}
'
.
format
(
self
.
peripheralname
),
clean_tex
=
True
)
time
.
sleep
(
0.5
)
except
CalledProcessError
:
pass
if
line_nr
==
1
:
row_data
=
[
bold
(
i
)
for
i
in
line
.
strip
()[
1
:
-
1
].
split
(
'
|
'
)]
else
:
row_data
=
[
i
for
i
in
line
.
strip
()[
1
:
-
1
].
split
(
'
|
'
)]
logger
.
debug
(
"
%s
"
,
str
(
row_data
))
row_n_cols
=
len
(
row_data
)
# if all colums used add data
if
row_n_cols
==
table_n_columns
:
if
len
(
table
)
>
1
:
table
.
add_hline
()
table
.
add_row
(
row_data
)
else
:
row_cells
=
[]
row_data_index
=
0
pos
=
table_column_pos
[
0
]
+
1
last_index
=
0
while
pos
>=
0
:
pos
=
line
.
find
(
'
|
'
,
pos
)
if
pos
>
-
1
:
for
index
,
tcp
in
enumerate
(
table_column_pos
):
if
pos
==
tcp
:
#rint "same pos, %d" % pos
#if (index - last_index) == 1:
# row_cells.append(row_data[row_data_index])
#else:
cols
=
index
-
last_index
text
=
row_data
[
row_data_index
]
if
len
(
row_data
[
row_data_index
][:
2
].
strip
())
==
0
:
row_cells
.
append
(
MultiColumn
(
cols
,
align
=
'
|c|
'
,
data
=
SmallText
(
text
)))
else
:
row_cells
.
append
(
MultiColumn
(
cols
,
align
=
'
|l|
'
,
data
=
SmallText
(
text
)))
last_index
=
index
row_data_index
+=
1
pos
+=
1
else
:
table
.
add_hline
()
table
.
add_row
(
row_cells
)
doc
.
append
(
table
)
doc
.
append
(
'
\n
'
)
return
table
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
# setup first log system before importing other user libraries
# setup first log system before importing other user libraries
...
...
This diff is collapsed.
Click to expand it.
tools/oneclick/prestudy/YAML/peripherals/bf.peripheral.yaml
+
6
−
6
View file @
117b30be
...
@@ -33,7 +33,7 @@ peripherals:
...
@@ -33,7 +33,7 @@ peripherals:
field_description
:
|
field_description
:
|
"Contains the weights.
"Contains the weights.
The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
slave_discription
:
|
slave_discription
:
>
" "
" "
-
-
...
@@ -50,7 +50,7 @@ peripherals:
...
@@ -50,7 +50,7 @@ peripherals:
number_of_fields
:
g_bf.nof_subbands * g_bf.nof_input_streams * c_nof_signal_paths_per_stream
# 16*4=64, nof_input_streams*nof_signal_paths_per_stream
number_of_fields
:
g_bf.nof_subbands * g_bf.nof_input_streams * c_nof_signal_paths_per_stream
# 16*4=64, nof_input_streams*nof_signal_paths_per_stream
field_description
:
|
field_description
:
|
"Contains the addresses to select from the stored subbands."
"Contains the addresses to select from the stored subbands."
slave_discription
:
|
slave_discription
:
>
" "
" "
-
-
...
@@ -69,7 +69,7 @@ peripherals:
...
@@ -69,7 +69,7 @@ peripherals:
field_description
:
|
field_description
:
|
"Contains the weights.
"Contains the weights.
The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
slave_discription
:
|
slave_discription
:
>
-
-
# reg_st_sst_bf
# reg_st_sst_bf
...
@@ -80,14 +80,14 @@ peripherals:
...
@@ -80,14 +80,14 @@ peripherals:
slave_type
:
REG
slave_type
:
REG
fields
:
fields
:
-
-
field_name
:
T
reshold
field_name
:
t
reshold
address_offset
:
0x0
address_offset
:
0x0
field_description
:
|
field_description
:
|
"When the treshold register is set to 0 the statistics will be auto-correlations.
"When the treshold register is set to 0 the statistics will be auto-correlations.
In case the treshold register is set to a non-zero value, it allows to create a sample & hold function
In case the treshold register is set to a non-zero value, it allows to create a sample & hold function
for the a-input of the multiplier.
for the a-input of the multiplier.
The a-input of the multiplier is updated every treshold clockcycle. Thereby cross statistics can be created."
The a-input of the multiplier is updated every treshold clockcycle. Thereby cross statistics can be created."
slave_discription
:
|
slave_discription
:
>
" "
" "
peripheral_description
:
|
peripheral_description
:
|
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment