mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
184:08ed48f1de7f
Child:
189:f392fc9709a3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/itm_api.c	Thu Apr 19 17:12:19 2018 +0100
@@ -0,0 +1,107 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(DEVICE_ITM)
+
+#include "hal/itm_api.h"
+#include "cmsis.h"
+#include "em_cmu.h"
+
+#include <stdbool.h>
+
+/* SWO frequency: 875 kHz */
+static void setupSWOForPrint(void)
+{
+#if defined( _GPIO_ROUTE_SWOPEN_MASK ) || defined( _GPIO_ROUTEPEN_SWVPEN_MASK )
+    // Enable GPIO clock.
+#if defined( _CMU_HFPERCLKEN0_GPIO_MASK )
+    CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
+#elif defined( _CMU_HFBUSCLKEN0_GPIO_MASK )
+    CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_GPIO;
+#endif
+  
+    // Enable Serial wire output pin
+#if defined( _GPIO_ROUTE_SWOPEN_MASK )
+    GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
+#elif defined( _GPIO_ROUTEPEN_SWVPEN_MASK )
+    GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN;
+#endif
+#endif
+  
+#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_LEOPARD_FAMILY) || defined(_EFM32_WONDER_FAMILY) || defined(_EFM32_PEARL_FAMILY)
+    // Set location 0
+#if defined( _GPIO_ROUTE_SWOPEN_MASK )
+    GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC0;
+#elif defined( _GPIO_ROUTEPEN_SWVPEN_MASK )
+    GPIO->ROUTELOC0 = (GPIO->ROUTELOC0 & ~(_GPIO_ROUTELOC0_SWVLOC_MASK)) | GPIO_ROUTELOC0_SWVLOC_LOC0;
+#endif
+
+    // Enable output on pin - GPIO Port F, Pin 2
+    GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
+    GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
+#else
+    // Set location 1
+    GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
+
+    // Enable output on pin
+    GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
+    GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
+#endif
+  
+    // Enable debug clock AUXHFRCO
+    CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
+  
+    // Wait until clock is ready
+    while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
+  
+    // Enable trace in core debug
+    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+
+    /* Set TPIU prescaler for the current debug clock frequency. Target frequency
+       is 875 kHz so we choose a divider that gives us the closest match.
+       Actual divider is TPI->ACPR + 1. */
+    uint32_t freq = CMU_ClockFreqGet(cmuClock_DBG) + (875000 / 2);
+    uint32_t div  = freq / 875000;
+    TPI->ACPR = div - 1;
+}
+
+static bool swoIsInitd()
+{
+#if defined( _CMU_HFPERCLKEN0_GPIO_MASK )
+    return ((CMU->HFPERCLKEN0 & CMU_HFPERCLKEN0_GPIO) &&
+            (GPIO->ROUTE & GPIO_ROUTE_SWOPEN) &&
+            (CMU->STATUS & CMU_STATUS_AUXHFRCORDY) &&
+            (CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk));
+#elif defined( _CMU_HFBUSCLKEN0_GPIO_MASK )
+    return ((CMU->HFBUSCLKEN0 & CMU_HFBUSCLKEN0_GPIO) &&
+            (GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN) &&
+            (CMU->STATUS & CMU_STATUS_AUXHFRCORDY) &&
+            (CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk));
+#endif
+}
+
+// As SWO has to be accessible everywhere, including ISRs, we can't easily
+// communicate the dependency on clocks etc. to other components - so this
+// function checks that things appear to be set up, and if not re-configures
+// everything
+void itm_init(void)
+{
+    if(!swoIsInitd()) {
+        setupSWOForPrint();
+    }
+}
+
+#endif