Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
gene
xmc4500-relax-linux
Commits
ad27d165
Commit
ad27d165
authored
Dec 01, 2017
by
Christian Eichler
Browse files
Merge branch 'dev' into 'master'
dev -> master See merge request gene/xmc4500-relax-linux!1
parents
14b8e467
22d5c131
Changes
4
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
ad27d165
.PHONY
:
flash/ids_% flash/bch_% reset_%
.PHONY
:
reset_%
.SECONDARY
:
$(bin/*.axf)
#### Setup ####
XMC
=
$(
shell
pwd
)
/XMC
...
...
@@ -16,19 +17,19 @@ LIBS = $(CMSIS)/Lib/GCC/libarm_cortexM4lf_math.a
LINKER_FILE
=
$(CMSIS)
/Infineon/
$(UC)
_series/Source/GCC/XMC4500x1024.ld
CMSIS_SRC
+=
$(CMSIS)
/Infineon/
$(UC)
_series/Source/System_
$(UC)
.c
JLINK
=
JLinkExe
SYSCC
=
$(TOOLCHAIN)
-gcc
CC
=
patmos-clang
CP
=
$(TOOLCHAIN)
-objcopy
OD
=
$(TOOLCHAIN)
-objdump
GDB
=
$(TOOLCHAIN)
-gdb
#STACK_SIZE?=2048
STACK_SIZE
?=
16384
JLINK
=
JLinkExe
JLFLAGS
=
-device
XMC4500-1024
-if
SWD
-speed
900
CFLAGS
=
-target
armv6m--none-eabi
-mcpu
=
cortex-m4
-mthumb
-integrated-as
-ccc-gcc-name
arm-none-eabi-gcc
CFLAGS
=
-mcpu
=
cortex-m4
-target
armv7m-none-eabi
-msoft-float
CFLAGS
+=
-integrated-as
-ccc-gcc-name
arm-none-eabi-gcc
CFLAGS
+=
-fno-builtin
CFLAGS
+=
-Os
-ffunction-sections
-fdata-sections
CFLAGS
+=
-MD
-std
=
c99
-Wall
...
...
@@ -36,6 +37,7 @@ CFLAGS+= -DUC_ID=$(UC_ID) -DARM_MATH_CM4 -DINTERRUPT_CONTROL_ENDPOINT
CFLAGS
+=
-DXMC4500_F100x1024
CFLAGS
+=
-I
$(CMSIS)
/Include
-I
$(CMSIS)
/Infineon/
$(UC)
_series/Include
CFLAGS
+=
-Ilib
/LUFA
-I
$(XMC)
/XMCLib/inc
CFLAGS
+=
$(CFLAGS_GENE)
ASFLAGS
=
-target
armv6m--none-eabi
-mcpu
=
cortex-m4
-marm
-mthumb
ASFLAGS
+=
-O0
-ffunction-sections
-fdata-sections
...
...
@@ -60,7 +62,7 @@ OBJS += src/System_$(UC).o
OBJS_MAIN
=
$(OBJS)
$(SRC_MAIN:.c=.o)
#### Rules ####
all
:
$(OBJS)
bin/xmc.bin xmccomm
all
:
$(OBJS)
src/System_$(UC).o
:
$(CMSIS_SRC)
$(CC)
-c
$(CFLAGS)
$<
-o
$@
...
...
@@ -88,24 +90,10 @@ bin/ids_%.axf: $(OBJS) bin/startup_XMC4500.o bin/ids_%.o
%.bin
:
%.axf
$(CP)
$(CPFLAGS)
$^
$@
flash/ids_%
:
bin/ids_%.bin
echo
"connect
\n\
loadbin
$<
0x8000000
\n\
r
\n\
g
\n\
exit
\n
"
|
$(JLINK)
$(JLFLAGS)
-SelectEmuBySN
$*
flash/bch_%
:
bin/xmc.bin
echo
"connect
\n\
loadbin bin/xmc.bin 0x8000000
\n\
r
\n\
g
\n\
exit
\n
"
|
$(JLINK)
$(JLFLAGS)
-SelectEmuBySN
$*
bin/xmc.axf
:
$(OBJS_MAIN) bin/startup_XMC4500.o gene.o
bin/system_%.axf
:
$(OBJS_MAIN) bin/startup_XMC4500.o %.o
mkdir
-p
bin
@
echo
LD
$
<
@
$(CC)
-T
$(LINKER_FILE)
$(LFLAGS)
-o
bin/xmc.axf
$^
$(LIBS)
@
echo
LD
$
@
@
$(CC)
-T
$(LINKER_FILE)
$(LFLAGS)
-o
$@
$^
$(LIBS)
reset_%
:
echo
"connect
\n\
...
...
@@ -124,8 +112,7 @@ fastgdb:
sleep
1
make gdb
xmccomm
:
xmccomm.c
gcc
-std
=
c99
-g
xmccomm.c
-o
xmccomm
clean
:
rm
-f
src/
*
.o src/
*
.d bin/
*
print-%
:
; @echo $* = $($*)
README.md
View file @
ad27d165
...
...
@@ -59,6 +59,9 @@ The **bch** supports the following requests:
*
`eic`
: enable instruction cache
*
`bch`
: run benchmark
Building the
**bch**
system requires a prior execution of GenE to generate
the file containing the actual benchmark (
`gene.o`
).
Usage: Communicate with the System
----------------------------------
...
...
src/main.c
View file @
ad27d165
...
...
@@ -11,7 +11,7 @@
#include
"timer.h"
#endif
/* ifndef ID_SYSTEM */
#define IHANDLER
__attribute__ ((naked))
#define IHANDLER
#define xstr(s) str(s)
#define str(s) #s
...
...
@@ -22,25 +22,48 @@
#define SERIALSTR "<none>"
#endif
#define VOID_ARG_TYPE 1
#define UINT32_ARG_TYPE 2
#ifndef BENCHMARK_MAIN
#if defined(BENCHMARK_ARG) || defined(BENCHMARK_INIT)
#error BENCHMARK_MAIN, BENCHMARK_ARG, BENCHMARK_INIT must be defined
#endif
#define BENCHMARK_MAIN gene_main
#define BENCHMARK_ARG uint32_t
#define ARG_TYPE UINT32_ARG_TYPE
#define BENCHMARK_INIT gene_init
#endif
// use void as default
#ifndef BENCHMARK_ARG
#define ARG_TYPE VOID_ARG_TYPE
#define BENCHMARK_ARG void
#endif
void
BENCHMARK_MAIN
(
BENCHMARK_ARG
);
void
BENCHMARK_INIT
(
void
);
extern
int
errno
;
void
_init
()
{}
void
_sbrk
()
{}
/* Clock configuration */
XMC_SCU_CLOCK_CONFIG_t
clock_config
=
{
.
syspll_config
.
p_div
=
2
,
.
syspll_config
.
n_div
=
80
,
.
syspll_config
.
k_div
=
4
,
.
syspll_config
.
mode
=
XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL
,
.
syspll_config
.
p_div
=
2
,
.
syspll_config
.
n_div
=
80
,
.
syspll_config
.
k_div
=
4
,
.
syspll_config
.
mode
=
XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL
,
.
syspll_config
.
clksrc
=
XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP
,
.
enable_oschp
=
true
,
.
calibration_mode
=
XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY
,
.
fsys_clksrc
=
XMC_SCU_CLOCK_SYSCLKSRC_PLL
,
.
fsys_clkdiv
=
1
,
.
fcpu_clkdiv
=
1
,
.
fccu_clkdiv
=
1
,
.
fperipheral_clkdiv
=
1
.
enable_oschp
=
true
,
.
calibration_mode
=
XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY
,
.
fsys_clksrc
=
XMC_SCU_CLOCK_SYSCLKSRC_PLL
,
.
fsys_clkdiv
=
1
,
.
fcpu_clkdiv
=
1
,
.
fccu_clkdiv
=
1
,
.
fperipheral_clkdiv
=
1
};
...
...
@@ -58,10 +81,7 @@ void SystemCoreClockSetup(void)
SystemCoreClockUpdate
();
}
void
gene_main
(
uint32_t
);
void
gene_init
(
void
);
/*** Begin: Interrupt Handlers ***/
IHANDLER
void
PendSV_Handler
()
{
P1_1_set
();
while
(
1
)
{}
}
IHANDLER
void
SysTick_Handler
()
{
P1_1_set
();
while
(
1
)
{}
}
IHANDLER
void
SVC_Handler
()
{
P1_1_set
();
while
(
1
)
{}
}
...
...
@@ -70,6 +90,8 @@ IHANDLER void NMI_Handler() { P1_1_set(); while(1) {} }
IHANDLER
void
MemManage_Handler
()
{
P1_1_set
();
while
(
1
)
{}
}
IHANDLER
void
UsageFault_Handler
()
{
P1_1_set
();
while
(
1
)
{}
}
IHANDLER
void
BusFault_Handler
()
{
P1_1_set
();
while
(
1
)
{}
}
/*** End: Interrupt Handlers ***/
static
void
uint64_to_string
(
char
*
buf
,
uint64_t
value
)
{
if
(
0
==
value
)
{
...
...
@@ -85,62 +107,87 @@ static void uint64_to_string(char *buf, uint64_t value) {
}
}
/*** Begin: USB helper functions ***/
static
void
usb_send
(
const
char
*
str
)
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
str
);
}
static
void
usb_send2
(
const
char
*
str1
,
const
char
*
str2
)
{
usb_send
(
str1
);
usb_send
(
str2
);
}
static
void
usb_send3
(
const
char
*
str1
,
const
char
*
str2
,
const
char
*
str3
)
{
usb_send
(
str1
);
usb_send
(
str2
);
usb_send
(
str3
);
}
static
void
usb_flush
()
{
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
}
/*** End: USB helper functions ***/
#ifndef ID_SYSTEM
static
void
command_bch
(
char
*
arg
)
{
errno
=
0
;
unsigned
long
long
val
=
strtoull
(
arg
,
NULL
,
10
);
if
(
0
!=
errno
||
val
>
(
unsigned
long
long
)
UINT32_MAX
)
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"e:ov
\n
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send
(
"e:ov
\n
"
);
usb_flush
(
);
return
;
}
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:start
\r
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send
(
"o:start
\r
"
);
usb_flush
(
);
P1_0_toggle
();
uint32_t
old_basepri
=
__get_BASEPRI
();
__set_BASEPRI
(
1
<<
(
8
-
__NVIC_PRIO_BITS
));
gene_init
();
BENCHMARK_INIT
();
// flush instruction cache prior to executing the benchmark to
// ensure a "clean" system state
XMC_PREFETCH_InvalidateInstructionBuffer
();
timer_reset
();
P5_7_set
();
timer_start
();
gene_main
(
val
);
#if ARG_TYPE == VOID_ARG_TYPE
BENCHMARK_MAIN
();
#else
BENCHMARK_MAIN
(
val
);
#endif
timer_stop
();
P5_7_reset
();
uint64_t
cycles
=
timer_get
();
__set_BASEPRI
(
old_basepri
);
P1_0_toggle
();
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:end "
);
CDC_Device_USBTask
(
&
VirtualSerial_CDC_Interface
);
char
buf
[
64
]
=
{
0
};
uint64_to_string
(
buf
,
cycles
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
buf
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"
\n
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send3
(
"o:end "
,
buf
,
"
\n
"
);
usb_flush
();
CDC_Device_USBTask
(
&
VirtualSerial_CDC_Interface
);
}
static
void
command_dic
(
char
*
arg
)
{
XMC_PREFETCH_DisableInstructionBuffer
();
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o
\n
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send
(
"o
\n
"
);
usb_flush
(
);
CDC_Device_USBTask
(
&
VirtualSerial_CDC_Interface
);
}
static
void
command_eic
(
char
*
arg
)
{
XMC_PREFETCH_EnableInstructionBuffer
();
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o
\n
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send
(
"o
\n
"
);
usb_flush
(
);
CDC_Device_USBTask
(
&
VirtualSerial_CDC_Interface
);
}
...
...
@@ -159,53 +206,39 @@ static void command_inf(char *arg) {
// send FREQUENCY
char
buf
[
128
]
=
{
0
};
uint64_to_string
(
buf
,
SystemCoreClock
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:freq "
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
buf
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"
\r
"
);
usb_send3
(
"o:freq "
,
buf
,
"
\r
"
);
// send PFLASH
{
char
buf
[
128
]
=
{
0
};
uint64_to_string
(
buf
,
(
FLASH0
->
FCON
&
(
uint32_t
)
FLASH_FCON_WSPFLASH_Msk
)
>>
FLASH_FCON_WSPFLASH_Pos
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:wspflash "
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
buf
);
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"
\r
"
);
usb_send3
(
"o:wspflash "
,
buf
,
"
\r
"
);
}
// send DWT status
switch
(
DWT
->
CTRL
&
0xFF000000
)
{
case
0x40000000
:
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:4wt
\r
"
);
break
;
case
0x4F000000
:
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:4w
\r
"
);
break
;
case
0x10000000
:
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:1wt
\r
"
);
break
;
case
0x1F000000
:
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:1w
\r
"
);
break
;
case
0x00000000
:
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:0
\r
"
);
break
;
default:
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"e:v
\r
"
);
break
;
case
0x40000000
:
usb_send
(
"o:4wt
\r
"
);
break
;
case
0x4F000000
:
usb_send
(
"o:4w
\r
"
);
break
;
case
0x10000000
:
usb_send
(
"o:1wt
\r
"
);
break
;
case
0x1F000000
:
usb_send
(
"o:1w
\r
"
);
break
;
case
0x00000000
:
usb_send
(
"o:0
\r
"
);
break
;
default:
usb_send
(
"e:v
\r
"
);
break
;
}
#ifndef ID_SYSTEM
if
(
timer_has_overflow_detection
())
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:ov e
\r
"
);
}
else
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:ov d
\r
"
);
}
usb_send
(
timer_has_overflow_detection
()
?
"o:ov e
\r
"
:
"o:ov d
\r
"
);
#endif
/* ifndef ID_SYSTEM */
usb_send
((
PREF
->
PCON
&
PREF_PCON_IBYP_Msk
)
?
"o:ic d
\n
"
:
"o:ic e
\n
"
);
if
(
PREF
->
PCON
&
PREF_PCON_IBYP_Msk
)
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:ic d
\n
"
);
}
else
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"o:ic e
\n
"
);
}
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_flush
();
CDC_Device_USBTask
(
&
VirtualSerial_CDC_Interface
);
}
void
*
__aeabi_memset
(
void
*
s
,
int
c
,
size_t
n
){
size_t
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
((
char
*
)
s
)[
i
]
=
(
char
)
c
;
}
return
s
;
void
*
__aeabi_memset
(
void
*
s
,
int
c
,
size_t
n
)
{
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
{
((
char
*
)
s
)[
i
]
=
(
char
)
c
;
}
return
s
;
}
int
main
(
void
)
{
...
...
@@ -216,12 +249,12 @@ int main(void) {
P1_1_set_mode
(
OUTPUT_PP_GP
);
P1_1_set_driver_strength
(
STRONG
);
#define BUFFER_SIZE 32
char
buffer
[
BUFFER_SIZE
+
1
];
buffer
[
BUFFER_SIZE
]
=
'\0'
;
P5_7_set_mode
(
OUTPUT_PP_GP
);
P5_7_set_driver_strength
(
WEAK
);
#define BUFFER_SIZE 32
uint8_t
pos
=
0
;
char
buffer
[
BUFFER_SIZE
+
1
]
=
{
0
};
// enable monitor debugging
CoreDebug
->
DHCSR
=
0xA05F
<<
CoreDebug_DHCSR_DBGKEY_Pos
;
...
...
@@ -270,8 +303,8 @@ int main(void) {
#undef COMMAND
if
(
!
handled
)
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"e:uc
\n
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send
(
"e:uc
\n
"
);
usb_flush
(
);
}
pos
=
0
;
...
...
@@ -283,8 +316,8 @@ int main(void) {
buffer
[
pos
]
=
byte
;
++
pos
;
}
else
{
CDC_Device_SendString
(
&
VirtualSerial_CDC_Interface
,
"e:OVERFLOW IN COMMAND BUFFER
\n
"
);
CDC_Device_Flush
(
&
VirtualSerial_CDC_Interface
);
usb_send
(
"e:ov
\n
"
);
usb_flush
(
);
pos
=
0
;
}
...
...
xmccomm.c
deleted
100644 → 0
View file @
14b8e467
#define _POSIX_C_SOURCE 199309L
#define _XOPEN_SOURCE 500
#include
<errno.h>
#include
<stdbool.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<sys/ioctl.h>
#include
<sys/stat.h>
#include
<sys/types.h>
#include
<string.h>
#include
<stdint.h>
#include
<fcntl.h>
#include
<termios.h>
#include
<unistd.h>
#define SHELL_ESC "\x1b"
#define streq(A,B) (!strcmp(A,B))
// stty -F /dev/ttyACM0 115200
static
void
print_ok
()
{
printf
(
SHELL_ESC
"[;32;02m[ok] "
SHELL_ESC
"[m"
);
}
static
void
print_er
()
{
printf
(
SHELL_ESC
"[;31;02m[ER] "
SHELL_ESC
"[m"
);
}
static
void
print_vb
(
char
*
msg
)
{
fprintf
(
stderr
,
SHELL_ESC
"[;36;02m[vb] "
SHELL_ESC
"[m%s"
,
msg
);
}
static
bool
recv_response
(
FILE
*
fh
,
char
*
buf
,
size_t
buf_size
)
{
int
pos
=
0
;
while
(
pos
<
buf_size
)
{
int
c
=
fgetc
(
fh
);
if
(
EOF
!=
c
)
{
if
(
'\n'
==
c
)
{
buf
[
pos
]
=
'\0'
;
return
true
;
}
else
if
(
'\r'
==
c
)
{
buf
[
pos
]
=
'\0'
;
return
false
;
}
else
{
buf
[
pos
]
=
c
;
++
pos
;
}
}
else
{
if
(
ferror
(
fh
))
{
perror
(
"fgetc(TTY)"
);
exit
(
EXIT_FAILURE
);
}
else
{
fprintf
(
stderr
,
"Unexpected EOF
\n
"
);
exit
(
EXIT_FAILURE
);
}
}
}
}
static
int
connect_tty
(
char
*
tty
)
{
bool
exists
=
false
;
unsigned
retry
=
0
;
do
{
print_vb
(
""
);
fprintf
(
stderr
,
"open('%s') try %u
\n
"
,
tty
,
retry
);
++
retry
;
struct
stat
sbuf
;
int
res
=
stat
(
tty
,
&
sbuf
);
exists
=
(
0
==
res
);
if
(
!
exists
)
{
usleep
(
500
*
1000
);
}
}
while
(
!
exists
&&
errno
!=
EACCES
&&
retry
<
10
);
int
fd
=
open
(
tty
,
O_RDWR
|
O_NOCTTY
);
if
(
-
1
==
fd
)
{
perror
(
"open(TTY)"
);
if
(
EACCES
==
errno
)
{
fprintf
(
stderr
,
"Make sure current user `%s` is in group `dialout`
\n
"
,
getlogin
());
}
exit
(
EXIT_FAILURE
);
}
else
{
print_vb
(
""
);
fprintf
(
stderr
,
"%s successfully opened
\n
"
,
tty
);
}
// setup control structure
struct
termios
toptions
;
if
(
0
!=
tcgetattr
(
fd
,
&
toptions
))
{
perror
(
"tcgetattr"
);
}
if
(
0
!=
cfsetispeed
(
&
toptions
,
B115200
))
{
perror
(
"cfsetispeed"
);
}
if
(
0
!=
cfsetospeed
(
&
toptions
,
B115200
))
{
perror
(
"cfsetospeed"
);
}
toptions
.
c_cflag
&=
~
PARENB
;
// no parity bit
toptions
.
c_cflag
&=
~
CSTOPB
;
// no stop bits
toptions
.
c_cflag
&=
~
CSIZE
;
// char. size
toptions
.
c_cflag
|=
CS8
;
// 8 bits
/* enable receiver, ignore status lines */
toptions
.
c_cflag
|=
CREAD
|
CLOCAL
;
/* disable input/output flow control, disable restart chars */
toptions
.
c_iflag
&=
~
(
IXON
|
IXOFF
|
IXANY
);
/* disable canonical input, disable echo,
disable visually erase chars,
disable terminal-generated signals */
toptions
.
c_lflag
&=
~
(
ICANON
|
ECHO
|
ECHOE
|
ISIG
);
toptions
.
c_oflag
&=
~
OPOST
;
// disable postprocessing
if
(
0
!=
tcsetattr
(
fd
,
TCSANOW
,
&
toptions
))
{
perror
(
"tcsetattr"
);
}
if
(
0
!=
tcflush
(
fd
,
TCIFLUSH
))
{
perror
(
"tcflush"
);
}
return
fd
;
}
static
char
*
strsw
(
char
*
str
,
char
*
start
)
{
const
uint32_t
N
=
strlen
(
start
);
if
(
!
strncmp
(
str
,
start
,
N
))
{
return
&
str
[
N
];
}
return
NULL
;
}
uint32_t
remote_frequency
=
0
;
static
void
resp_inf
(
bool
success
,
char
*
resp
)
{
char
*
rem
=
NULL
;
if
(
streq
(
resp
,
"4wt"
))
{
printf
(
"DWT: 4 comparators for watchpoints+triggers available"
);
}
else
if
(
streq
(
resp
,
"4w"
))
{
printf
(
"DWT: 4 comparators for watchpoints available"
);
}
else
if
(
streq
(
resp
,
"1wt"
))
{
printf
(
"DWT: 1 comparator for watchpoints+triggers available"
);
}
else
if
(
streq
(
resp
,
"1w"
))
{
printf
(
"DWT: 1 comparator for watchpoints available"
);
}
else
if
(
streq
(
resp
,
"0"
))
{
printf
(
"DWT: NOT AVAILABLE"
);
}
else
if
(
streq
(
resp
,
"v"
))
{
printf
(
"Unexpected value ain DWT->CTRL"
);
}
else
if
(
rem
=
strsw
(
resp
,
"freq "
))
{
remote_frequency
=
strtoull
(
rem
,
NULL
,
10
);
char
prefixes
[]
=
{
' '
,
'k'
,
'M'
,
'G'
};
double
freq_dbl
=
remote_frequency
;
int
idx
=
0
;
while
(
freq_dbl
>
500
)
{
++
idx
;
freq_dbl
/=
1000
.;
}
printf
(
"Frequency: %.2f%cHz"
,
freq_dbl
,
prefixes
[
idx
]);
}
else
if
(
rem
=
strsw
(
resp
,
"ic "
))
{
printf
(
"Instruction Cache: Currently %s"
,
(
'e'
==
*
rem
)
?
"enabled"
:
"disabled"
);
}
else
if
(
rem
=
strsw
(
resp
,
"ov "
))
{
printf
(
"Timer Overflow Detection: Currently %s"
,
(
'e'
==
*
rem
)
?
"enabled"
:
"disabled"
);
}
else
if
(
rem
=
strsw
(
resp
,
"id "
))
{
printf
(
"Device ID: %s"
,
rem
);
}
else
if
(
rem
=
strsw
(
resp
,
"wspflash "
))
{
printf
(
"Flash Wait States: %s"
,
rem
);
}
else
{
printf
(
"Unparsed: %s"
,
resp
);
}
}
static
void
resp_bch
(
bool
success
,
char
*
resp
)
{
char
*
rem
=
NULL
;
if
(
streq
(
resp
,
"start"
))
{
printf
(
"Benchmark started..."
);
}
else
if
(
rem
=
strsw
(
resp
,
"end "
))
{
printf
(
"Benchmark done: "
);
uint64_t
cycles
=
strtoull
(
rem
,
NULL
,
10
);
printf
(
"%lu cy / %0.2f s"
,
cycles
,
(
double
)
cycles
/
remote_frequency
);
}
else
if
(
rem
=
strsw
(
resp
,
"ov"
))
{
printf
(
"Overflow in input data"
);
}
else
{
printf
(
"Unparsed: %s"
,
resp
);
}
}
static
void
resp_dic
(
bool
success
,
char
*
resp
)
{
printf
(
"Instruction Cache now disabled!"
);
}
static
void
resp_eic
(
bool
success
,
char
*
resp
)
{
printf
(
"Instruction Cache now enabled!"
);
}
static
void
response_loop
(
FILE
*
fh
,
void
(
*
cb
)(
bool
,
char
*
))
{
bool
done
=
false
;
char
buf
[
128
];
while
(
!
done
)
{
done
=
recv_response
(
fh
,
buf
,
128
);
bool
success
;
switch
(
buf
[
0
])
{
case
'o'
:
success
=
true
;
print_ok
();
break
;
case
'e'
:
success
=
false
;
print_er
();
break
;
default:
printf
(
SHELL_ESC
"[;31;02m[ER] Invalid response!"
);
return
;
}
char
*
rem
=
NULL
;
if
(
rem
=
strsw
(
buf
,
"e:uc"
))
{
printf
(
"Command not known to device; are you trying to benchmark on an IDS?
\n
"
);
exit
(
EXIT_FAILURE
);
}
else
{
cb
(
success
,
'\0'
!=
&
buf
[
1
]
?
&
buf
[
2
]
:
NULL
);
}
printf
(
SHELL_ESC
"[m
\n
"
);
fflush
(
stdout
);
}
}
struct
command
{
char
*
cmd
;
uint32_t
nparam
;
void
(
*
callback
)(
bool
,
char
*
);
};
static
struct
command
commands
[]
=
{
{
"bch"
,
1
,
resp_bch
},