aboutsummaryrefslogtreecommitdiff
path: root/stm32/src/stm32f4_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'stm32/src/stm32f4_machdep.c')
-rw-r--r--stm32/src/stm32f4_machdep.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/stm32/src/stm32f4_machdep.c b/stm32/src/stm32f4_machdep.c
new file mode 100644
index 0000000..59f9ed7
--- /dev/null
+++ b/stm32/src/stm32f4_machdep.c
@@ -0,0 +1,92 @@
+
+/*---------------------------------------------------------------------------*\
+
+ FILE........: stm32f4_machdep.c
+ AUTHOR......: David Rowe
+ DATE CREATED: May 2 2013
+
+ STM32F4 implementation of the machine dependent timer functions,
+ e.g. profiling using a clock cycle counter..
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2013 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. 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 more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include "machdep.h"
+
+#ifdef SEMIHOST_USE_STDIO
+#include "stdio.h"
+#else
+#include "gdb_stdio.h"
+#define printf gdb_stdio_printf
+#endif
+
+volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004;
+volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000;
+volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC;
+
+#define CORE_CLOCK 168E6
+#define BUF_SZ 4096
+
+static char buf[BUF_SZ];
+
+void machdep_profile_init(void)
+{
+ static int enabled = 0;
+
+ if (!enabled) {
+ *SCB_DEMCR = *SCB_DEMCR | 0x01000000;
+ *DWT_CYCCNT = 0; // reset the counter
+ *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
+
+ enabled = 1;
+ }
+ *buf = 0;
+}
+
+void machdep_profile_reset(void)
+{
+ *DWT_CYCCNT = 0; // reset the counter
+}
+
+unsigned int machdep_profile_sample(void) {
+ return *DWT_CYCCNT;
+}
+
+/* log to a buffer, we only call printf after timing finished as it is slow */
+
+unsigned int machdep_profile_sample_and_log(unsigned int start, char s[])
+{
+ char tmp[80];
+ float msec;
+
+ unsigned int dwt = *DWT_CYCCNT - start;
+ msec = 1000.0*(float)dwt/CORE_CLOCK;
+ snprintf(tmp, sizeof(tmp), "%s %5.2f msecs\n",s,(double)msec);
+ if ((strlen(buf) + strlen(tmp)) < BUF_SZ)
+ strncat(buf, tmp, sizeof(buf)-1);
+ return *DWT_CYCCNT;
+}
+
+void machdep_profile_print_logged_samples(void)
+{
+ printf("%s", buf);
+ *buf = 0;
+}
+