1 /***************************************************************************//**
2 * @file
3 * @brief Debug (DBG) Peripheral API
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #include "em_dbg.h"
32
33 #if defined(CoreDebug_DHCSR_C_DEBUGEN_Msk)
34
35 #include "sl_assert.h"
36 #include "em_cmu.h"
37 #include "em_gpio.h"
38 #include "em_msc.h"
39 #if defined(_SILICON_LABS_32B_SERIES_2)
40 #include "em_se.h"
41 #endif
42
43 /***************************************************************************//**
44 * @addtogroup dbg DBG - Debug
45 * @brief Debug (DBG) Peripheral API
46 * @details
47 * This module contains functions to control the DBG peripheral of Silicon
48 * Labs 32-bit MCUs and SoCs. The Debug Interface is used to program and debug
49 * Silicon Labs devices.
50 * @{
51 ******************************************************************************/
52
53 /*******************************************************************************
54 ************************** GLOBAL FUNCTIONS *******************************
55 ******************************************************************************/
56
57 #if defined(GPIO_ROUTE_SWOPEN) || defined(GPIO_ROUTEPEN_SWVPEN) \
58 || defined(GPIO_TRACEROUTEPEN_SWVPEN)
59 /***************************************************************************//**
60 * @brief
61 * Enable Serial Wire Output (SWO) pin.
62 *
63 * @details
64 * The SWO pin (sometimes denoted SWV, serial wire viewer) allows for
65 * miscellaneous output to be passed from the Cortex-M3 debug trace module to
66 * an external debug probe. By default, the debug trace module and pin output
67 * may be disabled.
68 *
69 * Since the SWO pin is only useful when using a debugger, a suggested use
70 * of this function during startup may be:
71 * @verbatim
72 * if (DBG_Connected())
73 * {
74 * DBG_SWOEnable(1);
75 * }
76 * @endverbatim
77 * By checking if the debugger is attached, a setup leading to a higher energy
78 * consumption when the debugger is attached can be avoided when not using
79 * a debugger.
80 *
81 * Another alternative may be to set the debugger tool chain to configure
82 * the required setup (similar to the content of this function) by some
83 * sort of toolchain scripting during its attach/reset procedure. In that
84 * case, the above suggested code for enabling the SWO pin is not required
85 * in the application.
86 *
87 * @param[in] location
88 * A pin location used for SWO pin on the application in use.
89 ******************************************************************************/
DBG_SWOEnable(unsigned int location)90 void DBG_SWOEnable(unsigned int location)
91 {
92 int port;
93 int pin;
94
95 #if defined(GPIO_SWV_PORT)
96
97 port = GPIO_SWV_PORT;
98 pin = GPIO_SWV_PIN;
99
100 #else
101 EFM_ASSERT(location < AFCHANLOC_MAX);
102 #if defined (AF_DBG_SWO_PORT)
103 port = AF_DBG_SWO_PORT(location);
104 pin = AF_DBG_SWO_PIN(location);
105 #elif defined (AF_DBG_SWV_PORT)
106 port = AF_DBG_SWV_PORT(location);
107 pin = AF_DBG_SWV_PIN(location);
108
109 #else
110 #warning "AF debug port is not defined."
111 #endif
112 #endif
113
114 /* Port/pin location not defined for the device. */
115 if ((pin < 0) || (port < 0)) {
116 EFM_ASSERT(0);
117 return;
118 }
119
120 /* Ensure that the auxiliary clock going to the Cortex debug trace module is enabled. */
121 #if !defined(_SILICON_LABS_32B_SERIES_2)
122 CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, false);
123 #endif
124
125 /* Set the selected pin location for the SWO pin and enable it. */
126 GPIO_DbgLocationSet(location);
127 GPIO_DbgSWOEnable(true);
128
129 /* Configure the SWO pin for output. */
130 GPIO_PinModeSet((GPIO_Port_TypeDef)port, pin, gpioModePushPull, 0);
131 }
132 #endif
133
134 #if defined(LOCKBITS_BASE) && !defined(_EFM32_GECKO_FAMILY)
135
136 /***************************************************************************//**
137 * @brief
138 * Disable debug access.
139 *
140 * @cond DOXYDOC_S2_DEVICE
141 * @details
142 * SE interface is used to disable debug access. By choosing
143 * @ref dbgLockModePermanent, debug access is blocked permanently. SE disables
144 * the device erase command and thereafter disables debug access.
145 * @endcond
146 * @cond DOXYDOC_P2_DEVICE
147 * @
148 * @details
149 * Debug access is blocked using debug lock word. On series 1 devices,
150 * if @ref dbgLockModePermanent is chosen, debug access is blocked
151 * permanently using AAP lock word.
152 * @endcond
153 * @param[in] lockMode
154 * Debug lock mode to be used.
155 *
156 * @cond !DOXYDOC_P1_DEVICE
157 * @warning
158 * If @ref dbgLockModePermanent is chosen as the lock mode, the debug port
159 * will be closed permanently and is irreversible.
160 * @endcond
161 ******************************************************************************/
DBG_DisableDebugAccess(DBG_LockMode_TypeDef lockMode)162 void DBG_DisableDebugAccess(DBG_LockMode_TypeDef lockMode)
163 {
164 #if defined(SEMAILBOX_PRESENT)
165 if (lockMode == dbgLockModeAllowErase) {
166 SE_debugLockApply();
167 } else if (lockMode == dbgLockModePermanent) {
168 SE_deviceEraseDisable();
169 SE_debugLockApply();
170 } else {
171 /* Invalid input */
172 EFM_ASSERT(0);
173 }
174 #else
175 #if defined(_SILICON_LABS_32B_SERIES_0)
176 if (lockMode != dbgLockModeAllowErase) {
177 EFM_ASSERT(0);
178 }
179 #else
180 if ((lockMode != dbgLockModeAllowErase) && (lockMode != dbgLockModePermanent)) {
181 EFM_ASSERT(0);
182 }
183 #endif
184
185 bool wasLocked;
186 uint32_t lockWord = 0x0;
187 wasLocked = ((MSC->LOCK & _MSC_LOCK_MASK) != 0U);
188 MSC_Init();
189
190 uint32_t *dlw = (uint32_t*)(LOCKBITS_BASE + (127 * 4));
191
192 if (*dlw == 0xFFFFFFFF) {
193 MSC_WriteWord(dlw, &lockWord, sizeof(lockWord));
194 }
195 #if !defined(_SILICON_LABS_32B_SERIES_0)
196 uint32_t *alw = (uint32_t*)(LOCKBITS_BASE + (124 * 4));
197
198 if (lockMode == dbgLockModePermanent) {
199 if (*alw == 0xFFFFFFFF) {
200 MSC_WriteWord(alw, &lockWord, sizeof(lockWord));
201 }
202 }
203 #endif
204
205 if (wasLocked) {
206 MSC_Deinit();
207 }
208 #endif
209 }
210
211 #endif /* defined(LOCKBITS_BASE) && !defined(_EFM32_GECKO_FAMILY) */
212
213 /** @} (end addtogroup dbg) */
214 #endif /* defined( CoreDebug_DHCSR_C_DEBUGEN_Msk ) */
215