Orbcode Trace functions library
itm.h
Go to the documentation of this file.
1 
3 #pragma once
4 #include <stdbool.h>
5 #include <stdint.h>
6 #include <string.h>
7 
8 #if !defined(ITM)
9 # error \
10  "ITM not defined. Include itm.h AFTER core_cmX.h (typically after including device-specific header)"
11 #endif
12 
13 #if !defined(CoreDebug)
14 # error \
15  "CoreDebug not defined. Include itm.h AFTER core_cmX.h (typically after including device-specific header)"
16 #endif
17 
18 #ifdef __cplusplus
19 extern "C"
20 {
21 #endif
22 
44 #define ITM_ENABLE_STIMULUS_PORTS_ALL 0xFFFFFFFF
45 
51  typedef enum
52  {
53  ITMGlobalTimestampFrequencyDisabled = 0,
54  ITMGlobalTimestampFrequencyPosition7 = 1,
55  ITMGlobalTimestampFrequencyPosition13 = 2,
56  ITMGlobalTimestampFrequencyIfOutputFIFOEmpty = 3
58 
64  typedef enum
65  {
66  ITMLocalTimestampPrescalerNoPrescaling = 0,
67  ITMLocalTimestampPrescalerDivideBy4 = 1,
68  ITMLocalTimestampPrescalerDivideBy10 = 2,
69  ITMLocalTimestampPrescalerDivideBy64 = 3,
71 
77  typedef struct
78  {
85 
94 
103 
110 
117 
126 
136  } ITMOptions;
137 
146  static inline void ITMSetup(const ITMOptions* options);
147 
155  static inline bool ITMIsPortEnabled(uint8_t port);
156 
163  static inline void ITMWrite8(uint8_t port, uint8_t c);
164 
171  static inline void ITMWrite16(uint8_t port, uint16_t value);
172 
179  static inline void ITMWrite32(uint8_t port, uint32_t value);
180 
193  static inline void ITMWriteBuffer(uint8_t port, const void* buffer, size_t size);
194 
197  void ITMSetup(const ITMOptions* options)
198  {
199  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Enable ITM and DWT
200  ITM->LAR = 0xC5ACCE55; // unlock ITM access (magic number)
201 
202  uint32_t tcr = 0;
203 
204  tcr |= options->TraceBusID << ITM_TCR_TraceBusID_Pos;
205  tcr |= ((int)options->GlobalTimestampFrequency) << ITM_TCR_GTSFREQ_Pos;
206  tcr |= ((int)options->LocalTimestampPrescaler) << ITM_TCR_TSPrescale_Pos;
207  tcr |= (options->ForwardDWT ? 1 : 0) << ITM_TCR_DWTENA_Pos;
208  tcr |= (options->EnableSyncPacket ? 1 : 0) << ITM_TCR_SYNCENA_Pos;
209  tcr |= (options->EnableLocalTimestamp ? 1 : 0) << ITM_TCR_TSENA_Pos;
210  tcr |= ITM_TCR_ITMENA_Msk;
211 
212  ITM->TCR = tcr;
213 
214  ITM->TER = 0xFFFFFFFF; // Enable all stimulus ports
215  }
216 
217  bool ITMIsPortEnabled(uint8_t port)
218  {
219  return ((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
220  ((ITM->TER & (1 << port)) != 0UL); /* ITM Port enabled */
221  }
222 
223  void ITMWrite8(uint8_t port, uint8_t value)
224  {
225  if(!ITMIsPortEnabled(port))
226  {
227  return;
228  }
229 
230  while(ITM->PORT[port].u32 == 0UL)
231  {
232  __NOP();
233  }
234  ITM->PORT[port].u8 = value;
235  }
236 
237  void ITMWrite16(uint8_t port, uint16_t value)
238  {
239  if(!ITMIsPortEnabled(port))
240  {
241  return;
242  }
243 
244  while(ITM->PORT[port].u32 == 0UL)
245  {
246  __NOP();
247  }
248  ITM->PORT[port].u16 = value;
249  }
250 
251  void ITMWrite32(uint8_t port, uint32_t value)
252  {
253  if(!ITMIsPortEnabled(port))
254  {
255  return;
256  }
257 
258  while(ITM->PORT[port].u32 == 0UL)
259  {
260  __NOP();
261  }
262  ITM->PORT[port].u32 = value;
263  }
264 
265  void ITMWriteBuffer(uint8_t port, const void* buffer, size_t size)
266  {
267  if(!ITMIsPortEnabled(port))
268  {
269  return;
270  }
271 
272  const uint8_t* buf8 = (const uint8_t*)buffer;
273  while(size >= 4)
274  {
275  uint32_t v;
276  memcpy(&v, buf8, sizeof(v));
277  while(ITM->PORT[port].u32 == 0UL)
278  {
279  __NOP();
280  }
281  ITM->PORT[port].u32 = v;
282 
283  buf8 += sizeof(v);
284  size -= sizeof(v);
285  }
286 
287  while(size >= 2)
288  {
289  uint16_t v;
290  memcpy(&v, buf8, sizeof(v));
291  memcpy(&v, buf8, sizeof(v));
292  while(ITM->PORT[port].u32 == 0UL)
293  {
294  __NOP();
295  }
296  ITM->PORT[port].u16 = v;
297 
298  buf8 += sizeof(v);
299  size -= sizeof(v);
300  }
301 
302  while(size > 0)
303  {
304  while(ITM->PORT[port].u32 == 0UL)
305  {
306  __NOP();
307  }
308  ITM->PORT[port].u8 = *(buf8++);
309 
310  size--;
311  }
312  }
313 
314 #ifdef __cplusplus
315 }
316 #endif
static void ITMWrite8(uint8_t port, uint8_t c)
Writes 8-bit value to stimulus port.
Definition: itm.h:223
static void ITMWrite16(uint8_t port, uint16_t value)
Writes 16-bit value to stimulus port.
Definition: itm.h:237
ITMGlobalTimestampFrequency
Global timestamp frequency.
Definition: itm.h:52
static bool ITMIsPortEnabled(uint8_t port)
Checks if stimulus port is enabled.
Definition: itm.h:217
ITMLocalTimestampPrescaler
Local timestamp frequency.
Definition: itm.h:65
static void ITMWrite32(uint8_t port, uint32_t value)
Writes 32-bit value to stimulus port.
Definition: itm.h:251
static void ITMWriteBuffer(uint8_t port, const void *buffer, size_t size)
Writes buffer to stimulus port.
Definition: itm.h:265
static void ITMSetup(const ITMOptions *options)
Configures ITM as requested.
Definition: itm.h:197
ITM configuration options.
Definition: itm.h:78
int TraceBusID
Trace bus ID.
Definition: itm.h:84
ITMGlobalTimestampFrequency GlobalTimestampFrequency
Configure global timestamp frequency.
Definition: itm.h:93
bool EnableSyncPacket
Enable ITM synchronization packet.
Definition: itm.h:125
uint32_t EnabledStimulusPorts
Enable stimulus port.
Definition: itm.h:135
bool ForwardDWT
Forward DWT packets.
Definition: itm.h:116
bool EnableLocalTimestamp
Enable local timestamps.
Definition: itm.h:109
ITMLocalTimestampPrescaler LocalTimestampPrescaler
Configure local timestamp frequency.
Definition: itm.h:102