LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cpu_core.c
Go to the documentation of this file.
1 /*
2 *********************************************************************************************************
3 * uC/CPU
4 * CPU CONFIGURATION & PORT LAYER
5 *
6 * (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
7 *
8 * All rights reserved. Protected by international copyright laws.
9 *
10 * uC/CPU is provided in source form to registered licensees ONLY. It is
11 * illegal to distribute this source code to any third party unless you receive
12 * written permission by an authorized Micrium representative. Knowledge of
13 * the source code may NOT be used to develop a similar product.
14 *
15 * Please help us continue to provide the Embedded community with the finest
16 * software available. Your honesty is greatly appreciated.
17 *
18 * You can contact us at www.micrium.com.
19 *********************************************************************************************************
20 */
21 
22 /*
23 *********************************************************************************************************
24 *
25 * CORE CPU MODULE
26 *
27 * Filename : cpu_core.c
28 * Version : V1.28.00
29 * Programmer(s) : SR
30 * ITJ
31 *********************************************************************************************************
32 */
33 
34 
35 /*
36 *********************************************************************************************************
37 * INCLUDE FILES
38 *********************************************************************************************************
39 */
40 
41 #define CPU_CORE_MODULE
42 #include <cpu_core.h>
43 
44 
45 /*$PAGE*/
46 /*
47 *********************************************************************************************************
48 * LOCAL DEFINES
49 *********************************************************************************************************
50 */
51 
52 
53 /*
54 *********************************************************************************************************
55 * LOCAL CONSTANTS
56 *********************************************************************************************************
57 */
58 
59 
60 /*
61 *********************************************************************************************************
62 * LOCAL DATA TYPES
63 *********************************************************************************************************
64 */
65 
66 
67 /*
68 *********************************************************************************************************
69 * LOCAL TABLES
70 *********************************************************************************************************
71 */
72 
73 /*
74 *********************************************************************************************************
75 * CPU COUNT LEAD ZEROs LOOKUP TABLE
76 *
77 * Note(s) : (1) Index into bit pattern table determines the number of leading zeros in an 8-bit value :
78 *
79 * b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros
80 * --- --- --- --- --- --- --- --- ---------------
81 * 1 x x x x x x x 0
82 * 0 1 x x x x x x 1
83 * 0 0 1 x x x x x 2
84 * 0 0 0 1 x x x x 3
85 * 0 0 0 0 1 x x x 4
86 * 0 0 0 0 0 1 x x 5
87 * 0 0 0 0 0 0 1 x 6
88 * 0 0 0 0 0 0 0 1 7
89 * 0 0 0 0 0 0 0 0 8
90 *********************************************************************************************************
91 */
92 
93 #ifndef CPU_CFG_LEAD_ZEROS_ASM_PRESENT
94 static const CPU_INT08U CPU_CntLeadZerosTbl[256] = { /* Data vals : */
95 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
96  8u, 7u, 6u, 6u, 5u, 5u, 5u, 5u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, /* 0x00 to 0x0F */
97  3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, /* 0x10 to 0x1F */
98  2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, /* 0x20 to 0x2F */
99  2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, /* 0x30 to 0x3F */
100  1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x40 to 0x4F */
101  1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x50 to 0x5F */
102  1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x60 to 0x6F */
103  1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x70 to 0x7F */
104  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0x80 to 0x8F */
105  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0x90 to 0x9F */
106  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xA0 to 0xAF */
107  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xB0 to 0xBF */
108  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xC0 to 0xCF */
109  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xD0 to 0xDF */
110  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xE0 to 0xEF */
111  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u /* 0xF0 to 0xFF */
112 };
113 #endif
114 
115 
116 /*$PAGE*/
117 /*
118 *********************************************************************************************************
119 * LOCAL GLOBAL VARIABLES
120 *********************************************************************************************************
121 */
122 
123 
124 /*
125 *********************************************************************************************************
126 * LOCAL FUNCTION PROTOTYPES
127 *********************************************************************************************************
128 */
129 
130 #if (CPU_CFG_NAME_EN == DEF_ENABLED) /* ---------------- CPU NAME FNCTS ---------------- */
131 static void CPU_NameInit (void);
132 #endif
133 
134 
135  /* ----------------- CPU TS FNCTS ----------------- */
136 #if ((CPU_CFG_TS_EN == DEF_ENABLED) || \
137  (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
138 static void CPU_TS_Init (void);
139 #endif
140 
141 
142 #ifdef CPU_CFG_INT_DIS_MEAS_EN /* ---------- CPU INT DIS TIME MEAS FNCTS --------- */
143 static void CPU_IntDisMeasInit (void);
144 
145 static CPU_TS_TMR CPU_IntDisMeasMaxCalc(CPU_TS_TMR time_tot_cnts);
146 #endif
147 
148 
149 /*
150 *********************************************************************************************************
151 * LOCAL CONFIGURATION ERRORS
152 *********************************************************************************************************
153 */
154 
155 
156 /*$PAGE*/
157 /*
158 *********************************************************************************************************
159 * CPU_Init()
160 *
161 * Description : (1) Initialize CPU module :
162 *
163 * (a) Initialize CPU timestamps
164 * (b) Initialize CPU interrupts disabled time measurements
165 * (c) Initialize CPU host name
166 *
167 *
168 * Argument(s) : none.
169 *
170 * Return(s) : none.
171 *
172 * Caller(s) : Your Product's Application.
173 *
174 * This function is a CPU initialization function & MAY be called by application/
175 * initialization function(s).
176 *
177 * Note(s) : (2) CPU_Init() MUST be called ... :
178 *
179 * (a) ONLY ONCE from a product's application; ...
180 * (b) BEFORE product's application calls any core CPU module function(s)
181 *
182 * (3) The following initialization functions MUST be sequenced as follows :
183 *
184 * (a) CPU_TS_Init() SHOULD precede ALL calls to other CPU timestamp functions
185 *
186 * (b) CPU_IntDisMeasInit() SHOULD precede ALL calls to CPU_CRITICAL_ENTER()/CPU_CRITICAL_EXIT()
187 * & other CPU interrupts disabled time measurement functions
188 *********************************************************************************************************
189 */
190 
191 void CPU_Init (void)
192 {
193  /* --------------------- INIT TS ---------------------- */
194 #if ((CPU_CFG_TS_EN == DEF_ENABLED) || \
195  (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
196  CPU_TS_Init(); /* See Note #3a. */
197 #endif
198  /* -------------- INIT INT DIS TIME MEAS -------------- */
199 #ifdef CPU_CFG_INT_DIS_MEAS_EN
200  CPU_IntDisMeasInit(); /* See Note #3b. */
201 #endif
202 
203  /* ------------------ INIT CPU NAME ------------------- */
204 #if (CPU_CFG_NAME_EN == DEF_ENABLED)
205  CPU_NameInit();
206 #endif
207 }
208 
209 
210 /*$PAGE*/
211 /*
212 *********************************************************************************************************
213 * CPU_SW_Exception()
214 *
215 * Description : Trap unrecoverable software exception.
216 *
217 * Argument(s) : none.
218 *
219 * Return(s) : none.
220 *
221 * Caller(s) : various.
222 *
223 * Note(s) : (1) CPU_SW_Exception() deadlocks the current code execution -- whether multi-tasked/
224 * -processed/-threaded or single-threaded -- when the current code execution cannot
225 * gracefully recover or report a fault or exception condition.
226 *
227 * See also 'cpu_core.h CPU_SW_EXCEPTION() Note #1'.
228 *********************************************************************************************************
229 */
230 
231 void CPU_SW_Exception (void)
232 {
233  while (DEF_ON) {
234  ;
235  }
236 }
237 
238 
239 /*$PAGE*/
240 /*
241 *********************************************************************************************************
242 * CPU_NameClr()
243 *
244 * Description : Clear CPU Name.
245 *
246 * Argument(s) : none.
247 *
248 * Return(s) : none.
249 *
250 * Caller(s) : CPU_NameInit(),
251 * Application.
252 *
253 * This function is a CPU module application interface (API) function & MAY be called by
254 * application function(s).
255 *
256 * Note(s) : none.
257 *********************************************************************************************************
258 */
259 
260 #if (CPU_CFG_NAME_EN == DEF_ENABLED)
261 void CPU_NameClr (void)
262 {
263  CPU_SR_ALLOC();
264 
265 
267  Mem_Clr((void *)&CPU_Name[0],
270 }
271 #endif
272 
273 
274 /*$PAGE*/
275 /*
276 *********************************************************************************************************
277 * CPU_NameGet()
278 *
279 * Description : Get CPU host name.
280 *
281 * Argument(s) : p_name Pointer to an ASCII character array that will receive the return CPU host
282 * name ASCII string from this function (see Note #1).
283 *
284 * p_err Pointer to variable that will receive the return error code from this function :
285 *
286 * CPU_ERR_NONE CPU host name successfully returned.
287 * CPU_ERR_NULL_PTR Argument 'p_name' passed a NULL pointer.
288 *
289 * Return(s) : none.
290 *
291 * Caller(s) : Application.
292 *
293 * This function is a CPU module application interface (API) function & MAY be called by
294 * application function(s).
295 *
296 * Note(s) : (1) The size of the ASCII character array that will receive the return CPU host name
297 * ASCII string :
298 *
299 * (a) MUST be greater than or equal to the current CPU host name's ASCII string
300 * size including the terminating NULL character;
301 * (b) SHOULD be greater than or equal to CPU_CFG_NAME_SIZE
302 *********************************************************************************************************
303 */
304 
305 #if (CPU_CFG_NAME_EN == DEF_ENABLED)
306 void CPU_NameGet (CPU_CHAR *p_name,
307  CPU_ERR *p_err)
308 {
309  CPU_SR_ALLOC();
310 
311 
312  if (p_err == (CPU_ERR *)0) {
313  CPU_SW_EXCEPTION(;);
314  }
315 
316  if (p_name == (CPU_CHAR *)0) {
317  *p_err = CPU_ERR_NULL_PTR;
318  return;
319  }
320 
322  (void)Str_Copy_N(p_name,
323  &CPU_Name[0],
326 
327  *p_err = CPU_ERR_NONE;
328 }
329 #endif
330 
331 
332 /*$PAGE*/
333 /*
334 *********************************************************************************************************
335 * CPU_NameSet()
336 *
337 * Description : Set CPU host name.
338 *
339 * Argument(s) : p_name Pointer to CPU host name to set.
340 *
341 * p_err Pointer to variable that will receive the return error code from this function :
342 *
343 * CPU_ERR_NONE CPU host name successfully set.
344 * CPU_ERR_NULL_PTR Argument 'p_name' passed a NULL pointer.
345 * CPU_ERR_NAME_SIZE Invalid CPU host name size (see Note #1).
346 *
347 * Return(s) : none.
348 *
349 * Caller(s) : Application.
350 *
351 * This function is a CPU module application interface (API) function & MAY be called by
352 * application function(s).
353 *
354 * Note(s) : (1) 'p_name' ASCII string size, including the terminating NULL character, MUST be less
355 * than or equal to CPU_CFG_NAME_SIZE.
356 *********************************************************************************************************
357 */
358 
359 #if (CPU_CFG_NAME_EN == DEF_ENABLED)
360 void CPU_NameSet (const CPU_CHAR *p_name,
361  CPU_ERR *p_err)
362 {
363  CPU_SIZE_T len;
364  CPU_SR_ALLOC();
365 
366 
367  if (p_err == (CPU_ERR *)0) {
368  CPU_SW_EXCEPTION(;);
369  }
370 
371  if (p_name == (const CPU_CHAR *)0) {
372  *p_err = CPU_ERR_NULL_PTR;
373  return;
374  }
375 
376  len = Str_Len_N(p_name,
378  if (len < CPU_CFG_NAME_SIZE) { /* If cfg name len < max name size, ... */
380  (void)Str_Copy_N(&CPU_Name[0], /* ... copy cfg name to CPU host name. */
381  p_name,
384  *p_err = CPU_ERR_NONE;
385 
386  } else {
387  *p_err = CPU_ERR_NAME_SIZE;
388  }
389 }
390 #endif
391 
392 
393 /*$PAGE*/
394 /*
395 *********************************************************************************************************
396 * CPU_TS_Get32()
397 *
398 * Description : Get current 32-bit CPU timestamp.
399 *
400 * Argument(s) : none.
401 *
402 * Return(s) : Current 32-bit CPU timestamp (in timestamp timer counts).
403 *
404 * Caller(s) : Application.
405 *
406 * This function is a CPU module application interface (API) function & MAY be called by
407 * application function(s).
408 *
409 * Note(s) : (1) When applicable, the amount of time measured by CPU timestamps is calculated by
410 * either of the following equations :
411 *
412 * (a) Time measured = Number timer counts * Timer period
413 *
414 * where
415 *
416 * Number timer counts Number of timer counts measured
417 * Timer period Timer's period in some units of
418 * (fractional) seconds
419 * Time measured Amount of time measured, in same
420 * units of (fractional) seconds
421 * as the Timer period
422 *
423 * Number timer counts
424 * (b) Time measured = ---------------------
425 * Timer frequency
426 *
427 * where
428 *
429 * Number timer counts Number of timer counts measured
430 * Timer frequency Timer's frequency in some units
431 * of counts per second
432 * Time measured Amount of time measured, in seconds
433 *
434 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c1'.
435 *
436 * (2) In case the CPU timestamp timer has lower precision than the 32-bit CPU timestamp;
437 * its precision is extended via periodic updates by accumulating the deltas of the
438 * timestamp timer count values into the higher-precision 32-bit CPU timestamp.
439 *
440 * (3) After initialization, 'CPU_TS_32_Accum' & 'CPU_TS_32_TmrPrev' MUST ALWAYS
441 * be accessed AND updated exclusively with interrupts disabled -- but NOT
442 * with critical sections.
443 *********************************************************************************************************
444 */
445 
446 #if (CPU_CFG_TS_32_EN == DEF_ENABLED)
448 {
449  CPU_TS32 ts;
450 #if (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
451  CPU_TS_TMR tmr_cur;
452  CPU_TS_TMR tmr_delta;
453  CPU_SR_ALLOC();
454 #endif
455 
456 
457 #if (CPU_CFG_TS_TMR_SIZE >= CPU_WORD_SIZE_32)
458  ts = (CPU_TS32)CPU_TS_TmrRd(); /* Get cur ts tmr val (in 32-bit ts cnts). */
459 
460 #else
461  CPU_INT_DIS();
462  tmr_cur = (CPU_TS_TMR) CPU_TS_TmrRd(); /* Get cur ts tmr val (in ts tmr cnts). */
463  tmr_delta = (CPU_TS_TMR)(tmr_cur - CPU_TS_32_TmrPrev); /* Calc delta ts tmr cnts. */
464  CPU_TS_32_Accum += (CPU_TS32 ) tmr_delta; /* Inc ts by delta ts tmr cnts (see Note #2). */
465  CPU_TS_32_TmrPrev = (CPU_TS_TMR) tmr_cur; /* Save cur ts tmr cnts for next update. */
466  ts = (CPU_TS32 ) CPU_TS_32_Accum;
467  CPU_INT_EN();
468 #endif
469 
470  return (ts);
471 }
472 #endif
473 
474 
475 /*$PAGE*/
476 /*
477 *********************************************************************************************************
478 * CPU_TS_Get64()
479 *
480 * Description : Get current 64-bit CPU timestamp.
481 *
482 * Argument(s) : none.
483 *
484 * Return(s) : Current 64-bit CPU timestamp (in timestamp timer counts).
485 *
486 * Caller(s) : Application.
487 *
488 * This function is a CPU module application interface (API) function & MAY be called by
489 * application function(s).
490 *
491 * Note(s) : (1) When applicable, the amount of time measured by CPU timestamps is calculated by
492 * either of the following equations :
493 *
494 * (a) Time measured = Number timer counts * Timer period
495 *
496 * where
497 *
498 * Number timer counts Number of timer counts measured
499 * Timer period Timer's period in some units of
500 * (fractional) seconds
501 * Time measured Amount of time measured, in same
502 * units of (fractional) seconds
503 * as the Timer period
504 *
505 * Number timer counts
506 * (b) Time measured = ---------------------
507 * Timer frequency
508 *
509 * where
510 *
511 * Number timer counts Number of timer counts measured
512 * Timer frequency Timer's frequency in some units
513 * of counts per second
514 * Time measured Amount of time measured, in seconds
515 *
516 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c1'.
517 *
518 * (2) In case the CPU timestamp timer has lower precision than the 64-bit CPU timestamp;
519 * its precision is extended via periodic updates by accumulating the deltas of the
520 * timestamp timer count values into the higher-precision 64-bit CPU timestamp.
521 *
522 * (3) After initialization, 'CPU_TS_64_Accum' & 'CPU_TS_64_TmrPrev' MUST ALWAYS
523 * be accessed AND updated exclusively with interrupts disabled -- but NOT
524 * with critical sections.
525 *********************************************************************************************************
526 */
527 
528 #if (CPU_CFG_TS_64_EN == DEF_ENABLED)
530 {
531  CPU_TS64 ts;
532 #if (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)
533  CPU_TS_TMR tmr_cur;
534  CPU_TS_TMR tmr_delta;
535  CPU_SR_ALLOC();
536 #endif
537 
538 
539 #if (CPU_CFG_TS_TMR_SIZE >= CPU_WORD_SIZE_64)
540  ts = (CPU_TS64)CPU_TS_TmrRd(); /* Get cur ts tmr val (in 64-bit ts cnts). */
541 
542 #else
543  CPU_INT_DIS();
544  tmr_cur = (CPU_TS_TMR) CPU_TS_TmrRd(); /* Get cur ts tmr val (in ts tmr cnts). */
545  tmr_delta = (CPU_TS_TMR)(tmr_cur - CPU_TS_64_TmrPrev); /* Calc delta ts tmr cnts. */
546  CPU_TS_64_Accum += (CPU_TS64 ) tmr_delta; /* Inc ts by delta ts tmr cnts (see Note #2). */
547  CPU_TS_64_TmrPrev = (CPU_TS_TMR) tmr_cur; /* Save cur ts tmr cnts for next update. */
548  ts = (CPU_TS64 ) CPU_TS_64_Accum;
549  CPU_INT_EN();
550 #endif
551 
552  return (ts);
553 }
554 #endif
555 
556 
557 /*$PAGE*/
558 /*
559 *********************************************************************************************************
560 * CPU_TS_Update()
561 *
562 * Description : Update current CPU timestamp(s).
563 *
564 * Argument(s) : none.
565 *
566 * Return(s) : none.
567 *
568 * Caller(s) : Application/BSP periodic time handler (see Note #1).
569 *
570 * This function is a CPU timestamp BSP function & SHOULD be called only by appropriate
571 * application/BSP function(s).
572 *
573 * Note(s) : (1) (a) CPU timestamp(s) MUST be updated periodically by some application (or BSP) time
574 * handler in order to (adequately) maintain CPU timestamp(s)' time.
575 *
576 * (b) CPU timestamp(s) MUST be updated more frequently than the CPU timestamp timer
577 * overflows; otherwise, CPU timestamp(s) will lose time.
578 *
579 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c2'.
580 *********************************************************************************************************
581 */
582 
583 #if (CPU_CFG_TS_EN == DEF_ENABLED)
584 void CPU_TS_Update (void)
585 {
586 #if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \
587  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32))
588  (void)CPU_TS_Get32();
589 #endif
590 
591 #if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \
592  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64))
593  (void)CPU_TS_Get64();
594 #endif
595 }
596 #endif
597 
598 
599 /*$PAGE*/
600 /*
601 *********************************************************************************************************
602 * CPU_TS_TmrFreqGet()
603 *
604 * Description : Get CPU timestamp's timer frequency.
605 *
606 * Argument(s) : p_err Pointer to variable that will receive the return error code from this function :
607 *
608 * CPU_ERR_NONE CPU timestamp's timer frequency successfully
609 * returned.
610 * CPU_ERR_TS_FREQ_INVALID CPU timestamp's timer frequency invalid &/or
611 * NOT yet configured.
612 *
613 * Return(s) : CPU timestamp's timer frequency (in Hertz), if NO error(s).
614 *
615 * 0, otherwise.
616 *
617 * Caller(s) : Application.
618 *
619 * This function is a CPU module application interface (API) function & MAY be called by
620 * application function(s).
621 *
622 * Note(s) : none.
623 *********************************************************************************************************
624 */
625 
626 #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
628 {
629  CPU_TS_TMR_FREQ freq_hz;
630 
631 
632  if (p_err == (CPU_ERR *)0) {
633  CPU_SW_EXCEPTION(;);
634  }
635 
636  freq_hz = CPU_TS_TmrFreq_Hz;
637  *p_err = (freq_hz != 0) ? CPU_ERR_NONE : CPU_ERR_TS_FREQ_INVALID;
638 
639  return (freq_hz);
640 }
641 #endif
642 
643 
644 /*$PAGE*/
645 /*
646 *********************************************************************************************************
647 * CPU_TS_TmrFreqSet()
648 *
649 * Description : Set CPU timestamp's timer frequency.
650 *
651 * Argument(s) : freq_hz Frequency (in Hertz) to set for CPU timestamp's timer.
652 *
653 * Return(s) : none.
654 *
655 * Caller(s) : CPU_TS_TmrInit(),
656 * Application/BSP initialization function(s).
657 *
658 * This function is a CPU module BSP function & SHOULD be called only by appropriate
659 * application/BSP function(s) [see Note #1].
660 *
661 * Note(s) : (1) (a) (1) CPU timestamp timer frequency is NOT required for internal CPU timestamp
662 * operations but may OPTIONALLY be configured by CPU_TS_TmrInit() or other
663 * application/BSP initialization functions.
664 *
665 * (2) CPU timestamp timer frequency MAY be used with optional CPU_TSxx_to_uSec()
666 * to convert CPU timestamps from timer counts into microseconds.
667 *
668 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2a'.
669 *
670 * (b) CPU timestamp timer period SHOULD be less than the typical measured time but MUST
671 * be less than the maximum measured time; otherwise, timer resolution inadequate to
672 * measure desired times.
673 *
674 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2b'.
675 *********************************************************************************************************
676 */
677 
678 #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
680 {
681  CPU_TS_TmrFreq_Hz = freq_hz;
682 }
683 #endif
684 
685 
686 /*$PAGE*/
687 /*
688 *********************************************************************************************************
689 * CPU_IntDisMeasMaxCurReset()
690 *
691 * Description : Reset current maximum interrupts disabled time.
692 *
693 * Argument(s) : none.
694 *
695 * Return(s) : Maximum interrupts disabled time (in CPU timestamp timer counts) before resetting.
696 *
697 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
698 * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
699 *
700 * Caller(s) : Application.
701 *
702 * This function is a CPU module application interface (API) function & MAY be called
703 * by application function(s).
704 *
705 * Note(s) : (1) After initialization, 'CPU_IntDisMeasMaxCur_cnts' MUST ALWAYS be accessed
706 * exclusively with interrupts disabled -- but NOT with critical sections.
707 *********************************************************************************************************
708 */
709 
710 #ifdef CPU_CFG_INT_DIS_MEAS_EN
711 CPU_TS_TMR CPU_IntDisMeasMaxCurReset (void)
712 {
713  CPU_TS_TMR time_max_cnts;
714  CPU_SR_ALLOC();
715 
716 
717  time_max_cnts = CPU_IntDisMeasMaxCurGet();
718  CPU_INT_DIS();
719  CPU_IntDisMeasMaxCur_cnts = 0u;
720  CPU_INT_EN();
721 
722  return (time_max_cnts);
723 }
724 #endif
725 
726 
727 /*$PAGE*/
728 /*
729 *********************************************************************************************************
730 * CPU_IntDisMeasMaxCurGet()
731 *
732 * Description : Get current maximum interrupts disabled time.
733 *
734 * Argument(s) : none.
735 *
736 * Return(s) : Current maximum interrupts disabled time (in CPU timestamp timer counts).
737 *
738 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
739 * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
740 *
741 * Caller(s) : CPU_IntDisMeasMaxCurReset(),
742 * Application.
743 *
744 * This function is a CPU module application interface (API) function & MAY be called
745 * by application function(s).
746 *
747 * Note(s) : (1) After initialization, 'CPU_IntDisMeasMaxCur_cnts' MUST ALWAYS be accessed
748 * exclusively with interrupts disabled -- but NOT with critical sections.
749 *********************************************************************************************************
750 */
751 
752 #ifdef CPU_CFG_INT_DIS_MEAS_EN
753 CPU_TS_TMR CPU_IntDisMeasMaxCurGet (void)
754 {
755  CPU_TS_TMR time_tot_cnts;
756  CPU_TS_TMR time_max_cnts;
757  CPU_SR_ALLOC();
758 
759 
760  CPU_INT_DIS();
761  time_tot_cnts = CPU_IntDisMeasMaxCur_cnts;
762  CPU_INT_EN();
763  time_max_cnts = CPU_IntDisMeasMaxCalc(time_tot_cnts);
764 
765  return (time_max_cnts);
766 }
767 #endif
768 
769 
770 /*$PAGE*/
771 /*
772 *********************************************************************************************************
773 * CPU_IntDisMeasMaxGet()
774 *
775 * Description : Get (non-resetable) maximum interrupts disabled time.
776 *
777 * Argument(s) : none.
778 *
779 * Return(s) : (Non-resetable) maximum interrupts disabled time (in CPU timestamp timer counts).
780 *
781 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
782 * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
783 *
784 * Caller(s) : CPU_IntDisMeasInit(),
785 * Application.
786 *
787 * This function is a CPU module application interface (API) function & MAY be called
788 * by application function(s).
789 *
790 * Note(s) : (1) After initialization, 'CPU_IntDisMeasMax_cnts' MUST ALWAYS be accessed
791 * exclusively with interrupts disabled -- but NOT with critical sections.
792 *********************************************************************************************************
793 */
794 
795 #ifdef CPU_CFG_INT_DIS_MEAS_EN
796 CPU_TS_TMR CPU_IntDisMeasMaxGet (void)
797 {
798  CPU_TS_TMR time_tot_cnts;
799  CPU_TS_TMR time_max_cnts;
800  CPU_SR_ALLOC();
801 
802 
803  CPU_INT_DIS();
804  time_tot_cnts = CPU_IntDisMeasMax_cnts;
805  CPU_INT_EN();
806  time_max_cnts = CPU_IntDisMeasMaxCalc(time_tot_cnts);
807 
808  return (time_max_cnts);
809 }
810 #endif
811 
812 
813 /*$PAGE*/
814 /*
815 *********************************************************************************************************
816 * CPU_IntDisMeasStart()
817 *
818 * Description : Start interrupts disabled time measurement.
819 *
820 * Argument(s) : none.
821 *
822 * Return(s) : none.
823 *
824 * Caller(s) : CPU_CRITICAL_ENTER().
825 *
826 * This function is an INTERNAL CPU module function & MUST NOT be called by application
827 * function(s).
828 *
829 * Note(s) : none.
830 *********************************************************************************************************
831 */
832 
833 #ifdef CPU_CFG_INT_DIS_MEAS_EN
834 void CPU_IntDisMeasStart (void)
835 {
836  CPU_IntDisMeasCtr++;
837  if (CPU_IntDisNestCtr == 0u) { /* If ints NOT yet dis'd, ... */
838  CPU_IntDisMeasStart_cnts = CPU_TS_TmrRd(); /* ... get ints dis'd start time. */
839  }
840  CPU_IntDisNestCtr++;
841 }
842 #endif
843 
844 
845 /*$PAGE*/
846 /*
847 *********************************************************************************************************
848 * CPU_IntDisMeasStop()
849 *
850 * Description : Stop interrupts disabled time measurement.
851 *
852 * Argument(s) : none.
853 *
854 * Return(s) : none.
855 *
856 * Caller(s) : CPU_CRITICAL_EXIT().
857 *
858 * This function is an INTERNAL CPU module function & MUST NOT be called by application
859 * function(s).
860 *
861 * Note(s) : (1) (a) The total amount of time interrupts are disabled by system &/or application code
862 * during critical sections is calculated by the following equations :
863 *
864 * (1) When interrupts disabled time measurements are disabled :
865 *
866 *
867 * | CRITICAL | | CRITICAL |
868 * |<- SECTION ->| |<- SECTION ->|
869 * | ENTER | | EXIT |
870 *
871 * Disable Enable
872 * Interrupts Interrupts
873 *
874 * || || || ||
875 * || || || ||
876 * || | ||<------------------------->|| | ||
877 * || |<->|| | ||<----->| ||
878 * || | | || | || | | ||
879 * | | | | |
880 * interrupts time interrupts
881 * disabled interrupts |enabled
882 * | disabled |
883 * | (via application) |
884 * time time
885 * interrupts interrupts
886 * disabled ovrhd enabled ovrhd
887 *
888 *
889 * (A) time = [ time - time ] - time
890 * interrupts [ interrupts interrupts ] total
891 * disabled [ enabled disabled ] ovrhd
892 * (via application)
893 *
894 *
895 * (B) time = time + time
896 * total interrupts interrupts
897 * ovrhd enabled ovrhd disabled ovrhd
898 *
899 *
900 * where
901 *
902 * time time interrupts are disabled between
903 * interrupts first critical section enter &
904 * disabled last critical section exit (i.e.
905 * (via application) minus total overhead time)
906 *
907 * time time when interrupts are disabled
908 * interrupts
909 * disabled
910 *
911 * time time when interrupts are enabled
912 * interrupts
913 * enabled
914 *
915 *
916 * time total overhead time to disable/enable
917 * total interrupts during critical section
918 * ovrhd enter & exit
919 *
920 * time total overhead time to disable interrupts
921 * interrupts during critical section enter
922 * disabled ovrhd
923 *
924 * time total overhead time to enable interrupts
925 * interrupts during critical section exit
926 * enabled ovrhd
927 *
928 *$PAGE*
929 *
930 * (2) When interrupts disabled time measurements are enabled :
931 *
932 *
933 * | | | |
934 * |<----- CRITICAL SECTION ENTER ----->| |<------- CRITICAL SECTION EXIT ------->|
935 * | | | |
936 *
937 * Time Time
938 * Disable Measurement Measurement Enable
939 * Interrupts Start Stop Interrupts
940 *
941 * || | || || | ||
942 * || | || || | ||
943 * || | | ||<------------------------->|| | | ||
944 * || | | |<----------->|| | ||<------------->| | | ||
945 * || | | | | || | || | | | | ||
946 * | | | | | | |
947 * interrupts get | time | get interrupts
948 * disabled start time | interrupts | stop time enabled
949 * meas | disabled | meas
950 * time (via application) time
951 * start meas stop meas
952 * ovrhd ovrhd
953 *
954 *
955 * (A) time = [ time - time ] - time
956 * interrupts [ stop start ] total meas
957 * disabled [ meas meas ] ovrhd
958 * (via application)
959 *
960 *
961 * (B) time = time + time
962 * total meas start meas stop meas
963 * ovrhd ovrhd ovrhd
964 *
965 *
966 * where
967 *
968 * time time interrupts are disabled between first
969 * interrupts critical section enter & last critical
970 * disabled section exit (i.e. minus measurement
971 * (via application) overhead time; however, this does NOT
972 * include any overhead time to disable
973 * or enable interrupts during critical
974 * section enter & exit)
975 *
976 * time time of disable interrupts start time
977 * start measurement (in timer counts)
978 * meas
979 *
980 * time time of disable interrupts stop time
981 * stop measurement (in timer counts)
982 * meas
983 *
984 *
985 * time total overhead time to start/stop disabled
986 * total meas interrupts time measurements (in timer
987 * ovrhd counts)
988 *
989 * time total overhead time after getting start
990 * start meas time until end of start measurement
991 * ovrhd function (in timer counts)
992 *
993 * time total overhead time from beginning of stop
994 * stop meas measurement function until after getting
995 * ovrhd stop time (in timer counts)
996 *
997 *
998 *$PAGE*
999 * (b) (1) (A) In order to correctly handle unsigned subtraction overflows of start times
1000 * from stop times, CPU timestamp timer count values MUST be returned via
1001 * word-size-configurable 'CPU_TS_TMR' data type.
1002 *
1003 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'.
1004 *
1005 * (B) Since unsigned subtraction of start times from stop times assumes increasing
1006 * values, timestamp timer count values MUST increase with each time count.
1007 *
1008 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2b'.
1009 *
1010 * (2) (A) To expedite & reduce interrupts disabled time measurement overhead; only the
1011 * subtraction of start times from stop times is performed.
1012 *
1013 * (B) The final calculations to subtract the interrupts disabled time measurement
1014 * overhead is performed asynchronously in appropriate API functions.
1015 *
1016 * See also 'CPU_IntDisMeasMaxCalc() Note #1b'.
1017 *********************************************************************************************************
1018 */
1019 
1020 #ifdef CPU_CFG_INT_DIS_MEAS_EN
1021 void CPU_IntDisMeasStop (void)
1022 {
1023  CPU_TS_TMR time_ints_disd_cnts;
1024 
1025 
1026  CPU_IntDisNestCtr--;
1027  if (CPU_IntDisNestCtr == 0u) { /* If ints NO longer dis'd, ... */
1028  CPU_IntDisMeasStop_cnts = CPU_TS_TmrRd(); /* ... get ints dis'd stop time & ... */
1029  /* ... calc ints dis'd tot time (see Note #1b2A). */
1030  time_ints_disd_cnts = CPU_IntDisMeasStop_cnts -
1031  CPU_IntDisMeasStart_cnts;
1032  /* Calc max ints dis'd times. */
1033  if (CPU_IntDisMeasMaxCur_cnts < time_ints_disd_cnts) {
1034  CPU_IntDisMeasMaxCur_cnts = time_ints_disd_cnts;
1035  }
1036  if (CPU_IntDisMeasMax_cnts < time_ints_disd_cnts) {
1037  CPU_IntDisMeasMax_cnts = time_ints_disd_cnts;
1038  }
1039  }
1040 }
1041 #endif
1042 
1043 
1044 /*$PAGE*/
1045 /*
1046 *********************************************************************************************************
1047 * CPU_CntLeadZeros()
1048 *
1049 * Description : Count the number of contiguous, most-significant, leading zero bits in a data value.
1050 *
1051 * Argument(s) : val Data value to count leading zero bits.
1052 *
1053 * Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s).
1054 *
1055 * 0, otherwise.
1056 *
1057 * Caller(s) : Application.
1058 *
1059 * This function is an INTERNAL CPU module function but MAY be called by application function(s).
1060 *
1061 * Note(s) : (1) (a) Supports the following data value sizes :
1062 *
1063 * (1) 8-bits
1064 * (2) 16-bits
1065 * (3) 32-bits
1066 * (4) 64-bits
1067 *
1068 * See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'.
1069 *
1070 * (b) (1) For 8-bit values :
1071 *
1072 * b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros
1073 * --- --- --- --- --- --- --- --- ---------------
1074 * 1 x x x x x x x 0
1075 * 0 1 x x x x x x 1
1076 * 0 0 1 x x x x x 2
1077 * 0 0 0 1 x x x x 3
1078 * 0 0 0 0 1 x x x 4
1079 * 0 0 0 0 0 1 x x 5
1080 * 0 0 0 0 0 0 1 x 6
1081 * 0 0 0 0 0 0 0 1 7
1082 * 0 0 0 0 0 0 0 0 8
1083 *
1084 *
1085 * (2) For 16-bit values :
1086 *
1087 * b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros
1088 * --- --- --- --- --- --- --- --- ---------------
1089 * 1 x x x x x x x 0
1090 * 0 1 x x x x x x 1
1091 * 0 0 1 x x x x x 2
1092 * : : : : : : : : :
1093 * : : : : : : : : :
1094 * 0 0 0 1 x x x x 11
1095 * 0 0 0 0 1 x x x 12
1096 * 0 0 0 0 0 1 x x 13
1097 * 0 0 0 0 0 0 1 x 14
1098 * 0 0 0 0 0 0 0 1 15
1099 * 0 0 0 0 0 0 0 0 16
1100 *
1101 *
1102 * (3) For 32-bit values :
1103 *
1104 * b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros
1105 * --- --- --- --- --- --- --- --- ---------------
1106 * 1 x x x x x x x 0
1107 * 0 1 x x x x x x 1
1108 * 0 0 1 x x x x x 2
1109 * : : : : : : : : :
1110 * : : : : : : : : :
1111 * 0 0 0 1 x x x x 27
1112 * 0 0 0 0 1 x x x 28
1113 * 0 0 0 0 0 1 x x 29
1114 * 0 0 0 0 0 0 1 x 30
1115 * 0 0 0 0 0 0 0 1 31
1116 * 0 0 0 0 0 0 0 0 32
1117 *
1118 *$PAGE*
1119 * (4) For 64-bit values :
1120 *
1121 * b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros
1122 * --- --- --- --- --- --- --- --- ---------------
1123 * 1 x x x x x x x 0
1124 * 0 1 x x x x x x 1
1125 * 0 0 1 x x x x x 2
1126 * : : : : : : : : :
1127 * : : : : : : : : :
1128 * 0 0 0 1 x x x x 59
1129 * 0 0 0 0 1 x x x 60
1130 * 0 0 0 0 0 1 x x 61
1131 * 0 0 0 0 0 0 1 x 62
1132 * 0 0 0 0 0 0 0 1 63
1133 * 0 0 0 0 0 0 0 0 64
1134 *
1135 *
1136 * See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
1137 *********************************************************************************************************
1138 */
1139 
1140 #ifndef CPU_CFG_LEAD_ZEROS_ASM_PRESENT
1142 {
1143  CPU_DATA nbr_lead_zeros;
1144  CPU_INT08U ix;
1145 
1146 
1147 #if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_08) /* ---------- 8-BIT DATA VAL --------- */
1148  /* Chk bits [07:00] : */
1149  /* .. Nbr lead zeros = .. */
1150  ix = (CPU_INT08U)(val >> 0u); /* .. lookup tbl ix = 'val' >> 0 bits */
1151  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 0u); /* .. plus nbr msb lead zeros = 0 bits.*/
1152 
1153 
1154 #elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) /* ---------- 16-BIT DATA VAL --------- */
1155  if (val > 0x00FFu) { /* Chk bits [15:08] : */
1156  /* .. Nbr lead zeros = .. */
1157  ix = (CPU_INT08U)(val >> 8u); /* .. lookup tbl ix = 'val' >> 8 bits */
1158  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 0u); /* .. plus nbr msb lead zeros = 0 bits.*/
1159 
1160  } else { /* Chk bits [07:00] : */
1161  /* .. Nbr lead zeros = .. */
1162  ix = (CPU_INT08U)(val >> 0u); /* .. lookup tbl ix = 'val' >> 0 bits */
1163  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 8u); /* .. plus nbr msb lead zeros = 8 bits.*/
1164  }
1165 
1166 
1167 #elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) /* ---------- 32-BIT DATA VAL --------- */
1168  if (val > 0x0000FFFFu) {
1169  if (val > 0x00FFFFFFu) { /* Chk bits [31:24] : */
1170  /* .. Nbr lead zeros = .. */
1171  ix = (CPU_INT08U)(val >> 24u); /* .. lookup tbl ix = 'val' >> 24 bits */
1172  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 0u); /* .. plus nbr msb lead zeros = 0 bits.*/
1173 
1174  } else { /* Chk bits [23:16] : */
1175  /* .. Nbr lead zeros = .. */
1176  ix = (CPU_INT08U)(val >> 16u); /* .. lookup tbl ix = 'val' >> 16 bits */
1177  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 8u); /* .. plus nbr msb lead zeros = 8 bits.*/
1178  }
1179 
1180  } else {
1181  if (val > 0x000000FFu) { /* Chk bits [15:08] : */
1182  /* .. Nbr lead zeros = .. */
1183  ix = (CPU_INT08U)(val >> 8u); /* .. lookup tbl ix = 'val' >> 8 bits */
1184  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 16u); /* .. plus nbr msb lead zeros = 16 bits.*/
1185 
1186  } else { /* Chk bits [07:00] : */
1187  /* .. Nbr lead zeros = .. */
1188  ix = (CPU_INT08U)(val >> 0u); /* .. lookup tbl ix = 'val' >> 0 bits */
1189  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 24u); /* .. plus nbr msb lead zeros = 24 bits.*/
1190  }
1191  }
1192 
1193 /*$PAGE*/
1194 #elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) /* ---------- 64-BIT DATA VAL --------- */
1195  if (val > 0x00000000FFFFFFFFu) {
1196  if (val > 0x0000FFFFFFFFFFFFu) {
1197  if (val > 0x00FFFFFFFFFFFFFFu) { /* Chk bits [63:56] : */
1198  /* .. Nbr lead zeros = .. */
1199  ix = (CPU_INT08U)(val >> 56u); /* .. lookup tbl ix = 'val' >> 56 bits */
1200  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 0u); /* .. plus nbr msb lead zeros = 0 bits.*/
1201 
1202  } else { /* Chk bits [55:48] : */
1203  /* .. Nbr lead zeros = .. */
1204  ix = (CPU_INT08U)(val >> 48u); /* .. lookup tbl ix = 'val' >> 48 bits */
1205  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 8u); /* .. plus nbr msb lead zeros = 8 bits.*/
1206  }
1207 
1208  } else {
1209  if (val > 0x000000FFFFFFFFFFu) { /* Chk bits [47:40] : */
1210  /* .. Nbr lead zeros = .. */
1211  ix = (CPU_INT08U)(val >> 40u); /* .. lookup tbl ix = 'val' >> 40 bits */
1212  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 16u); /* .. plus nbr msb lead zeros = 16 bits.*/
1213 
1214  } else { /* Chk bits [39:32] : */
1215  /* .. Nbr lead zeros = .. */
1216  ix = (CPU_INT08U)(val >> 32u); /* .. lookup tbl ix = 'val' >> 32 bits */
1217  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 24u); /* .. plus nbr msb lead zeros = 24 bits.*/
1218  }
1219  }
1220 
1221  } else {
1222  if (val > 0x000000000000FFFFu) {
1223  if (val > 0x0000000000FFFFFFu) { /* Chk bits [31:24] : */
1224  /* .. Nbr lead zeros = .. */
1225  ix = (CPU_INT08U)(val >> 24u); /* .. lookup tbl ix = 'val' >> 24 bits */
1226  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 32u); /* .. plus nbr msb lead zeros = 32 bits.*/
1227 
1228  } else { /* Chk bits [23:16] : */
1229  /* .. Nbr lead zeros = .. */
1230  ix = (CPU_INT08U)(val >> 16u); /* .. lookup tbl ix = 'val' >> 16 bits */
1231  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 40u); /* .. plus nbr msb lead zeros = 40 bits.*/
1232  }
1233 
1234  } else {
1235  if (val > 0x00000000000000FFu) { /* Chk bits [15:08] : */
1236  /* .. Nbr lead zeros = .. */
1237  ix = (CPU_INT08U)(val >> 8u); /* .. lookup tbl ix = 'val' >> 8 bits */
1238  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 48u); /* .. plus nbr msb lead zeros = 48 bits.*/
1239 
1240  } else { /* Chk bits [07:00] : */
1241  /* .. Nbr lead zeros = .. */
1242  ix = (CPU_INT08U)(val >> 0u); /* .. lookup tbl ix = 'val' >> 0 bits */
1243  nbr_lead_zeros = (CPU_DATA )(CPU_CntLeadZerosTbl[ix] + 56u); /* .. plus nbr msb lead zeros = 56 bits.*/
1244  }
1245  }
1246  }
1247 
1248 
1249 #else /* See Note #1a. */
1250  (void)&ix;
1251  nbr_lead_zeros = 0u;
1252 #endif
1253 
1254  return (nbr_lead_zeros);
1255 }
1256 #endif
1257 
1258 
1259 /*$PAGE*/
1260 /*
1261 *********************************************************************************************************
1262 *********************************************************************************************************
1263 * LOCAL FUNCTIONS
1264 *********************************************************************************************************
1265 *********************************************************************************************************
1266 */
1267 
1268 /*
1269 *********************************************************************************************************
1270 * CPU_NameInit()
1271 *
1272 * Description : Initialize CPU Name.
1273 *
1274 * Argument(s) : none.
1275 *
1276 * Return(s) : none.
1277 *
1278 * Caller(s) : CPU_Init().
1279 *
1280 * Note(s) : none.
1281 *********************************************************************************************************
1282 */
1283 
1284 #if (CPU_CFG_NAME_EN == DEF_ENABLED)
1285 static void CPU_NameInit (void)
1286 {
1287  CPU_NameClr();
1288 }
1289 #endif
1290 
1291 
1292 /*$PAGE*/
1293 /*
1294 *********************************************************************************************************
1295 * CPU_TS_Init()
1296 *
1297 * Description : (1) Initialize CPU timestamp :
1298 *
1299 * (a) Initialize/start CPU timestamp timer See Note #1
1300 * (b) Initialize CPU timestamp controls
1301 *
1302 *
1303 * Argument(s) : none.
1304 *
1305 * Return(s) : none.
1306 *
1307 * Caller(s) : CPU_Init().
1308 *
1309 * Note(s) : (1) The following initialization MUST be sequenced as follows :
1310 *
1311 * (a) CPU_TS_TmrFreq_Hz MUST be initialized prior to CPU_TS_TmrInit()
1312 * (b) CPU_TS_TmrInit() SHOULD precede calls to all other CPU timestamp functions;
1313 * otherwise, invalid time measurements may be calculated/
1314 * returned.
1315 *
1316 * See also 'CPU_Init() Note #3a'.
1317 *********************************************************************************************************
1318 */
1319 
1320 #if ((CPU_CFG_TS_EN == DEF_ENABLED) || \
1321  (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
1322 static void CPU_TS_Init (void)
1323 {
1324 #if (((CPU_CFG_TS_32_EN == DEF_ENABLED ) && \
1325  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) || \
1326  ((CPU_CFG_TS_64_EN == DEF_ENABLED ) && \
1327  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)))
1328  CPU_TS_TMR ts_tmr_cnts;
1329 #endif
1330 
1331 
1332  /* ----------------- INIT CPU TS TMR ------------------ */
1333 #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
1334  CPU_TS_TmrFreq_Hz = 0u; /* Init/clr ts tmr freq (see Note #1a). */
1335  CPU_TS_TmrInit(); /* Init & start ts tmr (see Note #1b). */
1336 #endif
1337 
1338 
1339  /* ------------------- INIT CPU TS -------------------- */
1340 #if (((CPU_CFG_TS_32_EN == DEF_ENABLED ) && \
1341  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) || \
1342  ((CPU_CFG_TS_64_EN == DEF_ENABLED ) && \
1343  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)))
1344  ts_tmr_cnts = CPU_TS_TmrRd(); /* Get init ts tmr val (in ts tmr cnts). */
1345 #endif
1346 
1347 #if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \
1348  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32))
1349  CPU_TS_32_Accum = 0u; /* Init 32-bit accum'd ts. */
1350  CPU_TS_32_TmrPrev = ts_tmr_cnts; /* Init 32-bit ts prev tmr val. */
1351 #endif
1352 
1353 #if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \
1354  (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64))
1355  CPU_TS_64_Accum = 0u; /* Init 64-bit accum'd ts. */
1356  CPU_TS_64_TmrPrev = ts_tmr_cnts; /* Init 64-bit ts prev tmr val. */
1357 #endif
1358 }
1359 #endif
1360 
1361 
1362 /*$PAGE*/
1363 /*
1364 *********************************************************************************************************
1365 * CPU_IntDisMeasInit()
1366 *
1367 * Description : (1) Initialize interrupts disabled time measurements feature :
1368 *
1369 * (a) Initialize interrupts disabled time measurement controls
1370 * (b) Calculate interrupts disabled time measurement overhead
1371 *
1372 *
1373 * Argument(s) : none.
1374 *
1375 * Return(s) : none.
1376 *
1377 * Caller(s) : CPU_Init().
1378 *
1379 * Note(s) : (2) CPU_IntDisMeasInit() SHOULD precede ALL calls to CPU_CRITICAL_ENTER()/CPU_CRITICAL_EXIT()
1380 * & other CPU interrupts disabled time measurement functions; otherwise, invalid interrupts
1381 * disabled time measurements may be calculated/returned.
1382 *
1383 * See also 'CPU_Init() Note #3b'.
1384 *
1385 * (3) (a) (1) Interrupts disabled time measurement overhead performed multiple times to calculate
1386 * a rounded average with better accuracy, hopefully of +/- one timer count.
1387 *
1388 * (2) However, a single overhead time measurement is recommended, even for instruction-
1389 * cache-enabled CPUs, since critical sections are NOT typically called within
1390 * instruction-cached loops. Thus, a single non-cached/non-averaged time measurement
1391 * is a more realistic overhead for the majority of non-cached interrupts disabled
1392 * time measurements.
1393 *
1394 * (b) Interrupts MUST be disabled while measuring the interrupts disabled time measurement
1395 * overhead; otherwise, overhead measurements could be interrupted which would incorrectly
1396 * calculate an inflated overhead time which would then incorrectly calculate deflated
1397 * interrupts disabled times.
1398 *********************************************************************************************************
1399 */
1400 
1401 #ifdef CPU_CFG_INT_DIS_MEAS_EN
1402 static void CPU_IntDisMeasInit (void)
1403 {
1404  CPU_TS_TMR time_meas_tot_cnts;
1405  CPU_INT16U i;
1406  CPU_SR_ALLOC();
1407 
1408  /* ----------- INIT INT DIS TIME MEAS CTRLS ----------- */
1409  CPU_IntDisMeasCtr = 0u;
1410  CPU_IntDisNestCtr = 0u;
1411  CPU_IntDisMeasStart_cnts = 0u;
1412  CPU_IntDisMeasStop_cnts = 0u;
1413  CPU_IntDisMeasMaxCur_cnts = 0u;
1414  CPU_IntDisMeasMax_cnts = 0u;
1415  CPU_IntDisMeasOvrhd_cnts = 0u;
1416 
1417  /* ----------- CALC INT DIS TIME MEAS OVRHD ----------- */
1418  time_meas_tot_cnts = 0u;
1419  CPU_INT_DIS(); /* Ints MUST be dis'd for ovrhd calc (see Note #3b). */
1420  for (i = 0u; i < CPU_CFG_INT_DIS_MEAS_OVRHD_NBR; i++) {
1421  CPU_IntDisMeasMaxCur_cnts = 0u;
1422  CPU_IntDisMeasStart(); /* Perform multiple consecutive start/stop time meas's */
1423  CPU_IntDisMeasStop();
1424  time_meas_tot_cnts += CPU_IntDisMeasMaxCur_cnts; /* ... & sum time meas max's ... */
1425  }
1426  /* ... to calc avg time meas ovrhd (see Note #3a). */
1427  CPU_IntDisMeasOvrhd_cnts = (time_meas_tot_cnts + (CPU_CFG_INT_DIS_MEAS_OVRHD_NBR / 2))
1429  CPU_IntDisMeasMaxCur_cnts = 0u; /* Reset max ints dis'd times. */
1430  CPU_IntDisMeasMax_cnts = 0u;
1431  CPU_INT_EN();
1432 }
1433 #endif
1434 
1435 
1436 /*$PAGE*/
1437 /*
1438 *********************************************************************************************************
1439 * CPU_IntDisMeasMaxCalc()
1440 *
1441 * Description : Calculate maximum interrupts disabled time.
1442 *
1443 * Argument(s) : time_tot_cnts Total interrupt disabled time, in timer counts.
1444 *
1445 * Return(s) : Maximum interrupts disabled time (in CPU timestamp timer counts).
1446 *
1447 * Caller(s) : CPU_IntDisMeasMaxCurGet(),
1448 * CPU_IntDisMeasMaxGet().
1449 *
1450 * Note(s) : (1) (a) The total amount of time interrupts are disabled by system &/or application code
1451 * during critical sections is calculated by the following equations :
1452 *
1453 * (1) time = [ time - time ] - time
1454 * interrupts [ stop start ] total meas
1455 * disabled [ meas meas ] ovrhd
1456 * (via application)
1457 *
1458 *
1459 * (2) time = time + time
1460 * total meas start meas stop meas
1461 * ovrhd ovrhd ovrhd
1462 *
1463 *
1464 * where
1465 *
1466 * time time interrupts are disabled between
1467 * interrupts first critical section enter &
1468 * disabled last critical section exit minus
1469 * (via application) time measurement overhead
1470 *
1471 * time time of disable interrupts start time
1472 * start measurement (in timer counts)
1473 * meas
1474 *
1475 * time time of disable interrupts stop time
1476 * stop measurement (in timer counts)
1477 * meas
1478 *
1479 * time total overhead time to start/stop disabled
1480 * total meas interrupts time measurements (in timer
1481 * ovrhd counts)
1482 *
1483 * time total overhead time after getting start
1484 * start meas time until end of start measurement
1485 * ovrhd function (in timer counts)
1486 *
1487 * time total overhead time from beginning of stop
1488 * stop meas measurement function until after getting
1489 * ovrhd stop time (in timer counts)
1490 *
1491 *
1492 * (b) To expedite & reduce interrupts disabled time measurement overhead, the final
1493 * calculations to subtract the interrupts disabled time measurement overhead is
1494 * performed asynchronously in API functions.
1495 *
1496 * See also 'CPU_IntDisMeasStop() Note #1b2'.
1497 *$PAGE*
1498 * (c) The amount of time interrupts are disabled is calculated by either of the
1499 * following equations :
1500 *
1501 * (1) Interrupts disabled time = Number timer counts * Timer period
1502 *
1503 * where
1504 *
1505 * Number timer counts Number of timer counts measured
1506 * Timer period Timer's period in some units of
1507 * (fractional) seconds
1508 * Interrupts disabled time Amount of time interrupts are
1509 * disabled, in same units of
1510 * (fractional) seconds as the
1511 * Timer period
1512 *
1513 * Number timer counts
1514 * (2) Interrupts disabled time = ---------------------
1515 * Timer frequency
1516 *
1517 * where
1518 *
1519 * Number timer counts Number of timer counts measured
1520 * Timer frequency Timer's frequency in some units
1521 * of counts per second
1522 * Interrupts disabled time Amount of time interrupts are
1523 * disabled, in seconds
1524 *
1525 * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
1526 * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
1527 *
1528 * (2) Although it is not typical, it is possible for an interrupts disabled time
1529 * measurement to be less than the interrupts disabled time measurement overhead;
1530 * especially if the overhead was calculated with a single, non-cached measurement
1531 * & critical sections are called within instruction-cached loops.
1532 *********************************************************************************************************
1533 */
1534 
1535 #ifdef CPU_CFG_INT_DIS_MEAS_EN
1536 static CPU_TS_TMR CPU_IntDisMeasMaxCalc (CPU_TS_TMR time_tot_cnts)
1537 {
1538  CPU_TS_TMR time_max_cnts;
1539 
1540 
1541  time_max_cnts = time_tot_cnts;
1542  if (time_max_cnts > CPU_IntDisMeasOvrhd_cnts) { /* If max ints dis'd time > ovrhd time, ... */
1543  time_max_cnts -= CPU_IntDisMeasOvrhd_cnts; /* ... adj max ints dis'd time by ovrhd time; ... */
1544  } else { /* ... else max ints dis'd time < ovrhd time, ... */
1545  time_max_cnts = 0u; /* ... clr max ints dis'd time (see Note #2). */
1546  }
1547 
1548  return (time_max_cnts);
1549 }
1550 #endif
1551