您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

1516 行
58 KiB

  1. #include "plsr_planner.h"
  2. #include <stddef.h>
  3. #include <string.h>
  4. #define PLSR_PLANNER_Q32_ONE (4294967296ULL)
  5. #if !defined(PLSR_HOST_TEST)
  6. #define PLSR_PLANNER_BENCHMARK_DEMCR_ADDRESS (0xE000EDFCUL)
  7. #define PLSR_PLANNER_BENCHMARK_DWT_CTRL (0xE0001000UL)
  8. #define PLSR_PLANNER_BENCHMARK_DWT_CYCCNT (0xE0001004UL)
  9. #define PLSR_PLANNER_BENCHMARK_TRCENA (1UL << 24U)
  10. #define PLSR_PLANNER_BENCHMARK_CYCCNTENA (1UL << 0U)
  11. #define PLSR_PLANNER_BENCHMARK_PULSES (100000UL)
  12. #define PLSR_PLANNER_BENCHMARK_BATCH_CALLS (128UL)
  13. #define PLSR_PLANNER_BENCHMARK_TARGET_HZ (100000UL)
  14. volatile uint32_t PlsrPlannerBenchmarkRequest;
  15. volatile uint32_t PlsrPlannerBenchmarkRunning;
  16. volatile uint32_t PlsrPlannerBenchmarkRunCount;
  17. volatile uint32_t PlsrPlannerBenchmarkCoreClockHz = 168000000UL;
  18. volatile PLSR_PLANNER_BENCHMARK_RESULT PlsrPlannerBenchmarkResults[3];
  19. #endif
  20. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  21. && !defined(PLSR_HOST_TEST)
  22. #define PLSR_PLANNER_CYCCNT_ADDRESS (0xE0001004UL)
  23. volatile PLSR_PLANNER_TIMING PlsrPlannerTiming;
  24. static uint32_t PlsrPlannerTimingNow(void)
  25. {
  26. return *((volatile uint32_t *)PLSR_PLANNER_CYCCNT_ADDRESS);
  27. }
  28. static void PlsrPlannerTimingRecord(
  29. volatile PLSR_PLANNER_TIMING_SAMPLE *sample,
  30. uint32_t startedAt)
  31. {
  32. uint32_t elapsed = PlsrPlannerTimingNow() - startedAt;
  33. uint32_t total = sample->totalCycles;
  34. sample->lastCycles = elapsed;
  35. if ((sample->callCount == 0UL) || (elapsed < sample->minCycles))
  36. {
  37. sample->minCycles = elapsed;
  38. }
  39. if (sample->callCount != 0xFFFFFFFFUL)
  40. {
  41. sample->callCount++;
  42. }
  43. sample->totalCycles = (elapsed > (0xFFFFFFFFUL - total))
  44. ? 0xFFFFFFFFUL : total + elapsed;
  45. if (elapsed > sample->maxCycles)
  46. {
  47. sample->maxCycles = elapsed;
  48. }
  49. }
  50. void PlsrPlannerTimingReset(void)
  51. {
  52. (void)memset((void *)&PlsrPlannerTiming, 0, sizeof(PlsrPlannerTiming));
  53. }
  54. #endif
  55. #define PLSR_PLANNER_CURVE_TABLE_BITS (9U)
  56. #define PLSR_PLANNER_CURVE_TABLE_INTERVALS (1UL << PLSR_PLANNER_CURVE_TABLE_BITS)
  57. #define PLSR_PLANNER_CURVE_TABLE_SIZE (PLSR_PLANNER_CURVE_TABLE_INTERVALS + 1UL)
  58. #define PLSR_PLANNER_CURVE_DERIVATIVE_SHIFT (8U + PLSR_PLANNER_CURVE_TABLE_BITS)
  59. /* curveMode 1: fixed seven-section jerk profile. Each entry/exit ramp
  60. uses a 1:2:1 constant-jerk/constant-acceleration/constant-jerk ratio.
  61. The table stores the integral of the normalized frequency blend. */
  62. static const uint32_t PlsrPlannerSmoothIntegralQ24[PLSR_PLANNER_CURVE_TABLE_SIZE] =
  63. {
  64. 0UL, 0UL, 1UL, 3UL, 7UL, 14UL, 24UL, 38UL,
  65. 57UL, 81UL, 111UL, 148UL, 192UL, 244UL, 305UL, 375UL,
  66. 455UL, 546UL, 648UL, 762UL, 889UL, 1029UL, 1183UL, 1352UL,
  67. 1536UL, 1736UL, 1953UL, 2187UL, 2439UL, 2710UL, 3000UL, 3310UL,
  68. 3641UL, 3993UL, 4367UL, 4764UL, 5184UL, 5628UL, 6097UL, 6591UL,
  69. 7111UL, 7658UL, 8232UL, 8834UL, 9465UL, 10125UL, 10815UL, 11536UL,
  70. 12288UL, 13072UL, 13889UL, 14739UL, 15623UL, 16542UL, 17496UL, 18486UL,
  71. 19513UL, 20577UL, 21679UL, 22820UL, 24000UL, 25220UL, 26481UL, 27783UL,
  72. 29127UL, 30514UL, 31944UL, 33418UL, 34937UL, 36501UL, 38111UL, 39768UL,
  73. 41472UL, 43224UL, 45025UL, 46875UL, 48775UL, 50726UL, 52728UL, 54782UL,
  74. 56889UL, 59049UL, 61263UL, 63532UL, 65856UL, 68236UL, 70673UL, 73167UL,
  75. 75719UL, 78330UL, 81000UL, 83730UL, 86521UL, 89373UL, 92287UL, 95264UL,
  76. 98304UL, 101408UL, 104577UL, 107811UL, 111111UL, 114478UL, 117912UL, 121414UL,
  77. 124985UL, 128625UL, 132335UL, 136116UL, 139968UL, 143892UL, 147889UL, 151959UL,
  78. 156103UL, 160322UL, 164616UL, 168986UL, 173433UL, 177957UL, 182559UL, 187240UL,
  79. 192000UL, 196840UL, 201761UL, 206763UL, 211847UL, 217014UL, 222264UL, 227598UL,
  80. 233017UL, 238521UL, 244110UL, 249785UL, 255545UL, 261390UL, 267321UL, 273337UL,
  81. 279438UL, 285625UL, 291897UL, 298254UL, 304697UL, 311225UL, 317838UL, 324537UL,
  82. 331321UL, 338190UL, 345145UL, 352185UL, 359310UL, 366521UL, 373817UL, 381198UL,
  83. 388665UL, 396217UL, 403854UL, 411577UL, 419385UL, 427278UL, 435257UL, 443321UL,
  84. 451470UL, 459705UL, 468025UL, 476430UL, 484921UL, 493497UL, 502158UL, 510905UL,
  85. 519737UL, 528654UL, 537657UL, 546745UL, 555918UL, 565177UL, 574521UL, 583950UL,
  86. 593465UL, 603065UL, 612750UL, 622521UL, 632377UL, 642318UL, 652345UL, 662457UL,
  87. 672654UL, 682937UL, 693305UL, 703758UL, 714297UL, 724921UL, 735630UL, 746425UL,
  88. 757305UL, 768270UL, 779321UL, 790457UL, 801678UL, 812985UL, 824377UL, 835854UL,
  89. 847417UL, 859065UL, 870798UL, 882617UL, 894521UL, 906510UL, 918585UL, 930745UL,
  90. 942990UL, 955321UL, 967737UL, 980238UL, 992825UL, 1005497UL, 1018254UL, 1031097UL,
  91. 1044025UL, 1057038UL, 1070137UL, 1083321UL, 1096590UL, 1109945UL, 1123385UL, 1136910UL,
  92. 1150521UL, 1164217UL, 1177998UL, 1191865UL, 1205817UL, 1219854UL, 1233977UL, 1248185UL,
  93. 1262478UL, 1276857UL, 1291321UL, 1305870UL, 1320505UL, 1335225UL, 1350030UL, 1364921UL,
  94. 1379897UL, 1394958UL, 1410105UL, 1425337UL, 1440654UL, 1456057UL, 1471545UL, 1487118UL,
  95. 1502777UL, 1518521UL, 1534350UL, 1550265UL, 1566265UL, 1582350UL, 1598521UL, 1614777UL,
  96. 1631118UL, 1647545UL, 1664057UL, 1680654UL, 1697337UL, 1714105UL, 1730958UL, 1747897UL,
  97. 1764921UL, 1782030UL, 1799225UL, 1816505UL, 1833870UL, 1851321UL, 1868857UL, 1886478UL,
  98. 1904185UL, 1921977UL, 1939854UL, 1957817UL, 1975865UL, 1993998UL, 2012217UL, 2030521UL,
  99. 2048910UL, 2067385UL, 2085945UL, 2104590UL, 2123321UL, 2142137UL, 2161038UL, 2180025UL,
  100. 2199097UL, 2218254UL, 2237497UL, 2256825UL, 2276238UL, 2295737UL, 2315321UL, 2334990UL,
  101. 2354745UL, 2374585UL, 2394510UL, 2414521UL, 2434617UL, 2454798UL, 2475065UL, 2495417UL,
  102. 2515854UL, 2536377UL, 2556985UL, 2577678UL, 2598457UL, 2619321UL, 2640270UL, 2661305UL,
  103. 2682425UL, 2703630UL, 2724921UL, 2746297UL, 2767758UL, 2789305UL, 2810937UL, 2832654UL,
  104. 2854457UL, 2876345UL, 2898318UL, 2920377UL, 2942521UL, 2964750UL, 2987065UL, 3009465UL,
  105. 3031950UL, 3054521UL, 3077177UL, 3099918UL, 3122745UL, 3145657UL, 3168654UL, 3191737UL,
  106. 3214905UL, 3238158UL, 3261497UL, 3284921UL, 3308430UL, 3332025UL, 3355705UL, 3379470UL,
  107. 3403321UL, 3427257UL, 3451278UL, 3475385UL, 3499577UL, 3523854UL, 3548217UL, 3572665UL,
  108. 3597198UL, 3621817UL, 3646521UL, 3671310UL, 3696185UL, 3721145UL, 3746190UL, 3771321UL,
  109. 3796537UL, 3821838UL, 3847225UL, 3872697UL, 3898254UL, 3923897UL, 3949625UL, 3975438UL,
  110. 4001337UL, 4027321UL, 4053390UL, 4079545UL, 4105785UL, 4132110UL, 4158521UL, 4185017UL,
  111. 4211598UL, 4238265UL, 4265017UL, 4291854UL, 4318777UL, 4345785UL, 4372878UL, 4400057UL,
  112. 4427321UL, 4454670UL, 4482104UL, 4509622UL, 4537223UL, 4564907UL, 4592673UL, 4620520UL,
  113. 4648448UL, 4676456UL, 4704543UL, 4732709UL, 4760953UL, 4789274UL, 4817672UL, 4846146UL,
  114. 4874695UL, 4903319UL, 4932017UL, 4960788UL, 4989632UL, 5018548UL, 5047535UL, 5076593UL,
  115. 5105721UL, 5134918UL, 5164184UL, 5193518UL, 5222919UL, 5252387UL, 5281921UL, 5311520UL,
  116. 5341184UL, 5370912UL, 5400703UL, 5430557UL, 5460473UL, 5490450UL, 5520488UL, 5550586UL,
  117. 5580743UL, 5610959UL, 5641233UL, 5671564UL, 5701952UL, 5732396UL, 5762895UL, 5793449UL,
  118. 5824057UL, 5854718UL, 5885432UL, 5916198UL, 5947015UL, 5977883UL, 6008801UL, 6039768UL,
  119. 6070784UL, 6101848UL, 6132959UL, 6164117UL, 6195321UL, 6226570UL, 6257864UL, 6289202UL,
  120. 6320583UL, 6352007UL, 6383473UL, 6414980UL, 6446528UL, 6478116UL, 6509743UL, 6541409UL,
  121. 6573113UL, 6604854UL, 6636632UL, 6668446UL, 6700295UL, 6732179UL, 6764097UL, 6796048UL,
  122. 6828032UL, 6860048UL, 6892095UL, 6924173UL, 6956281UL, 6988418UL, 7020584UL, 7052778UL,
  123. 7084999UL, 7117247UL, 7149521UL, 7181820UL, 7214144UL, 7246492UL, 7278863UL, 7311257UL,
  124. 7343673UL, 7376110UL, 7408568UL, 7441046UL, 7473543UL, 7506059UL, 7538593UL, 7571144UL,
  125. 7603712UL, 7636296UL, 7668895UL, 7701509UL, 7734137UL, 7766778UL, 7799432UL, 7832098UL,
  126. 7864775UL, 7897463UL, 7930161UL, 7962868UL, 7995584UL, 8028308UL, 8061039UL, 8093777UL,
  127. 8126521UL, 8159270UL, 8192024UL, 8224782UL, 8257543UL, 8290307UL, 8323073UL, 8355840UL,
  128. 8388608UL
  129. };
  130. static const uint32_t PlsrPlannerSineIntegralQ24[PLSR_PLANNER_CURVE_TABLE_SIZE] =
  131. {
  132. 0UL, 0UL, 1UL, 3UL, 7UL, 13UL, 22UL, 35UL,
  133. 53UL, 75UL, 103UL, 137UL, 178UL, 226UL, 282UL, 347UL,
  134. 421UL, 505UL, 599UL, 705UL, 822UL, 951UL, 1094UL, 1250UL,
  135. 1420UL, 1604UL, 1805UL, 2021UL, 2254UL, 2503UL, 2771UL, 3057UL,
  136. 3362UL, 3687UL, 4032UL, 4398UL, 4785UL, 5194UL, 5626UL, 6081UL,
  137. 6560UL, 7063UL, 7592UL, 8146UL, 8726UL, 9333UL, 9967UL, 10630UL,
  138. 11321UL, 12041UL, 12791UL, 13571UL, 14382UL, 15225UL, 16100UL, 17008UL,
  139. 17949UL, 18923UL, 19933UL, 20977UL, 22057UL, 23173UL, 24325UL, 25516UL,
  140. 26744UL, 28010UL, 29316UL, 30661UL, 32046UL, 33472UL, 34939UL, 36449UL,
  141. 38000UL, 39595UL, 41233UL, 42915UL, 44642UL, 46414UL, 48232UL, 50096UL,
  142. 52007UL, 53966UL, 55972UL, 58027UL, 60131UL, 62284UL, 64487UL, 66742UL,
  143. 69047UL, 71404UL, 73813UL, 76275UL, 78790UL, 81359UL, 83982UL, 86660UL,
  144. 89393UL, 92182UL, 95028UL, 97930UL, 100890UL, 103908UL, 106984UL, 110119UL,
  145. 113314UL, 116568UL, 119882UL, 123258UL, 126695UL, 130194UL, 133755UL, 137379UL,
  146. 141066UL, 144817UL, 148632UL, 152512UL, 156457UL, 160468UL, 164545UL, 168688UL,
  147. 172899UL, 177177UL, 181523UL, 185937UL, 190421UL, 194973UL, 199596UL, 204289UL,
  148. 209052UL, 213886UL, 218792UL, 223770UL, 228820UL, 233943UL, 239140UL, 244409UL,
  149. 249753UL, 255172UL, 260665UL, 266234UL, 271878UL, 277599UL, 283396UL, 289270UL,
  150. 295221UL, 301250UL, 307358UL, 313543UL, 319808UL, 326151UL, 332575UL, 339078UL,
  151. 345662UL, 352326UL, 359072UL, 365899UL, 372808UL, 379799UL, 386873UL, 394029UL,
  152. 401269UL, 408592UL, 416000UL, 423491UL, 431068UL, 438729UL, 446475UL, 454307UL,
  153. 462225UL, 470229UL, 478320UL, 486497UL, 494762UL, 503114UL, 511554UL, 520082UL,
  154. 528698UL, 537403UL, 546197UL, 555080UL, 564053UL, 573116UL, 582268UL, 591511UL,
  155. 600845UL, 610269UL, 619785UL, 629392UL, 639090UL, 648881UL, 658763UL, 668739UL,
  156. 678806UL, 688967UL, 699221UL, 709568UL, 720008UL, 730543UL, 741171UL, 751894UL,
  157. 762711UL, 773623UL, 784629UL, 795731UL, 806928UL, 818220UL, 829608UL, 841092UL,
  158. 852672UL, 864348UL, 876121UL, 887990UL, 899955UL, 912018UL, 924178UL, 936435UL,
  159. 948789UL, 961241UL, 973790UL, 986438UL, 999183UL, 1012026UL, 1024968UL, 1038007UL,
  160. 1051146UL, 1064383UL, 1077718UL, 1091153UL, 1104686UL, 1118319UL, 1132051UL, 1145882UL,
  161. 1159812UL, 1173841UL, 1187971UL, 1202200UL, 1216528UL, 1230956UL, 1245485UL, 1260113UL,
  162. 1274841UL, 1289669UL, 1304597UL, 1319626UL, 1334754UL, 1349983UL, 1365312UL, 1380742UL,
  163. 1396271UL, 1411902UL, 1427632UL, 1443464UL, 1459395UL, 1475428UL, 1491560UL, 1507793UL,
  164. 1524127UL, 1540561UL, 1557096UL, 1573732UL, 1590467UL, 1607304UL, 1624240UL, 1641278UL,
  165. 1658415UL, 1675654UL, 1692992UL, 1710431UL, 1727970UL, 1745610UL, 1763349UL, 1781189UL,
  166. 1799129UL, 1817169UL, 1835309UL, 1853548UL, 1871888UL, 1890328UL, 1908867UL, 1927505UL,
  167. 1946244UL, 1965082UL, 1984019UL, 2003055UL, 2022190UL, 2041425UL, 2060758UL, 2080191UL,
  168. 2099722UL, 2119351UL, 2139080UL, 2158906UL, 2178831UL, 2198854UL, 2218974UL, 2239193UL,
  169. 2259509UL, 2279923UL, 2300434UL, 2321042UL, 2341747UL, 2362550UL, 2383449UL, 2404444UL,
  170. 2425536UL, 2446724UL, 2468008UL, 2489388UL, 2510864UL, 2532435UL, 2554101UL, 2575863UL,
  171. 2597719UL, 2619670UL, 2641715UL, 2663855UL, 2686088UL, 2708416UL, 2730837UL, 2753351UL,
  172. 2775958UL, 2798659UL, 2821451UL, 2844337UL, 2867314UL, 2890384UL, 2913545UL, 2936797UL,
  173. 2960141UL, 2983575UL, 3007100UL, 3030716UL, 3054421UL, 3078216UL, 3102101UL, 3126075UL,
  174. 3150138UL, 3174290UL, 3198530UL, 3222858UL, 3247274UL, 3271777UL, 3296368UL, 3321045UL,
  175. 3345809UL, 3370659UL, 3395595UL, 3420617UL, 3445724UL, 3470915UL, 3496192UL, 3521552UL,
  176. 3546997UL, 3572525UL, 3598137UL, 3623831UL, 3649608UL, 3675467UL, 3701408UL, 3727430UL,
  177. 3753534UL, 3779718UL, 3805983UL, 3832327UL, 3858752UL, 3885255UL, 3911838UL, 3938498UL,
  178. 3965237UL, 3992054UL, 4018948UL, 4045919UL, 4072966UL, 4100090UL, 4127289UL, 4154564UL,
  179. 4181913UL, 4209337UL, 4236836UL, 4264407UL, 4292052UL, 4319770UL, 4347560UL, 4375422UL,
  180. 4403356UL, 4431361UL, 4459436UL, 4487581UL, 4515797UL, 4544081UL, 4572435UL, 4600857UL,
  181. 4629347UL, 4657904UL, 4686529UL, 4715220UL, 4743977UL, 4772800UL, 4801688UL, 4830641UL,
  182. 4859658UL, 4888739UL, 4917883UL, 4947090UL, 4976359UL, 5005690UL, 5035082UL, 5064536UL,
  183. 5094050UL, 5123623UL, 5153256UL, 5182948UL, 5212698UL, 5242506UL, 5272372UL, 5302294UL,
  184. 5332273UL, 5362308UL, 5392398UL, 5422543UL, 5452742UL, 5482995UL, 5513301UL, 5543660UL,
  185. 5574071UL, 5604534UL, 5635047UL, 5665612UL, 5696227UL, 5726891UL, 5757604UL, 5788366UL,
  186. 5819175UL, 5850032UL, 5880936UL, 5911886UL, 5942882UL, 5973923UL, 6005009UL, 6036139UL,
  187. 6067312UL, 6098529UL, 6129787UL, 6161088UL, 6192430UL, 6223813UL, 6255236UL, 6286698UL,
  188. 6318200UL, 6349740UL, 6381317UL, 6412933UL, 6444585UL, 6476273UL, 6507997UL, 6539755UL,
  189. 6571549UL, 6603376UL, 6635236UL, 6667129UL, 6699054UL, 6731011UL, 6762999UL, 6795017UL,
  190. 6827065UL, 6859142UL, 6891247UL, 6923381UL, 6955542UL, 6987730UL, 7019944UL, 7052183UL,
  191. 7084448UL, 7116737UL, 7149050UL, 7181386UL, 7213745UL, 7246126UL, 7278528UL, 7310951UL,
  192. 7343394UL, 7375857UL, 7408339UL, 7440839UL, 7473358UL, 7505893UL, 7538445UL, 7571012UL,
  193. 7603596UL, 7636194UL, 7668806UL, 7701431UL, 7734070UL, 7766721UL, 7799383UL, 7832057UL,
  194. 7864741UL, 7897435UL, 7930138UL, 7962850UL, 7995570UL, 8028297UL, 8061031UL, 8093771UL,
  195. 8126517UL, 8159267UL, 8192022UL, 8224781UL, 8257543UL, 8290307UL, 8323073UL, 8355840UL,
  196. 8388608UL
  197. };
  198. static uint32_t PlsrPlannerAbsDifference(uint32_t first, uint32_t second)
  199. {
  200. return (first > second) ? (first - second) : (second - first);
  201. }
  202. static uint32_t PlsrPlannerRampTime(const PLSR_MOTION_BLOCK *block,uint32_t fromHz, uint32_t toHz)
  203. {
  204. uint32_t baseTimeMs;
  205. uint64_t durationMs;
  206. if (fromHz == toHz)
  207. {
  208. return 0UL;
  209. }
  210. baseTimeMs = (toHz > fromHz) ? block->accelerationTimeMs
  211. : block->decelerationTimeMs;
  212. if (baseTimeMs == 0UL)
  213. {
  214. return 0UL;
  215. }
  216. durationMs = ((uint64_t)PlsrPlannerAbsDifference(fromHz, toHz)
  217. * baseTimeMs + block->referenceSpeedHz - 1UL)
  218. / block->referenceSpeedHz;
  219. return (durationMs > 0xFFFFFFFFULL) ? 0xFFFFFFFFUL
  220. : (uint32_t)durationMs;
  221. }
  222. static uint16_t PlsrPlannerBaseRampTime(const PLSR_MOTION_BLOCK *block,
  223. uint32_t fromHz,
  224. uint32_t toHz)
  225. {
  226. if (toHz > fromHz)
  227. {
  228. return block->accelerationTimeMs;
  229. }
  230. if (toHz < fromHz)
  231. {
  232. return block->decelerationTimeMs;
  233. }
  234. return 0U;
  235. }
  236. static uint64_t PlsrPlannerRampWeight(uint32_t fromHz,
  237. uint32_t toHz,
  238. uint16_t baseTimeMs)
  239. {
  240. uint64_t fromSquared = (uint64_t)fromHz * fromHz;
  241. uint64_t toSquared = (uint64_t)toHz * toHz;
  242. uint64_t difference = (fromSquared > toSquared)
  243. ? (fromSquared - toSquared)
  244. : (toSquared - fromSquared);
  245. return difference * baseTimeMs;
  246. }
  247. static uint64_t PlsrPlannerRequiredPulses(const PLSR_MOTION_BLOCK *block,
  248. uint64_t rampWeight)
  249. {
  250. uint64_t denominator = (uint64_t)2U * block->referenceSpeedHz * 1000UL;
  251. return (rampWeight == 0ULL) ? 0ULL
  252. : (rampWeight + denominator - 1ULL)
  253. / denominator;
  254. }
  255. static uint32_t PlsrPlannerIntegerSquareRoot(uint64_t value)
  256. {
  257. uint64_t bit = (uint64_t)1U << 62U;
  258. uint64_t root = 0ULL;
  259. while (bit > value)
  260. {
  261. bit >>= 2U;
  262. }
  263. while (bit != 0ULL)
  264. {
  265. if (value >= root + bit)
  266. {
  267. value -= root + bit;
  268. root = (root >> 1U) + bit;
  269. }
  270. else
  271. {
  272. root >>= 1U;
  273. }
  274. bit >>= 2U;
  275. }
  276. return (uint32_t)root;
  277. }
  278. static uint32_t PlsrPlannerReachableFrequency(
  279. const PLSR_MOTION_BLOCK *block,
  280. uint32_t fromHz,
  281. uint32_t towardHz,
  282. uint32_t pulseCount)
  283. {
  284. uint16_t baseTimeMs = PlsrPlannerBaseRampTime(block, fromHz, towardHz);
  285. uint64_t frequencySquared = (uint64_t)fromHz * fromHz;
  286. uint64_t changeSquared;
  287. uint32_t reachableHz;
  288. if ((baseTimeMs == 0U) || (fromHz == towardHz))
  289. {
  290. return towardHz;
  291. }
  292. changeSquared = (uint64_t)2U * pulseCount * block->referenceSpeedHz
  293. * 1000UL / baseTimeMs;
  294. if (towardHz > fromHz)
  295. {
  296. reachableHz = PlsrPlannerIntegerSquareRoot(
  297. frequencySquared + changeSquared);
  298. return (reachableHz > towardHz) ? towardHz : reachableHz;
  299. }
  300. frequencySquared = (changeSquared >= frequencySquared)
  301. ? 0ULL : (frequencySquared - changeSquared);
  302. reachableHz = PlsrPlannerIntegerSquareRoot(frequencySquared);
  303. if ((uint64_t)reachableHz * reachableHz < frequencySquared)
  304. {
  305. reachableHz++;
  306. }
  307. return (reachableHz < towardHz) ? towardHz : reachableHz;
  308. }
  309. static uint32_t PlsrPlannerPeak(const PLSR_MOTION_BLOCK *block,
  310. uint32_t startHz,
  311. uint32_t endHz)
  312. {
  313. uint32_t targetHz = block->cruiseHz;
  314. uint32_t upperEndpoint = (startHz > endHz) ? startHz : endHz;
  315. uint32_t lowerEndpoint = (startHz < endHz) ? startHz : endHz;
  316. uint16_t entryTimeMs;
  317. uint16_t exitTimeMs;
  318. uint32_t timeSumMs;
  319. uint64_t weightedEndpoints;
  320. uint64_t availableArea;
  321. uint64_t peakSquared;
  322. uint32_t peakHz;
  323. if ((targetHz <= upperEndpoint) && (targetHz >= lowerEndpoint))
  324. {
  325. return targetHz;
  326. }
  327. entryTimeMs = PlsrPlannerBaseRampTime(block, startHz, targetHz);
  328. exitTimeMs = PlsrPlannerBaseRampTime(block, targetHz, endHz);
  329. timeSumMs = (uint32_t)entryTimeMs + exitTimeMs;
  330. if (timeSumMs == 0UL)
  331. {
  332. return targetHz;
  333. }
  334. weightedEndpoints = (uint64_t)startHz * startHz * entryTimeMs
  335. + (uint64_t)endHz * endHz * exitTimeMs;
  336. availableArea = (uint64_t)2U * block->pulseBudget
  337. * block->referenceSpeedHz * 1000UL;
  338. if (targetHz > upperEndpoint)
  339. {
  340. peakSquared = (availableArea + weightedEndpoints) / timeSumMs;
  341. peakHz = PlsrPlannerIntegerSquareRoot(peakSquared);
  342. if (peakHz < upperEndpoint)
  343. {
  344. peakHz = upperEndpoint;
  345. }
  346. return (peakHz > targetHz) ? targetHz : peakHz;
  347. }
  348. if (availableArea >= weightedEndpoints)
  349. {
  350. return targetHz;
  351. }
  352. peakSquared = (weightedEndpoints - availableArea) / timeSumMs;
  353. peakHz = PlsrPlannerIntegerSquareRoot(peakSquared);
  354. if (peakHz < targetHz)
  355. {
  356. peakHz = targetHz;
  357. }
  358. return (peakHz > lowerEndpoint) ? lowerEndpoint : peakHz;
  359. }
  360. //C(x)函数
  361. //瞬时速度=delta*C(x)
  362. static uint64_t PlsrPlannerCurveIntegralQ32(uint64_t progressQ32,
  363. uint16_t curveMode)
  364. {
  365. const uint32_t *table;
  366. uint64_t scaled;
  367. uint32_t index;
  368. uint32_t fraction;
  369. uint64_t first;
  370. uint64_t second;
  371. if (progressQ32 >= PLSR_PLANNER_Q32_ONE)
  372. {
  373. return PLSR_PLANNER_Q32_ONE / 2ULL;
  374. }
  375. if (curveMode == 0U)
  376. {
  377. return (progressQ32 * progressQ32) >> 33U;
  378. }
  379. table = (curveMode == 1U) ? PlsrPlannerSmoothIntegralQ24
  380. : PlsrPlannerSineIntegralQ24;
  381. scaled = progressQ32 * PLSR_PLANNER_CURVE_TABLE_INTERVALS;
  382. index = (uint32_t)(scaled >> 32U);
  383. fraction = (uint32_t)scaled;
  384. first = (uint64_t)table[index] << 8U;
  385. second = (uint64_t)table[index + 1UL] << 8U;
  386. return first + (((second - first) * fraction) >> 32U);
  387. }
  388. static uint64_t PlsrPlannerRampAreaQ32(const PLSR_PLANNER_CONTEXT *context,
  389. uint32_t fromHz,
  390. uint32_t toHz,
  391. uint64_t progressQ32)
  392. {
  393. int64_t delta = (int64_t)toHz - (int64_t)fromHz;
  394. int64_t area = (int64_t)((uint64_t)fromHz * progressQ32)
  395. + delta * (int64_t)PlsrPlannerCurveIntegralQ32(
  396. progressQ32, context->block.curveMode);
  397. return (uint64_t)area;
  398. }
  399. static uint64_t PlsrPlannerExactBoundaryQ32(
  400. const PLSR_PLANNER_CONTEXT *context,
  401. uint64_t previousBoundaryQ32,
  402. uint64_t targetAreaQ32)
  403. {
  404. uint64_t lowerQ32 = previousBoundaryQ32;
  405. uint64_t upperQ32 = PLSR_PLANNER_Q32_ONE;
  406. uint64_t middleQ32;
  407. uint32_t iteration;
  408. for (iteration = 0UL; iteration < 32UL; iteration++)
  409. {
  410. middleQ32 = lowerQ32 + ((upperQ32 - lowerQ32) >> 1U);
  411. if (PlsrPlannerRampAreaQ32(context, context->rampFromHz,
  412. context->rampToHz, middleQ32)
  413. < targetAreaQ32)
  414. {
  415. lowerQ32 = middleQ32;
  416. }
  417. else
  418. {
  419. upperQ32 = middleQ32;
  420. }
  421. }
  422. return upperQ32;
  423. }
  424. static uint32_t PlsrPlannerInstantFrequency(
  425. const PLSR_PLANNER_CONTEXT *context,
  426. uint64_t progressQ32)
  427. {
  428. const uint32_t *table;
  429. uint64_t scaled;
  430. uint64_t curveProgressQ32;
  431. uint32_t index;
  432. uint32_t gap;
  433. if (progressQ32 >= PLSR_PLANNER_Q32_ONE)
  434. {
  435. return context->rampToHz;
  436. }
  437. if (context->block.curveMode == 0U)
  438. {
  439. curveProgressQ32 = progressQ32;
  440. }
  441. else
  442. {
  443. table = (context->block.curveMode == 1U)
  444. ? PlsrPlannerSmoothIntegralQ24
  445. : PlsrPlannerSineIntegralQ24;
  446. scaled = progressQ32 * PLSR_PLANNER_CURVE_TABLE_INTERVALS;
  447. index = (uint32_t)(scaled >> 32U);
  448. curveProgressQ32 =
  449. (uint64_t)(table[index + 1UL] - table[index])
  450. << PLSR_PLANNER_CURVE_DERIVATIVE_SHIFT;
  451. }
  452. if (context->rampToHz >= context->rampFromHz)
  453. {
  454. gap = context->rampToHz - context->rampFromHz;
  455. return context->rampFromHz
  456. + (uint32_t)(((uint64_t)gap * curveProgressQ32) >> 32U);
  457. }
  458. gap = context->rampFromHz - context->rampToHz;
  459. return context->rampFromHz
  460. - (uint32_t)(((uint64_t)gap * curveProgressQ32) >> 32U);
  461. }
  462. static uint64_t PlsrPlannerPredictedBoundaryQ32(
  463. const PLSR_PLANNER_CONTEXT *context,
  464. uint64_t targetAreaQ32)
  465. {
  466. uint64_t previousQ32 = context->rampBoundaryQ32;
  467. uint64_t currentAreaQ32 = (previousQ32 == 0ULL)
  468. ? 0ULL
  469. : PlsrPlannerRampAreaQ32(
  470. context, context->rampFromHz,
  471. context->rampToHz, previousQ32);
  472. uint64_t candidateQ32;
  473. uint64_t candidateAreaQ32;
  474. uint64_t differenceQ32;
  475. uint64_t correctionQ32;
  476. uint32_t derivativeHz;
  477. if (context->rampLastPhaseStepQ32
  478. >= PLSR_PLANNER_Q32_ONE - previousQ32)
  479. {
  480. candidateQ32 = PLSR_PLANNER_Q32_ONE;
  481. }
  482. else if (context->rampLastPhaseStepQ32 != 0ULL)
  483. {
  484. candidateQ32 = previousQ32 + context->rampLastPhaseStepQ32;
  485. }
  486. else
  487. {
  488. derivativeHz = PlsrPlannerInstantFrequency(context, previousQ32);
  489. if (derivativeHz == 0UL)
  490. {
  491. derivativeHz = 1UL;
  492. }
  493. differenceQ32 = targetAreaQ32 - currentAreaQ32;
  494. correctionQ32 = (differenceQ32 + derivativeHz - 1UL)
  495. / derivativeHz;
  496. candidateQ32 = (correctionQ32
  497. >= PLSR_PLANNER_Q32_ONE - previousQ32)
  498. ? PLSR_PLANNER_Q32_ONE
  499. : previousQ32 + correctionQ32;
  500. }
  501. candidateAreaQ32 = PlsrPlannerRampAreaQ32(
  502. context, context->rampFromHz, context->rampToHz, candidateQ32);
  503. derivativeHz = PlsrPlannerInstantFrequency(context, candidateQ32);
  504. if (derivativeHz == 0UL)
  505. {
  506. derivativeHz = 1UL;
  507. }
  508. if (candidateAreaQ32 < targetAreaQ32)
  509. {
  510. differenceQ32 = targetAreaQ32 - candidateAreaQ32;
  511. correctionQ32 = (differenceQ32 + derivativeHz - 1UL)
  512. / derivativeHz;
  513. candidateQ32 = (correctionQ32
  514. >= PLSR_PLANNER_Q32_ONE - candidateQ32)
  515. ? PLSR_PLANNER_Q32_ONE
  516. : candidateQ32 + correctionQ32;
  517. }
  518. else if (candidateAreaQ32 > targetAreaQ32)
  519. {
  520. differenceQ32 = candidateAreaQ32 - targetAreaQ32;
  521. correctionQ32 = differenceQ32 / derivativeHz;
  522. if (correctionQ32 == 0ULL)
  523. {
  524. correctionQ32 = 1ULL;
  525. }
  526. candidateQ32 = (correctionQ32 >= candidateQ32 - previousQ32)
  527. ? previousQ32 + 1ULL
  528. : candidateQ32 - correctionQ32;
  529. }
  530. return candidateQ32;
  531. }
  532. static void PlsrPlannerStartRamp(PLSR_PLANNER_CONTEXT *context,
  533. uint8_t rampKind,
  534. uint32_t fromHz,
  535. uint32_t toHz,
  536. uint32_t pulseCount)
  537. {
  538. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  539. && !defined(PLSR_HOST_TEST)
  540. uint32_t totalStartedAt = PlsrPlannerTimingNow();
  541. uint32_t phaseStartedAt;
  542. #endif
  543. context->rampKind = rampKind;
  544. context->rampRelativePulse = 0UL;
  545. context->rampPulseCount = pulseCount;
  546. context->rampFromHz = fromHz;
  547. context->rampToHz = toHz;
  548. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  549. && !defined(PLSR_HOST_TEST)
  550. phaseStartedAt = PlsrPlannerTimingNow();
  551. #endif
  552. context->rampDurationMs = PlsrPlannerRampTime(&context->block, fromHz, toHz);
  553. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  554. && !defined(PLSR_HOST_TEST)
  555. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampTime, phaseStartedAt);
  556. phaseStartedAt = PlsrPlannerTimingNow();
  557. #endif
  558. context->rampTotalAreaQ32 = PlsrPlannerRampAreaQ32(
  559. context, fromHz, toHz, PLSR_PLANNER_Q32_ONE);
  560. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  561. && !defined(PLSR_HOST_TEST)
  562. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampTotalArea,
  563. phaseStartedAt);
  564. phaseStartedAt = PlsrPlannerTimingNow();
  565. #endif
  566. context->rampAreaStepQ32 = context->rampTotalAreaQ32 / pulseCount;
  567. context->rampAreaRemainder =
  568. (uint32_t)(context->rampTotalAreaQ32 % pulseCount);
  569. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  570. && !defined(PLSR_HOST_TEST)
  571. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampAreaSplit,
  572. phaseStartedAt);
  573. #endif
  574. context->rampRemainderAccumulator = 0UL;
  575. context->rampTargetAreaQ32 = 0ULL;
  576. context->rampBoundaryQ32 = 0ULL;
  577. context->rampActualTimeQ32 = 0ULL;
  578. context->rampLastPhaseStepQ32 = 0ULL;
  579. context->lastRampHz = 0UL;
  580. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  581. && !defined(PLSR_HOST_TEST)
  582. phaseStartedAt = PlsrPlannerTimingNow();
  583. #endif
  584. context->rampFirstBoundaryQ32 = PlsrPlannerExactBoundaryQ32(
  585. context, 0ULL, context->rampAreaStepQ32);
  586. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  587. && !defined(PLSR_HOST_TEST)
  588. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampFirstBoundary,
  589. phaseStartedAt);
  590. #endif
  591. if (pulseCount > 1UL)
  592. {
  593. uint64_t secondTargetAreaQ32;
  594. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  595. && !defined(PLSR_HOST_TEST)
  596. phaseStartedAt = PlsrPlannerTimingNow();
  597. #endif
  598. secondTargetAreaQ32 = context->rampAreaStepQ32 * 2ULL
  599. + ((uint64_t)context->rampAreaRemainder * 2ULL) / pulseCount;
  600. context->rampSecondBoundaryQ32 = PlsrPlannerExactBoundaryQ32(
  601. context, context->rampFirstBoundaryQ32,
  602. secondTargetAreaQ32);
  603. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  604. && !defined(PLSR_HOST_TEST)
  605. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampSecondBoundary,
  606. phaseStartedAt);
  607. #endif
  608. }
  609. else
  610. {
  611. context->rampSecondBoundaryQ32 = PLSR_PLANNER_Q32_ONE;
  612. }
  613. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  614. && !defined(PLSR_HOST_TEST)
  615. PlsrPlannerTimingRecord(&PlsrPlannerTiming.startRamp, totalStartedAt);
  616. #endif
  617. }
  618. static uint8_t PlsrPlannerSameSetting(
  619. const PLSR_PLATFORM_TIMER_SETTING *first,
  620. const PLSR_PLATFORM_TIMER_SETTING *second)
  621. {
  622. return ((first->actualFrequencyHz == second->actualFrequencyHz)
  623. && (first->prescaler == second->prescaler)
  624. && (first->pairPrescaler == second->pairPrescaler)
  625. && (first->period == second->period)
  626. && (first->compare == second->compare)) ? 1U : 0U;
  627. }
  628. static uint8_t PlsrPlannerBuildStep(PLSR_PLANNER_CONTEXT *context,
  629. uint32_t requestedHz,
  630. PLSR_PLATFORM_TIMER_SETTING *setting,
  631. uint32_t *normalizedRequestedHz)
  632. {
  633. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  634. && !defined(PLSR_HOST_TEST)
  635. uint32_t startedAt;
  636. uint8_t result;
  637. #endif
  638. if (requestedHz == 0UL)
  639. {
  640. requestedHz = 1UL;
  641. }
  642. if (requestedHz > PLSR_FREQUENCY_MAX_HZ)
  643. {
  644. requestedHz = PLSR_FREQUENCY_MAX_HZ;
  645. }
  646. *normalizedRequestedHz = requestedHz;
  647. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  648. && !defined(PLSR_HOST_TEST)
  649. startedAt = PlsrPlannerTimingNow();
  650. result = PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
  651. PLSR_OUTPUT_PULSE_DIR,
  652. requestedHz, setting);
  653. PlsrPlannerTimingRecord(&PlsrPlannerTiming.timerSetting, startedAt);
  654. return result;
  655. #else
  656. return PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
  657. PLSR_OUTPUT_PULSE_DIR,
  658. requestedHz, setting);
  659. #endif
  660. }
  661. static uint8_t PlsrPlannerTakeRampStep(
  662. PLSR_PLANNER_CONTEXT *context,
  663. PLSR_PLATFORM_TIMER_SETTING *setting,
  664. uint32_t *requestedFrequencyHz)
  665. {
  666. uint64_t nextBoundaryQ32;
  667. uint64_t desiredDeltaQ32;
  668. uint64_t denominator;
  669. uint64_t requestedHz;
  670. uint64_t actualDeltaQ32;
  671. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  672. && !defined(PLSR_HOST_TEST)
  673. uint32_t totalStartedAt = PlsrPlannerTimingNow();
  674. uint32_t phaseStartedAt;
  675. #endif
  676. context->rampTargetAreaQ32 += context->rampAreaStepQ32;
  677. context->rampRemainderAccumulator += context->rampAreaRemainder;
  678. if (context->rampRemainderAccumulator >= context->rampPulseCount)
  679. {
  680. context->rampTargetAreaQ32++;
  681. context->rampRemainderAccumulator -= context->rampPulseCount;
  682. }
  683. if (context->rampRelativePulse + 1UL >= context->rampPulseCount)
  684. {
  685. context->rampTargetAreaQ32 = context->rampTotalAreaQ32;
  686. nextBoundaryQ32 = PLSR_PLANNER_Q32_ONE;
  687. }
  688. else if (context->rampRelativePulse == 0UL)
  689. {
  690. nextBoundaryQ32 = context->rampFirstBoundaryQ32;
  691. }
  692. else if (context->rampRelativePulse == 1UL)
  693. {
  694. nextBoundaryQ32 = context->rampSecondBoundaryQ32;
  695. }
  696. else
  697. {
  698. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  699. && !defined(PLSR_HOST_TEST)
  700. phaseStartedAt = PlsrPlannerTimingNow();
  701. #endif
  702. nextBoundaryQ32 = PlsrPlannerPredictedBoundaryQ32(
  703. context, context->rampTargetAreaQ32);
  704. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  705. && !defined(PLSR_HOST_TEST)
  706. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampPredictedBoundary,
  707. phaseStartedAt);
  708. #endif
  709. }
  710. desiredDeltaQ32 = (nextBoundaryQ32 > context->rampActualTimeQ32)
  711. ? (nextBoundaryQ32 - context->rampActualTimeQ32)
  712. : 1ULL;
  713. /* The allocated pulse count closes the ramp area exactly. Derive the
  714. physical duration from N/averageHz instead of rounding it to whole
  715. milliseconds; short clipped ramps can be well below 1 ms. */
  716. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  717. && !defined(PLSR_HOST_TEST)
  718. phaseStartedAt = PlsrPlannerTimingNow();
  719. #endif
  720. denominator = (uint64_t)context->rampPulseCount * desiredDeltaQ32;
  721. requestedHz = (denominator == 0ULL)
  722. ? context->rampToHz
  723. : (context->rampTotalAreaQ32
  724. + denominator / 2ULL) / denominator;
  725. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  726. && !defined(PLSR_HOST_TEST)
  727. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampRequestedDivide,
  728. phaseStartedAt);
  729. #endif
  730. if (requestedHz == 0ULL)
  731. {
  732. requestedHz = 1ULL;
  733. }
  734. if (requestedHz > PLSR_FREQUENCY_MAX_HZ)
  735. {
  736. requestedHz = PLSR_FREQUENCY_MAX_HZ;
  737. }
  738. if ((context->lastRampHz != 0UL)
  739. && (((context->rampToHz > context->rampFromHz)
  740. && (requestedHz < context->lastRampHz))
  741. || ((context->rampToHz < context->rampFromHz)
  742. && (requestedHz > context->lastRampHz))))
  743. {
  744. requestedHz = context->lastRampHz;
  745. }
  746. if (PlsrPlannerBuildStep(context, (uint32_t)requestedHz, setting,
  747. requestedFrequencyHz) == 0U)
  748. {
  749. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  750. && !defined(PLSR_HOST_TEST)
  751. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampStep,
  752. totalStartedAt);
  753. #endif
  754. return 0U;
  755. }
  756. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  757. && !defined(PLSR_HOST_TEST)
  758. phaseStartedAt = PlsrPlannerTimingNow();
  759. #endif
  760. denominator = (uint64_t)context->rampPulseCount
  761. * setting->actualFrequencyHz;
  762. actualDeltaQ32 = (denominator == 0ULL)
  763. ? desiredDeltaQ32
  764. : (context->rampTotalAreaQ32
  765. + denominator / 2ULL) / denominator;
  766. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  767. && !defined(PLSR_HOST_TEST)
  768. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampActualDivide,
  769. phaseStartedAt);
  770. #endif
  771. context->rampActualTimeQ32 += actualDeltaQ32;
  772. context->rampLastPhaseStepQ32 =
  773. nextBoundaryQ32 - context->rampBoundaryQ32;
  774. context->rampBoundaryQ32 = nextBoundaryQ32;
  775. context->lastRampHz = setting->actualFrequencyHz;
  776. context->rampRelativePulse++;
  777. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  778. && !defined(PLSR_HOST_TEST)
  779. PlsrPlannerTimingRecord(&PlsrPlannerTiming.rampStep, totalStartedAt);
  780. #endif
  781. return 1U;
  782. }
  783. static uint8_t PlsrPlannerTakeStep(PLSR_PLANNER_CONTEXT *context,
  784. PLSR_PLATFORM_TIMER_SETTING *setting,
  785. uint32_t *requestedFrequencyHz,
  786. uint32_t *repeatCount)
  787. {
  788. uint32_t entryEnd = context->entryPulses;
  789. //加速段结束门槛。已经吐出的脉冲 < entryEnd 还在加速。例如加速 1000,这里就是 1000
  790. uint32_t steadyEnd = entryEnd + context->steadyPulses;
  791. //匀速段结束门槛。< steadyEnd 且 ≥ entryEnd 就是匀速。例如再加 5000 匀速,这里就是 6000。再往后是减速
  792. *repeatCount = 1UL;
  793. if (context->generatedPulses >= context->block.pulseBudget)
  794. {
  795. return 0U;
  796. }
  797. if (context->generatedPulses < entryEnd)
  798. { //加速段
  799. if (context->rampKind != 1U)
  800. { // 第一次走进加速
  801. PlsrPlannerStartRamp(context, 1U, context->startHz,context->peakHz, context->entryPulses);
  802. }
  803. return PlsrPlannerTakeRampStep(context, setting,requestedFrequencyHz);
  804. }
  805. if (context->generatedPulses < steadyEnd)
  806. {
  807. *repeatCount = steadyEnd - context->generatedPulses;
  808. context->rampKind = 0U;
  809. return PlsrPlannerBuildStep(context, context->peakHz, setting,
  810. requestedFrequencyHz);
  811. }
  812. if (context->rampKind != 2U)
  813. { // 第一次走进减速
  814. PlsrPlannerStartRamp(context, 2U, context->peakHz,
  815. context->endHz, context->exitPulses);
  816. }
  817. return PlsrPlannerTakeRampStep(context, setting,
  818. requestedFrequencyHz);
  819. }
  820. PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
  821. const PLSR_MOTION_BLOCK *block,
  822. uint32_t appliedHz,
  823. uint64_t phasePulses)
  824. {
  825. uint64_t directRequired;
  826. uint64_t entryRequired;
  827. uint64_t exitRequired;
  828. uint64_t entryWeight;
  829. uint64_t exitWeight;
  830. uint64_t totalWeight;
  831. uint64_t scaledEntry;
  832. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  833. && !defined(PLSR_HOST_TEST)
  834. uint32_t startedAt = PlsrPlannerTimingNow();
  835. #endif
  836. if ((context == NULL) || (block == NULL)
  837. || (block->pulseBudget == 0UL)
  838. || (block->referenceSpeedHz == 0UL)
  839. || (block->referenceSpeedHz > PLSR_FREQUENCY_MAX_HZ)
  840. || (block->entryHz > PLSR_FREQUENCY_MAX_HZ)
  841. || (block->cruiseHz == 0UL)
  842. || (block->cruiseHz > PLSR_FREQUENCY_MAX_HZ)
  843. || (block->exitHz > PLSR_FREQUENCY_MAX_HZ)
  844. || (appliedHz > PLSR_FREQUENCY_MAX_HZ)
  845. || (block->curveMode > 2U) || (block->pulseOutput > 3U))
  846. {
  847. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  848. && !defined(PLSR_HOST_TEST)
  849. PlsrPlannerTimingRecord(&PlsrPlannerTiming.begin, startedAt);
  850. #endif
  851. return PLSR_PLANNER_INVALID;
  852. }
  853. (void)memset(context, 0, sizeof(*context));
  854. context->block = *block;
  855. context->phasePulses = phasePulses;
  856. context->startHz = (appliedHz != 0UL) ? appliedHz : block->entryHz;
  857. if (context->startHz == 0UL)
  858. {
  859. context->startHz = 1UL;
  860. }
  861. context->endHz = (block->exitHz == 0UL) ? 1UL : block->exitHz;
  862. directRequired = PlsrPlannerRequiredPulses(
  863. block, PlsrPlannerRampWeight(
  864. context->startHz, context->endHz,
  865. PlsrPlannerBaseRampTime(block, context->startHz,
  866. context->endHz)));
  867. if (directRequired > block->pulseBudget)
  868. {
  869. context->peakHz = PlsrPlannerReachableFrequency(
  870. block, context->startHz, context->endHz, block->pulseBudget);
  871. context->endHz = context->peakHz;
  872. context->entryPulses = block->pulseBudget;
  873. context->clipped = 1U;
  874. context->active = 1U;
  875. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  876. && !defined(PLSR_HOST_TEST)
  877. PlsrPlannerTimingRecord(&PlsrPlannerTiming.begin, startedAt);
  878. #endif
  879. return PLSR_PLANNER_CLIPPED;
  880. }
  881. context->peakHz = PlsrPlannerPeak(block, context->startHz,
  882. context->endHz);
  883. entryWeight = PlsrPlannerRampWeight(
  884. context->startHz, context->peakHz,
  885. PlsrPlannerBaseRampTime(block, context->startHz, context->peakHz));
  886. exitWeight = PlsrPlannerRampWeight(
  887. context->peakHz, context->endHz,
  888. PlsrPlannerBaseRampTime(block, context->peakHz, context->endHz));
  889. entryRequired = PlsrPlannerRequiredPulses(block, entryWeight);
  890. exitRequired = PlsrPlannerRequiredPulses(block, exitWeight);
  891. if ((entryRequired + exitRequired) <= block->pulseBudget)
  892. {
  893. context->entryPulses = (uint32_t)entryRequired;
  894. context->exitPulses = (uint32_t)exitRequired;
  895. context->steadyPulses = block->pulseBudget
  896. - context->entryPulses
  897. - context->exitPulses;
  898. }
  899. else if (entryRequired == 0ULL)
  900. {
  901. context->exitPulses = block->pulseBudget;
  902. context->clipped = 1U;
  903. }
  904. else if (exitRequired == 0ULL)
  905. {
  906. context->entryPulses = block->pulseBudget;
  907. context->clipped = 1U;
  908. }
  909. else
  910. {
  911. totalWeight = entryWeight + exitWeight;
  912. scaledEntry = ((uint64_t)block->pulseBudget * entryWeight
  913. + totalWeight / 2ULL) / totalWeight;
  914. if (scaledEntry == 0ULL)
  915. {
  916. scaledEntry = 1ULL;
  917. }
  918. if (scaledEntry >= block->pulseBudget)
  919. {
  920. scaledEntry = block->pulseBudget - 1UL;
  921. }
  922. context->entryPulses = (uint32_t)scaledEntry;
  923. context->exitPulses = block->pulseBudget
  924. - context->entryPulses;
  925. context->clipped = 1U;
  926. }
  927. if (context->peakHz != block->cruiseHz)
  928. {
  929. context->clipped = 1U;
  930. }
  931. context->active = 1U;
  932. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  933. && !defined(PLSR_HOST_TEST)
  934. PlsrPlannerTimingRecord(&PlsrPlannerTiming.begin, startedAt);
  935. #endif
  936. return (context->clipped != 0U) ? PLSR_PLANNER_CLIPPED
  937. : PLSR_PLANNER_OK;
  938. }
  939. //返回值:实际写了几项(合并后的项数,不是脉冲数)。0 = 没吐出任何东西
  940. uint16_t PlsrPlannerGenerate(PLSR_PLANNER_CONTEXT *context,//规划账本:三段脉冲、已经吐了多少、斜坡面积指针
  941. PLSR_STREAM_ITEM *output,//输出数组,调用方准备好的格子
  942. uint16_t capacity)//这一次最多往 output 里写几项
  943. {
  944. PLSR_PLATFORM_TIMER_SETTING setting;
  945. uint32_t requestedFrequencyHz;
  946. uint32_t repeatCount;
  947. uint16_t produced = 0U;
  948. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  949. && !defined(PLSR_HOST_TEST)
  950. uint32_t startedAt = PlsrPlannerTimingNow();
  951. #endif
  952. if ((context == NULL) || (output == NULL) || (capacity == 0U)
  953. || (context->active == 0U))
  954. {
  955. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  956. && !defined(PLSR_HOST_TEST)
  957. PlsrPlannerTimingRecord(&PlsrPlannerTiming.generate, startedAt);
  958. #endif
  959. return 0U;
  960. }
  961. while ((produced < capacity)&& (context->generatedPulses < context->block.pulseBudget))
  962. { //输出数组还没写满&&本段预算还没全部交给外面。generatedPulses 按脉冲个数计
  963. if (PlsrPlannerTakeStep(context, &setting, &requestedFrequencyHz, &repeatCount) == 0U)
  964. //本圈 TakeStep 算出的量化后 PSC/ARR/actualHz,先放栈上
  965. {
  966. context->active = 0U;//规划器关掉
  967. break;
  968. }
  969. if ((produced != 0U)
  970. && (PlsrPlannerSameSetting(&output[produced - 1U].setting,&setting) != 0U)
  971. && (output[produced - 1U].requestedFrequencyHz
  972. == requestedFrequencyHz)
  973. && (output[produced - 1U].repeatCount
  974. <= 0xFFFFFFFFUL - repeatCount))
  975. {
  976. output[produced - 1U].repeatCount += repeatCount;
  977. //不用开新格
  978. }
  979. else
  980. {
  981. output[produced].setting = setting;
  982. output[produced].requestedFrequencyHz = requestedFrequencyHz;
  983. output[produced].repeatCount = repeatCount;
  984. produced++;
  985. }
  986. context->generatedPulses += repeatCount;
  987. }
  988. if (context->generatedPulses >= context->block.pulseBudget)
  989. {
  990. context->active = 0U;
  991. }
  992. #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
  993. && !defined(PLSR_HOST_TEST)
  994. PlsrPlannerTimingRecord(&PlsrPlannerTiming.generate, startedAt);
  995. #endif
  996. return produced;
  997. }
  998. #if !defined(PLSR_HOST_TEST)
  999. static uint32_t PlsrPlannerBenchmarkCyclesNow(void)
  1000. {
  1001. return *((volatile uint32_t *)PLSR_PLANNER_BENCHMARK_DWT_CYCCNT);
  1002. }
  1003. static void PlsrPlannerBenchmarkEnableCounter(void)
  1004. {
  1005. *((volatile uint32_t *)PLSR_PLANNER_BENCHMARK_DEMCR_ADDRESS) |=
  1006. PLSR_PLANNER_BENCHMARK_TRCENA;
  1007. *((volatile uint32_t *)PLSR_PLANNER_BENCHMARK_DWT_CYCCNT) = 0UL;
  1008. *((volatile uint32_t *)PLSR_PLANNER_BENCHMARK_DWT_CTRL) |=
  1009. PLSR_PLANNER_BENCHMARK_CYCCNTENA;
  1010. }
  1011. static uint32_t PlsrPlannerBenchmarkCyclesQ16(uint32_t cycles,
  1012. uint32_t pulses)
  1013. {
  1014. if (pulses == 0UL)
  1015. {
  1016. return 0UL;
  1017. }
  1018. return (uint32_t)((((uint64_t)cycles << 16U) + pulses / 2UL)
  1019. / pulses);
  1020. }
  1021. static void PlsrPlannerBenchmarkMode(uint16_t curveMode)
  1022. {
  1023. PLSR_MOTION_BLOCK block;
  1024. PLSR_PLANNER_CONTEXT context;
  1025. PLSR_STREAM_ITEM item;
  1026. PLSR_PLANNER_BENCHMARK_RESULT result;
  1027. PLSR_PLANNER_STATUS status;
  1028. uint64_t totalCycles = 0ULL;
  1029. uint32_t minimumBlockQ16 = 0xFFFFFFFFUL;
  1030. uint32_t maximumBlockQ16 = 0UL;
  1031. uint32_t generateCalls = 0UL;
  1032. uint8_t failed = 0U;
  1033. (void)memset(&block, 0, sizeof(block));
  1034. (void)memset(&context, 0, sizeof(context));
  1035. (void)memset(&item, 0, sizeof(item));
  1036. (void)memset(&result, 0, sizeof(result));
  1037. block.entryHz = 1UL;
  1038. block.cruiseHz = PLSR_PLANNER_BENCHMARK_TARGET_HZ;
  1039. block.exitHz = 1UL;
  1040. block.pulseBudget = PLSR_PLANNER_BENCHMARK_PULSES;
  1041. block.referenceSpeedHz = PLSR_PLANNER_BENCHMARK_TARGET_HZ;
  1042. block.accelerationTimeMs = 1000U;
  1043. block.decelerationTimeMs = 1000U;
  1044. block.curveMode = curveMode;
  1045. block.pulseOutput = 0U;
  1046. block.boundary = PLSR_BOUNDARY_STOP;
  1047. status = PlsrPlannerBegin(&context, &block, 0UL, 0ULL);
  1048. result.curveMode = curveMode;
  1049. result.beginStatus = (uint32_t)status;
  1050. if (status == PLSR_PLANNER_OK)
  1051. {
  1052. while (context.active != 0U)
  1053. {
  1054. uint32_t batchCalls = 0UL;
  1055. uint32_t startedAt = PlsrPlannerBenchmarkCyclesNow();
  1056. uint32_t elapsed;
  1057. uint32_t blockQ16;
  1058. while ((batchCalls < PLSR_PLANNER_BENCHMARK_BATCH_CALLS)
  1059. && (context.active != 0U))
  1060. {
  1061. if (PlsrPlannerGenerate(&context, &item, 1U) == 0U)
  1062. {
  1063. failed = 1U;
  1064. break;
  1065. }
  1066. batchCalls++;
  1067. }
  1068. elapsed = PlsrPlannerBenchmarkCyclesNow() - startedAt;
  1069. if (batchCalls != 0UL)
  1070. {
  1071. blockQ16 = PlsrPlannerBenchmarkCyclesQ16(elapsed,
  1072. batchCalls);
  1073. totalCycles += elapsed;
  1074. generateCalls += batchCalls;
  1075. if (blockQ16 < minimumBlockQ16)
  1076. {
  1077. minimumBlockQ16 = blockQ16;
  1078. }
  1079. if (blockQ16 > maximumBlockQ16)
  1080. {
  1081. maximumBlockQ16 = blockQ16;
  1082. }
  1083. }
  1084. if (failed != 0U)
  1085. {
  1086. break;
  1087. }
  1088. }
  1089. }
  1090. result.plannedPulses = context.generatedPulses;
  1091. result.generateCalls = generateCalls;
  1092. result.totalCycles = totalCycles;
  1093. result.minimumBlockCyclesPerPulseQ16 =
  1094. (minimumBlockQ16 == 0xFFFFFFFFUL) ? 0UL : minimumBlockQ16;
  1095. result.maximumBlockCyclesPerPulseQ16 = maximumBlockQ16;
  1096. if ((context.generatedPulses != 0UL) && (totalCycles != 0ULL))
  1097. {
  1098. uint64_t averageQ16 = ((totalCycles << 16U)
  1099. + context.generatedPulses / 2UL)
  1100. / context.generatedPulses;
  1101. uint64_t estimatedHz =
  1102. ((uint64_t)PlsrPlannerBenchmarkCoreClockHz
  1103. * context.generatedPulses + totalCycles / 2ULL)
  1104. / totalCycles;
  1105. uint64_t targetCyclesQ16 =
  1106. ((uint64_t)PlsrPlannerBenchmarkCoreClockHz << 16U)
  1107. / PLSR_PLANNER_BENCHMARK_TARGET_HZ;
  1108. result.averageCyclesPerPulseQ16 =
  1109. (averageQ16 > 0xFFFFFFFFULL) ? 0xFFFFFFFFUL
  1110. : (uint32_t)averageQ16;
  1111. result.estimatedPulsesPerSecond =
  1112. (estimatedHz > 0xFFFFFFFFULL) ? 0xFFFFFFFFUL
  1113. : (uint32_t)estimatedHz;
  1114. result.passes100k = (averageQ16 <= targetCyclesQ16) ? 1UL : 0UL;
  1115. }
  1116. result.completed = ((failed == 0U)
  1117. && (context.generatedPulses
  1118. == PLSR_PLANNER_BENCHMARK_PULSES)
  1119. && (context.active == 0U)) ? 1UL : 0UL;
  1120. PlsrPlannerBenchmarkResults[curveMode] = result;
  1121. }
  1122. void PlsrPlannerBenchmarkService(void)
  1123. {
  1124. uint16_t curveMode;
  1125. if ((PlsrPlannerBenchmarkRequest == 0UL)
  1126. || (PlsrPlannerBenchmarkRunning != 0UL))
  1127. {
  1128. return;
  1129. }
  1130. PlsrPlannerBenchmarkRequest = 0UL;
  1131. PlsrPlannerBenchmarkRunning = 1UL;
  1132. (void)memset((void *)PlsrPlannerBenchmarkResults, 0,
  1133. sizeof(PlsrPlannerBenchmarkResults));
  1134. PlsrPlannerBenchmarkEnableCounter();
  1135. for (curveMode = 0U; curveMode < 3U; curveMode++)
  1136. {
  1137. PlsrPlannerBenchmarkMode(curveMode);
  1138. }
  1139. if (PlsrPlannerBenchmarkRunCount != 0xFFFFFFFFUL)
  1140. {
  1141. PlsrPlannerBenchmarkRunCount++;
  1142. }
  1143. PlsrPlannerBenchmarkRunning = 0UL;
  1144. }
  1145. #endif
  1146. static uint64_t PlsrPlannerRampDurationUs(uint32_t pulseCount,
  1147. uint32_t fromHz,
  1148. uint32_t toHz)
  1149. {
  1150. uint64_t frequencySum = (uint64_t)fromHz + toHz;
  1151. if ((pulseCount == 0UL) || (frequencySum == 0ULL))
  1152. {
  1153. return 0ULL;
  1154. }
  1155. return ((uint64_t)2U * pulseCount * 1000000ULL
  1156. + frequencySum - 1ULL) / frequencySum;
  1157. }
  1158. /* Return floor(numerator / denominator * 2^32) without requiring a
  1159. 128-bit intermediate. Both operands are bounded by the planner's
  1160. 100 kHz Q32 ramp area, so the normalized remainder can be doubled safely. */
  1161. static uint32_t PlsrPlannerRatioQ32(uint64_t numerator,
  1162. uint64_t denominator)
  1163. {
  1164. uint64_t remainder;
  1165. uint32_t ratio = 0UL;
  1166. uint8_t bit;
  1167. if ((numerator == 0ULL) || (denominator == 0ULL))
  1168. {
  1169. return 0UL;
  1170. }
  1171. if (numerator >= denominator)
  1172. {
  1173. return 0xFFFFFFFFUL;
  1174. }
  1175. remainder = numerator;
  1176. for (bit = 0U; bit < 32U; bit++)
  1177. {
  1178. ratio <<= 1U;
  1179. remainder <<= 1U;
  1180. if (remainder >= denominator)
  1181. {
  1182. remainder -= denominator;
  1183. ratio |= 1UL;
  1184. }
  1185. }
  1186. return ratio;
  1187. }
  1188. static uint32_t PlsrPlannerRampPulsesAtTime(
  1189. const PLSR_PLANNER_CONTEXT *context,
  1190. uint32_t pulseCount,
  1191. uint32_t fromHz,
  1192. uint32_t toHz,
  1193. uint64_t elapsedUs,
  1194. uint64_t durationUs,
  1195. uint64_t *progressQ32)
  1196. {
  1197. PLSR_PLANNER_CONTEXT ramp = *context;
  1198. uint64_t partialAreaQ32;
  1199. uint64_t totalAreaQ32;
  1200. uint64_t product;
  1201. uint32_t areaRatioQ32;
  1202. uint32_t result;
  1203. if ((pulseCount == 0UL) || (elapsedUs == 0ULL)
  1204. || (durationUs == 0ULL))
  1205. {
  1206. *progressQ32 = 0ULL;
  1207. return 0UL;
  1208. }
  1209. if (elapsedUs >= durationUs)
  1210. {
  1211. *progressQ32 = PLSR_PLANNER_Q32_ONE;
  1212. return pulseCount;
  1213. }
  1214. *progressQ32 = (elapsedUs * PLSR_PLANNER_Q32_ONE) / durationUs;
  1215. ramp.rampFromHz = fromHz;
  1216. ramp.rampToHz = toHz;
  1217. partialAreaQ32 = PlsrPlannerRampAreaQ32(
  1218. &ramp, fromHz, toHz, *progressQ32);
  1219. totalAreaQ32 = PlsrPlannerRampAreaQ32(
  1220. &ramp, fromHz, toHz, PLSR_PLANNER_Q32_ONE);
  1221. areaRatioQ32 = PlsrPlannerRatioQ32(partialAreaQ32,
  1222. totalAreaQ32);
  1223. product = (uint64_t)pulseCount * areaRatioQ32;
  1224. result = (uint32_t)(product >> 32U);
  1225. if ((uint32_t)product != 0UL)
  1226. {
  1227. result++;
  1228. }
  1229. return (result > pulseCount) ? pulseCount : result;
  1230. }
  1231. static uint8_t PlsrPlannerSetPredictedFrequency(
  1232. const PLSR_PLANNER_CONTEXT *context,
  1233. uint32_t fromHz,
  1234. uint32_t toHz,
  1235. uint64_t progressQ32,
  1236. PLSR_PLANNER_TIME_PREDICTION *prediction)
  1237. {
  1238. PLSR_PLANNER_CONTEXT ramp = *context;
  1239. PLSR_PLATFORM_TIMER_SETTING setting;
  1240. uint32_t requestedHz;
  1241. ramp.rampFromHz = fromHz;
  1242. ramp.rampToHz = toHz;
  1243. requestedHz = PlsrPlannerInstantFrequency(&ramp, progressQ32);
  1244. if (PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
  1245. PLSR_OUTPUT_PULSE_DIR,
  1246. requestedHz, &setting) == 0U)
  1247. {
  1248. return 0U;
  1249. }
  1250. prediction->actualFrequencyHz = setting.actualFrequencyHz;
  1251. return 1U;
  1252. }
  1253. static uint64_t PlsrPlannerRampTargetAreaQ32(uint64_t totalAreaQ32,
  1254. uint32_t pulseCount,
  1255. uint32_t pulseIndex)
  1256. {
  1257. uint64_t step = totalAreaQ32 / pulseCount;
  1258. uint64_t remainder = totalAreaQ32 % pulseCount;
  1259. return step * pulseIndex
  1260. + (remainder * pulseIndex) / pulseCount;
  1261. }
  1262. /* Predict the timer setting of the last complete ramp pulse at the deadline.
  1263. A ramp pulse represents the average frequency between two equal-area curve
  1264. boundaries; carrying that run setting is closer to the hardware state than
  1265. carrying the mathematical instantaneous frequency at the boundary. */
  1266. static uint8_t PlsrPlannerSetPredictedRampRunFrequency(
  1267. const PLSR_PLANNER_CONTEXT *context,
  1268. uint32_t pulseCount,
  1269. uint32_t fromHz,
  1270. uint32_t toHz,
  1271. uint32_t pulseIndex,
  1272. PLSR_PLANNER_TIME_PREDICTION *prediction)
  1273. {
  1274. PLSR_PLANNER_CONTEXT ramp = *context;
  1275. PLSR_PLATFORM_TIMER_SETTING setting;
  1276. uint64_t totalAreaQ32;
  1277. uint64_t previousTargetAreaQ32;
  1278. uint64_t targetAreaQ32;
  1279. uint64_t previousBoundaryQ32;
  1280. uint64_t boundaryQ32;
  1281. uint64_t denominator;
  1282. uint64_t requestedHz;
  1283. if ((pulseCount == 0UL) || (pulseIndex == 0UL))
  1284. {
  1285. return PlsrPlannerSetPredictedFrequency(
  1286. context, fromHz, toHz, 0ULL, prediction);
  1287. }
  1288. if (pulseIndex > pulseCount)
  1289. {
  1290. pulseIndex = pulseCount;
  1291. }
  1292. ramp.rampFromHz = fromHz;
  1293. ramp.rampToHz = toHz;
  1294. totalAreaQ32 = PlsrPlannerRampAreaQ32(
  1295. &ramp, fromHz, toHz, PLSR_PLANNER_Q32_ONE);
  1296. previousTargetAreaQ32 = PlsrPlannerRampTargetAreaQ32(
  1297. totalAreaQ32, pulseCount, pulseIndex - 1UL);
  1298. targetAreaQ32 = PlsrPlannerRampTargetAreaQ32(
  1299. totalAreaQ32, pulseCount, pulseIndex);
  1300. previousBoundaryQ32 = (pulseIndex == 1UL)
  1301. ? 0ULL
  1302. : PlsrPlannerExactBoundaryQ32(
  1303. &ramp, 0ULL,
  1304. previousTargetAreaQ32);
  1305. boundaryQ32 = (pulseIndex == pulseCount)
  1306. ? PLSR_PLANNER_Q32_ONE
  1307. : PlsrPlannerExactBoundaryQ32(
  1308. &ramp, previousBoundaryQ32,
  1309. targetAreaQ32);
  1310. if (boundaryQ32 <= previousBoundaryQ32)
  1311. {
  1312. return 0U;
  1313. }
  1314. denominator = (uint64_t)pulseCount
  1315. * (boundaryQ32 - previousBoundaryQ32);
  1316. requestedHz = (denominator == 0ULL)
  1317. ? toHz
  1318. : (totalAreaQ32 + denominator / 2ULL)
  1319. / denominator;
  1320. if (requestedHz == 0ULL)
  1321. {
  1322. requestedHz = 1ULL;
  1323. }
  1324. if (requestedHz > PLSR_FREQUENCY_MAX_HZ)
  1325. {
  1326. requestedHz = PLSR_FREQUENCY_MAX_HZ;
  1327. }
  1328. if (PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
  1329. PLSR_OUTPUT_PULSE_DIR,
  1330. (uint32_t)requestedHz,
  1331. &setting) == 0U)
  1332. {
  1333. return 0U;
  1334. }
  1335. prediction->actualFrequencyHz = setting.actualFrequencyHz;
  1336. return 1U;
  1337. }
  1338. uint8_t PlsrPlannerPredictTime(
  1339. const PLSR_PLANNER_CONTEXT *context,
  1340. uint32_t elapsedUs,
  1341. PLSR_PLANNER_TIME_PREDICTION *prediction)
  1342. {
  1343. PLSR_PLATFORM_TIMER_SETTING steadySetting;
  1344. uint64_t remainingUs = elapsedUs;
  1345. uint64_t durationUs;
  1346. uint64_t progressQ32;
  1347. uint64_t partialPulses;
  1348. if ((context == NULL) || (prediction == NULL)
  1349. || (context->block.pulseBudget == 0UL))
  1350. {
  1351. return 0U;
  1352. }
  1353. (void)memset(prediction, 0, sizeof(*prediction));
  1354. durationUs = PlsrPlannerRampDurationUs(
  1355. context->entryPulses, context->startHz, context->peakHz);
  1356. if ((context->entryPulses != 0UL) && (remainingUs <= durationUs))
  1357. {
  1358. prediction->pulseCount = PlsrPlannerRampPulsesAtTime(
  1359. context, context->entryPulses, context->startHz,
  1360. context->peakHz, remainingUs, durationUs, &progressQ32);
  1361. prediction->phase = PLSR_PLANNER_PHASE_ENTRY;
  1362. prediction->deadlineInProfile = 1U;
  1363. return PlsrPlannerSetPredictedRampRunFrequency(
  1364. context, context->entryPulses, context->startHz,
  1365. context->peakHz, prediction->pulseCount, prediction);
  1366. }
  1367. if (context->entryPulses != 0UL)
  1368. {
  1369. remainingUs -= durationUs;
  1370. }
  1371. if (PlsrPlatformBuildTimerSetting(context->block.pulseOutput,
  1372. PLSR_OUTPUT_PULSE_DIR,
  1373. context->peakHz,
  1374. &steadySetting) == 0U)
  1375. {
  1376. return 0U;
  1377. }
  1378. durationUs = (context->steadyPulses == 0UL)
  1379. ? 0ULL
  1380. : ((uint64_t)context->steadyPulses * 1000000ULL
  1381. + steadySetting.actualFrequencyHz - 1UL)
  1382. / steadySetting.actualFrequencyHz;
  1383. if ((context->steadyPulses != 0UL) && (remainingUs <= durationUs))
  1384. {
  1385. partialPulses = (remainingUs * steadySetting.actualFrequencyHz
  1386. + 999999ULL) / 1000000ULL;
  1387. if (partialPulses > context->steadyPulses)
  1388. {
  1389. partialPulses = context->steadyPulses;
  1390. }
  1391. prediction->pulseCount = context->entryPulses
  1392. + (uint32_t)partialPulses;
  1393. prediction->actualFrequencyHz = steadySetting.actualFrequencyHz;
  1394. prediction->phase = PLSR_PLANNER_PHASE_STEADY;
  1395. prediction->deadlineInProfile = 1U;
  1396. return 1U;
  1397. }
  1398. if (context->steadyPulses != 0UL)
  1399. {
  1400. remainingUs -= durationUs;
  1401. }
  1402. durationUs = PlsrPlannerRampDurationUs(
  1403. context->exitPulses, context->peakHz, context->endHz);
  1404. if ((context->exitPulses != 0UL) && (remainingUs <= durationUs))
  1405. {
  1406. partialPulses = PlsrPlannerRampPulsesAtTime(
  1407. context, context->exitPulses, context->peakHz,
  1408. context->endHz, remainingUs, durationUs, &progressQ32);
  1409. prediction->pulseCount = context->entryPulses
  1410. + context->steadyPulses
  1411. + (uint32_t)partialPulses;
  1412. prediction->phase = PLSR_PLANNER_PHASE_EXIT;
  1413. prediction->deadlineInProfile = 1U;
  1414. return PlsrPlannerSetPredictedRampRunFrequency(
  1415. context, context->exitPulses, context->peakHz,
  1416. context->endHz, (uint32_t)partialPulses, prediction);
  1417. }
  1418. prediction->pulseCount = context->block.pulseBudget;
  1419. prediction->phase = PLSR_PLANNER_PHASE_COMPLETE;
  1420. prediction->deadlineInProfile = 0U;
  1421. return PlsrPlannerSetPredictedFrequency(
  1422. context, context->endHz, context->endHz,
  1423. PLSR_PLANNER_Q32_ONE, prediction);
  1424. }