训练营PLSR题目
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

2339 řádky
113 KiB

  1. /*
  2. *********************************************************************************************************
  3. * uC/CPU
  4. * CPU CONFIGURATION & PORT LAYER
  5. *
  6. * (c) Copyright 2004-2013; 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 find our product's user manual, API reference, release notes and
  19. * more information at https://doc.micrium.com.
  20. * You can contact us at www.micrium.com.
  21. *********************************************************************************************************
  22. */
  23. /*
  24. *********************************************************************************************************
  25. *
  26. * CORE CPU MODULE
  27. *
  28. * Filename : cpu_core.c
  29. * Version : V1.30.01
  30. * Programmer(s) : SR
  31. * ITJ
  32. *********************************************************************************************************
  33. */
  34. /*
  35. *********************************************************************************************************
  36. * INCLUDE FILES
  37. *********************************************************************************************************
  38. */
  39. #define MICRIUM_SOURCE
  40. #define CPU_CORE_MODULE
  41. #include "cpu_core.h"
  42. #if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED)
  43. #include "cpu_cache.h"
  44. #endif
  45. /*
  46. *********************************************************************************************************
  47. * LOCAL DEFINES
  48. *********************************************************************************************************
  49. */
  50. /*
  51. *********************************************************************************************************
  52. * LOCAL CONSTANTS
  53. *********************************************************************************************************
  54. */
  55. /*
  56. *********************************************************************************************************
  57. * LOCAL DATA TYPES
  58. *********************************************************************************************************
  59. */
  60. /*
  61. *********************************************************************************************************
  62. * LOCAL TABLES
  63. *********************************************************************************************************
  64. */
  65. /*
  66. *********************************************************************************************************
  67. * CPU COUNT LEAD ZEROs LOOKUP TABLE
  68. *
  69. * Note(s) : (1) Index into bit pattern table determines the number of leading zeros in an 8-bit value :
  70. *
  71. * b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros
  72. * --- --- --- --- --- --- --- --- ---------------
  73. * 1 x x x x x x x 0
  74. * 0 1 x x x x x x 1
  75. * 0 0 1 x x x x x 2
  76. * 0 0 0 1 x x x x 3
  77. * 0 0 0 0 1 x x x 4
  78. * 0 0 0 0 0 1 x x 5
  79. * 0 0 0 0 0 0 1 x 6
  80. * 0 0 0 0 0 0 0 1 7
  81. * 0 0 0 0 0 0 0 0 8
  82. *********************************************************************************************************
  83. */
  84. #if (!(defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) || \
  85. (CPU_CFG_DATA_SIZE_MAX > CPU_CFG_DATA_SIZE))
  86. static const CPU_INT08U CPU_CntLeadZerosTbl[256] = { /* Data vals : */
  87. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  88. 8u, 7u, 6u, 6u, 5u, 5u, 5u, 5u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, /* 0x00 to 0x0F */
  89. 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, /* 0x10 to 0x1F */
  90. 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, /* 0x20 to 0x2F */
  91. 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, /* 0x30 to 0x3F */
  92. 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x40 to 0x4F */
  93. 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x50 to 0x5F */
  94. 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x60 to 0x6F */
  95. 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, /* 0x70 to 0x7F */
  96. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0x80 to 0x8F */
  97. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0x90 to 0x9F */
  98. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xA0 to 0xAF */
  99. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xB0 to 0xBF */
  100. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xC0 to 0xCF */
  101. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xD0 to 0xDF */
  102. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /* 0xE0 to 0xEF */
  103. 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u /* 0xF0 to 0xFF */
  104. };
  105. #endif
  106. /*
  107. *********************************************************************************************************
  108. * LOCAL GLOBAL VARIABLES
  109. *********************************************************************************************************
  110. */
  111. CPU_INT32U const CPU_EndiannessTest = 0x12345678LU; /* Variable to test CPU endianness. */
  112. /*
  113. *********************************************************************************************************
  114. * LOCAL FUNCTION PROTOTYPES
  115. *********************************************************************************************************
  116. */
  117. #if (CPU_CFG_NAME_EN == DEF_ENABLED) /* ---------------- CPU NAME FNCTS ---------------- */
  118. static void CPU_NameInit (void);
  119. #endif
  120. /* ----------------- CPU TS FNCTS ----------------- */
  121. #if ((CPU_CFG_TS_EN == DEF_ENABLED) || \
  122. (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
  123. static void CPU_TS_Init (void);
  124. #endif
  125. #ifdef CPU_CFG_INT_DIS_MEAS_EN /* ---------- CPU INT DIS TIME MEAS FNCTS --------- */
  126. static void CPU_IntDisMeasInit (void);
  127. static CPU_TS_TMR CPU_IntDisMeasMaxCalc(CPU_TS_TMR time_tot_cnts);
  128. #endif
  129. /*
  130. *********************************************************************************************************
  131. * LOCAL CONFIGURATION ERRORS
  132. *********************************************************************************************************
  133. */
  134. /*
  135. *********************************************************************************************************
  136. * CPU_Init()
  137. *
  138. * Description : (1) Initialize CPU module :
  139. *
  140. * (a) Initialize CPU timestamps
  141. * (b) Initialize CPU interrupts disabled time measurements
  142. * (c) Initialize CPU host name
  143. *
  144. *
  145. * Argument(s) : none.
  146. *
  147. * Return(s) : none.
  148. *
  149. * Caller(s) : Your Product's Application.
  150. *
  151. * This function is a CPU initialization function & MAY be called by application/
  152. * initialization function(s).
  153. *
  154. * Note(s) : (2) CPU_Init() MUST be called ... :
  155. *
  156. * (a) ONLY ONCE from a product's application; ...
  157. * (b) BEFORE product's application calls any core CPU module function(s)
  158. *
  159. * (3) The following initialization functions MUST be sequenced as follows :
  160. *
  161. * (a) CPU_TS_Init() SHOULD precede ALL calls to other CPU timestamp functions
  162. *
  163. * (b) CPU_IntDisMeasInit() SHOULD precede ALL calls to CPU_CRITICAL_ENTER()/CPU_CRITICAL_EXIT()
  164. * & other CPU interrupts disabled time measurement functions
  165. *********************************************************************************************************
  166. */
  167. void CPU_Init (void)
  168. {
  169. /* --------------------- INIT TS ---------------------- */
  170. #if ((CPU_CFG_TS_EN == DEF_ENABLED) || \
  171. (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
  172. CPU_TS_Init(); /* See Note #3a. */
  173. #endif
  174. /* -------------- INIT INT DIS TIME MEAS -------------- */
  175. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  176. CPU_IntDisMeasInit(); /* See Note #3b. */
  177. #endif
  178. /* ------------------ INIT CPU NAME ------------------- */
  179. #if (CPU_CFG_NAME_EN == DEF_ENABLED)
  180. CPU_NameInit();
  181. #endif
  182. #if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED)
  183. CPU_Cache_Init();
  184. #endif
  185. }
  186. /*
  187. *********************************************************************************************************
  188. * CPU_SW_Exception()
  189. *
  190. * Description : Trap unrecoverable software exception.
  191. *
  192. * Argument(s) : none.
  193. *
  194. * Return(s) : none.
  195. *
  196. * Caller(s) : various.
  197. *
  198. * Note(s) : (1) CPU_SW_Exception() deadlocks the current code execution -- whether multi-tasked/
  199. * -processed/-threaded or single-threaded -- when the current code execution cannot
  200. * gracefully recover or report a fault or exception condition.
  201. *
  202. * See also 'cpu_core.h CPU_SW_EXCEPTION() Note #1'.
  203. *********************************************************************************************************
  204. */
  205. void CPU_SW_Exception (void)
  206. {
  207. while (DEF_ON) {
  208. ;
  209. }
  210. }
  211. /*
  212. *********************************************************************************************************
  213. * CPU_NameClr()
  214. *
  215. * Description : Clear CPU Name.
  216. *
  217. * Argument(s) : none.
  218. *
  219. * Return(s) : none.
  220. *
  221. * Caller(s) : CPU_NameInit(),
  222. * Application.
  223. *
  224. * This function is a CPU module application programming interface (API) function & MAY be
  225. * called by application function(s).
  226. *
  227. * Note(s) : none.
  228. *********************************************************************************************************
  229. */
  230. #if (CPU_CFG_NAME_EN == DEF_ENABLED)
  231. void CPU_NameClr (void)
  232. {
  233. CPU_SR_ALLOC();
  234. CPU_CRITICAL_ENTER();
  235. Mem_Clr((void *)&CPU_Name[0],
  236. (CPU_SIZE_T) CPU_CFG_NAME_SIZE);
  237. CPU_CRITICAL_EXIT();
  238. }
  239. #endif
  240. /*
  241. *********************************************************************************************************
  242. * CPU_NameGet()
  243. *
  244. * Description : Get CPU host name.
  245. *
  246. * Argument(s) : p_name Pointer to an ASCII character array that will receive the return CPU host
  247. * name ASCII string from this function (see Note #1).
  248. *
  249. * p_err Pointer to variable that will receive the return error code from this function :
  250. *
  251. * CPU_ERR_NONE CPU host name successfully returned.
  252. * CPU_ERR_NULL_PTR Argument 'p_name' passed a NULL pointer.
  253. *
  254. * Return(s) : none.
  255. *
  256. * Caller(s) : Application.
  257. *
  258. * This function is a CPU module application programming interface (API) function & MAY
  259. * be called by application function(s).
  260. *
  261. * Note(s) : (1) The size of the ASCII character array that will receive the return CPU host name
  262. * ASCII string :
  263. *
  264. * (a) MUST be greater than or equal to the current CPU host name's ASCII string
  265. * size including the terminating NULL character;
  266. * (b) SHOULD be greater than or equal to CPU_CFG_NAME_SIZE
  267. *********************************************************************************************************
  268. */
  269. #if (CPU_CFG_NAME_EN == DEF_ENABLED)
  270. void CPU_NameGet (CPU_CHAR *p_name,
  271. CPU_ERR *p_err)
  272. {
  273. CPU_SR_ALLOC();
  274. if (p_err == (CPU_ERR *)0) {
  275. CPU_SW_EXCEPTION(;);
  276. }
  277. if (p_name == (CPU_CHAR *)0) {
  278. *p_err = CPU_ERR_NULL_PTR;
  279. return;
  280. }
  281. CPU_CRITICAL_ENTER();
  282. (void)Str_Copy_N(p_name,
  283. &CPU_Name[0],
  284. CPU_CFG_NAME_SIZE);
  285. CPU_CRITICAL_EXIT();
  286. *p_err = CPU_ERR_NONE;
  287. }
  288. #endif
  289. /*
  290. *********************************************************************************************************
  291. * CPU_NameSet()
  292. *
  293. * Description : Set CPU host name.
  294. *
  295. * Argument(s) : p_name Pointer to CPU host name to set.
  296. *
  297. * p_err Pointer to variable that will receive the return error code from this function :
  298. *
  299. * CPU_ERR_NONE CPU host name successfully set.
  300. * CPU_ERR_NULL_PTR Argument 'p_name' passed a NULL pointer.
  301. * CPU_ERR_NAME_SIZE Invalid CPU host name size (see Note #1).
  302. *
  303. * Return(s) : none.
  304. *
  305. * Caller(s) : Application.
  306. *
  307. * This function is a CPU module application programming interface (API) function & MAY be
  308. * called by application function(s).
  309. *
  310. * Note(s) : (1) 'p_name' ASCII string size, including the terminating NULL character, MUST be less
  311. * than or equal to CPU_CFG_NAME_SIZE.
  312. *********************************************************************************************************
  313. */
  314. #if (CPU_CFG_NAME_EN == DEF_ENABLED)
  315. void CPU_NameSet (const CPU_CHAR *p_name,
  316. CPU_ERR *p_err)
  317. {
  318. CPU_SIZE_T len;
  319. CPU_SR_ALLOC();
  320. if (p_err == (CPU_ERR *)0) {
  321. CPU_SW_EXCEPTION(;);
  322. }
  323. if (p_name == (const CPU_CHAR *)0) {
  324. *p_err = CPU_ERR_NULL_PTR;
  325. return;
  326. }
  327. len = Str_Len_N(p_name,
  328. CPU_CFG_NAME_SIZE);
  329. if (len < CPU_CFG_NAME_SIZE) { /* If cfg name len < max name size, ... */
  330. CPU_CRITICAL_ENTER();
  331. (void)Str_Copy_N(&CPU_Name[0], /* ... copy cfg name to CPU host name. */
  332. p_name,
  333. CPU_CFG_NAME_SIZE);
  334. CPU_CRITICAL_EXIT();
  335. *p_err = CPU_ERR_NONE;
  336. } else {
  337. *p_err = CPU_ERR_NAME_SIZE;
  338. }
  339. }
  340. #endif
  341. /*
  342. *********************************************************************************************************
  343. * CPU_TS_Get32()
  344. *
  345. * Description : Get current 32-bit CPU timestamp.
  346. *
  347. * Argument(s) : none.
  348. *
  349. * Return(s) : Current 32-bit CPU timestamp (in timestamp timer counts).
  350. *
  351. * Caller(s) : Application.
  352. *
  353. * This function is a CPU module application programming interface (API) function & MAY
  354. * be called by application function(s).
  355. *
  356. * Note(s) : (1) When applicable, the amount of time measured by CPU timestamps is calculated by
  357. * either of the following equations :
  358. *
  359. * (a) Time measured = Number timer counts * Timer period
  360. *
  361. * where
  362. *
  363. * Number timer counts Number of timer counts measured
  364. * Timer period Timer's period in some units of
  365. * (fractional) seconds
  366. * Time measured Amount of time measured, in same
  367. * units of (fractional) seconds
  368. * as the Timer period
  369. *
  370. * Number timer counts
  371. * (b) Time measured = ---------------------
  372. * Timer frequency
  373. *
  374. * where
  375. *
  376. * Number timer counts Number of timer counts measured
  377. * Timer frequency Timer's frequency in some units
  378. * of counts per second
  379. * Time measured Amount of time measured, in seconds
  380. *
  381. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c1'.
  382. *
  383. * (2) In case the CPU timestamp timer has lower precision than the 32-bit CPU timestamp;
  384. * its precision is extended via periodic updates by accumulating the deltas of the
  385. * timestamp timer count values into the higher-precision 32-bit CPU timestamp.
  386. *
  387. * (3) After initialization, 'CPU_TS_32_Accum' & 'CPU_TS_32_TmrPrev' MUST ALWAYS
  388. * be accessed AND updated exclusively with interrupts disabled -- but NOT
  389. * with critical sections.
  390. *********************************************************************************************************
  391. */
  392. #if (CPU_CFG_TS_32_EN == DEF_ENABLED)
  393. CPU_TS32 CPU_TS_Get32 (void)
  394. {
  395. CPU_TS32 ts;
  396. #if (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
  397. CPU_TS_TMR tmr_cur;
  398. CPU_TS_TMR tmr_delta;
  399. CPU_SR_ALLOC();
  400. #endif
  401. #if (CPU_CFG_TS_TMR_SIZE >= CPU_WORD_SIZE_32)
  402. ts = (CPU_TS32)CPU_TS_TmrRd(); /* Get cur ts tmr val (in 32-bit ts cnts). */
  403. #else
  404. CPU_INT_DIS();
  405. tmr_cur = (CPU_TS_TMR) CPU_TS_TmrRd(); /* Get cur ts tmr val (in ts tmr cnts). */
  406. tmr_delta = (CPU_TS_TMR)(tmr_cur - CPU_TS_32_TmrPrev); /* Calc delta ts tmr cnts. */
  407. CPU_TS_32_Accum += (CPU_TS32 ) tmr_delta; /* Inc ts by delta ts tmr cnts (see Note #2). */
  408. CPU_TS_32_TmrPrev = (CPU_TS_TMR) tmr_cur; /* Save cur ts tmr cnts for next update. */
  409. ts = (CPU_TS32 ) CPU_TS_32_Accum;
  410. CPU_INT_EN();
  411. #endif
  412. return (ts);
  413. }
  414. #endif
  415. /*
  416. *********************************************************************************************************
  417. * CPU_TS_Get64()
  418. *
  419. * Description : Get current 64-bit CPU timestamp.
  420. *
  421. * Argument(s) : none.
  422. *
  423. * Return(s) : Current 64-bit CPU timestamp (in timestamp timer counts).
  424. *
  425. * Caller(s) : Application.
  426. *
  427. * This function is a CPU module application programming interface (API) function & MAY
  428. * be called by application function(s).
  429. *
  430. * Note(s) : (1) When applicable, the amount of time measured by CPU timestamps is calculated by
  431. * either of the following equations :
  432. *
  433. * (a) Time measured = Number timer counts * Timer period
  434. *
  435. * where
  436. *
  437. * Number timer counts Number of timer counts measured
  438. * Timer period Timer's period in some units of
  439. * (fractional) seconds
  440. * Time measured Amount of time measured, in same
  441. * units of (fractional) seconds
  442. * as the Timer period
  443. *
  444. * Number timer counts
  445. * (b) Time measured = ---------------------
  446. * Timer frequency
  447. *
  448. * where
  449. *
  450. * Number timer counts Number of timer counts measured
  451. * Timer frequency Timer's frequency in some units
  452. * of counts per second
  453. * Time measured Amount of time measured, in seconds
  454. *
  455. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c1'.
  456. *
  457. * (2) In case the CPU timestamp timer has lower precision than the 64-bit CPU timestamp;
  458. * its precision is extended via periodic updates by accumulating the deltas of the
  459. * timestamp timer count values into the higher-precision 64-bit CPU timestamp.
  460. *
  461. * (3) After initialization, 'CPU_TS_64_Accum' & 'CPU_TS_64_TmrPrev' MUST ALWAYS
  462. * be accessed AND updated exclusively with interrupts disabled -- but NOT
  463. * with critical sections.
  464. *********************************************************************************************************
  465. */
  466. #if (CPU_CFG_TS_64_EN == DEF_ENABLED)
  467. CPU_TS64 CPU_TS_Get64 (void)
  468. {
  469. CPU_TS64 ts;
  470. #if (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)
  471. CPU_TS_TMR tmr_cur;
  472. CPU_TS_TMR tmr_delta;
  473. CPU_SR_ALLOC();
  474. #endif
  475. #if (CPU_CFG_TS_TMR_SIZE >= CPU_WORD_SIZE_64)
  476. ts = (CPU_TS64)CPU_TS_TmrRd(); /* Get cur ts tmr val (in 64-bit ts cnts). */
  477. #else
  478. CPU_INT_DIS();
  479. tmr_cur = (CPU_TS_TMR) CPU_TS_TmrRd(); /* Get cur ts tmr val (in ts tmr cnts). */
  480. tmr_delta = (CPU_TS_TMR)(tmr_cur - CPU_TS_64_TmrPrev); /* Calc delta ts tmr cnts. */
  481. CPU_TS_64_Accum += (CPU_TS64 ) tmr_delta; /* Inc ts by delta ts tmr cnts (see Note #2). */
  482. CPU_TS_64_TmrPrev = (CPU_TS_TMR) tmr_cur; /* Save cur ts tmr cnts for next update. */
  483. ts = (CPU_TS64 ) CPU_TS_64_Accum;
  484. CPU_INT_EN();
  485. #endif
  486. return (ts);
  487. }
  488. #endif
  489. /*
  490. *********************************************************************************************************
  491. * CPU_TS_Update()
  492. *
  493. * Description : Update current CPU timestamp(s).
  494. *
  495. * Argument(s) : none.
  496. *
  497. * Return(s) : none.
  498. *
  499. * Caller(s) : Application/BSP periodic time handler (see Note #1).
  500. *
  501. * This function is a CPU timestamp BSP function & SHOULD be called only by appropriate
  502. * application/BSP function(s).
  503. *
  504. * Note(s) : (1) (a) CPU timestamp(s) MUST be updated periodically by some application (or BSP) time
  505. * handler in order to (adequately) maintain CPU timestamp(s)' time.
  506. *
  507. * (b) CPU timestamp(s) MUST be updated more frequently than the CPU timestamp timer
  508. * overflows; otherwise, CPU timestamp(s) will lose time.
  509. *
  510. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c2'.
  511. *********************************************************************************************************
  512. */
  513. #if (CPU_CFG_TS_EN == DEF_ENABLED)
  514. void CPU_TS_Update (void)
  515. {
  516. #if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \
  517. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32))
  518. (void)CPU_TS_Get32();
  519. #endif
  520. #if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \
  521. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64))
  522. (void)CPU_TS_Get64();
  523. #endif
  524. }
  525. #endif
  526. /*
  527. *********************************************************************************************************
  528. * CPU_TS_TmrFreqGet()
  529. *
  530. * Description : Get CPU timestamp's timer frequency.
  531. *
  532. * Argument(s) : p_err Pointer to variable that will receive the return error code from this function :
  533. *
  534. * CPU_ERR_NONE CPU timestamp's timer frequency successfully
  535. * returned.
  536. * CPU_ERR_TS_FREQ_INVALID CPU timestamp's timer frequency invalid &/or
  537. * NOT yet configured.
  538. *
  539. * Return(s) : CPU timestamp's timer frequency (in Hertz), if NO error(s).
  540. *
  541. * 0, otherwise.
  542. *
  543. * Caller(s) : Application.
  544. *
  545. * This function is a CPU module application programming interface (API) function & MAY be
  546. * called by application function(s).
  547. *
  548. * Note(s) : none.
  549. *********************************************************************************************************
  550. */
  551. #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
  552. CPU_TS_TMR_FREQ CPU_TS_TmrFreqGet (CPU_ERR *p_err)
  553. {
  554. CPU_TS_TMR_FREQ freq_hz;
  555. if (p_err == (CPU_ERR *)0) {
  556. CPU_SW_EXCEPTION(;);
  557. }
  558. freq_hz = CPU_TS_TmrFreq_Hz;
  559. *p_err = (freq_hz != 0u) ? CPU_ERR_NONE : CPU_ERR_TS_FREQ_INVALID;
  560. return (freq_hz);
  561. }
  562. #endif
  563. /*
  564. *********************************************************************************************************
  565. * CPU_TS_TmrFreqSet()
  566. *
  567. * Description : Set CPU timestamp's timer frequency.
  568. *
  569. * Argument(s) : freq_hz Frequency (in Hertz) to set for CPU timestamp's timer.
  570. *
  571. * Return(s) : none.
  572. *
  573. * Caller(s) : CPU_TS_TmrInit(),
  574. * Application/BSP initialization function(s).
  575. *
  576. * This function is a CPU module BSP function & SHOULD be called only by appropriate
  577. * application/BSP function(s) [see Note #1].
  578. *
  579. * Note(s) : (1) (a) (1) CPU timestamp timer frequency is NOT required for internal CPU timestamp
  580. * operations but may OPTIONALLY be configured by CPU_TS_TmrInit() or other
  581. * application/BSP initialization functions.
  582. *
  583. * (2) CPU timestamp timer frequency MAY be used with optional CPU_TSxx_to_uSec()
  584. * to convert CPU timestamps from timer counts into microseconds.
  585. *
  586. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2a'.
  587. *
  588. * (b) CPU timestamp timer period SHOULD be less than the typical measured time but MUST
  589. * be less than the maximum measured time; otherwise, timer resolution inadequate to
  590. * measure desired times.
  591. *
  592. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2b'.
  593. *********************************************************************************************************
  594. */
  595. #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
  596. void CPU_TS_TmrFreqSet (CPU_TS_TMR_FREQ freq_hz)
  597. {
  598. CPU_TS_TmrFreq_Hz = freq_hz;
  599. }
  600. #endif
  601. /*
  602. *********************************************************************************************************
  603. * CPU_IntDisMeasMaxCurReset()
  604. *
  605. * Description : Reset current maximum interrupts disabled time.
  606. *
  607. * Argument(s) : none.
  608. *
  609. * Return(s) : Maximum interrupts disabled time (in CPU timestamp timer counts) before resetting.
  610. *
  611. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
  612. * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
  613. *
  614. * Caller(s) : Application.
  615. *
  616. * This function is a CPU module application programming interface (API) function
  617. * & MAY be called by application function(s).
  618. *
  619. * Note(s) : (1) After initialization, 'CPU_IntDisMeasMaxCur_cnts' MUST ALWAYS be accessed
  620. * exclusively with interrupts disabled -- but NOT with critical sections.
  621. *********************************************************************************************************
  622. */
  623. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  624. CPU_TS_TMR CPU_IntDisMeasMaxCurReset (void)
  625. {
  626. CPU_TS_TMR time_max_cnts;
  627. CPU_SR_ALLOC();
  628. time_max_cnts = CPU_IntDisMeasMaxCurGet();
  629. CPU_INT_DIS();
  630. CPU_IntDisMeasMaxCur_cnts = 0u;
  631. CPU_INT_EN();
  632. return (time_max_cnts);
  633. }
  634. #endif
  635. /*
  636. *********************************************************************************************************
  637. * CPU_IntDisMeasMaxCurGet()
  638. *
  639. * Description : Get current maximum interrupts disabled time.
  640. *
  641. * Argument(s) : none.
  642. *
  643. * Return(s) : Current maximum interrupts disabled time (in CPU timestamp timer counts).
  644. *
  645. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
  646. * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
  647. *
  648. * Caller(s) : CPU_IntDisMeasMaxCurReset(),
  649. * Application.
  650. *
  651. * This function is a CPU module application programming interface (API) function
  652. * & MAY be called by application function(s).
  653. *
  654. * Note(s) : (1) After initialization, 'CPU_IntDisMeasMaxCur_cnts' MUST ALWAYS be accessed
  655. * exclusively with interrupts disabled -- but NOT with critical sections.
  656. *********************************************************************************************************
  657. */
  658. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  659. CPU_TS_TMR CPU_IntDisMeasMaxCurGet (void)
  660. {
  661. CPU_TS_TMR time_tot_cnts;
  662. CPU_TS_TMR time_max_cnts;
  663. CPU_SR_ALLOC();
  664. CPU_INT_DIS();
  665. time_tot_cnts = CPU_IntDisMeasMaxCur_cnts;
  666. CPU_INT_EN();
  667. time_max_cnts = CPU_IntDisMeasMaxCalc(time_tot_cnts);
  668. return (time_max_cnts);
  669. }
  670. #endif
  671. /*
  672. *********************************************************************************************************
  673. * CPU_IntDisMeasMaxGet()
  674. *
  675. * Description : Get (non-resetable) maximum interrupts disabled time.
  676. *
  677. * Argument(s) : none.
  678. *
  679. * Return(s) : (Non-resetable) maximum interrupts disabled time (in CPU timestamp timer counts).
  680. *
  681. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
  682. * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
  683. *
  684. * Caller(s) : CPU_IntDisMeasInit(),
  685. * Application.
  686. *
  687. * This function is a CPU module application programming interface (API) function
  688. * & MAY be called by application function(s).
  689. *
  690. * Note(s) : (1) After initialization, 'CPU_IntDisMeasMax_cnts' MUST ALWAYS be accessed
  691. * exclusively with interrupts disabled -- but NOT with critical sections.
  692. *********************************************************************************************************
  693. */
  694. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  695. CPU_TS_TMR CPU_IntDisMeasMaxGet (void)
  696. {
  697. CPU_TS_TMR time_tot_cnts;
  698. CPU_TS_TMR time_max_cnts;
  699. CPU_SR_ALLOC();
  700. CPU_INT_DIS();
  701. time_tot_cnts = CPU_IntDisMeasMax_cnts;
  702. CPU_INT_EN();
  703. time_max_cnts = CPU_IntDisMeasMaxCalc(time_tot_cnts);
  704. return (time_max_cnts);
  705. }
  706. #endif
  707. /*
  708. *********************************************************************************************************
  709. * CPU_IntDisMeasStart()
  710. *
  711. * Description : Start interrupts disabled time measurement.
  712. *
  713. * Argument(s) : none.
  714. *
  715. * Return(s) : none.
  716. *
  717. * Caller(s) : CPU_CRITICAL_ENTER().
  718. *
  719. * This function is an INTERNAL CPU module function & MUST NOT be called by application
  720. * function(s).
  721. *
  722. * Note(s) : none.
  723. *********************************************************************************************************
  724. */
  725. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  726. void CPU_IntDisMeasStart (void)
  727. {
  728. CPU_IntDisMeasCtr++;
  729. if (CPU_IntDisNestCtr == 0u) { /* If ints NOT yet dis'd, ... */
  730. CPU_IntDisMeasStart_cnts = CPU_TS_TmrRd(); /* ... get ints dis'd start time. */
  731. }
  732. CPU_IntDisNestCtr++;
  733. }
  734. #endif
  735. /*
  736. *********************************************************************************************************
  737. * CPU_IntDisMeasStop()
  738. *
  739. * Description : Stop interrupts disabled time measurement.
  740. *
  741. * Argument(s) : none.
  742. *
  743. * Return(s) : none.
  744. *
  745. * Caller(s) : CPU_CRITICAL_EXIT().
  746. *
  747. * This function is an INTERNAL CPU module function & MUST NOT be called by application
  748. * function(s).
  749. *
  750. * Note(s) : (1) (a) The total amount of time interrupts are disabled by system &/or application code
  751. * during critical sections is calculated by the following equations :
  752. *
  753. * (1) When interrupts disabled time measurements are disabled :
  754. *
  755. *
  756. * | CRITICAL | | CRITICAL |
  757. * |<- SECTION ->| |<- SECTION ->|
  758. * | ENTER | | EXIT |
  759. *
  760. * Disable Enable
  761. * Interrupts Interrupts
  762. *
  763. * || || || ||
  764. * || || || ||
  765. * || | ||<------------------------->|| | ||
  766. * || |<->|| | ||<----->| ||
  767. * || | | || | || | | ||
  768. * | | | | |
  769. * interrupts time interrupts
  770. * disabled interrupts |enabled
  771. * | disabled |
  772. * | (via application) |
  773. * time time
  774. * interrupts interrupts
  775. * disabled ovrhd enabled ovrhd
  776. *
  777. *
  778. * (A) time = [ time - time ] - time
  779. * interrupts [ interrupts interrupts ] total
  780. * disabled [ enabled disabled ] ovrhd
  781. * (via application)
  782. *
  783. *
  784. * (B) time = time + time
  785. * total interrupts interrupts
  786. * ovrhd enabled ovrhd disabled ovrhd
  787. *
  788. *
  789. * where
  790. *
  791. * time time interrupts are disabled between
  792. * interrupts first critical section enter &
  793. * disabled last critical section exit (i.e.
  794. * (via application) minus total overhead time)
  795. *
  796. * time time when interrupts are disabled
  797. * interrupts
  798. * disabled
  799. *
  800. * time time when interrupts are enabled
  801. * interrupts
  802. * enabled
  803. *
  804. *
  805. * time total overhead time to disable/enable
  806. * total interrupts during critical section
  807. * ovrhd enter & exit
  808. *
  809. * time total overhead time to disable interrupts
  810. * interrupts during critical section enter
  811. * disabled ovrhd
  812. *
  813. * time total overhead time to enable interrupts
  814. * interrupts during critical section exit
  815. * enabled ovrhd
  816. *
  817. *
  818. * (2) When interrupts disabled time measurements are enabled :
  819. *
  820. *
  821. * | | | |
  822. * |<----- CRITICAL SECTION ENTER ----->| |<------- CRITICAL SECTION EXIT ------->|
  823. * | | | |
  824. *
  825. * Time Time
  826. * Disable Measurement Measurement Enable
  827. * Interrupts Start Stop Interrupts
  828. *
  829. * || | || || | ||
  830. * || | || || | ||
  831. * || | | ||<------------------------->|| | | ||
  832. * || | | |<----------->|| | ||<------------->| | | ||
  833. * || | | | | || | || | | | | ||
  834. * | | | | | | |
  835. * interrupts get | time | get interrupts
  836. * disabled start time | interrupts | stop time enabled
  837. * meas | disabled | meas
  838. * time (via application) time
  839. * start meas stop meas
  840. * ovrhd ovrhd
  841. *
  842. *
  843. * (A) time = [ time - time ] - time
  844. * interrupts [ stop start ] total meas
  845. * disabled [ meas meas ] ovrhd
  846. * (via application)
  847. *
  848. *
  849. * (B) time = time + time
  850. * total meas start meas stop meas
  851. * ovrhd ovrhd ovrhd
  852. *
  853. *
  854. * where
  855. *
  856. * time time interrupts are disabled between first
  857. * interrupts critical section enter & last critical
  858. * disabled section exit (i.e. minus measurement
  859. * (via application) overhead time; however, this does NOT
  860. * include any overhead time to disable
  861. * or enable interrupts during critical
  862. * section enter & exit)
  863. *
  864. * time time of disable interrupts start time
  865. * start measurement (in timer counts)
  866. * meas
  867. *
  868. * time time of disable interrupts stop time
  869. * stop measurement (in timer counts)
  870. * meas
  871. *
  872. *
  873. * time total overhead time to start/stop disabled
  874. * total meas interrupts time measurements (in timer
  875. * ovrhd counts)
  876. *
  877. * time total overhead time after getting start
  878. * start meas time until end of start measurement
  879. * ovrhd function (in timer counts)
  880. *
  881. * time total overhead time from beginning of stop
  882. * stop meas measurement function until after getting
  883. * ovrhd stop time (in timer counts)
  884. *
  885. *
  886. * (b) (1) (A) In order to correctly handle unsigned subtraction overflows of start times
  887. * from stop times, CPU timestamp timer count values MUST be returned via
  888. * word-size-configurable 'CPU_TS_TMR' data type.
  889. *
  890. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'.
  891. *
  892. * (B) Since unsigned subtraction of start times from stop times assumes increasing
  893. * values, timestamp timer count values MUST increase with each time count.
  894. *
  895. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2b'.
  896. *
  897. * (2) (A) To expedite & reduce interrupts disabled time measurement overhead; only the
  898. * subtraction of start times from stop times is performed.
  899. *
  900. * (B) The final calculations to subtract the interrupts disabled time measurement
  901. * overhead is performed asynchronously in appropriate API functions.
  902. *
  903. * See also 'CPU_IntDisMeasMaxCalc() Note #1b'.
  904. *********************************************************************************************************
  905. */
  906. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  907. void CPU_IntDisMeasStop (void)
  908. {
  909. CPU_TS_TMR time_ints_disd_cnts;
  910. CPU_IntDisNestCtr--;
  911. if (CPU_IntDisNestCtr == 0u) { /* If ints NO longer dis'd, ... */
  912. CPU_IntDisMeasStop_cnts = CPU_TS_TmrRd(); /* ... get ints dis'd stop time & ... */
  913. /* ... calc ints dis'd tot time (see Note #1b2A). */
  914. time_ints_disd_cnts = CPU_IntDisMeasStop_cnts -
  915. CPU_IntDisMeasStart_cnts;
  916. /* Calc max ints dis'd times. */
  917. if (CPU_IntDisMeasMaxCur_cnts < time_ints_disd_cnts) {
  918. CPU_IntDisMeasMaxCur_cnts = time_ints_disd_cnts;
  919. }
  920. if (CPU_IntDisMeasMax_cnts < time_ints_disd_cnts) {
  921. CPU_IntDisMeasMax_cnts = time_ints_disd_cnts;
  922. }
  923. }
  924. }
  925. #endif
  926. /*
  927. *********************************************************************************************************
  928. * CPU_CntLeadZeros()
  929. *
  930. * Description : Count the number of contiguous, most-significant, leading zero bits in a data value.
  931. *
  932. * Argument(s) : val Data value to count leading zero bits.
  933. *
  934. * Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s).
  935. *
  936. * DEF_INT_CPU_U_MAX_VAL, otherwise.
  937. *
  938. * Caller(s) : CPU_CntTrailZeros(),
  939. * Application.
  940. *
  941. * This function is a CPU module application programming interface (API) function & MAY
  942. * be called by application function(s).
  943. *
  944. * Note(s) : (1) (a) Supports the following data value sizes :
  945. *
  946. * (1) 8-bits
  947. * (2) 16-bits
  948. * (3) 32-bits
  949. * (4) 64-bits
  950. *
  951. * See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'.
  952. *
  953. * (b) (1) For 8-bit values :
  954. *
  955. * b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros
  956. * --- --- --- --- --- --- --- --- ---------------
  957. * 1 x x x x x x x 0
  958. * 0 1 x x x x x x 1
  959. * 0 0 1 x x x x x 2
  960. * 0 0 0 1 x x x x 3
  961. * 0 0 0 0 1 x x x 4
  962. * 0 0 0 0 0 1 x x 5
  963. * 0 0 0 0 0 0 1 x 6
  964. * 0 0 0 0 0 0 0 1 7
  965. * 0 0 0 0 0 0 0 0 8
  966. *
  967. *
  968. * (2) For 16-bit values :
  969. *
  970. * b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros
  971. * --- --- --- --- --- --- --- --- ---------------
  972. * 1 x x x x x x x 0
  973. * 0 1 x x x x x x 1
  974. * 0 0 1 x x x x x 2
  975. * : : : : : : : : :
  976. * : : : : : : : : :
  977. * 0 0 0 1 x x x x 11
  978. * 0 0 0 0 1 x x x 12
  979. * 0 0 0 0 0 1 x x 13
  980. * 0 0 0 0 0 0 1 x 14
  981. * 0 0 0 0 0 0 0 1 15
  982. * 0 0 0 0 0 0 0 0 16
  983. *
  984. * (3) For 32-bit values :
  985. *
  986. * b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros
  987. * --- --- --- --- --- --- --- --- ---------------
  988. * 1 x x x x x x x 0
  989. * 0 1 x x x x x x 1
  990. * 0 0 1 x x x x x 2
  991. * : : : : : : : : :
  992. * : : : : : : : : :
  993. * 0 0 0 1 x x x x 27
  994. * 0 0 0 0 1 x x x 28
  995. * 0 0 0 0 0 1 x x 29
  996. * 0 0 0 0 0 0 1 x 30
  997. * 0 0 0 0 0 0 0 1 31
  998. * 0 0 0 0 0 0 0 0 32
  999. *
  1000. *
  1001. * (4) For 64-bit values :
  1002. *
  1003. * b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros
  1004. * --- --- --- --- --- --- --- --- ---------------
  1005. * 1 x x x x x x x 0
  1006. * 0 1 x x x x x x 1
  1007. * 0 0 1 x x x x x 2
  1008. * : : : : : : : : :
  1009. * : : : : : : : : :
  1010. * 0 0 0 1 x x x x 59
  1011. * 0 0 0 0 1 x x x 60
  1012. * 0 0 0 0 0 1 x x 61
  1013. * 0 0 0 0 0 0 1 x 62
  1014. * 0 0 0 0 0 0 0 1 63
  1015. * 0 0 0 0 0 0 0 0 64
  1016. *
  1017. *
  1018. * See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
  1019. *********************************************************************************************************
  1020. */
  1021. #ifndef CPU_CFG_LEAD_ZEROS_ASM_PRESENT
  1022. CPU_DATA CPU_CntLeadZeros (CPU_DATA val)
  1023. {
  1024. CPU_DATA nbr_lead_zeros;
  1025. #if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_08)
  1026. nbr_lead_zeros = CPU_CntLeadZeros08((CPU_INT08U)val);
  1027. #elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16)
  1028. nbr_lead_zeros = CPU_CntLeadZeros16((CPU_INT16U)val);
  1029. #elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)
  1030. nbr_lead_zeros = CPU_CntLeadZeros32((CPU_INT32U)val);
  1031. #elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64)
  1032. nbr_lead_zeros = CPU_CntLeadZeros64((CPU_INT64U)val);
  1033. #else /* See Note #1a. */
  1034. nbr_lead_zeros = DEF_INT_CPU_U_MAX_VAL;
  1035. #endif
  1036. return (nbr_lead_zeros);
  1037. }
  1038. #endif
  1039. /*
  1040. *********************************************************************************************************
  1041. * CPU_CntLeadZeros08()
  1042. *
  1043. * Description : Count the number of contiguous, most-significant, leading zero bits in an 8-bit data value.
  1044. *
  1045. * Argument(s) : val Data value to count leading zero bits.
  1046. *
  1047. * Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
  1048. *
  1049. * Caller(s) : CPU_CntLeadZeros(),
  1050. * CPU_CntTrailZeros08(),
  1051. * Application.
  1052. *
  1053. * This function is a CPU module application programming interface (API) function & MAY be
  1054. * called by application function(s).
  1055. *
  1056. * Note(s) : (1) Supports 8-bit values :
  1057. *
  1058. * b07 b06 b05 b04 b03 b02 b01 b00 # Leading Zeros
  1059. * --- --- --- --- --- --- --- --- ---------------
  1060. * 1 x x x x x x x 0
  1061. * 0 1 x x x x x x 1
  1062. * 0 0 1 x x x x x 2
  1063. * 0 0 0 1 x x x x 3
  1064. * 0 0 0 0 1 x x x 4
  1065. * 0 0 0 0 0 1 x x 5
  1066. * 0 0 0 0 0 0 1 x 6
  1067. * 0 0 0 0 0 0 0 1 7
  1068. * 0 0 0 0 0 0 0 0 8
  1069. *
  1070. *
  1071. * See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
  1072. *********************************************************************************************************
  1073. */
  1074. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_08)
  1075. CPU_DATA CPU_CntLeadZeros08 (CPU_INT08U val)
  1076. {
  1077. #if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1078. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08)))
  1079. CPU_DATA ix;
  1080. #endif
  1081. CPU_DATA nbr_lead_zeros;
  1082. /* ---------- ASM-OPTIMIZED ----------- */
  1083. #if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1084. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08))
  1085. nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val);
  1086. nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_08) * DEF_OCTET_NBR_BITS;
  1087. #else /* ----------- C-OPTIMIZED ------------ */
  1088. /* Chk bits [07:00] : */
  1089. /* .. Nbr lead zeros = .. */
  1090. ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */
  1091. nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/
  1092. #endif
  1093. return (nbr_lead_zeros);
  1094. }
  1095. #endif
  1096. /*
  1097. *********************************************************************************************************
  1098. * CPU_CntLeadZeros16()
  1099. *
  1100. * Description : Count the number of contiguous, most-significant, leading zero bits in a 16-bit data value.
  1101. *
  1102. * Argument(s) : val Data value to count leading zero bits.
  1103. *
  1104. * Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
  1105. *
  1106. * Caller(s) : CPU_CntLeadZeros(),
  1107. * CPU_CntTrailZeros16(),
  1108. * Application.
  1109. *
  1110. * This function is a CPU module application programming interface (API) function & MAY be
  1111. * called by application function(s).
  1112. *
  1113. * Note(s) : (1) Supports 16-bit values :
  1114. *
  1115. * b15 b14 b13 ... b04 b03 b02 b01 b00 # Leading Zeros
  1116. * --- --- --- --- --- --- --- --- ---------------
  1117. * 1 x x x x x x x 0
  1118. * 0 1 x x x x x x 1
  1119. * 0 0 1 x x x x x 2
  1120. * : : : : : : : : :
  1121. * : : : : : : : : :
  1122. * 0 0 0 1 x x x x 11
  1123. * 0 0 0 0 1 x x x 12
  1124. * 0 0 0 0 0 1 x x 13
  1125. * 0 0 0 0 0 0 1 x 14
  1126. * 0 0 0 0 0 0 0 1 15
  1127. * 0 0 0 0 0 0 0 0 16
  1128. *
  1129. *
  1130. * See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
  1131. *********************************************************************************************************
  1132. */
  1133. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_16)
  1134. CPU_DATA CPU_CntLeadZeros16 (CPU_INT16U val)
  1135. {
  1136. #if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1137. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16)))
  1138. CPU_DATA ix;
  1139. #endif
  1140. CPU_DATA nbr_lead_zeros;
  1141. /* ---------- ASM-OPTIMIZED ----------- */
  1142. #if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1143. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16))
  1144. nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val);
  1145. nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_16) * DEF_OCTET_NBR_BITS;
  1146. #else /* ----------- C-OPTIMIZED ------------ */
  1147. if (val > 0x00FFu) { /* Chk bits [15:08] : */
  1148. /* .. Nbr lead zeros = .. */
  1149. ix = (CPU_DATA)((CPU_DATA)val >> 8u); /* .. lookup tbl ix = 'val' >> 8 bits */
  1150. nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/
  1151. } else { /* Chk bits [07:00] : */
  1152. /* .. Nbr lead zeros = .. */
  1153. ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */
  1154. nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 8u); /* .. plus nbr msb lead zeros = 8 bits.*/
  1155. }
  1156. #endif
  1157. return (nbr_lead_zeros);
  1158. }
  1159. #endif
  1160. /*
  1161. *********************************************************************************************************
  1162. * CPU_CntLeadZeros32()
  1163. *
  1164. * Description : Count the number of contiguous, most-significant, leading zero bits in a 32-bit data value.
  1165. *
  1166. * Argument(s) : val Data value to count leading zero bits.
  1167. *
  1168. * Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
  1169. *
  1170. * Caller(s) : CPU_CntLeadZeros(),
  1171. * CPU_CntTrailZeros32(),
  1172. * Application.
  1173. *
  1174. * This function is a CPU module application programming interface (API) function & MAY be
  1175. * called by application function(s).
  1176. *
  1177. * Note(s) : (1) Supports 32-bit values :
  1178. *
  1179. * b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros
  1180. * --- --- --- --- --- --- --- --- ---------------
  1181. * 1 x x x x x x x 0
  1182. * 0 1 x x x x x x 1
  1183. * 0 0 1 x x x x x 2
  1184. * : : : : : : : : :
  1185. * : : : : : : : : :
  1186. * 0 0 0 1 x x x x 27
  1187. * 0 0 0 0 1 x x x 28
  1188. * 0 0 0 0 0 1 x x 29
  1189. * 0 0 0 0 0 0 1 x 30
  1190. * 0 0 0 0 0 0 0 1 31
  1191. * 0 0 0 0 0 0 0 0 32
  1192. *
  1193. *
  1194. * See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
  1195. *********************************************************************************************************
  1196. */
  1197. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_32)
  1198. CPU_DATA CPU_CntLeadZeros32 (CPU_INT32U val)
  1199. {
  1200. #if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1201. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32)))
  1202. CPU_DATA ix;
  1203. #endif
  1204. CPU_DATA nbr_lead_zeros;
  1205. /* ---------- ASM-OPTIMIZED ----------- */
  1206. #if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1207. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32))
  1208. nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val);
  1209. nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_32) * DEF_OCTET_NBR_BITS;
  1210. #else /* ----------- C-OPTIMIZED ------------ */
  1211. if (val > 0x0000FFFFu) {
  1212. if (val > 0x00FFFFFFu) { /* Chk bits [31:24] : */
  1213. /* .. Nbr lead zeros = .. */
  1214. ix = (CPU_DATA)((CPU_DATA)val >> 24u); /* .. lookup tbl ix = 'val' >> 24 bits */
  1215. nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/
  1216. } else { /* Chk bits [23:16] : */
  1217. /* .. Nbr lead zeros = .. */
  1218. ix = (CPU_DATA)((CPU_DATA)val >> 16u); /* .. lookup tbl ix = 'val' >> 16 bits */
  1219. nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 8u);/* .. plus nbr msb lead zeros = 8 bits.*/
  1220. }
  1221. } else {
  1222. if (val > 0x000000FFu) { /* Chk bits [15:08] : */
  1223. /* .. Nbr lead zeros = .. */
  1224. ix = (CPU_DATA)((CPU_DATA)val >> 8u); /* .. lookup tbl ix = 'val' >> 8 bits */
  1225. nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 16u);/* .. plus nbr msb lead zeros = 16 bits.*/
  1226. } else { /* Chk bits [07:00] : */
  1227. /* .. Nbr lead zeros = .. */
  1228. ix = (CPU_DATA)((CPU_DATA)val >> 0u); /* .. lookup tbl ix = 'val' >> 0 bits */
  1229. nbr_lead_zeros = (CPU_DATA)((CPU_DATA)CPU_CntLeadZerosTbl[ix] + 24u);/* .. plus nbr msb lead zeros = 24 bits.*/
  1230. }
  1231. }
  1232. #endif
  1233. return (nbr_lead_zeros);
  1234. }
  1235. #endif
  1236. /*
  1237. *********************************************************************************************************
  1238. * CPU_CntLeadZeros64()
  1239. *
  1240. * Description : Count the number of contiguous, most-significant, leading zero bits in a 64-bit data value.
  1241. *
  1242. * Argument(s) : val Data value to count leading zero bits.
  1243. *
  1244. * Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
  1245. *
  1246. * Caller(s) : CPU_CntLeadZeros(),
  1247. * CPU_CntTrailZeros64(),
  1248. * Application.
  1249. *
  1250. * This function is a CPU module application programming interface (API) function & MAY be
  1251. * called by application function(s).
  1252. *
  1253. * Note(s) : (1) Supports 64-bit values :
  1254. *
  1255. * b63 b62 b61 ... b04 b03 b02 b01 b00 # Leading Zeros
  1256. * --- --- --- --- --- --- --- --- ---------------
  1257. * 1 x x x x x x x 0
  1258. * 0 1 x x x x x x 1
  1259. * 0 0 1 x x x x x 2
  1260. * : : : : : : : : :
  1261. * : : : : : : : : :
  1262. * 0 0 0 1 x x x x 59
  1263. * 0 0 0 0 1 x x x 60
  1264. * 0 0 0 0 0 1 x x 61
  1265. * 0 0 0 0 0 0 1 x 62
  1266. * 0 0 0 0 0 0 0 1 63
  1267. * 0 0 0 0 0 0 0 0 64
  1268. *
  1269. *
  1270. * See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
  1271. *********************************************************************************************************
  1272. */
  1273. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_64)
  1274. CPU_DATA CPU_CntLeadZeros64 (CPU_INT64U val)
  1275. {
  1276. #if (!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1277. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64)))
  1278. CPU_DATA ix;
  1279. #endif
  1280. CPU_DATA nbr_lead_zeros;
  1281. /* ---------- ASM-OPTIMIZED ----------- */
  1282. #if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
  1283. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64))
  1284. nbr_lead_zeros = CPU_CntLeadZeros((CPU_DATA)val);
  1285. nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_64) * DEF_OCTET_NBR_BITS;
  1286. #else /* ----------- C-OPTIMIZED ------------ */
  1287. if (val > 0x00000000FFFFFFFFu) {
  1288. if (val > 0x0000FFFFFFFFFFFFu) {
  1289. if (val > 0x00FFFFFFFFFFFFFFu) { /* Chk bits [63:56] : */
  1290. /* .. Nbr lead zeros = .. */
  1291. ix = (CPU_DATA)((CPU_INT64U)val >> 56u); /* .. lookup tbl ix = 'val' >> 56 bits */
  1292. nbr_lead_zeros = (CPU_DATA)(CPU_CntLeadZerosTbl[ix]); /* .. plus nbr msb lead zeros = 0 bits.*/
  1293. } else { /* Chk bits [55:48] : */
  1294. /* .. Nbr lead zeros = .. */
  1295. ix = (CPU_DATA)((CPU_INT64U)val >> 48u); /* .. lookup tbl ix = 'val' >> 48 bits */
  1296. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 8u);/* .. plus nbr msb lead zeros = 8 bits.*/
  1297. }
  1298. } else {
  1299. if (val > 0x000000FFFFFFFFFFu) { /* Chk bits [47:40] : */
  1300. /* .. Nbr lead zeros = .. */
  1301. ix = (CPU_DATA)((CPU_INT64U)val >> 40u); /* .. lookup tbl ix = 'val' >> 40 bits */
  1302. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 16u);/* .. plus nbr msb lead zeros = 16 bits.*/
  1303. } else { /* Chk bits [39:32] : */
  1304. /* .. Nbr lead zeros = .. */
  1305. ix = (CPU_DATA)((CPU_INT64U)val >> 32u); /* .. lookup tbl ix = 'val' >> 32 bits */
  1306. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 24u);/* .. plus nbr msb lead zeros = 24 bits.*/
  1307. }
  1308. }
  1309. } else {
  1310. if (val > 0x000000000000FFFFu) {
  1311. if (val > 0x0000000000FFFFFFu) { /* Chk bits [31:24] : */
  1312. /* .. Nbr lead zeros = .. */
  1313. ix = (CPU_DATA)((CPU_INT64U)val >> 24u); /* .. lookup tbl ix = 'val' >> 24 bits */
  1314. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 32u);/* .. plus nbr msb lead zeros = 32 bits.*/
  1315. } else { /* Chk bits [23:16] : */
  1316. /* .. Nbr lead zeros = .. */
  1317. ix = (CPU_DATA)((CPU_INT64U)val >> 16u); /* .. lookup tbl ix = 'val' >> 16 bits */
  1318. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 40u);/* .. plus nbr msb lead zeros = 40 bits.*/
  1319. }
  1320. } else {
  1321. if (val > 0x00000000000000FFu) { /* Chk bits [15:08] : */
  1322. /* .. Nbr lead zeros = .. */
  1323. ix = (CPU_DATA)((CPU_INT64U)val >> 8u); /* .. lookup tbl ix = 'val' >> 8 bits */
  1324. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 48u);/* .. plus nbr msb lead zeros = 48 bits.*/
  1325. } else { /* Chk bits [07:00] : */
  1326. /* .. Nbr lead zeros = .. */
  1327. ix = (CPU_DATA)(val); /* .. lookup tbl ix = 'val' >> 0 bits */
  1328. nbr_lead_zeros = (CPU_DATA)((CPU_INT64U)CPU_CntLeadZerosTbl[ix] + 56u);/* .. plus nbr msb lead zeros = 56 bits.*/
  1329. }
  1330. }
  1331. }
  1332. #endif
  1333. return (nbr_lead_zeros);
  1334. }
  1335. #endif
  1336. /*
  1337. *********************************************************************************************************
  1338. * CPU_CntTrailZeros()
  1339. *
  1340. * Description : Count the number of contiguous, least-significant, trailing zero bits in a data value.
  1341. *
  1342. * Argument(s) : val Data value to count trailing zero bits.
  1343. *
  1344. * Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
  1345. *
  1346. * Caller(s) : Application.
  1347. *
  1348. * This function is a CPU module application programming interface (API) function & MAY
  1349. * be called by application function(s).
  1350. *
  1351. * Note(s) : (1) (a) Supports the following data value sizes :
  1352. *
  1353. * (1) 8-bits
  1354. * (2) 16-bits
  1355. * (3) 32-bits
  1356. * (4) 64-bits
  1357. *
  1358. * See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'.
  1359. *
  1360. * (b) (1) For 8-bit values :
  1361. *
  1362. * b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros
  1363. * --- --- --- --- --- --- --- --- ----------------
  1364. * x x x x x x x 1 0
  1365. * x x x x x x 1 0 1
  1366. * x x x x x 1 0 0 2
  1367. * x x x x 1 0 0 0 3
  1368. * x x x 1 0 0 0 0 4
  1369. * x x 1 0 0 0 0 0 5
  1370. * x 1 0 0 0 0 0 0 6
  1371. * 1 0 0 0 0 0 0 0 7
  1372. * 0 0 0 0 0 0 0 0 8
  1373. *
  1374. *
  1375. * (2) For 16-bit values :
  1376. *
  1377. * b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros
  1378. * --- --- --- --- --- --- --- --- ----------------
  1379. * x x x x x x x 1 0
  1380. * x x x x x x 1 0 1
  1381. * x x x x x 1 0 0 2
  1382. * : : : : : : : : :
  1383. * : : : : : : : : :
  1384. * x x x x 1 0 0 0 11
  1385. * x x x 1 0 0 0 0 12
  1386. * x x 1 0 0 0 0 0 13
  1387. * x 1 0 0 0 0 0 0 14
  1388. * 1 0 0 0 0 0 0 0 15
  1389. * 0 0 0 0 0 0 0 0 16
  1390. *
  1391. *
  1392. * (3) For 32-bit values :
  1393. *
  1394. * b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros
  1395. * --- --- --- --- --- --- --- --- ----------------
  1396. * x x x x x x x 1 0
  1397. * x x x x x x 1 0 1
  1398. * x x x x x 1 0 0 2
  1399. * : : : : : : : : :
  1400. * : : : : : : : : :
  1401. * x x x x 1 0 0 0 27
  1402. * x x x 1 0 0 0 0 28
  1403. * x x 1 0 0 0 0 0 29
  1404. * x 1 0 0 0 0 0 0 30
  1405. * 1 0 0 0 0 0 0 0 31
  1406. * 0 0 0 0 0 0 0 0 32
  1407. *
  1408. *
  1409. * (4) For 64-bit values :
  1410. *
  1411. * b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros
  1412. * --- --- --- --- --- --- --- --- ----------------
  1413. * x x x x x x x 1 0
  1414. * x x x x x x 1 0 1
  1415. * x x x x x 1 0 0 2
  1416. * : : : : : : : : :
  1417. * : : : : : : : : :
  1418. * x x x x 1 0 0 0 59
  1419. * x x x 1 0 0 0 0 60
  1420. * x x 1 0 0 0 0 0 61
  1421. * x 1 0 0 0 0 0 0 62
  1422. * 1 0 0 0 0 0 0 0 63
  1423. * 0 0 0 0 0 0 0 0 64
  1424. *
  1425. * (2) For non-zero values, the returned number of contiguous, least-significant, trailing
  1426. * zero bits is also equivalent to the bit position of the least-significant set bit.
  1427. *
  1428. * (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations :
  1429. *
  1430. * (a) CPU_CntTrailZeros()'s final conditional statement calculates 'val's number of
  1431. * trailing zeros based on its return data size, 'CPU_CFG_DATA_SIZE', & 'val's
  1432. * calculated number of lead zeros ONLY if the initial 'val' is non-'0' :
  1433. *
  1434. * if (val != 0u) {
  1435. * nbr_trail_zeros = ((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1436. * } else {
  1437. * nbr_trail_zeros = nbr_lead_zeros;
  1438. * }
  1439. *
  1440. * Therefore, initially validating all non-'0' values avoids having to conditionally
  1441. * execute the final 'if' statement.
  1442. *********************************************************************************************************
  1443. */
  1444. #ifndef CPU_CFG_TRAIL_ZEROS_ASM_PRESENT
  1445. CPU_DATA CPU_CntTrailZeros (CPU_DATA val)
  1446. {
  1447. CPU_DATA val_bit_mask;
  1448. CPU_DATA nbr_lead_zeros;
  1449. CPU_DATA nbr_trail_zeros;
  1450. if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */
  1451. return (CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS);
  1452. }
  1453. val_bit_mask = val & ((CPU_DATA)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */
  1454. nbr_lead_zeros = CPU_CntLeadZeros(val_bit_mask); /* Cnt nbr lead 0s. */
  1455. /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/
  1456. nbr_trail_zeros = ((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1457. return (nbr_trail_zeros);
  1458. }
  1459. #endif
  1460. /*
  1461. *********************************************************************************************************
  1462. * CPU_CntTrailZeros08()
  1463. *
  1464. * Description : Count the number of contiguous, least-significant, trailing zero bits in an 8-bit data value.
  1465. *
  1466. * Argument(s) : val Data value to count trailing zero bits.
  1467. *
  1468. * Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
  1469. *
  1470. * Caller(s) : Application.
  1471. *
  1472. * This function is a CPU module application programming interface (API) function & MAY be
  1473. * called by application function(s).
  1474. *
  1475. * Note(s) : (1) Supports 8-bit values :
  1476. *
  1477. * b07 b06 b05 b04 b03 b02 b01 b00 # Trailing Zeros
  1478. * --- --- --- --- --- --- --- --- ----------------
  1479. * x x x x x x x 1 0
  1480. * x x x x x x 1 0 1
  1481. * x x x x x 1 0 0 2
  1482. * x x x x 1 0 0 0 3
  1483. * x x x 1 0 0 0 0 4
  1484. * x x 1 0 0 0 0 0 5
  1485. * x 1 0 0 0 0 0 0 6
  1486. * 1 0 0 0 0 0 0 0 7
  1487. * 0 0 0 0 0 0 0 0 8
  1488. *
  1489. *
  1490. * (2) For non-zero values, the returned number of contiguous, least-significant, trailing
  1491. * zero bits is also equivalent to the bit position of the least-significant set bit.
  1492. *
  1493. * (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations :
  1494. *
  1495. * (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's
  1496. * number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'.
  1497. * If the returned number of zeros exceeds CPU_CntTrailZeros08()'s 8-bit return
  1498. * data size, then the returned number of zeros must be offset by the difference
  1499. * between CPU_CntTrailZeros()'s & CPU_CntTrailZeros08()'s return data size :
  1500. *
  1501. * nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1502. * if (nbr_trail_zeros > (CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS)) {
  1503. * nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_08) * DEF_OCTET_NBR_BITS;
  1504. * }
  1505. *
  1506. * However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 8-bit
  1507. * values would return a number of trailing zeros less than or equal to 8 bits.
  1508. *
  1509. * Therefore, initially validating all non-'0' values prior to calling assembly-
  1510. * optimized CPU_CntTrailZeros() avoids having to offset the number of returned
  1511. * trailing zeros by the difference in CPU data size and 8-bit data value bits.
  1512. *
  1513. * (b) For CPU_CntTrailZeros08()'s C implementation, the final conditional statement
  1514. * calculates 'val's number of trailing zeros based on CPU_CntTrailZeros08()'s
  1515. * 8-bit return data size & 'val's calculated number of lead zeros ONLY if the
  1516. * initial 'val' is non-'0' :
  1517. *
  1518. * if (val != 0u) {
  1519. * nbr_trail_zeros = ((CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1520. * } else {
  1521. * nbr_trail_zeros = nbr_lead_zeros;
  1522. * }
  1523. *
  1524. * Therefore, initially validating all non-'0' values avoids having to conditionally
  1525. * execute the final 'if' statement.
  1526. *********************************************************************************************************
  1527. */
  1528. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_08)
  1529. CPU_DATA CPU_CntTrailZeros08 (CPU_INT08U val)
  1530. {
  1531. #if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1532. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08)))
  1533. CPU_INT08U val_bit_mask;
  1534. CPU_DATA nbr_lead_zeros;
  1535. #endif
  1536. CPU_DATA nbr_trail_zeros;
  1537. if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */
  1538. return (CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS);
  1539. }
  1540. /* ------------------ ASM-OPTIMIZED ------------------- */
  1541. #if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1542. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_08))
  1543. nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1544. #else /* ------------------- C-OPTIMIZED -------------------- */
  1545. val_bit_mask = val & ((CPU_INT08U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */
  1546. nbr_lead_zeros = CPU_CntLeadZeros08(val_bit_mask); /* Cnt nbr lead 0s. */
  1547. /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/
  1548. nbr_trail_zeros = ((CPU_WORD_SIZE_08 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1549. #endif
  1550. return (nbr_trail_zeros);
  1551. }
  1552. #endif
  1553. /*
  1554. *********************************************************************************************************
  1555. * CPU_CntTrailZeros16()
  1556. *
  1557. * Description : Count the number of contiguous, least-significant, trailing zero bits in a 16-bit data value.
  1558. *
  1559. * Argument(s) : val Data value to count trailing zero bits.
  1560. *
  1561. * Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
  1562. *
  1563. * Caller(s) : Application.
  1564. *
  1565. * This function is a CPU module application programming interface (API) function & MAY be
  1566. * called by application function(s).
  1567. *
  1568. * Note(s) : (1) Supports 16-bit values :
  1569. *
  1570. * b15 b14 b13 b12 b11 ... b02 b01 b00 # Trailing Zeros
  1571. * --- --- --- --- --- --- --- --- ----------------
  1572. * x x x x x x x 1 0
  1573. * x x x x x x 1 0 1
  1574. * x x x x x 1 0 0 2
  1575. * : : : : : : : : :
  1576. * : : : : : : : : :
  1577. * x x x x 1 0 0 0 11
  1578. * x x x 1 0 0 0 0 12
  1579. * x x 1 0 0 0 0 0 13
  1580. * x 1 0 0 0 0 0 0 14
  1581. * 1 0 0 0 0 0 0 0 15
  1582. * 0 0 0 0 0 0 0 0 16
  1583. *
  1584. *
  1585. * (2) For non-zero values, the returned number of contiguous, least-significant, trailing
  1586. * zero bits is also equivalent to the bit position of the least-significant set bit.
  1587. *
  1588. * (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations :
  1589. *
  1590. * (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's
  1591. * number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'.
  1592. * If the returned number of zeros exceeds CPU_CntTrailZeros16()'s 16-bit return
  1593. * data size, then the returned number of zeros must be offset by the difference
  1594. * between CPU_CntTrailZeros()'s & CPU_CntTrailZeros16()'s return data size :
  1595. *
  1596. * nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1597. * if (nbr_trail_zeros > (CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS)) {
  1598. * nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_16) * DEF_OCTET_NBR_BITS;
  1599. * }
  1600. *
  1601. * However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 16-bit
  1602. * values would return a number of trailing zeros less than or equal to 16 bits.
  1603. *
  1604. * Therefore, initially validating all non-'0' values prior to calling assembly-
  1605. * optimized CPU_CntTrailZeros() avoids having to offset the number of returned
  1606. * trailing zeros by the difference in CPU data size and 16-bit data value bits.
  1607. *
  1608. * (b) For CPU_CntTrailZeros16()'s C implementation, the final conditional statement
  1609. * calculates 'val's number of trailing zeros based on CPU_CntTrailZeros16()'s
  1610. * 16-bit return data size & 'val's calculated number of lead zeros ONLY if the
  1611. * initial 'val' is non-'0' :
  1612. *
  1613. * if (val != 0u) {
  1614. * nbr_trail_zeros = ((CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1615. * } else {
  1616. * nbr_trail_zeros = nbr_lead_zeros;
  1617. * }
  1618. *
  1619. * Therefore, initially validating all non-'0' values avoids having to conditionally
  1620. * execute the final 'if' statement.
  1621. *********************************************************************************************************
  1622. */
  1623. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_16)
  1624. CPU_DATA CPU_CntTrailZeros16 (CPU_INT16U val)
  1625. {
  1626. #if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1627. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16)))
  1628. CPU_INT16U val_bit_mask;
  1629. CPU_DATA nbr_lead_zeros;
  1630. #endif
  1631. CPU_DATA nbr_trail_zeros;
  1632. if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */
  1633. return (CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS);
  1634. }
  1635. /* ------------------ ASM-OPTIMIZED ------------------- */
  1636. #if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1637. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_16))
  1638. nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1639. #else /* ------------------- C-OPTIMIZED -------------------- */
  1640. val_bit_mask = val & ((CPU_INT16U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */
  1641. nbr_lead_zeros = CPU_CntLeadZeros16(val_bit_mask); /* Cnt nbr lead 0s. */
  1642. /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/
  1643. nbr_trail_zeros = ((CPU_WORD_SIZE_16 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1644. #endif
  1645. return (nbr_trail_zeros);
  1646. }
  1647. #endif
  1648. /*
  1649. *********************************************************************************************************
  1650. * CPU_CntTrailZeros32()
  1651. *
  1652. * Description : Count the number of contiguous, least-significant, trailing zero bits in a 32-bit data value.
  1653. *
  1654. * Argument(s) : val Data value to count trailing zero bits.
  1655. *
  1656. * Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
  1657. *
  1658. * Caller(s) : Application.
  1659. *
  1660. * This function is a CPU module application programming interface (API) function & MAY be
  1661. * called by application function(s).
  1662. *
  1663. * Note(s) : (1) Supports 32-bit values :
  1664. *
  1665. * b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros
  1666. * --- --- --- --- --- --- --- --- ----------------
  1667. * x x x x x x x 1 0
  1668. * x x x x x x 1 0 1
  1669. * x x x x x 1 0 0 2
  1670. * : : : : : : : : :
  1671. * : : : : : : : : :
  1672. * x x x x 1 0 0 0 27
  1673. * x x x 1 0 0 0 0 28
  1674. * x x 1 0 0 0 0 0 29
  1675. * x 1 0 0 0 0 0 0 30
  1676. * 1 0 0 0 0 0 0 0 31
  1677. * 0 0 0 0 0 0 0 0 32
  1678. *
  1679. *
  1680. * (2) For non-zero values, the returned number of contiguous, least-significant, trailing
  1681. * zero bits is also equivalent to the bit position of the least-significant set bit.
  1682. *
  1683. * (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations :
  1684. *
  1685. * (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's
  1686. * number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'.
  1687. * If the returned number of zeros exceeds CPU_CntTrailZeros32()'s 32-bit return
  1688. * data size, then the returned number of zeros must be offset by the difference
  1689. * between CPU_CntTrailZeros()'s & CPU_CntTrailZeros32()'s return data size :
  1690. *
  1691. * nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1692. * if (nbr_trail_zeros > (CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS)) {
  1693. * nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_32) * DEF_OCTET_NBR_BITS;
  1694. * }
  1695. *
  1696. * However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 32-bit
  1697. * values would return a number of trailing zeros less than or equal to 32 bits.
  1698. *
  1699. * Therefore, initially validating all non-'0' values prior to calling assembly-
  1700. * optimized CPU_CntTrailZeros() avoids having to offset the number of returned
  1701. * trailing zeros by the difference in CPU data size and 32-bit data value bits.
  1702. *
  1703. * (b) For CPU_CntTrailZeros32()'s C implementation, the final conditional statement
  1704. * calculates 'val's number of trailing zeros based on CPU_CntTrailZeros32()'s
  1705. * 32-bit return data size & 'val's calculated number of lead zeros ONLY if the
  1706. * initial 'val' is non-'0' :
  1707. *
  1708. * if (val != 0u) {
  1709. * nbr_trail_zeros = ((CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1710. * } else {
  1711. * nbr_trail_zeros = nbr_lead_zeros;
  1712. * }
  1713. *
  1714. * Therefore, initially validating all non-'0' values avoids having to conditionally
  1715. * execute the final 'if' statement.
  1716. *********************************************************************************************************
  1717. */
  1718. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_32)
  1719. CPU_DATA CPU_CntTrailZeros32 (CPU_INT32U val)
  1720. {
  1721. #if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1722. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32)))
  1723. CPU_INT32U val_bit_mask;
  1724. CPU_DATA nbr_lead_zeros;
  1725. #endif
  1726. CPU_DATA nbr_trail_zeros;
  1727. if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */
  1728. return (CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS);
  1729. }
  1730. /* ------------------ ASM-OPTIMIZED ------------------- */
  1731. #if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1732. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_32))
  1733. nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1734. #else /* ------------------- C-OPTIMIZED -------------------- */
  1735. val_bit_mask = val & ((CPU_INT32U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */
  1736. nbr_lead_zeros = CPU_CntLeadZeros32(val_bit_mask); /* Cnt nbr lead 0s. */
  1737. /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/
  1738. nbr_trail_zeros = ((CPU_WORD_SIZE_32 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1739. #endif
  1740. return (nbr_trail_zeros);
  1741. }
  1742. #endif
  1743. /*
  1744. *********************************************************************************************************
  1745. * CPU_CntTrailZeros64()
  1746. *
  1747. * Description : Count the number of contiguous, least-significant, trailing zero bits in a 64-bit data value.
  1748. *
  1749. * Argument(s) : val Data value to count trailing zero bits.
  1750. *
  1751. * Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
  1752. *
  1753. * Caller(s) : Application.
  1754. *
  1755. * This function is a CPU module application programming interface (API) function & MAY be
  1756. * called by application function(s).
  1757. *
  1758. * Note(s) : (1) Supports 64-bit values :
  1759. *
  1760. * b63 b62 b61 b60 b59 ... b02 b01 b00 # Trailing Zeros
  1761. * --- --- --- --- --- --- --- --- ----------------
  1762. * x x x x x x x 1 0
  1763. * x x x x x x 1 0 1
  1764. * x x x x x 1 0 0 2
  1765. * : : : : : : : : :
  1766. * : : : : : : : : :
  1767. * x x x x 1 0 0 0 59
  1768. * x x x 1 0 0 0 0 60
  1769. * x x 1 0 0 0 0 0 61
  1770. * x 1 0 0 0 0 0 0 62
  1771. * 1 0 0 0 0 0 0 0 63
  1772. * 0 0 0 0 0 0 0 0 64
  1773. *
  1774. *
  1775. * (2) For non-zero values, the returned number of contiguous, least-significant, trailing
  1776. * zero bits is also equivalent to the bit position of the least-significant set bit.
  1777. *
  1778. * (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations :
  1779. *
  1780. * (a) For assembly-optimized implementations, CPU_CntTrailZeros() returns 'val's
  1781. * number of trailing zeros via CPU's native data size, 'CPU_CFG_DATA_SIZE'.
  1782. * If the returned number of zeros exceeds CPU_CntTrailZeros64()'s 64-bit return
  1783. * data size, then the returned number of zeros must be offset by the difference
  1784. * between CPU_CntTrailZeros()'s & CPU_CntTrailZeros64()'s return data size :
  1785. *
  1786. * nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1787. * if (nbr_trail_zeros > (CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS)) {
  1788. * nbr_trail_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_64) * DEF_OCTET_NBR_BITS;
  1789. * }
  1790. *
  1791. * However, this ONLY occurs for an initial 'val' of '0' since all non-'0' 64-bit
  1792. * values would return a number of trailing zeros less than or equal to 64 bits.
  1793. *
  1794. * Therefore, initially validating all non-'0' values prior to calling assembly-
  1795. * optimized CPU_CntTrailZeros() avoids having to offset the number of returned
  1796. * trailing zeros by the difference in CPU data size and 64-bit data value bits.
  1797. *
  1798. * (b) For CPU_CntTrailZeros64()'s C implementation, the final conditional statement
  1799. * calculates 'val's number of trailing zeros based on CPU_CntTrailZeros64()'s
  1800. * 64-bit return data size & 'val's calculated number of lead zeros ONLY if the
  1801. * initial 'val' is non-'0' :
  1802. *
  1803. * if (val != 0u) {
  1804. * nbr_trail_zeros = ((CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1805. * } else {
  1806. * nbr_trail_zeros = nbr_lead_zeros;
  1807. * }
  1808. *
  1809. * Therefore, initially validating all non-'0' values avoids having to conditionally
  1810. * execute the final 'if' statement.
  1811. *********************************************************************************************************
  1812. */
  1813. #if (CPU_CFG_DATA_SIZE_MAX >= CPU_WORD_SIZE_64)
  1814. CPU_DATA CPU_CntTrailZeros64 (CPU_INT64U val)
  1815. {
  1816. #if (!((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1817. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64)))
  1818. CPU_INT64U val_bit_mask;
  1819. CPU_DATA nbr_lead_zeros;
  1820. #endif
  1821. CPU_DATA nbr_trail_zeros;
  1822. if (val == 0u) { /* Rtn ALL val bits as zero'd (see Note #3). */
  1823. return (CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS);
  1824. }
  1825. /* ------------------ ASM-OPTIMIZED ------------------- */
  1826. #if ((defined(CPU_CFG_TRAIL_ZEROS_ASM_PRESENT)) && \
  1827. (CPU_CFG_DATA_SIZE >= CPU_WORD_SIZE_64))
  1828. nbr_trail_zeros = CPU_CntTrailZeros((CPU_DATA)val);
  1829. #else /* ------------------- C-OPTIMIZED -------------------- */
  1830. val_bit_mask = val & ((CPU_INT64U)~val + 1u); /* Zero/clr all bits EXCEPT least-sig set bit. */
  1831. nbr_lead_zeros = CPU_CntLeadZeros64(val_bit_mask); /* Cnt nbr lead 0s. */
  1832. /* Calc nbr trail 0s = (nbr val bits - 1) - nbr lead 0s.*/
  1833. nbr_trail_zeros = ((CPU_WORD_SIZE_64 * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
  1834. #endif
  1835. return (nbr_trail_zeros);
  1836. }
  1837. #endif
  1838. /*
  1839. *********************************************************************************************************
  1840. *********************************************************************************************************
  1841. * LOCAL FUNCTIONS
  1842. *********************************************************************************************************
  1843. *********************************************************************************************************
  1844. */
  1845. /*
  1846. *********************************************************************************************************
  1847. * CPU_NameInit()
  1848. *
  1849. * Description : Initialize CPU Name.
  1850. *
  1851. * Argument(s) : none.
  1852. *
  1853. * Return(s) : none.
  1854. *
  1855. * Caller(s) : CPU_Init().
  1856. *
  1857. * Note(s) : none.
  1858. *********************************************************************************************************
  1859. */
  1860. #if (CPU_CFG_NAME_EN == DEF_ENABLED)
  1861. static void CPU_NameInit (void)
  1862. {
  1863. CPU_NameClr();
  1864. }
  1865. #endif
  1866. /*
  1867. *********************************************************************************************************
  1868. * CPU_TS_Init()
  1869. *
  1870. * Description : (1) Initialize CPU timestamp :
  1871. *
  1872. * (a) Initialize/start CPU timestamp timer See Note #1
  1873. * (b) Initialize CPU timestamp controls
  1874. *
  1875. *
  1876. * Argument(s) : none.
  1877. *
  1878. * Return(s) : none.
  1879. *
  1880. * Caller(s) : CPU_Init().
  1881. *
  1882. * Note(s) : (1) The following initialization MUST be sequenced as follows :
  1883. *
  1884. * (a) CPU_TS_TmrFreq_Hz MUST be initialized prior to CPU_TS_TmrInit()
  1885. * (b) CPU_TS_TmrInit() SHOULD precede calls to all other CPU timestamp functions;
  1886. * otherwise, invalid time measurements may be calculated/
  1887. * returned.
  1888. *
  1889. * See also 'CPU_Init() Note #3a'.
  1890. *********************************************************************************************************
  1891. */
  1892. #if ((CPU_CFG_TS_EN == DEF_ENABLED) || \
  1893. (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
  1894. static void CPU_TS_Init (void)
  1895. {
  1896. #if (((CPU_CFG_TS_32_EN == DEF_ENABLED ) && \
  1897. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) || \
  1898. ((CPU_CFG_TS_64_EN == DEF_ENABLED ) && \
  1899. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)))
  1900. CPU_TS_TMR ts_tmr_cnts;
  1901. #endif
  1902. /* ----------------- INIT CPU TS TMR ------------------ */
  1903. #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
  1904. CPU_TS_TmrFreq_Hz = 0u; /* Init/clr ts tmr freq (see Note #1a). */
  1905. CPU_TS_TmrInit(); /* Init & start ts tmr (see Note #1b). */
  1906. #endif
  1907. /* ------------------- INIT CPU TS -------------------- */
  1908. #if (((CPU_CFG_TS_32_EN == DEF_ENABLED ) && \
  1909. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) || \
  1910. ((CPU_CFG_TS_64_EN == DEF_ENABLED ) && \
  1911. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)))
  1912. ts_tmr_cnts = CPU_TS_TmrRd(); /* Get init ts tmr val (in ts tmr cnts). */
  1913. #endif
  1914. #if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \
  1915. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32))
  1916. CPU_TS_32_Accum = 0u; /* Init 32-bit accum'd ts. */
  1917. CPU_TS_32_TmrPrev = ts_tmr_cnts; /* Init 32-bit ts prev tmr val. */
  1918. #endif
  1919. #if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \
  1920. (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64))
  1921. CPU_TS_64_Accum = 0u; /* Init 64-bit accum'd ts. */
  1922. CPU_TS_64_TmrPrev = ts_tmr_cnts; /* Init 64-bit ts prev tmr val. */
  1923. #endif
  1924. }
  1925. #endif
  1926. /*
  1927. *********************************************************************************************************
  1928. * CPU_IntDisMeasInit()
  1929. *
  1930. * Description : (1) Initialize interrupts disabled time measurements feature :
  1931. *
  1932. * (a) Initialize interrupts disabled time measurement controls
  1933. * (b) Calculate interrupts disabled time measurement overhead
  1934. *
  1935. *
  1936. * Argument(s) : none.
  1937. *
  1938. * Return(s) : none.
  1939. *
  1940. * Caller(s) : CPU_Init().
  1941. *
  1942. * Note(s) : (2) CPU_IntDisMeasInit() SHOULD precede ALL calls to CPU_CRITICAL_ENTER()/CPU_CRITICAL_EXIT()
  1943. * & other CPU interrupts disabled time measurement functions; otherwise, invalid interrupts
  1944. * disabled time measurements may be calculated/returned.
  1945. *
  1946. * See also 'CPU_Init() Note #3b'.
  1947. *
  1948. * (3) (a) (1) Interrupts disabled time measurement overhead performed multiple times to calculate
  1949. * a rounded average with better accuracy, hopefully of +/- one timer count.
  1950. *
  1951. * (2) However, a single overhead time measurement is recommended, even for instruction-
  1952. * cache-enabled CPUs, since critical sections are NOT typically called within
  1953. * instruction-cached loops. Thus a single non-cached/non-averaged time measurement
  1954. * is a more realistic overhead for the majority of non-cached interrupts disabled
  1955. * time measurements.
  1956. *
  1957. * (b) Interrupts MUST be disabled while measuring the interrupts disabled time measurement
  1958. * overhead; otherwise, overhead measurements could be interrupted which would incorrectly
  1959. * calculate an inflated overhead time which would then incorrectly calculate deflated
  1960. * interrupts disabled times.
  1961. *********************************************************************************************************
  1962. */
  1963. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  1964. static void CPU_IntDisMeasInit (void)
  1965. {
  1966. CPU_TS_TMR time_meas_tot_cnts;
  1967. CPU_INT16U i;
  1968. CPU_SR_ALLOC();
  1969. /* ----------- INIT INT DIS TIME MEAS CTRLS ----------- */
  1970. CPU_IntDisMeasCtr = 0u;
  1971. CPU_IntDisNestCtr = 0u;
  1972. CPU_IntDisMeasStart_cnts = 0u;
  1973. CPU_IntDisMeasStop_cnts = 0u;
  1974. CPU_IntDisMeasMaxCur_cnts = 0u;
  1975. CPU_IntDisMeasMax_cnts = 0u;
  1976. CPU_IntDisMeasOvrhd_cnts = 0u;
  1977. /* ----------- CALC INT DIS TIME MEAS OVRHD ----------- */
  1978. time_meas_tot_cnts = 0u;
  1979. CPU_INT_DIS(); /* Ints MUST be dis'd for ovrhd calc (see Note #3b). */
  1980. for (i = 0u; i < CPU_CFG_INT_DIS_MEAS_OVRHD_NBR; i++) {
  1981. CPU_IntDisMeasMaxCur_cnts = 0u;
  1982. CPU_IntDisMeasStart(); /* Perform multiple consecutive start/stop time meas's */
  1983. CPU_IntDisMeasStop();
  1984. time_meas_tot_cnts += CPU_IntDisMeasMaxCur_cnts; /* ... & sum time meas max's ... */
  1985. }
  1986. /* ... to calc avg time meas ovrhd (see Note #3a). */
  1987. CPU_IntDisMeasOvrhd_cnts = (time_meas_tot_cnts + (CPU_CFG_INT_DIS_MEAS_OVRHD_NBR / 2u))
  1988. / CPU_CFG_INT_DIS_MEAS_OVRHD_NBR;
  1989. CPU_IntDisMeasMaxCur_cnts = 0u; /* Reset max ints dis'd times. */
  1990. CPU_IntDisMeasMax_cnts = 0u;
  1991. CPU_INT_EN();
  1992. }
  1993. #endif
  1994. /*
  1995. *********************************************************************************************************
  1996. * CPU_IntDisMeasMaxCalc()
  1997. *
  1998. * Description : Calculate maximum interrupts disabled time.
  1999. *
  2000. * Argument(s) : time_tot_cnts Total interrupt disabled time, in timer counts.
  2001. *
  2002. * Return(s) : Maximum interrupts disabled time (in CPU timestamp timer counts).
  2003. *
  2004. * Caller(s) : CPU_IntDisMeasMaxCurGet(),
  2005. * CPU_IntDisMeasMaxGet().
  2006. *
  2007. * Note(s) : (1) (a) The total amount of time interrupts are disabled by system &/or application code
  2008. * during critical sections is calculated by the following equations :
  2009. *
  2010. * (1) time = [ time - time ] - time
  2011. * interrupts [ stop start ] total meas
  2012. * disabled [ meas meas ] ovrhd
  2013. * (via application)
  2014. *
  2015. *
  2016. * (2) time = time + time
  2017. * total meas start meas stop meas
  2018. * ovrhd ovrhd ovrhd
  2019. *
  2020. *
  2021. * where
  2022. *
  2023. * time time interrupts are disabled between
  2024. * interrupts first critical section enter &
  2025. * disabled last critical section exit minus
  2026. * (via application) time measurement overhead
  2027. *
  2028. * time time of disable interrupts start time
  2029. * start measurement (in timer counts)
  2030. * meas
  2031. *
  2032. * time time of disable interrupts stop time
  2033. * stop measurement (in timer counts)
  2034. * meas
  2035. *
  2036. * time total overhead time to start/stop disabled
  2037. * total meas interrupts time measurements (in timer
  2038. * ovrhd counts)
  2039. *
  2040. * time total overhead time after getting start
  2041. * start meas time until end of start measurement
  2042. * ovrhd function (in timer counts)
  2043. *
  2044. * time total overhead time from beginning of stop
  2045. * stop meas measurement function until after getting
  2046. * ovrhd stop time (in timer counts)
  2047. *
  2048. *
  2049. * (b) To expedite & reduce interrupts disabled time measurement overhead, the final
  2050. * calculations to subtract the interrupts disabled time measurement overhead is
  2051. * performed asynchronously in API functions.
  2052. *
  2053. * See also 'CPU_IntDisMeasStop() Note #1b2'.
  2054. *
  2055. * (c) The amount of time interrupts are disabled is calculated by either of the
  2056. * following equations :
  2057. *
  2058. * (1) Interrupts disabled time = Number timer counts * Timer period
  2059. *
  2060. * where
  2061. *
  2062. * Number timer counts Number of timer counts measured
  2063. * Timer period Timer's period in some units of
  2064. * (fractional) seconds
  2065. * Interrupts disabled time Amount of time interrupts are
  2066. * disabled, in same units of
  2067. * (fractional) seconds as the
  2068. * Timer period
  2069. *
  2070. * Number timer counts
  2071. * (2) Interrupts disabled time = ---------------------
  2072. * Timer frequency
  2073. *
  2074. * where
  2075. *
  2076. * Number timer counts Number of timer counts measured
  2077. * Timer frequency Timer's frequency in some units
  2078. * of counts per second
  2079. * Interrupts disabled time Amount of time interrupts are
  2080. * disabled, in seconds
  2081. *
  2082. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2c'
  2083. * & 'cpu_core.h FUNCTION PROTOTYPES CPU_TSxx_to_uSec() Note #2'.
  2084. *
  2085. * (2) Although it is not typical, it is possible for an interrupts disabled time
  2086. * measurement to be less than the interrupts disabled time measurement overhead;
  2087. * especially if the overhead was calculated with a single, non-cached measurement
  2088. * & critical sections are called within instruction-cached loops.
  2089. *********************************************************************************************************
  2090. */
  2091. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  2092. static CPU_TS_TMR CPU_IntDisMeasMaxCalc (CPU_TS_TMR time_tot_cnts)
  2093. {
  2094. CPU_TS_TMR time_max_cnts;
  2095. time_max_cnts = time_tot_cnts;
  2096. if (time_max_cnts > CPU_IntDisMeasOvrhd_cnts) { /* If max ints dis'd time > ovrhd time, ... */
  2097. time_max_cnts -= CPU_IntDisMeasOvrhd_cnts; /* ... adj max ints dis'd time by ovrhd time; ... */
  2098. } else { /* ... else max ints dis'd time < ovrhd time, ... */
  2099. time_max_cnts = 0u; /* ... clr max ints dis'd time (see Note #2). */
  2100. }
  2101. return (time_max_cnts);
  2102. }
  2103. #endif