Kévin Redon has uploaded this change for review. ( 
https://gerrit.osmocom.org/13055


Change subject: add debug tracing using SWO
......................................................................

add debug tracing using SWO

the UART_TX debug pin is connected to PB30, allowing to output
printf debug information using SWO and save SERCOM7 for SIM7.

SWO is configured as UART output at 921600 bps, with blocking
write.
The DEBUG flag must be set to enable output.
WARNING: SWO output is also only enabled if a SWD debugger is
attached. I did not find in the datasheets how to always have it
enabled.

Change-Id: I4c6d66e7089971294d7c006fbb600e8085e58595
---
M sysmoOCTSIM/atmel_start_config.atstart
M sysmoOCTSIM/atmel_start_pins.h
M sysmoOCTSIM/driver_init.c
M sysmoOCTSIM/gcc/Makefile
M sysmoOCTSIM/main.c
A sysmoOCTSIM/trace.c
A sysmoOCTSIM/trace.h
7 files changed, 179 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware 
refs/changes/55/13055/1

diff --git a/sysmoOCTSIM/atmel_start_config.atstart 
b/sysmoOCTSIM/atmel_start_config.atstart
index 29ec468..a5b73bd 100644
--- a/sysmoOCTSIM/atmel_start_config.atstart
+++ b/sysmoOCTSIM/atmel_start_config.atstart
@@ -1583,4 +1583,14 @@
     mode: Digital output
     user_label: SDA2
     configuration: null
+  UART_TX:
+    name: PB30
+    definition: Atmel:SAME54_Drivers:0.0.1::SAME54N19A-AF::pad::PB30
+    mode: Advanced
+    user_label: UART_TX
+    configuration:
+      pad_direction: Out
+      pad_function: H
+      pad_initial_level: Low
+      pad_pull_config: 'Off'
 toolchain_options: []
diff --git a/sysmoOCTSIM/atmel_start_pins.h b/sysmoOCTSIM/atmel_start_pins.h
index 18a55fa..a2a4206 100644
--- a/sysmoOCTSIM/atmel_start_pins.h
+++ b/sysmoOCTSIM/atmel_start_pins.h
@@ -52,6 +52,7 @@
 #define SIM5_IO GPIO(GPIO_PORTB, 16)
 #define SIM3_IO GPIO(GPIO_PORTB, 20)
 #define SIM7_IO GPIO(GPIO_PORTB, 21)
+#define UART_TX GPIO(GPIO_PORTB, 30)
 #define SIM0_INT GPIO(GPIO_PORTC, 0)
 #define SIM1_INT GPIO(GPIO_PORTC, 1)
 #define SIM2_INT GPIO(GPIO_PORTC, 2)
diff --git a/sysmoOCTSIM/driver_init.c b/sysmoOCTSIM/driver_init.c
index ef9c56b..f442359 100644
--- a/sysmoOCTSIM/driver_init.c
+++ b/sysmoOCTSIM/driver_init.c
@@ -758,6 +758,53 @@

        gpio_set_pin_function(SDA1, GPIO_PIN_FUNCTION_OFF);

+       // GPIO on PB30
+
+       gpio_set_pin_direction(UART_TX,
+                              // <y> Pin direction
+                              // <id> pad_direction
+                              // <GPIO_DIRECTION_OFF"> Off
+                              // <GPIO_DIRECTION_IN"> In
+                              // <GPIO_DIRECTION_OUT"> Out
+                              GPIO_DIRECTION_OUT);
+
+       gpio_set_pin_pull_mode(UART_TX,
+                              // <y> Pull configuration
+                              // <id> pad_pull_config
+                              // <GPIO_PULL_OFF"> Off
+                              // <GPIO_PULL_UP"> Pull-up
+                              // <GPIO_PULL_DOWN"> Pull-down
+                              GPIO_PULL_OFF);
+
+       gpio_set_pin_level(UART_TX,
+                          // <y> Initial level
+                          // <id> pad_initial_level
+                          // <false"> Low
+                          // <true"> High
+                          false);
+
+       gpio_set_pin_function(UART_TX,
+                             // <y> Pin function
+                             // <id> pad_function
+                             // <i> Auto : use driver pinmux if signal is 
imported by driver, else turn off function
+                             // <GPIO_PIN_FUNCTION_OFF"> Auto
+                             // <GPIO_PIN_FUNCTION_OFF"> Off
+                             // <GPIO_PIN_FUNCTION_A"> A
+                             // <GPIO_PIN_FUNCTION_B"> B
+                             // <GPIO_PIN_FUNCTION_C"> C
+                             // <GPIO_PIN_FUNCTION_D"> D
+                             // <GPIO_PIN_FUNCTION_E"> E
+                             // <GPIO_PIN_FUNCTION_F"> F
+                             // <GPIO_PIN_FUNCTION_G"> G
+                             // <GPIO_PIN_FUNCTION_H"> H
+                             // <GPIO_PIN_FUNCTION_I"> I
+                             // <GPIO_PIN_FUNCTION_J"> J
+                             // <GPIO_PIN_FUNCTION_K"> K
+                             // <GPIO_PIN_FUNCTION_L"> L
+                             // <GPIO_PIN_FUNCTION_M"> M
+                             // <GPIO_PIN_FUNCTION_N"> N
+                             GPIO_PIN_FUNCTION_H);
+
        // GPIO on PC00

        // Set pin direction to input
diff --git a/sysmoOCTSIM/gcc/Makefile b/sysmoOCTSIM/gcc/Makefile
index 5e3c38c..e5c7306 100644
--- a/sysmoOCTSIM/gcc/Makefile
+++ b/sysmoOCTSIM/gcc/Makefile
@@ -76,6 +76,7 @@
 hpl/osc32kctrl/hpl_osc32kctrl.o \
 examples/driver_examples.o \
 driver_init.o \
+trace.o \
 hal/src/hal_usart_async.o \
 hpl/sercom/hpl_sercom.o \
 hal/utils/src/utils_ringbuffer.o \
@@ -117,6 +118,7 @@
 "hpl/osc32kctrl/hpl_osc32kctrl.o" \
 "examples/driver_examples.o" \
 "driver_init.o" \
+"trace.o" \
 "hal/src/hal_usart_async.o" \
 "hpl/sercom/hpl_sercom.o" \
 "hal/utils/src/utils_ringbuffer.o" \
@@ -155,6 +157,7 @@
 "hal/src/hal_init.d" \
 "hpl/mclk/hpl_mclk.d" \
 "driver_init.d" \
+"trace.d" \
 "hal/src/hal_usart_async.d" \
 "hpl/osc32kctrl/hpl_osc32kctrl.d" \
 "main.d" \
@@ -256,4 +259,4 @@
        rm -f $(DEPS_AS_ARGS)
        rm -f $(OUTPUT_FILE_NAME).a $(OUTPUT_FILE_NAME).hex 
$(OUTPUT_FILE_NAME).bin \
         $(OUTPUT_FILE_NAME).lss $(OUTPUT_FILE_NAME).eep 
$(OUTPUT_FILE_NAME).map \
-        $(OUTPUT_FILE_NAME).srec
\ No newline at end of file
+        $(OUTPUT_FILE_NAME).srec
diff --git a/sysmoOCTSIM/main.c b/sysmoOCTSIM/main.c
index 9500e08..515f546 100644
--- a/sysmoOCTSIM/main.c
+++ b/sysmoOCTSIM/main.c
@@ -22,6 +22,7 @@

 #include "atmel_start.h"
 #include "atmel_start_pins.h"
+#include "trace.h"

 #include "i2c_bitbang.h"
 #include "octsim_i2c.h"
@@ -50,5 +51,7 @@
 {
        atmel_start_init();
        board_init();
+       trace_swo_init(); // initialize SWO for debug trace output
+       TRACE("\r\n\r\ninitialization complete\r\n");
        usb_start();
 }
diff --git a/sysmoOCTSIM/trace.c b/sysmoOCTSIM/trace.c
new file mode 100644
index 0000000..7048dbe
--- /dev/null
+++ b/sysmoOCTSIM/trace.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon 
<kre...@sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
+*/
+#include <same54.h>
+#include <hpl_gclk_base.h>
+#include <peripheral_clk_config.h>
+#include <stdio.h>
+#include "trace.h"
+
+int __attribute__((weak)) _read(int file, char *ptr, int len);
+
+int __attribute__((weak)) _read(int file, char *ptr, int len)
+{
+       (void)file;
+       (void)ptr;
+       (void)len;
+       return -1;
+}
+
+int __attribute__((weak)) _write(int file, char *ptr, int len);
+
+/** \warning ITM/SWO outputs only if a debugger is attached
+ *  \warning this call is blocking
+ *  \note since ITM does not generate interrupts upon completion, to implement 
non-blocking writing a timer would be required (along with a ring buffer)
+ */
+int __attribute__((weak)) _write(int file, char *ptr, int len)
+{
+#ifdef DEBUG
+       if ((file != 1) && (file != 2) && (file != 3)) {
+               return -1;
+       }
+
+       for (int i = 0; i < len; i++) {
+               ITM_SendChar(*ptr++);
+       }
+       return len;
+#else
+       (void)file;
+       (void)ptr;
+       (void)len;
+       return -1;
+#endif
+}
+
+void trace_swo_init(void)
+{
+       hri_gclk_write_PCHCTRL_reg(GCLK, CM4_TRACE_GCLK_ID, 
GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN); // enable clock for CM4 TRACE
+       while(!hri_gclk_get_PCHCTRL_reg(GCLK, CM4_TRACE_GCLK_ID, 
GCLK_PCHCTRL_CHEN)); // wait for clock to be ready
+       CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // enable trace 
subsystem
+       TPI->SPPR = (2 << TPI_SPPR_TXMODE_Pos) & TPI_SPPR_TXMODE_Msk; // set 
SWO protocol to UART-like (asynchronous using NRZ encoding)
+       TPI->ACPR = ((CONF_CPU_FREQUENCY / TRACE_SWO_BAUDRATE - 1) << 
TPI_ACPR_PRESCALER_Pos) & TPI_ACPR_PRESCALER_Msk;  // set prescaler
+       TPI->FFCR &= ~TPI_FFCR_EnFCont_Msk; // disable continuous formatting
+       ITM->LAR = 0xC5ACCE55; // unlock write access to ITM registers
+       ITM->TCR = ITM_TCR_TraceBusID_Msk | ITM_TCR_ITMENA_Msk; // enable 
multi-source trace, SWO, synchronisation packet, and ITM
+       ITM->TER = 1; // enable stimulus 1
+       ITM->TPR = 0; // permit unprivileged access
+       CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // enable trace 
subsystem
+
+#if defined(__GNUC__)
+       setbuf(stdout, NULL); // don't use any buffer
+#endif
+}
diff --git a/sysmoOCTSIM/trace.h b/sysmoOCTSIM/trace.h
new file mode 100644
index 0000000..67afb53
--- /dev/null
+++ b/sysmoOCTSIM/trace.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon 
<kre...@sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
+*/
+#ifndef TRACE_H
+#define TARCE_H
+#include <stdio.h>
+
+/** CM4 Trace clock ID, not defined in ASFv4 but in the datasheet */
+#define CM4_TRACE_GCLK_ID 47
+/** SWO UART-like trace output in bps */
+#define TRACE_SWO_BAUDRATE 921600
+
+/** Output trace debug information */
+#ifndef DEBUG
+#define TRACE(...)      { }
+#else
+#define TRACE(...)      { printf(__VA_ARGS__); }
+#endif
+
+/** Initialise trace output over SWO
+ *  \note SWO pin must be configured separately
+ */
+void trace_swo_init(void);
+#endif

--
To view, visit https://gerrit.osmocom.org/13055
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4c6d66e7089971294d7c006fbb600e8085e58595
Gerrit-Change-Number: 13055
Gerrit-PatchSet: 1
Gerrit-Owner: Kévin Redon <kre...@sysmocom.de>

Reply via email to