1 /*
2  * Copyright 2018 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_common.h"
9 #include "fsl_component_serial_manager.h"
10 #include "fsl_component_serial_port_internal.h"
11 
12 #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
13 #include "fsl_component_serial_port_swo.h"
14 
15 /*******************************************************************************
16  * Definitions
17  ******************************************************************************/
18 #ifndef NDEBUG
19 #if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
20 #undef assert
21 #define assert(n)
22 #else
23 /* MISRA C-2012 Rule 17.2 */
24 #undef assert
25 #define assert(n) \
26     while (!(n))  \
27     {             \
28         ;         \
29     }
30 #endif
31 #endif
32 
33 typedef struct _serial_swo_state
34 {
35     serial_manager_callback_t txCallback;
36     void *txCallbackParam;
37     uint32_t port;
38 } serial_swo_state_t;
39 
40 /*******************************************************************************
41  * Prototypes
42  ******************************************************************************/
43 
44 /*******************************************************************************
45  * Variables
46  ******************************************************************************/
47 
48 /*******************************************************************************
49  * Code
50  ******************************************************************************/
Serial_SwoInit(serial_handle_t serialHandle,void * config)51 serial_manager_status_t Serial_SwoInit(serial_handle_t serialHandle, void *config)
52 {
53     serial_swo_state_t *serialSwoHandle;
54     serial_port_swo_config_t *swoConfig;
55     uint32_t prescaler;
56 
57     assert(config);
58     assert(serialHandle);
59 
60     assert(SERIAL_PORT_SWO_HANDLE_SIZE >= sizeof(serial_swo_state_t));
61 
62     swoConfig = (serial_port_swo_config_t *)config;
63 
64     assert(swoConfig->baudRate <= swoConfig->clockRate);
65     assert((swoConfig->clockRate / swoConfig->baudRate) <= TPI_ACPR_PRESCALER_Msk);
66     assert((TPI->DEVID & (TPI_DEVID_NRZVALID_Msk | TPI_DEVID_MANCVALID_Msk)) != 0U);
67 
68     serialSwoHandle = (serial_swo_state_t *)serialHandle;
69 
70     serialSwoHandle->port = swoConfig->port;
71 
72     prescaler = swoConfig->clockRate / swoConfig->baudRate - 1U;
73 
74     /* enable the ITM and DWT units */
75     CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk;
76 
77     if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) == 0U)
78     {
79         return kStatus_SerialManager_Error;
80     }
81 
82     /* Lock access */
83     ITM->LAR = 0xC5ACCE55U;
84     /* Disable ITM */
85     ITM->TER &= ~(1UL << swoConfig->port);
86     ITM->TCR = 0U;
87     /* select SWO encoding protocol */
88     TPI->SPPR = (uint32_t)swoConfig->protocol;
89     /* select asynchronous clock prescaler */
90     TPI->ACPR = prescaler & 0xFFFFU;
91     /* allow unprivilege access */
92     ITM->TPR = 0U;
93     /* enable ITM */
94     ITM->TCR = ITM_TCR_ITMENA_Msk | ITM_TCR_SYNCENA_Msk
95 #ifdef ITM_TCR_TraceBusID_Msk
96                | ITM_TCR_TraceBusID_Msk
97 #elif defined(ITM_TCR_TRACEBUSID_Msk)
98                | ITM_TCR_TRACEBUSID_Msk
99 #else
100 #endif
101                | ITM_TCR_SWOENA_Msk | ITM_TCR_DWTENA_Msk;
102     /* enable the port bits */
103     ITM->TER = 1UL << swoConfig->port;
104 
105     return kStatus_SerialManager_Success;
106 }
107 
Serial_SwoDeinit(serial_handle_t serialHandle)108 serial_manager_status_t Serial_SwoDeinit(serial_handle_t serialHandle)
109 {
110     serial_swo_state_t *serialSwoHandle;
111 
112     assert(serialHandle);
113 
114     serialSwoHandle = (serial_swo_state_t *)serialHandle;
115     /* disable ITM */
116     ITM->TER &= ~(1UL << serialSwoHandle->port);
117 
118     return kStatus_SerialManager_Success;
119 }
120 
Serial_SwoWrite(serial_handle_t serialHandle,uint8_t * buffer,uint32_t length)121 serial_manager_status_t Serial_SwoWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
122 {
123     serial_swo_state_t *serialSwoHandle;
124     uint8_t *strAddr;
125 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
126     serial_manager_callback_message_t msg;
127 #endif
128 
129     assert(serialHandle);
130     assert(buffer);
131     assert(length);
132 
133     serialSwoHandle = (serial_swo_state_t *)serialHandle;
134 
135     assert((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0U);
136     assert((ITM->TER & (1UL << serialSwoHandle->port)) != 0U);
137 
138     strAddr = buffer;
139 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
140     msg.buffer = buffer;
141     msg.length = length;
142 #endif
143     while (0U != length)
144     {
145         /* wait FIFO ready */
146         while (ITM->PORT[serialSwoHandle->port].u32 == 0U)
147         {
148         }
149 
150         length -= 1U;
151         ITM->PORT[serialSwoHandle->port].u8 = *strAddr;
152 
153         strAddr++;
154     }
155 
156 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
157     if (NULL != serialSwoHandle->txCallback)
158     {
159         serialSwoHandle->txCallback(serialSwoHandle->txCallbackParam, &msg, kStatus_SerialManager_Success);
160     }
161 #endif
162     return kStatus_SerialManager_Success;
163 }
164 
165 #if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
Serial_SwoRead(serial_handle_t serialHandle,uint8_t * buffer,uint32_t length)166 serial_manager_status_t Serial_SwoRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
167 {
168     return kStatus_SerialManager_Error;
169 }
170 #endif
171 
172 #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
Serial_SwoCancelWrite(serial_handle_t serialHandle)173 serial_manager_status_t Serial_SwoCancelWrite(serial_handle_t serialHandle)
174 {
175     return kStatus_SerialManager_Error;
176 }
177 
Serial_SwoInstallTxCallback(serial_handle_t serialHandle,serial_manager_callback_t callback,void * callbackParam)178 serial_manager_status_t Serial_SwoInstallTxCallback(serial_handle_t serialHandle,
179                                                     serial_manager_callback_t callback,
180                                                     void *callbackParam)
181 {
182     serial_swo_state_t *serialSwoHandle;
183 
184     assert(serialHandle);
185 
186     serialSwoHandle = (serial_swo_state_t *)serialHandle;
187 
188     serialSwoHandle->txCallback      = callback;
189     serialSwoHandle->txCallbackParam = callbackParam;
190 
191     return kStatus_SerialManager_Success;
192 }
193 
Serial_SwoInstallRxCallback(serial_handle_t serialHandle,serial_manager_callback_t callback,void * callbackParam)194 serial_manager_status_t Serial_SwoInstallRxCallback(serial_handle_t serialHandle,
195                                                     serial_manager_callback_t callback,
196                                                     void *callbackParam)
197 {
198     return kStatus_SerialManager_Error;
199 }
200 
Serial_SwoIsrFunction(serial_handle_t serialHandle)201 void Serial_SwoIsrFunction(serial_handle_t serialHandle)
202 {
203 }
204 #endif
205 
206 #endif
207