Forráskód Böngészése

Merge remote-tracking branch 'origin/tmp/CppTest' into tmp/chouxiangceng

# Conflicts:
#	.gitignore
#	User project/1.FrameLayer/Source/gd32f30x_it.c
#	User project/2.MotorDrive/Source/adc.c
#	User project/2.MotorDrive/Source/pwm.c
#	User project/3.BasicFunction/Include/classB.h
#	User project/3.BasicFunction/Source/torquesensor.c
#	User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/board_config.h
#	User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hwsetup.h
#	User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/glbcof.h
#	User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/user.h
#	User project/5.Api_rt/api_rt.c
#	User project/5.Api_rt/api_rt.h
#	User project/5.Api_rt/api_rt_adc.c
#	User project/5.Api_rt/api_rt_gpio.c
#	User project/5.Api_rt/api_rt_gpio.h
#	User project/5.Api_rt/api_rt_pwm.c
#	User project/5.Api_rt/api_rt_pwm.h
#	User project/5.Api_rt/api_rt_timer.c
#	User project/5.Api_rt/api_rt_timer.h
#	WLMCP.ewp
CN\zhangkai71 2 éve
szülő
commit
3f1a839c2d
100 módosított fájl, 4091 hozzáadás és 1333 törlés
  1. 1 3
      .gitignore
  2. 60 40
      User project/1.FrameLayer/Source/TimeTask_Event.c
  3. 124 126
      User project/1.FrameLayer/Source/main.c
  4. 14 3
      User project/2.MotorDrive/Include/adc.h
  5. 7 1
      User project/2.MotorDrive/Include/asr.h
  6. 8 0
      User project/2.MotorDrive/Include/brake.h
  7. 9 1
      User project/2.MotorDrive/Include/pwm.h
  8. 7 1
      User project/2.MotorDrive/Include/pwrlim.h
  9. 7 1
      User project/2.MotorDrive/Include/spdctrmode.h
  10. 8 1
      User project/2.MotorDrive/Include/torqobs.h
  11. BIN
      User project/2.MotorDrive/Lib/WLMCP_LIB.lib
  12. 92 36
      User project/2.MotorDrive/Source/adc.c
  13. 0 2
      User project/2.MotorDrive/Source/alarm.c
  14. 7 7
      User project/2.MotorDrive/Source/pwm.c
  15. 23 4
      User project/2.MotorDrive/Source/spdctrFSM.c
  16. 1 0
      User project/3.BasicFunction/Include/bikespeed.h
  17. 1 1
      User project/3.BasicFunction/Include/can.h
  18. 14 0
      User project/3.BasicFunction/Include/canAppl.h
  19. 9 5
      User project/3.BasicFunction/Include/torquesensor.h
  20. 54 31
      User project/3.BasicFunction/Source/AssistCurve.c
  21. 1 4
      User project/3.BasicFunction/Source/Cadence.c
  22. 2 0
      User project/3.BasicFunction/Source/bikespeed.c
  23. 290 247
      User project/3.BasicFunction/Source/i2c_master.c
  24. 4 4
      User project/3.BasicFunction/Source/power.c
  25. 83 175
      User project/3.BasicFunction/Source/torquesensor.c
  26. 0 68
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/app_tasks.h
  27. 10 0
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/board_config.h
  28. 0 84
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_adc.h
  29. 0 65
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_dio.h
  30. 0 108
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_harderr.h
  31. 0 296
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_pwm.h
  32. 12 4
      User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hwsetup.h
  33. 7 0
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/CodePara.h
  34. 7 1
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/glbcof.h
  35. 6 1
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/macroequ.h
  36. 6 1
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/mathtool.h
  37. 9 3
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/syspar.h
  38. 8 1
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/typedefine.h
  39. 13 7
      User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/user.h
  40. 1 0
      User project/5.Api_rt/api_rt.c
  41. 1 0
      User project/5.Api_rt/api_rt.h
  42. 597 0
      User project/5.Api_rt/api_rt_i2c.c
  43. 58 0
      User project/5.Api_rt/api_rt_i2c.h
  44. 0 1
      User project/5.Api_rt/api_rt_pwm.c
  45. 11 0
      tests/sim/.gitignore
  46. BIN
      tests/sim/FanPlatformAuto.slx
  47. BIN
      tests/sim/FanPlatform_Debug.slx
  48. 0 0
      tests/sim/automation/.gitignore
  49. 7 0
      tests/sim/automation/ApplyInit.m
  50. 34 0
      tests/sim/automation/ApplyInjection.m
  51. BIN
      tests/sim/automation/AutomationPortLib.slx
  52. 13 0
      tests/sim/automation/CommentBlocks.m
  53. 100 0
      tests/sim/automation/ConditionCheck.m
  54. 18 0
      tests/sim/automation/LoadModelPorts.m
  55. 54 0
      tests/sim/automation/LoadTest.m
  56. 138 0
      tests/sim/automation/ParseCheck.m
  57. 75 0
      tests/sim/automation/RunTest.m
  58. 35 0
      tests/sim/automation/SelectConnection.m
  59. 20 0
      tests/sim/automation/SelectPort.m
  60. 16 0
      tests/sim/automation/SetPortEnable.m
  61. 8 0
      tests/sim/automation/SetPortInterpolation.m
  62. 12 0
      tests/sim/automation/SetPortSignal.m
  63. 4 0
      tests/sim/automation/SetPortThrough.m
  64. BIN
      tests/sim/automation/injection_dtype.mat
  65. 25 0
      tests/sim/automation/slblocks.m
  66. 26 0
      tests/sim/init_model.m
  67. 3 0
      tests/sim/prepare_test.m
  68. 2 0
      tests/sim/pytest/.gitignore
  69. 17 0
      tests/sim/pytest/base_case.py
  70. 11 0
      tests/sim/pytest/conftest.py
  71. 28 0
      tests/sim/pytest/matlab_wrapper.py
  72. 15 0
      tests/sim/pytest/test_Sim.py
  73. 363 0
      tests/sim/sim_board/.gitignore
  74. 12 0
      tests/sim/sim_board/api_rt/api_rt.c
  75. 17 0
      tests/sim/sim_board/api_rt/api_rt.h
  76. 81 0
      tests/sim/sim_board/api_rt/api_rt_adc.c
  77. 29 0
      tests/sim/sim_board/api_rt/api_rt_adc.h
  78. 109 0
      tests/sim/sim_board/api_rt/api_rt_cap.c
  79. 25 0
      tests/sim/sim_board/api_rt/api_rt_cap.h
  80. 21 0
      tests/sim/sim_board/api_rt/api_rt_common.h
  81. 10 0
      tests/sim/sim_board/api_rt/api_rt_dbg.c
  82. 47 0
      tests/sim/sim_board/api_rt/api_rt_dbg.h
  83. 7 0
      tests/sim/sim_board/api_rt/api_rt_delay.c
  84. 14 0
      tests/sim/sim_board/api_rt/api_rt_delay.h
  85. 78 0
      tests/sim/sim_board/api_rt/api_rt_fault.c
  86. 17 0
      tests/sim/sim_board/api_rt/api_rt_fault.h
  87. 65 0
      tests/sim/sim_board/api_rt/api_rt_gpio.c
  88. 27 0
      tests/sim/sim_board/api_rt/api_rt_gpio.h
  89. 439 0
      tests/sim/sim_board/api_rt/api_rt_pwm.c
  90. 43 0
      tests/sim/sim_board/api_rt/api_rt_pwm.h
  91. 153 0
      tests/sim/sim_board/api_rt/api_rt_test_probe.c
  92. 49 0
      tests/sim/sim_board/api_rt/api_rt_test_probe.h
  93. 69 0
      tests/sim/sim_board/api_rt/api_rt_timer.c
  94. 29 0
      tests/sim/sim_board/api_rt/api_rt_timer.h
  95. 50 0
      tests/sim/sim_board/api_rt/api_rt_uart.c
  96. 43 0
      tests/sim/sim_board/api_rt/api_rt_uart.h
  97. 18 0
      tests/sim/sim_board/include/board.h
  98. 15 0
      tests/sim/sim_board/include/isr.h
  99. 16 0
      tests/sim/sim_board/include/mcu_instance.h
  100. 12 0
      tests/sim/sim_board/include/sfun_wrapper.h

+ 1 - 3
.gitignore

@@ -20,7 +20,5 @@ Release/**
 .xmake/
 build/
 
-build/
-
 # Generated Fingerprint File
-fp.def
+fp.def

+ 60 - 40
User project/1.FrameLayer/Source/TimeTask_Event.c

@@ -198,44 +198,44 @@ void  Event_1ms(void) /* parasoft-suppress METRICS-28 "本项目圈复杂度无
         /* Speed assist mode flag */
         if((cp_stFlg.RunModelSelect == CityBIKE) || (cp_stFlg.RunModelSelect == MountainBIKE))
         {
-            if(cp_stBikeRunInfoPara.uwBikeGear == 0x22)
-            {
-                Event_pvt_uwAssistCnt ++;
-                if(Event_pvt_uwAssistCnt > 200 && cp_stFlg.RunPermitFlg == TRUE)
-                {
-                    signal_state.Assist = TRUE;
-                    Event_pvt_uwAssistCnt = 200;
-                }
-            }
-            else
-            {
-                Event_pvt_uwAssistCnt = 0;
-                signal_state.Assist = FALSE;
-            }
-
-            if(signal_state.Assist == TRUE)
-            {
-                //6km/H = 100m/min = 1.67m/s
-                if(cp_stFlg.RunModelSelect == CityBIKE)
-                {
-                    uart_slSpdRefRpm = -(10000/(ass_stParaCong.uwWheelPerimeter))*ass_stParaCong.uwNmBackChainring*ass_stParaCong.uwMechRationMotor/ass_stParaCong.uwNmFrontChainring;
-    //                cp_stBikeRunInfoPara.BikeSpeedKmH = 60;      //constant display of 6km/h
-                }
-                else if(cp_stFlg.RunModelSelect == MountainBIKE)
-                {
-                    uart_slSpdRefRpm = (10000/(ass_stParaCong.uwWheelPerimeter))*ass_stParaCong.uwNmBackChainring*ass_stParaCong.uwMechRationMotor/ass_stParaCong.uwNmFrontChainring;
-    //                cp_stBikeRunInfoPara.BikeSpeedKmH = 60;      //constant display of 6km/h
-                }
-                else
-                {
-                	//do nothing
-                }
-
-            }
-            else
-            {
-                uart_slSpdRefRpm = 0;
-            }
+//            if(cp_stBikeRunInfoPara.uwBikeGear == 0x22)
+//            {
+//                Event_pvt_uwAssistCnt ++;
+//                if(Event_pvt_uwAssistCnt > 200 && cp_stFlg.RunPermitFlg == TRUE)
+//                {
+//                    signal_state.Assist = TRUE;
+//                    Event_pvt_uwAssistCnt = 200;
+//                }
+//            }
+//            else
+//            {
+//                Event_pvt_uwAssistCnt = 0;
+//                signal_state.Assist = FALSE;
+//            }
+//
+//            if(signal_state.Assist == TRUE)
+//            {
+//                //6km/H = 100m/min = 1.67m/s
+//                if(cp_stFlg.RunModelSelect == CityBIKE)
+//                {
+//                    uart_slSpdRefRpm = -(10000/(ass_stParaCong.uwWheelPerimeter))*ass_stParaCong.uwNmBackChainring*ass_stParaCong.uwMechRationMotor/ass_stParaCong.uwNmFrontChainring;
+//    //                cp_stBikeRunInfoPara.BikeSpeedKmH = 60;      //constant display of 6km/h
+//                }
+//                else if(cp_stFlg.RunModelSelect == MountainBIKE)
+//                {
+//                    uart_slSpdRefRpm = (10000/(ass_stParaCong.uwWheelPerimeter))*ass_stParaCong.uwNmBackChainring*ass_stParaCong.uwMechRationMotor/ass_stParaCong.uwNmFrontChainring;
+//    //                cp_stBikeRunInfoPara.BikeSpeedKmH = 60;      //constant display of 6km/h
+//                }
+//                else
+//                {
+//                	//do nothing
+//                }
+//
+//            }
+//            else
+//            {
+//                uart_slSpdRefRpm = 0;
+//            }
         }
         else
         {          
@@ -336,17 +336,37 @@ void Event_100ms(void)
     SWORD swIqLowerPu;
     if(switch_flg.SysCoef_Flag == TRUE)
     {
+      
+        if(cp_stBikeRunInfoPara.uwBikeGear == 0x22)
+        {
+            Event_pvt_uwAssistCnt ++;
+            if(Event_pvt_uwAssistCnt >= 2 && cp_stFlg.RunPermitFlg == TRUE)
+            {
+                Event_pvt_uwAssistCnt = 2;
+            }
+        }
+        else
+        {
+            Event_pvt_uwAssistCnt = 0;
+        }
         /* Bike Speed LPF */
         bikespeed_stFreGetOut.uwLPFFrequencyPu = (bikespeed_stFreGetOut.uwLPFFrequencyPu * bikespeed_stFreGetCof.uwBikeSpeedLPFGain +
                                                   bikespeed_stFreGetOut.uwFrequencyPu * (100 - bikespeed_stFreGetCof.uwBikeSpeedLPFGain)) /
                                                  100;
         /* Bike Throttle Assist */
-        if((bikethrottle_stBikeThrottleOut.uwThrottlePercent > 200)  && (cp_stBikeRunInfoPara.uwBikeGear > 0) && (cp_stFlg.RunPermitFlg == TRUE) && (BikeBrake_blGetstate() == FALSE))
+        if(((bikethrottle_stBikeThrottleOut.uwThrottlePercent > 200) || Event_pvt_uwAssistCnt == 2)&& (cp_stBikeRunInfoPara.uwBikeGear > 0) && (cp_stFlg.RunPermitFlg == TRUE) && (BikeBrake_blGetstate() == FALSE))
         {
             Event_pvt_blBikeThroFlg = TRUE;
 
             /* Bike Speed Ref, 200-890Percent: 4-25km/h */
-            Event_pvt_uwBikeSpdRefTarget = (UWORD)((((ULONG)25 - (ULONG)4) *(bikethrottle_stBikeThrottleOut.uwThrottlePercent - 200)/690 + 4) * BIKESPEED_KMPERH2FREQPU); // Q20
+            if(Event_pvt_uwAssistCnt == 2)
+            {
+                Event_pvt_uwBikeSpdRefTarget = (UWORD)BIKESPEED_KMPERH2FREQPU * 6; // Q20
+            }
+            else
+            {
+                Event_pvt_uwBikeSpdRefTarget = (UWORD)((((ULONG)25 - (ULONG)4) *(bikethrottle_stBikeThrottleOut.uwThrottlePercent - 200)/690 + 4) * BIKESPEED_KMPERH2FREQPU); // Q20   
+            }
             
             /* Bike Speed Ref Ramp */
             if(Event_pvt_uwBikeSpdRef < Event_pvt_uwBikeSpdRefTarget - 80)

+ 124 - 126
User project/1.FrameLayer/Source/main.c

@@ -33,6 +33,7 @@
 #include "torquesensor.h"
 #include "power.h"
 #include "STLmain.h"
+//#include "api_rt.h"
 /************************************************************************
  Exported Functions:
 ************************************************************************/
@@ -351,139 +352,136 @@ void mn_voParaSet(void)
 ****************************************************************/
 void mn_voParaUpdate(void)
 {
-    if (cp_stFlg.ParaUpdateFlg == TRUE)
+    if (cp_stFlg.ParaMInfoUpdateFlg == TRUE)
     {
-        if (cp_stFlg.ParaMInfoUpdateFlg == TRUE)
-        {
-            cp_stMotorPara.swMotrPolePairs = (SWORD)MC_UpcInfo.stMotorInfo.uwPolePairs;
-            cp_stMotorPara.swRsOhm = (SWORD)MC_UpcInfo.stMotorInfo.uwRsmOhm;
-            cp_stMotorPara.swLdmH = (SWORD)MC_UpcInfo.stMotorInfo.uwLduH;
-            cp_stMotorPara.swLqmH = (SWORD)MC_UpcInfo.stMotorInfo.uwLquH;
-            cp_stMotorPara.swFluxWb = (SWORD)MC_UpcInfo.stMotorInfo.uwFluxmWb;
-            cp_stMotorPara.swIdMaxA = (SWORD)MC_UpcInfo.stMotorInfo.uwIdMaxA;
-            cp_stMotorPara.swIdMinA = (SWORD)MC_UpcInfo.stMotorInfo.uwIdMinA;
-            cp_stMotorPara.swRSpeedRpm = (SWORD)MC_UpcInfo.stMotorInfo.uwRSpdRpm;
-            cp_stMotorPara.swRPwrWt = (SWORD)MC_UpcInfo.stMotorInfo.uwRPwrWt;
-            cp_stMotorPara.swRIarmsA = (SWORD)MC_UpcInfo.stMotorInfo.uwRCurA;
-            cp_stMotorPara.swRUdcV = (SWORD)MC_UpcInfo.stMotorInfo.uwRVolV;
-            cp_stMotorPara.swJD = (SWORD)MC_UpcInfo.stMotorInfo.uwJD;
-            cp_stMotorPara.swTorMax = (SWORD)MC_UpcInfo.stMotorInfo.uwTorMaxNm;
-
-            cp_stFlg.ParaMotorDriveUpdateFinishFlg = TRUE;
-            cp_stFlg.ParaMInfoUpdateFlg = FALSE;
-        }
-
-        if (cp_stFlg.ParaBikeInfoUpdateFlg == TRUE)
-        {
-            ass_stParaCong.uwWheelPerimeter = MC_UpcInfo.stBikeInfo.uwWheelPerimeter;
-            ass_stParaCong.uwMechRationMotor = MC_UpcInfo.stBikeInfo.uwMechRationMotor;
-            ass_stParaCong.uwAssistMaxSpdKmH = MC_UpcInfo.stBikeInfo.uwAssistMaxSpdKmH;
-            ass_stParaCong.uwThrottleMaxSpdKmH = MC_UpcInfo.stBikeInfo.uwThrottleMaxSpdKmH;
-            ass_stParaCong.uwNmFrontChainring = MC_UpcInfo.stBikeInfo.uwNmFrontChainring;
-            ass_stParaCong.uwNmBackChainring = MC_UpcInfo.stBikeInfo.uwNmBackChainring;
-            ass_stParaCong.uwAssistSelect1 = MC_UpcInfo.stBikeInfo.uwAssistSelect1;
-            ass_stParaCong.uwAssistSelect2 = MC_UpcInfo.stBikeInfo.uwAssistSelect2;
-            ass_stParaCong.uwLightVoltage = MC_UpcInfo.stBikeInfo.uwLightVoltage;
-            ass_stParaCong.swDeltPerimeter = MC_UpcInfo.stBikeInfo.swWheelSizeAdjust;
-            ass_stParaCong.uwStartMode = MC_UpcInfo.stBikeInfo.uwStartMode;
-            ass_stParaCong.uwAutoPowerOffTime = MC_UpcInfo.stBikeInfo.uwAutoPowerOffTime;
-
-            cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
-            cp_stFlg.ParaBikeInfoUpdateFlg = FALSE;
-        }
+        cp_stMotorPara.swMotrPolePairs = (SWORD)MC_UpcInfo.stMotorInfo.uwPolePairs;
+        cp_stMotorPara.swRsOhm = (SWORD)MC_UpcInfo.stMotorInfo.uwRsmOhm;
+        cp_stMotorPara.swLdmH = (SWORD)MC_UpcInfo.stMotorInfo.uwLduH;
+        cp_stMotorPara.swLqmH = (SWORD)MC_UpcInfo.stMotorInfo.uwLquH;
+        cp_stMotorPara.swFluxWb = (SWORD)MC_UpcInfo.stMotorInfo.uwFluxmWb;
+        cp_stMotorPara.swIdMaxA = (SWORD)MC_UpcInfo.stMotorInfo.uwIdMaxA;
+        cp_stMotorPara.swIdMinA = (SWORD)MC_UpcInfo.stMotorInfo.uwIdMinA;
+        cp_stMotorPara.swRSpeedRpm = (SWORD)MC_UpcInfo.stMotorInfo.uwRSpdRpm;
+        cp_stMotorPara.swRPwrWt = (SWORD)MC_UpcInfo.stMotorInfo.uwRPwrWt;
+        cp_stMotorPara.swRIarmsA = (SWORD)MC_UpcInfo.stMotorInfo.uwRCurA;
+        cp_stMotorPara.swRUdcV = (SWORD)MC_UpcInfo.stMotorInfo.uwRVolV;
+        cp_stMotorPara.swJD = (SWORD)MC_UpcInfo.stMotorInfo.uwJD;
+        cp_stMotorPara.swTorMax = (SWORD)MC_UpcInfo.stMotorInfo.uwTorMaxNm;
+
+        cp_stFlg.ParaMotorDriveUpdateFinishFlg = TRUE;
+        cp_stFlg.ParaMInfoUpdateFlg = FALSE;
+    }
 
-        if (cp_stFlg.ParaMCInfoUpdateFlg == TRUE)
-        {
-            cp_stFlg.ParaFirstSetFlg = MC_UpcInfo.stTestParaInfo.uwEEFirstDefaultSetFlg;
-            cp_stFlg.SpiOffsetFirstSetFlg = MC_UpcInfo.stTestParaInfo.uwSPIOffsetFirstSetFlg;
-            spi_stResolverOut.swSpiThetaOffsetOrignPu = MC_UpcInfo.stMContorlInfo.uwSPIPosOffsetOrigin;
-            spi_stResolverOut.swSpiThetaOffsetPu = MC_UpcInfo.stMContorlInfo.uwSPIPosOffsetNow;
-            cp_stMotorPara.swIpeakMaxA = (SWORD)MC_UpcInfo.stMContorlInfo.uwIPeakMaxA;
-            cp_stControlPara.swAlmOverCurrentVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOCurA;
-            cp_stControlPara.swAlmOverVolVal3 = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOVolV;
-            cp_stControlPara.swAlmUnderVolVal2 = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamUVolV;
-            cp_stControlPara.swAlmOverSpdVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOverSpdRpm;
-            cp_stControlPara.swAlmOverHeatCeVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOverHeatCe;
-            cp_stControlPara.swAlmRecOHeatVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamRecHeatCe;
-            cp_stControlPara.swAlmPwrLimitStartTempVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwPwrLimitStartCe;
-
-            cp_stFlg.ParaMotorDriveUpdateFinishFlg = TRUE;
-            cp_stFlg.ParaMCInfoUpdateFlg = FALSE;
-        }
+    if (cp_stFlg.ParaBikeInfoUpdateFlg == TRUE)
+    {
+        ass_stParaCong.uwWheelPerimeter = MC_UpcInfo.stBikeInfo.uwWheelPerimeter;
+        ass_stParaCong.uwMechRationMotor = MC_UpcInfo.stBikeInfo.uwMechRationMotor;
+        ass_stParaCong.uwAssistMaxSpdKmH = MC_UpcInfo.stBikeInfo.uwAssistMaxSpdKmH;
+        ass_stParaCong.uwThrottleMaxSpdKmH = MC_UpcInfo.stBikeInfo.uwThrottleMaxSpdKmH;
+        ass_stParaCong.uwNmFrontChainring = MC_UpcInfo.stBikeInfo.uwNmFrontChainring;
+        ass_stParaCong.uwNmBackChainring = MC_UpcInfo.stBikeInfo.uwNmBackChainring;
+        ass_stParaCong.uwAssistSelect1 = MC_UpcInfo.stBikeInfo.uwAssistSelect1;
+        ass_stParaCong.uwAssistSelect2 = MC_UpcInfo.stBikeInfo.uwAssistSelect2;
+        ass_stParaCong.uwLightVoltage = MC_UpcInfo.stBikeInfo.uwLightVoltage;
+        ass_stParaCong.swDeltPerimeter = MC_UpcInfo.stBikeInfo.swWheelSizeAdjust;
+        ass_stParaCong.uwStartMode = MC_UpcInfo.stBikeInfo.uwStartMode;
+        ass_stParaCong.uwAutoPowerOffTime = MC_UpcInfo.stBikeInfo.uwAutoPowerOffTime;
+
+        cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
+        cp_stFlg.ParaBikeInfoUpdateFlg = FALSE;
+    }
 
-        if (cp_stFlg.ParaSensorInfoUpdateFlg == TRUE)
-        {
-            torsensor_stTorSensorCof.uwTorqueOffsetOrign = MC_UpcInfo.stSensorInfo.uwTorSensorOffsetOrigin;
-            torsensor_stTorSensorCof.uwMaxSensorTorquePu = MC_UpcInfo.stSensorInfo.uwBikeTorMaxNm;
-            torsensor_stTorSensorCof.uwBikeTorStep1RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor1StepRealNm;
-            torsensor_stTorSensorCof.uwBikeTorStep1ADC = MC_UpcInfo.stSensorInfo.uwBikeTor1StepADC;
-            torsensor_stTorSensorCof.uwBikeTorStep2RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor2StepRealNm;
-            torsensor_stTorSensorCof.uwBikeTorStep2ADC = MC_UpcInfo.stSensorInfo.uwBikeTor2StepADC;
-            torsensor_stTorSensorCof.uwBikeTorStep3RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor3StepRealNm;
-            torsensor_stTorSensorCof.uwBikeTorStep3ADC = MC_UpcInfo.stSensorInfo.uwBikeTor3StepADC;
-            torsensor_stTorSensorCof.uwBikeTorStep4RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor4StepRealNm;
-            torsensor_stTorSensorCof.uwBikeTorStep4ADC = MC_UpcInfo.stSensorInfo.uwBikeTor4StepADC;
-            cadence_stFreGetCof.uwNumbersPulses = MC_UpcInfo.stSensorInfo.uwCadSensorPulseNm;
-            bikespeed_stFreGetCof.uwNumbersPulses = MC_UpcInfo.stSensorInfo.uwBikeSpdSensorPulseNm;
-
-            cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
-            cp_stFlg.ParaSensorInfoUpdateFlg = FALSE;
-        }
+    if (cp_stFlg.ParaMCInfoUpdateFlg == TRUE)
+    {
+        cp_stFlg.ParaFirstSetFlg = MC_UpcInfo.stTestParaInfo.uwEEFirstDefaultSetFlg;
+        cp_stFlg.SpiOffsetFirstSetFlg = MC_UpcInfo.stTestParaInfo.uwSPIOffsetFirstSetFlg;
+        spi_stResolverOut.swSpiThetaOffsetOrignPu = MC_UpcInfo.stMContorlInfo.uwSPIPosOffsetOrigin;
+        spi_stResolverOut.swSpiThetaOffsetPu = MC_UpcInfo.stMContorlInfo.uwSPIPosOffsetNow;
+        cp_stMotorPara.swIpeakMaxA = (SWORD)MC_UpcInfo.stMContorlInfo.uwIPeakMaxA;
+        cp_stControlPara.swAlmOverCurrentVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOCurA;
+        cp_stControlPara.swAlmOverVolVal3 = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOVolV;
+        cp_stControlPara.swAlmUnderVolVal2 = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamUVolV;
+        cp_stControlPara.swAlmOverSpdVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOverSpdRpm;
+        cp_stControlPara.swAlmOverHeatCeVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamOverHeatCe;
+        cp_stControlPara.swAlmRecOHeatVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwAlamRecHeatCe;
+        cp_stControlPara.swAlmPwrLimitStartTempVal = (SWORD)MC_UpcInfo.stMContorlInfo.uwPwrLimitStartCe;
+
+        cp_stFlg.ParaMotorDriveUpdateFinishFlg = TRUE;
+        cp_stFlg.ParaMCInfoUpdateFlg = FALSE;
+    }
 
-        if (cp_stFlg.ParaAInfoUpdateFlg == TRUE)
-        {
-            ass_stParaSet.uwStartupCoef = MC_UpcInfo.stAssistInfo.swStartupGain;
-            ass_stParaSet.uwStartupCruiseCoef = MC_UpcInfo.stAssistInfo.swStartcruiseGain;
-            ass_stParaSet.uwAssistStartNm = MC_UpcInfo.stAssistInfo.uwAssistStartNm;
-            ass_stParaSet.uwAssistStopNm = MC_UpcInfo.stAssistInfo.uwAssistStopNm;
-            ass_stParaSet.uwStartUpGainStep = MC_UpcInfo.stAssistInfo.uwStartUpGainStep;
-            ass_stParaSet.uwStartUpCadNm = MC_UpcInfo.stAssistInfo.uwStartUpCadNm;
-            ass_stParaSet.uwTorLPFCadNm = MC_UpcInfo.stAssistInfo.uwTorLPFCadNm;
-            ass_stParaSet.uwSpeedAssistSpdRpm = MC_UpcInfo.stAssistInfo.uwSpeedAssistSpdRpm;
-            ass_stParaSet.uwSpeedAssistIMaxA = MC_UpcInfo.stAssistInfo.uwSpeedAssistIMaxA;
-            ass_stParaSet.uwAssistLimitBikeSpdStart = MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStart;
-            ass_stParaSet.uwAssistLimitBikeSpdStop = MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStop;
-            ass_stParaSet.uwCadenceWeight = MC_UpcInfo.stAssistInfo.uwCadenceAssistWeight;
-//            ass_stParaSet.uwTorWeight = Q12_1 - ass_stParaSet.uwCadenceWeight;
-
-            cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
-            cp_stFlg.ParaAInfoUpdateFlg = FALSE;
-        }
+    if (cp_stFlg.ParaSensorInfoUpdateFlg == TRUE)
+    {
+        torsensor_stTorSensorCof.uwTorqueOffsetOrign = MC_UpcInfo.stSensorInfo.uwTorSensorOffsetOrigin;
+        torsensor_stTorSensorCof.uwMaxSensorTorquePu = MC_UpcInfo.stSensorInfo.uwBikeTorMaxNm;
+        torsensor_stTorSensorCof.uwBikeTorStep1RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor1StepRealNm;
+        torsensor_stTorSensorCof.uwBikeTorStep1ADC = MC_UpcInfo.stSensorInfo.uwBikeTor1StepADC;
+        torsensor_stTorSensorCof.uwBikeTorStep2RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor2StepRealNm;
+        torsensor_stTorSensorCof.uwBikeTorStep2ADC = MC_UpcInfo.stSensorInfo.uwBikeTor2StepADC;
+        torsensor_stTorSensorCof.uwBikeTorStep3RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor3StepRealNm;
+        torsensor_stTorSensorCof.uwBikeTorStep3ADC = MC_UpcInfo.stSensorInfo.uwBikeTor3StepADC;
+        torsensor_stTorSensorCof.uwBikeTorStep4RealNm = MC_UpcInfo.stSensorInfo.uwBikeTor4StepRealNm;
+        torsensor_stTorSensorCof.uwBikeTorStep4ADC = MC_UpcInfo.stSensorInfo.uwBikeTor4StepADC;
+        cadence_stFreGetCof.uwNumbersPulses = MC_UpcInfo.stSensorInfo.uwCadSensorPulseNm;
+        bikespeed_stFreGetCof.uwNumbersPulses = MC_UpcInfo.stSensorInfo.uwBikeSpdSensorPulseNm;
+
+        cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
+        cp_stFlg.ParaSensorInfoUpdateFlg = FALSE;
+    }
 
-        if(cp_stFlg.TestParaInfoUpdateFlg == TRUE)
-        {
-            cp_stControlPara.swAlignCurAp = (SWORD)MC_UpcInfo.stTestParaInfo.uwInitPosCurAmp;
-            cp_stControlPara.swDragVolAp = (SWORD)MC_UpcInfo.stTestParaInfo.uwVFControlVolAmp;
-            cp_stControlPara.swDragCurAp = (SWORD)MC_UpcInfo.stTestParaInfo.uwIFControlCurAmp;
-            cp_stControlPara.swDragSpdHz = (SWORD)MC_UpcInfo.stTestParaInfo.uwVFIFTargetFreHz;
-
-            cp_stControlPara.swSpeedAccRate = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopAccRate;
-            cp_stControlPara.swSpeedDccRate = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopDecRate;
-            cp_stControlPara.swAsrPIBandwidth = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopBandWidthHz;
-            cp_stControlPara.swAsrPIM = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopCoefM;
-
-            cp_stControlPara.swAcrPIBandwidth = (SWORD)MC_UpcInfo.stTestParaInfo.uwCuerrentLoopBandWidthHz;
-            cp_stControlPara.swAcrRaCoef = (SWORD)MC_UpcInfo.stTestParaInfo.uwCurrentLoopCoefM;
-
-            cp_stControlPara.swObsFluxPICrossfreHz = (SWORD)MC_UpcInfo.stTestParaInfo.uwFluxObsBandWidthHz;
-            cp_stControlPara.swObsFluxPIDampratio = (SWORD)MC_UpcInfo.stTestParaInfo.uwFluxObsCoefM;
-            cp_stControlPara.swObsSpdPLLBandWidthHz = (SWORD)MC_UpcInfo.stTestParaInfo.uwThetaObsPLLBandWidthHz;
-            cp_stControlPara.swObsSpdPLLM = (SWORD)MC_UpcInfo.stTestParaInfo.uwThetaObsPLLCoefM;
-
-            cp_stMotorPara.swJD = (SWORD)MC_UpcInfo.stTestParaInfo.uwJm;
-            cp_stControlPara.swPWMMaxDuty = (SWORD)MC_UpcInfo.stTestParaInfo.uwPWMMaxDuty;
-            cp_stControlPara.swPWM7to5Duty = (SWORD)MC_UpcInfo.stTestParaInfo.uwPWM7to5Duty;
-            cp_stControlPara.swPwrLimitValWt = (SWORD)MC_UpcInfo.stTestParaInfo.uwPwrLimit;
-            cp_stControlPara.swPwrLimitErrWt =(SWORD) MC_UpcInfo.stTestParaInfo.uwPwrLimitError;
-            cp_stControlPara.swPwrLimitKpPu = (SWORD)MC_UpcInfo.stTestParaInfo.uwPwrLimitKp;
-            cp_stControlPara.swPwrLimitKiPu = (SWORD)MC_UpcInfo.stTestParaInfo.uwPwrLimitKi;
-
-            cp_stFlg.ParaMotorDriveUpdateFinishFlg = TRUE;
-            // cp_stFlg.TestParaInfoUpdateFlg = FALSE;
-        }
+    if (cp_stFlg.ParaAInfoUpdateFlg == TRUE)
+    {
+        ass_stParaSet.uwStartupCoef = MC_UpcInfo.stAssistInfo.swStartupGain;
+        ass_stParaSet.uwStartupCruiseCoef = MC_UpcInfo.stAssistInfo.swStartcruiseGain;
+        ass_stParaSet.uwAssistStartNm = MC_UpcInfo.stAssistInfo.uwAssistStartNm;
+        ass_stParaSet.uwAssistStopNm = MC_UpcInfo.stAssistInfo.uwAssistStopNm;
+        ass_stParaSet.uwStartUpGainStep = MC_UpcInfo.stAssistInfo.uwStartUpGainStep;
+        ass_stParaSet.uwStartUpCadNm = MC_UpcInfo.stAssistInfo.uwStartUpCadNm;
+        ass_stParaSet.uwTorLPFCadNm = MC_UpcInfo.stAssistInfo.uwTorLPFCadNm;
+        ass_stParaSet.uwSpeedAssistSpdRpm = MC_UpcInfo.stAssistInfo.uwSpeedAssistSpdRpm;
+        ass_stParaSet.uwSpeedAssistIMaxA = MC_UpcInfo.stAssistInfo.uwSpeedAssistIMaxA;
+        ass_stParaSet.uwAssistLimitBikeSpdStart = MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStart;
+        ass_stParaSet.uwAssistLimitBikeSpdStop = MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStop;
+        ass_stParaSet.uwCadenceWeight = MC_UpcInfo.stAssistInfo.uwCadenceAssistWeight;
+        // ass_stParaSet.uwTorWeight = Q12_1 - ass_stParaSet.uwCadenceWeight;
+
+        cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
+        cp_stFlg.ParaAInfoUpdateFlg = FALSE;
+    }
 
-        cp_stFlg.ParaUpdateFlg = FALSE;
+    if(cp_stFlg.TestParaInfoUpdateFlg == TRUE)
+    {
+        cp_stControlPara.swAlignCurAp = (SWORD)MC_UpcInfo.stTestParaInfo.uwInitPosCurAmp;
+        cp_stControlPara.swDragVolAp = (SWORD)MC_UpcInfo.stTestParaInfo.uwVFControlVolAmp;
+        cp_stControlPara.swDragCurAp = (SWORD)MC_UpcInfo.stTestParaInfo.uwIFControlCurAmp;
+        cp_stControlPara.swDragSpdHz = (SWORD)MC_UpcInfo.stTestParaInfo.uwVFIFTargetFreHz;
+
+        cp_stControlPara.swSpeedAccRate = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopAccRate;
+        cp_stControlPara.swSpeedDccRate = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopDecRate;
+        cp_stControlPara.swAsrPIBandwidth = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopBandWidthHz;
+        cp_stControlPara.swAsrPIM = (SWORD)MC_UpcInfo.stTestParaInfo.uwSpeedLoopCoefM;
+
+        cp_stControlPara.swAcrPIBandwidth = (SWORD)MC_UpcInfo.stTestParaInfo.uwCuerrentLoopBandWidthHz;
+        cp_stControlPara.swAcrRaCoef = (SWORD)MC_UpcInfo.stTestParaInfo.uwCurrentLoopCoefM;
+
+        cp_stControlPara.swObsFluxPICrossfreHz = (SWORD)MC_UpcInfo.stTestParaInfo.uwFluxObsBandWidthHz;
+        cp_stControlPara.swObsFluxPIDampratio = (SWORD)MC_UpcInfo.stTestParaInfo.uwFluxObsCoefM;
+        cp_stControlPara.swObsSpdPLLBandWidthHz = (SWORD)MC_UpcInfo.stTestParaInfo.uwThetaObsPLLBandWidthHz;
+        cp_stControlPara.swObsSpdPLLM = (SWORD)MC_UpcInfo.stTestParaInfo.uwThetaObsPLLCoefM;
+
+        cp_stMotorPara.swJD = (SWORD)MC_UpcInfo.stTestParaInfo.uwJm;
+        cp_stControlPara.swPWMMaxDuty = (SWORD)MC_UpcInfo.stTestParaInfo.uwPWMMaxDuty;
+        cp_stControlPara.swPWM7to5Duty = (SWORD)MC_UpcInfo.stTestParaInfo.uwPWM7to5Duty;
+        cp_stControlPara.swPwrLimitValWt = (SWORD)MC_UpcInfo.stTestParaInfo.uwPwrLimit;
+        cp_stControlPara.swPwrLimitErrWt =(SWORD) MC_UpcInfo.stTestParaInfo.uwPwrLimitError;
+        cp_stControlPara.swPwrLimitKpPu = (SWORD)MC_UpcInfo.stTestParaInfo.uwPwrLimitKp;
+        cp_stControlPara.swPwrLimitKiPu = (SWORD)MC_UpcInfo.stTestParaInfo.uwPwrLimitKi;
+
+        cp_stFlg.ParaMotorDriveUpdateFinishFlg = TRUE;
+        // cp_stFlg.TestParaInfoUpdateFlg = FALSE;
     }
+
+    cp_stFlg.ParaUpdateFlg = FALSE;
 }
 /***************************************************************
  Function: mn_voSoftwareInit;

+ 14 - 3
User project/2.MotorDrive/Include/adc.h

@@ -21,6 +21,9 @@ Revising History (ECL of this file):
 #ifndef ADCDRV_H
 #define ADCDRV_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives
 *************************************************************************/
@@ -50,6 +53,7 @@ typedef struct
     UWORD uwIbAbsPu;  // Q14, Phase B current absolute value
     UWORD uwIcAbsPu;  // Q14, Phase C current absolute value
     UWORD uwIpeakPu;  // Q14, Max value of phase current
+    UWORD ulISamplePeakPu;
 
     UWORD uwIaAvgPu; // Ia register value
     UWORD uwIbAvgPu; // Ib register value
@@ -136,6 +140,7 @@ typedef struct
     SWORD swMotorTempKcof;
     UWORD uwCalibCoefK;
 
+    BOOL blCalibCalFlag;
 } ADC_COF;
 
 /************************************************************************
@@ -165,6 +170,8 @@ _ADCDRV_EXT UWORD adc_uwRdsonUReg;
 _ADCDRV_EXT UWORD adc_uwRdsonVReg;
 _ADCDRV_EXT UWORD adc_uwRdsonWReg;
 
+_ADCDRV_EXT BOOL tsttstFlg = FALSE;
+
 #else
 _ADCDRV_EXT ADC_COF      adc_stCof;
 _ADCDRV_EXT ADC_UP_OUT   adc_stUpOut;
@@ -185,6 +192,8 @@ _ADCDRV_EXT UWORD adc_uwRdsonUReg;
 _ADCDRV_EXT UWORD adc_uwRdsonVReg;
 _ADCDRV_EXT UWORD adc_uwRdsonWReg;
 
+_ADCDRV_EXT BOOL tsttstFlg;
+
 #endif
 /************************************************************************
  RAM ALLOCATION:
@@ -199,21 +208,23 @@ _ADCDRV_EXT void adc_voSampleUp(const ADC_COF *cof, ADC_UP_OUT *out);
 _ADCDRV_EXT void adc_voSampleDown(const ADC_COF *cof, ADC_DOWN_OUT *out);
 _ADCDRV_EXT void adc_voSampleCoef(ADC_COF *cof);
 _ADCDRV_EXT void adc_voSampleInit(void);
-_ADCDRV_EXT void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, const ADC_DOWN_OUT *down_out);
+_ADCDRV_EXT void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, ADC_DOWN_OUT *down_out);
 #else
 _ADCDRV_EXT void adc_voCalibration(ADC_COF *cof, ADC_DOWN_OUT *out1, ADC_UP_OUT *out2); // Phase A and B current zero point, other A/D sample value
 _ADCDRV_EXT void adc_voSampleUp(const ADC_COF *cof, ADC_UP_OUT *out);
 _ADCDRV_EXT void adc_voSampleDown(const ADC_COF *cof, ADC_DOWN_OUT *out);
 _ADCDRV_EXT void adc_voSampleCoef(ADC_COF *cof);
 _ADCDRV_EXT void adc_voSampleInit(void);
-_ADCDRV_EXT void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, const ADC_DOWN_OUT *down_out);
+_ADCDRV_EXT void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, ADC_DOWN_OUT *down_out);
 #endif
 
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/***********************************************************************/
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 7 - 1
User project/2.MotorDrive/Include/asr.h

@@ -21,6 +21,9 @@ Revising History (ECL of this file):
 #ifndef ASR_H
 #define ASR_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 *************************************************************************/
@@ -135,8 +138,11 @@ _ASR_EXT void asr_voSpdPIInit(void);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
-#endif
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
+#endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  All rights reserved.

+ 8 - 0
User project/2.MotorDrive/Include/brake.h

@@ -20,6 +20,10 @@ WLBDM_M4_SR_201809071-new FSM1.1, by mz, create this file;
 *************************************************************************/
 #ifndef BRAKE_H
 #define BRAKE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 *************************************************************************/
@@ -128,6 +132,10 @@ BRAKE_EXT void cvb_voBrakeInit(void);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 9 - 1
User project/2.MotorDrive/Include/pwm.h

@@ -20,6 +20,10 @@
 ************************************************************************/
 #ifndef PWM_H
 #define PWM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 ************************************************************************/
@@ -119,7 +123,7 @@ typedef struct
     RDSON_SAMPLE_AREA   uwSampleArea;
     SINGELR_SAMPLE_AREA uwSingelRSampleAreaLast;
     SINGELR_SAMPLE_AREA uwSingelRSampleArea;
-    UWORD               uwRDSONTrig;
+    UWORD               uwRdsonTrig;
     UWORD               uwSigRTrig;
     BOOL                blOvmFlag;
     BOOL                blSampleCalibFlag;
@@ -175,6 +179,10 @@ PWM_EXT void pwm_voInit(void);
 ************************************************************************/
 
 /***********************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 7 - 1
User project/2.MotorDrive/Include/pwrlim.h

@@ -21,6 +21,9 @@
 #ifndef PWRLIM_H
 #define PWRLIM_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 ************************************************************************/
@@ -136,7 +139,10 @@ _PWRLIM_EXT void pwr_voPwrLim2(const PWRLIM_IN *in, const PWRLIM_COF *cof, PWRLI
  Flag Define (N/A)
 ************************************************************************/
 
-/***********************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 7 - 1
User project/2.MotorDrive/Include/spdctrmode.h

@@ -22,6 +22,10 @@ Revising History (ECL of this file):
 #define SPDCTRMODE_H
 #include "spdctrFSM.h"
 #include "mathtool.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 *************************************************************************/
@@ -264,8 +268,10 @@ _SPDCTRMODE_EXT SWORD scm_swStopPWMOffFlag;
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/***********************************************************************/
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 8 - 1
User project/2.MotorDrive/Include/torqobs.h

@@ -22,6 +22,10 @@ Revising History (ECL of this file):
 #define TORQOBS_H
 
 #include "typedefine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Definitions & Macros (#define ...)
 *************************************************************************/
@@ -106,8 +110,11 @@ void torqobs_voCal(const TORQOBS_IN *in, const TORQOBS_COEFOUT *cof, TORQOBS_OUT
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
-#endif
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
+#endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  All rights reserved.

BIN
User project/2.MotorDrive/Lib/WLMCP_LIB.lib


+ 92 - 36
User project/2.MotorDrive/Source/adc.c

@@ -30,6 +30,10 @@ Revising History (ECL of this file):
 #include "Temp.h"
 #include "api.h"
 #include "api_rt.h"
+
+#ifdef RUN_ARCH_SIM
+#include "test_user.h"
+#endif
 /************************************************************************
  Constant Table:
 *************************************************************************/
@@ -46,6 +50,9 @@ Revising History (ECL of this file):
  Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
+#ifdef RUN_ARCH_SIM
+
+#else
 void adc_voCalibration(ADC_COF *cof, ADC_DOWN_OUT *out1, ADC_UP_OUT *out2)
 {
 
@@ -148,6 +155,7 @@ void adc_voCalibration(ADC_COF *cof, ADC_DOWN_OUT *out1, ADC_UP_OUT *out2)
         }
     }
 }
+#endif
 /***************************************************************
  Function: adc_voSample;
  Description: Get three-phase current value after zero point and gain process
@@ -364,22 +372,24 @@ void adc_voSampleUp(const ADC_COF *cof, ADC_UP_OUT *out)
     }
 
     ////////////////// PCB TEMP//////////////////////////////////////////////////////
-    out->PCBTempR = (UWORD)((ULONG)4096 * PCB_TEMP_SAMPLER / out->PCBTempReg - PCB_TEMP_SAMPLER); // Q14=Q24-Q10;
+    if(out->PCBTempReg != 0)
+    {
+        out->PCBTempR = (UWORD)((ULONG)4096 * PCB_TEMP_SAMPLER / out->PCBTempReg - PCB_TEMP_SAMPLER); // Q14=Q24-Q10;
+    }
     PcbTempCal((SWORD)out->PCBTempR);
     out->PCBTemp = tmp_PcbTemp;
 }
 
-static SWORD adc_pvt_swSingleReg;
-static SLONG adc_pvt_slRdsonReg;
-static LPF_OUT adc_pvt_stRdsonCoefLpf;
-static UWORD adc_pvt_uwCalGainFlg;
-static ULONG adc_pvt_ulGainTemp1;
-void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, const ADC_DOWN_OUT *down_out)
+static SWORD adc_pvt_swSingleReg = 0;
+static SLONG adc_pvt_slRdsonReg = 0;
+static LPF_OUT adc_pvt_stRdsonCoefLpf = {.slY.sw.hi = 1024, .slY.sw.low = 0};
+static BOOL adc_pvt_blCalGainFlg = FALSE;
+static ULONG adc_pvt_ulGainTemp1 = 0;
+static ULONG adc_pvt_ulIaAbsPu, adc_pvt_ulIbAbsPu, adc_pvt_ulIcAbsPu, adc_pvt_ulIPeakPu;
+void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, ADC_DOWN_OUT *down_out)
 { 
-
     if (pwm_stGenOut.blSampleCalibFlag == TRUE)
     {             
-
         switch (pwm_stGenOut.uwSingelRSampleArea)
         {
         case 0:
@@ -419,21 +429,57 @@ void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, const ADC_DOWN_
             break;
         }
       
-        adc_pvt_uwCalGainFlg = 1;
-           
+        adc_pvt_blCalGainFlg = TRUE;
     }
     else
-    {
-         if(scm_uwSpdFbkLpfAbsPu <= 2500)
+    {         
+         ULONG ulOverflowCurPu = (ULONG)(4095 - cof->uwIaOffset) * cof->uwCurReg2Pu >> 10;
+
+         if(scm_uwSpdFbkLpfAbsPu < 2500)
          {
+            adc_pvt_ulIaAbsPu = abs(down_out->slSampIaPu);
+            adc_pvt_ulIbAbsPu = abs(down_out->slSampIbPu);
+            adc_pvt_ulIcAbsPu = abs(down_out->slSampIcPu);
+            
+            adc_pvt_ulIPeakPu = adc_pvt_ulIaAbsPu > adc_pvt_ulIbAbsPu ? adc_pvt_ulIaAbsPu : adc_pvt_ulIbAbsPu;
+            down_out->ulISamplePeakPu = adc_pvt_ulIcAbsPu > adc_pvt_ulIPeakPu ? adc_pvt_ulIcAbsPu : adc_pvt_ulIPeakPu;
+
+            if(down_out->ulISamplePeakPu > 32767)  
+            {
+                adc_pvt_ulGainTemp1 = 780;     ///< Rdson电流采样溢出SWORD时校准系数需小于1024
+                adc_pvt_stRdsonCoefLpf.slY.sw.hi = (SWORD)adc_pvt_ulGainTemp1;  ///< 系数立刻变化,不经过滤波,防止down_out->swIaPu溢出
+            }
+            // else if(down_out->ulISamplePeakPu > 25800) ///<  25800 = 32767 / (1300 / 1024)
+            // {
+            //     adc_pvt_ulGainTemp1 = 1024;
+            //     adc_pvt_stRdsonCoefLpf.slY.sw.hi = (SWORD)adc_pvt_ulGainTemp1;
+            // }
+            else
+            {
+                adc_pvt_ulGainTemp1 = 1024;    ///< 允许其他数值,但大于1024需注意溢出SWORD
+            }
 
-            adc_pvt_ulGainTemp1 = 1300;
+            cof->blCalibCalFlag = FALSE;
+            adc_pvt_blCalGainFlg = FALSE;
          }
          else
          {
-            if(adc_pvt_uwCalGainFlg ==1)
+            if(adc_pvt_blCalGainFlg)
             {
-                adc_pvt_ulGainTemp1 = (SLONG)((SLONG)adc_pvt_swSingleReg << 10) / (SLONG)adc_pvt_slRdsonReg;               
+                if(adc_pvt_slRdsonReg != 0 && abs(adc_pvt_slRdsonReg) < ulOverflowCurPu)
+                {
+                    adc_pvt_ulGainTemp1 = (SLONG)((SLONG)adc_pvt_swSingleReg << 10) / (SLONG)adc_pvt_slRdsonReg;
+                }
+                else if(abs(adc_pvt_slRdsonReg) >= ulOverflowCurPu)
+                {
+                    adc_pvt_ulGainTemp1 = 780;     ///< Rdson电流采样削顶时不再校准电流,强制输出为119A防止溢出,尽快报出过流故障
+                    adc_pvt_stRdsonCoefLpf.slY.sw.hi = (SWORD)adc_pvt_ulGainTemp1;
+                }
+                else 
+                {
+                    // do nothing
+                }
+                                
                 if(adc_pvt_ulGainTemp1 > cof->uwCalibcoefMax)
                 {
                     adc_pvt_ulGainTemp1 = cof->uwCalibcoefMax;
@@ -444,23 +490,23 @@ void adc_voSRCalibration(ADC_COF *cof, const ADC_UP_OUT *up_out, const ADC_DOWN_
                 }
                 else
                 {
-                	//do nothing
+                    //do nothing
                 }
-                adc_pvt_uwCalGainFlg = 0;
-               
-               }
-            else
+
+                cof->blCalibCalFlag = TRUE;
+                adc_pvt_blCalGainFlg = FALSE;
+            }
+            else 
             {
                 adc_pvt_swSingleReg = 0;
                 adc_pvt_slRdsonReg = 0;
             }
-         }
+            
+        }
                   
         mth_voLPFilter((SWORD)adc_pvt_ulGainTemp1, &adc_pvt_stRdsonCoefLpf);
         cof->uwCalibcoef = adc_pvt_stRdsonCoefLpf.slY.sw.hi; 
-    }
-      ////////////////////////////////////////////////////////////////////////////////////
-       
+    }     
 }
 
 /***************************************************************
@@ -514,6 +560,16 @@ void adc_voSampleInit(void)
     adc_stDownOut.uwIaAvgPu = 0;
     adc_stDownOut.uwIbAvgPu = 0;
     adc_stDownOut.uwIcAvgPu = 0;
+    adc_stDownOut.ulUaRegSum = 0;
+    adc_stDownOut.ulUbRegSum = 0;
+    adc_stDownOut.ulUcRegSum = 0;
+    adc_stDownOut.ulIdcRegSum = 0;
+    adc_stDownOut.ulIaRegSum = 0;
+    adc_stDownOut.ulIbRegSum = 0;
+    adc_stDownOut.ulIcRegSum = 0;
+    adc_stDownOut.uwADCCalibCt = 0;
+    adc_stDownOut.blADCCalibFlg = FALSE;
+    adc_stDownOut.ulISamplePeakPu = 0;
 
     adc_stUpOut.uwVdcPu = 0;
     adc_stUpOut.uwVdcLpfPu = 0;
@@ -533,20 +589,20 @@ void adc_voSampleInit(void)
     adc_stUpOut.swCalibIaPu = 0;
     adc_stUpOut.swCalibIbPu = 0;
     adc_stUpOut.swCalibIcPu = 0;
-
-    adc_stDownOut.ulUaRegSum = 0;
-    adc_stDownOut.ulUbRegSum = 0;
-    adc_stDownOut.ulUcRegSum = 0;
-    adc_stDownOut.ulIdcRegSum = 0;
-    adc_stDownOut.ulIaRegSum = 0;
-    adc_stDownOut.ulIbRegSum = 0;
-    adc_stDownOut.ulIcRegSum = 0;
-    adc_stDownOut.uwADCCalibCt = 0;
-    adc_stDownOut.blADCCalibFlg = FALSE;
-
     adc_stUpOut.uwADCCalibCt = 0;
     adc_stUpOut.blADCCalibFlg = FALSE;
     adc_stUpOut.swIPMTempCe = 0;
+
+    adc_pvt_swSingleReg = 0;
+    adc_pvt_slRdsonReg = 0;
+    adc_pvt_stRdsonCoefLpf.slY.sw.hi = 1024;
+    adc_pvt_stRdsonCoefLpf.slY.sw.low = 0;
+    adc_pvt_blCalGainFlg = FALSE;
+    adc_pvt_ulGainTemp1 = 0;
+    adc_pvt_ulIaAbsPu = 0;
+    adc_pvt_ulIbAbsPu = 0;
+    adc_pvt_ulIcAbsPu = 0;
+    adc_pvt_ulIPeakPu = 0;
 }
 
 /*************************************************************************

+ 0 - 2
User project/2.MotorDrive/Source/alarm.c

@@ -1290,8 +1290,6 @@ void alm_voDetec200MS(const ALM_BIKE_IN *in, const ALM_DETEC200MS_COF *coef) /*
     {
         alm_stDecCt.uwCadenceFlt = 0;
     }
-
-    
     
     /* Bike torque sensor fault */
     if((in->uwTroqReg < coef->uwTorqMinReg) || (in->uwTroqReg >= coef->uwTorqMaxReg)) //Fault: U_Torq < 0.1V or  >=3V

+ 7 - 7
User project/2.MotorDrive/Source/pwm.c

@@ -79,8 +79,9 @@ void pwm_voInit(void)
     pwm_stGenOut.uwOldTrig = 0;
     pwm_stGenOut.uwNewTrig = 0;
     pwm_stGenOut.uwSampleArea = IgnoreNone;
-    pwm_stGenOut.uwRDSONTrig = 129;
+    pwm_stGenOut.uwRdsonTrig = 129;
     pwm_stGenOut.uwSigRTrig = HW_HHHPWM_PERIOD;
+    pwm_stGenOut.blSampleCalibFlag = FALSE;
 }
 
 /************************************************************************
@@ -522,7 +523,7 @@ void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) /* pa
         out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14
         out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14;                // Q14=Q14+Q14-Q14
 
-        out->uwRDSONTrig = 129;
+        out->uwRdsonTrig = 129;
     }    
     else if(cp_stFlg.CurrentSampleModelSelect == SINGLERESISITANCE)
     {
@@ -581,8 +582,7 @@ void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) /* pa
                 else
                 {
                     swPWMPRD21 = swPWMPRD1 - pwm_pvt_swMin_Cur_Smpl_Ct;
-                    swPWMPRD22 = (swPWMPRD2 << 1) - swPWMPRD21;
-                    
+                    swPWMPRD22 = (swPWMPRD2 << 1) - swPWMPRD21;                  
                 }
             }
             else if ((swOvmT1 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0)
@@ -804,7 +804,7 @@ void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) /* pa
         if ((16384 - swOvmT1 - swOvmT2) > coef->uwPWMMinSample1Pu)
         {
             out->uwSampleArea = IgnoreNone;
-            out->uwRDSONTrig = 129;
+            out->uwRdsonTrig = 129;
         }
         else
         {
@@ -834,7 +834,7 @@ void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) /* pa
                     out->uwSampleArea = IgnoreNone;
                     break;
                 }
-                out->uwRDSONTrig = swPWMPRD3 + coef->uwSampleSteadyCt;
+                out->uwRdsonTrig = swPWMPRD3 + coef->uwSampleSteadyCt;
             }
             else
             {
@@ -862,7 +862,7 @@ void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) /* pa
                     out->uwSampleArea = IgnoreNone;
                     break;
                 }
-                out->uwRDSONTrig = swPWMPRD2 + coef->uwSampleSteadyCt;
+                out->uwRdsonTrig = swPWMPRD2 + coef->uwSampleSteadyCt;
             }
         }
     }

+ 23 - 4
User project/2.MotorDrive/Source/spdctrFSM.c

@@ -126,8 +126,28 @@ void ClzLoop_TbcupHook(void)
     pwr_stPwrLimIn.PCBTemp = adc_stUpOut.PCBTemp;
     pwr_voPwrLim2(&pwr_stPwrLimIn, &pwr_stPwrLimCof, &pwr_stPwrLimOut2); // Q14
 
-    scm_swIqRefPu = swCurRefrompu;
-    scm_swIdRefPu = 0; //flx_stCtrlOut.swIdRefPu;
+    /*======================================================================= 
+             Set Iq and Id reference for Constant Voltage Break
+    =======================================================================*/
+    cvb_stBrakeIn.uwVdcLpfPu = adc_stUpOut.uwVdcLpfPu;
+    cvb_stBrakeIn.swIdRefPu = scm_swIdRefPu;
+    cvb_stBrakeIn.swIqRefPu = swCurRefrompu;             
+    cvb_stBrakeIn.swSpdPu = scm_stSpdFbkLpf.slY.sw.hi;
+    cvb_stBrakeIn.uwAngelPu = scm_uwAngRefPu;
+    cvb_stBrakeIn.uwSpdLpfAbsPu = scm_uwSpdFbkLpfAbsPu;
+    cvb_voBrake(&cvb_stBrakeIn,&cvb_stBrakeCoef,&cvb_stBrakeOut);
+ 
+    /** Idref可变范围-3A~0A且未弱磁,暂不做过多处理;Angle在down中更新,暂不改为改为恒压制动角度 **/
+    if(cvb_stBrakeIn.uwVdcLpfPu >= cvb_stBrakeCoef.uwVdcStartCvbPu)
+    {
+        scm_swIdRefPu = cvb_stBrakeOut.swIdRefPu;
+    }
+    else
+    {
+        scm_swIdRefPu = 0;  //flx_stCtrlOut.swIdRefPu;  
+    }  
+
+    scm_swIqRefPu = cvb_stBrakeOut.swIqRefPu;
 }
 
 void Stop_TbcupHook(void)
@@ -159,8 +179,7 @@ void ParDet_TbcdownHook(void)
 }
 void StartUp_TbcdownHook(void)
 {
-
-/* Speed feedback LPF */
+    /* Speed feedback LPF */
     if(cp_stFlg.ThetaGetModelSelect == ANG_OBSERVER)
     {
         mth_voLPFilter(obs_stObsOutPu.swElecFreqPu, &scm_stSpdFbkLpf);

+ 1 - 0
User project/3.BasicFunction/Include/bikespeed.h

@@ -114,6 +114,7 @@ typedef struct
     BIKESPEED_FSM bikespeed_fsm;
     
     UWORD uwCaputureOverflowMinCnt;
+    UWORD uwCaputureOverflowMinCntTest;
     UWORD uwBikeForwardCnt;   // Count number to calculate trip
     BOOL  blUpdateTripCntFlg; // Unit the same as BIKESPEED_COF.uwMinTriptoUpdate ��need clear after update trip.
     UWORD uwOverflowfirst;

+ 1 - 1
User project/3.BasicFunction/Include/can.h

@@ -22,7 +22,7 @@ Revising History (ECL of this file):
 #define CAN_H
 
 #include "typedefine.h"
-#include "gd32F30x.h"
+#include "gd32f30x.h"
 /************************************************************************
  Compiler Directives (N/A)
 *************************************************************************/

+ 14 - 0
User project/3.BasicFunction/Include/canAppl.h

@@ -16,7 +16,13 @@
 #define CANAPPL_H
 
 #include "typedefine.h"
+#ifndef RUN_ARCH_SIM
 #include "gd32f30x.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /****************************************
  *
  *          Definitions & Macros
@@ -730,6 +736,14 @@ void Can_AssistCoef_Read(const UPC_CurveOrderInfo_Struct_t *order);
  *
  */
 void Can_AssistCoef_Write(const UPC_CurveOrderInfo_Struct_t *order);
+
+/************************************************************************
+ Flag Define (N/A)
+*************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 
 /************************************************************************

+ 9 - 5
User project/3.BasicFunction/Include/torquesensor.h

@@ -16,6 +16,10 @@
 #define TORQUESENSOR_H
 
 #include "typedefine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /****************************************
  *
  *          Definitions & Macros
@@ -43,7 +47,7 @@
     } // Default value of CADENCE_OUT
 #define TORQUESENSOR_COF_DEFAULT                                         \
     {                                                                    \
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE, 1,1,2,2,3,3,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE, 1,1,2,2,3,3,4,4,0,0,0,0,0,0,0,0,0,0 \
     } // Default value of CADENCE_OUT
 
 #define TORQUESENSITIVE_COF_DEFAULT                                         \
@@ -110,10 +114,6 @@ typedef struct
     UWORD uwBikeTorStep4NmPu;
 
     UWORD uwSensorVolPerTorqDefault;
-    UWORD uwSensorVolPerTorq1; // mV/Nm,the output gain1
-    UWORD uwSensorVolPerTorq2; // mV/Nm,the output gain2
-    UWORD uwSensorVolPerTorq3; // mV/Nm,the output gain3
-    UWORD uwSensorVolPerTorq4; // mV/Nm,the output gain4
 
     ULONG ulTorqueReg2PuDefault;
     ULONG ulTorqueReg2Pu1; // Gain1 of register to Pu
@@ -145,6 +145,10 @@ void torsensor_voCadenceCnt(void);
 void torsensor_voDynamicOffset(void);
 void torsensor_voOffsetUpdate(void);
 /************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /************************************************************************
  End of this File (EOF):

+ 54 - 31
User project/3.BasicFunction/Source/AssistCurve.c

@@ -435,12 +435,13 @@ void ass_voAssitCoef(void)
 
 static SWORD ass_pvt_swVoltCnt=0;
 static UWORD ass_pvt_uwTorqAccCnt=0,ass_pvt_uwTorqDecCnt=0,ass_pvt_uwSpd2TorqCnt=0;
+UWORD AssCnt1ms; 
 static void AssitCuvApplPerVolt(void) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */
 {  
     SLONG slTeTorAssitTmpPu,slTeTorAssitLinerPu,slTeCadAssitTmpPu;
     SWORD swTeTorAssitPu1, swTeTorAssitPu2;
     SWORD swTeCadAssitPu1, swTeCadAssitPu2;
-    SWORD swTmpSpdtoTorqCur;
+    SWORD swTmpSpdtoTorqCur;   
     SLONG slTmpSmoothCur;
     SWORD swTorqCmd1, swTorqCmd, swCadCmd;
     UWORD uwTorqAccStep = 50,uwTorqDecStep = 80;
@@ -481,6 +482,13 @@ static void AssitCuvApplPerVolt(void) /* parasoft-suppress METRICS-28 "本项目
     }
     uwTorqDecStep = 80;
     
+    AssCnt1ms ++;
+    if(AssCnt1ms >= 10000)
+    {
+        AssCnt1ms = 0;
+    }
+    
+    
     /* Select TorqRef: LPFTorq or MAFTorq */
     swTorqCmd1 = (SWORD)(((SLONG)ass_stCalIn.uwtorque * ass_stCalCoef.swTorqFilterGain >> 14) +
                ((SLONG)ass_stCalIn.uwtorquelpf * (Q14_1 - ass_stCalCoef.swTorqFilterGain) >> 14)); //转矩指令滤波切换,由低通滤波到踏频相关的滑动平均滤波
@@ -494,7 +502,7 @@ static void AssitCuvApplPerVolt(void) /* parasoft-suppress METRICS-28 "本项目
     slTeTorAssitTmpPu = (SLONG)(ass_slPolynomial(&ass_stCalCoef.uwTorqueAssGain[ass_stCalIn.uwGearSt], &swTorqCmd, 14)); // Q14  转矩助力曲线
     if(ass_stCalIn.uwGearSt == 5)
     {
-        slTeTorAssitLinerPu = (((SLONG)swTorqCmd * LinerAssist[ass_stCalIn.uwGearSt-1] )>> 12) + 273;
+        slTeTorAssitLinerPu = (((SLONG)swTorqCmd * LinerAssist[ass_stCalIn.uwGearSt-1] )>> 12) + 273; // Q14  转矩助力曲线线性段
     }
     else
     {
@@ -577,24 +585,36 @@ static void AssitCuvApplPerVolt(void) /* parasoft-suppress METRICS-28 "本项目
             else
             {
             	//do nothing
-            }
-            
+            }          
             ass_stCalOut.swVoltLimitPu = (SWORD)slTmpVoltLim;
             
-            if(slSpdErr <= 1000)
+//            if(slSpdErr <= 1000)
+//            {
+//                ass_stCalCoef.StartFlag = 1;
+//            }  
+            if(abs(scm_swIqRefPu- scm_swIqFdbLpfPu) > 200)
+            {
+                ass_pvt_swVoltCnt++;  
+            }    
+            else
             {
+                ass_pvt_swVoltCnt=0;
+            }
+            if(ass_pvt_swVoltCnt > 10)
+            {
+                ass_pvt_swVoltCnt=0;
                 ass_stCalCoef.StartFlag = 1;
-            }     
+            }      
         }
         else if(ass_stCalCoef.StartFlag ==1 )
         {
-            if(ass_stCalOut.swVoltLimitPu < (scm_swVsDcpLimPu - uwVoltAccStep))
+            if(0 == (AssCnt1ms%5))
             {
-                ass_stCalOut.swVoltLimitPu += (SWORD)uwVoltAccStep;//ass_stCalCoef.uwStartUpGainAddStep;
-            }
-            else
-            {
-                ass_stCalOut.swVoltLimitPu = scm_swVsDcpLimPu;
+                ass_stCalOut.swVoltLimitPu += ass_stCalCoef.uwStartUpGainAddStep; 
+                if (ass_stCalOut.swVoltLimitPu > scm_swVsDcpLimPu)
+                {
+                    ass_stCalOut.swVoltLimitPu = scm_swVsDcpLimPu;
+                }
             }
  
             if(slSpdErr <= 100)
@@ -668,25 +688,28 @@ static void AssitCuvApplPerVolt(void) /* parasoft-suppress METRICS-28 "本项目
         }
         
         /* Reduce Voltage Limit When LPFTorq < Switch1TorqThreshold */     
-//         if(ass_stCalIn.uwtorquelpf >= ass_stCalCoef.uwSwitch1TorqThreshold)
-//         {             
-             ass_stCalOut.swVoltLimitPu +=  (SWORD)uwVoltAccStep; //ass_stCalCoef.uwStartUpGainAddStep;
-//         }
-//         else if (ass_stCalIn.uwtorquelpf <= ass_stCalCoef.uwSwitch1TorqThreshold)
-//         {
-//             ass_stCalOut.swVoltLimitPu -=  uwVoltDecStep; //ass_stCalCoef.uwSpeedConstantCommand;
-//         }
-//         else
-//         {
-//         }
-         if (ass_stCalOut.swVoltLimitPu > scm_swVsDcpLimPu)
-         {
-             ass_stCalOut.swVoltLimitPu = scm_swVsDcpLimPu;
-         }
-//         else if (ass_stCalOut.swVoltLimitPu <= (swTmpVoltPu + ass_stParaSet.uwStartUpCadNm))
-//         {
-//             ass_stCalOut.swVoltLimitPu =  swTmpVoltPu + ass_stParaSet.uwStartUpCadNm;
-//         }
+        if(0 == (AssCnt1ms%5))
+        {
+//            if(ass_stCalIn.uwtorque >= ass_stCalCoef.uwSwitch1TorqThreshold)
+//            {             
+                ass_stCalOut.swVoltLimitPu +=  ass_stCalCoef.uwStartUpGainAddStep;
+                if (ass_stCalOut.swVoltLimitPu > scm_swVsDcpLimPu)
+                {
+                    ass_stCalOut.swVoltLimitPu = scm_swVsDcpLimPu;
+                }
+//            }
+//            else if (ass_stCalIn.uwtorque <= ass_stCalCoef.uwSwitch1TorqThreshold)
+//            {
+////                ass_stCalOut.swVoltLimitPu -=  ass_stCalCoef.uwSpeedConstantCommand;
+////                if (ass_stCalOut.swVoltLimitPu <= (tmpVoltargetPu + ass_ParaSet.uwStartUpCadNm))
+////                {
+////                    ass_stCalOut.swVoltLimitPu =  tmpVoltargetPu + ass_ParaSet.uwStartUpCadNm;
+////                }
+//            }
+//            else
+//            {
+//            }
+        }
        
         /* TorqueRef Select Coef */
         ass_stCalCoef.swTorqFilterGain += 4; // Q14 转矩滤波方式切换系数

+ 1 - 4
User project/3.BasicFunction/Source/Cadence.c

@@ -78,6 +78,7 @@ static void cadence_voCadenceIdle(UWORD source)
         {
             cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
             cadence_stFreGetOut.uwCaputureNumCnt = 0;
+            cadence_stFreGetOut.cadence_fsm = CADENCE_BACKWOR;
         }
 
         if (cadence_stFreGetOut.cadence_dir == CADENCE_DIR_FORWARD)
@@ -255,10 +256,6 @@ static void cadence_voCadenceHighFrequencyWork(UWORD source)
 ****************************************************************/
 static void cadence_voCadenceBackword(UWORD source)
 {
-    if (source == 1)
-    {
-        cadence_stFreGetOut.uwCaputureOverflowCnt++;
-    }
     cadence_stFreGetOut.uwFrequencyPu = 0;
     cadence_stFreGetOut.uwLPFFrequencyPu = 0;
     cadence_stFreGetOut.uwFreqPercent = 0;

+ 2 - 0
User project/3.BasicFunction/Source/bikespeed.c

@@ -188,6 +188,7 @@ static void bikespeed_voBikeSpeedWork(UWORD source)
             {
                 //do noting
             }
+            bikespeed_stFreGetOut.uwCaputureOverflowMinCntTest = bikespeed_stFreGetOut.uwCaputureOverflowMinCnt;
 
             /* BikeSpeed Freq Cal */
             bikespeed_pvt_FreqPu = (ULONG)(((UQWORD)720000 << 20) / ((UQWORD)ulCaputureCntErr * bikespeed_stFreGetCof.uwNumbersPulses * FBASE));
@@ -340,6 +341,7 @@ void bikespeed_voBikeSpeedInit(void)
     bikespeed_stFreGetOut.uwBikespeedPwrErrorCnt = 0;
     bikespeed_stFreGetOut.uwBikespeedPwrErrorCnt = 0;
     bikespeed_stFreGetOut.uwBikespeedPwrRecoverCnt = 0;
+    bikespeed_stFreGetOut.uwCaputureOverflowMinCntTest = 0;
 }
 
 /***************************************************************

+ 290 - 247
User project/3.BasicFunction/Source/i2c_master.c

@@ -27,7 +27,7 @@
 #include "i2c_master.h"
 #include "api_rt.h"
 #include "gd32f30x_dma.h"
-
+#include "api.h"
 /*************************************************************************
  Exported Functions (N/A)
 *************************************************************************/
@@ -564,7 +564,7 @@ static void i2c_voBufferWrite2EE(const UBYTE *pBuffer, UBYTE SlaveAddr, UBYTE Wr
     UBYTE ubNPages = 0, ubNSingleBytes = 0, ubAddr = 0, ubCnt = 0, ubTemp = 0;
     
     ubAddr = WriteAddr % I2C_EE_PAGESIZE_NBYTES;
-    ubCnt = I2C_EE_PAGESIZE_NBYTES - 1 - ubAddr; // Cnt datas away from page alignment
+    ubCnt = I2C_EE_PAGESIZE_NBYTES - ubAddr; // Cnt datas away from page alignment
     ubNPages = NBytesToWrite / I2C_EE_PAGESIZE_NBYTES;
     ubNSingleBytes = NBytesToWrite % I2C_EE_PAGESIZE_NBYTES;    
 
@@ -680,7 +680,8 @@ void i2c_voInfoWrite2EE(const I2C_TX_COF *coef, I2C_TX_OUT *out)
         {
             ubSlaveAddr = I2C_SLAVEADDR_BLOCK1;
         }
-        i2c_voBufferWrite2EE(I2C_pWriteBuffer, ubSlaveAddr, ubWriteAddr, ubNBytes);
+        //i2c_voBufferWrite2EE(I2C_pWriteBuffer, ubSlaveAddr, ubWriteAddr, ubNBytes);
+        iI2C_Write(0, ubSlaveAddr, ubWriteAddr, 8, I2C_pWriteBuffer, ubNBytes);
     }
 
     if ((ubReTX1 == 0) && (I2C_EE_ComuFltFlg != TRUE))
@@ -714,7 +715,7 @@ void i2c_voHistoryWrite2EE(const I2C_TX_COF *coef, I2C_TX_OUT *out)
 	ubReTX2 = 2;
 #endif
 
-	ubSlaveAddr = I2C_SLAVEADDR_BLOCK3;
+    ubSlaveAddr = I2C_SLAVEADDR_BLOCK3;
     ubWriteAddr = 0x00;
 
     while (ubReTX2 != 0)
@@ -729,7 +730,9 @@ void i2c_voHistoryWrite2EE(const I2C_TX_COF *coef, I2C_TX_OUT *out)
         {
             ubSlaveAddr = I2C_SLAVEADDR_BLOCK3;
         }
-        i2c_voBufferWrite2EE(I2C_pHistoryWriteBuffer, ubSlaveAddr, ubWriteAddr, ubNBytes);
+        
+        //i2c_voBufferWrite2EE(I2C_pHistoryWriteBuffer, ubSlaveAddr, ubWriteAddr, ubNBytes);
+        iI2C_Write(0, ubSlaveAddr, ubWriteAddr, 8, I2C_pHistoryWriteBuffer, ubNBytes);
     }
     if ((ubReTX2 == 0) && (I2C_EE_ComuFltFlg != TRUE))
     {
@@ -798,262 +801,302 @@ void i2c_bus_reset(void)
  Subroutine Call:
  Reference:
 *************************************************************************/
-void i2c_voSysparaReadFromEE(I2C_RXCRC_OUT *out) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */
-{
+//  void i2c_voSysparaReadFromEE(I2C_RXCRC_OUT *out) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */
+//  {
   
-    UWORD timeout = 0;
-    UBYTE ubRdNBytes = 0, ubRdSlaveAddr = 0, ubRdAddr = 0;
-    UBYTE state = (UBYTE)I2C_START;
-    UBYTE read_cycle = 0;
-    UBYTE ubRdCnt = 2;
+//      UWORD timeout = 0;
+//      UBYTE ubRdNBytes = 0, ubRdSlaveAddr = 0, ubRdAddr = 0;
+//      UBYTE state = (UBYTE)I2C_START;
+//      UBYTE read_cycle = 0;
+//      UBYTE ubRdCnt = 2;
    
-    UBYTE i2c_timeout_flag = 0;
-    UBYTE *p_buffer;
-     while(ubRdCnt != 0)
-     {
-    	 ubRdCnt--;
-        /* enable acknowledge */
-        i2c_ack_config(I2C0, I2C_ACK_ENABLE);
-
-        if (ubRdCnt == 1)
-        {
-            ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK1;
-            ubRdAddr = 0x00;
-            ubRdNBytes = I2C_RX1_NBYTES;           
-            p_buffer = I2C_ubReadBuffer[0];
-            i2c_timeout_flag = 0;
-        }
-        else if (ubRdCnt == 0)
-        {
-            ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK3;
-            ubRdAddr = 0x00;
-            ubRdNBytes = I2C_RX2_NBYTES;
-            p_buffer = I2C_ubReadBuffer[1];
-            i2c_timeout_flag = 0;
-        }
-        else
-        {
-        	//do nothing
-        }
+//      UBYTE i2c_timeout_flag = 0;
+//      UBYTE *p_buffer;
+    
+//       while(ubRdCnt != 0)
+//       {
+//      	 ubRdCnt--;
+
+//          if (ubRdCnt == 1)
+//          {
+//              ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK1;
+//              ubRdAddr = 0x00;
+//              ubRdNBytes = I2C_RX1_NBYTES;           
+//              p_buffer = I2C_ubReadBuffer[0];
+//              i2c_timeout_flag = 0;
+//          }
+//          else if (ubRdCnt == 0)
+//          {
+//              ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK3;
+//              ubRdAddr = 0x00;
+//              ubRdNBytes = I2C_RX2_NBYTES;
+//              p_buffer = I2C_ubReadBuffer[1];
+//              i2c_timeout_flag = 0;
+//          }
+//          else
+//          {
+//          	//do nothing
+//          }
         
-        while(i2c_timeout_flag ==0)
-        {
-            switch(state) 
-            {
-            case I2C_START:
-                if(RESET == read_cycle) 
-                {
-                    /* disable I2C0 */
-                    i2c_disable(I2C0);
-                    /* enable I2C0 */
-                    i2c_enable(I2C0);
-                    /* enable acknowledge */
-                    i2c_ack_config(I2C0, I2C_ACK_ENABLE);
-                    /* i2c master sends start signal only when the bus is idle */
-                    while((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) != 0) && (timeout < I2C_SHORT_TIMEOUT))
-                    {
-                        timeout++;
-                    }
-                    
-                    if(timeout < I2C_SHORT_TIMEOUT) 
-                    {
-                        /* send the start signal */
-                        i2c_start_on_bus(I2C0);
-                        timeout = 0;
-                        state = (UBYTE)I2C_SEND_ADDRESS;
-                    } 
-                    else 
-                    {
-                        i2c_bus_reset();
-                        timeout = 0;
-                        state = (UBYTE)I2C_START;
-                       
-                    }
-                } 
-                else 
-                {
-                    i2c_start_on_bus(I2C0);
-                    timeout = 0;
-                    state = (UBYTE)I2C_SEND_ADDRESS;
-                }
-                break;
-            case I2C_SEND_ADDRESS:
-                /* i2c master sends START signal successfully */
-                while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (timeout < I2C_SHORT_TIMEOUT))
-                {
-                    timeout++;
-                }
-                if(timeout < I2C_SHORT_TIMEOUT) 
-                {
-                    if(RESET == read_cycle) 
-                    {
-                        i2c_master_addressing(I2C0, ubRdSlaveAddr, I2C_TRANSMITTER);
-                        state = (UBYTE)I2C_CLEAR_ADDRESS_FLAG;
-                    } 
-                    else 
-                    {
-                        i2c_master_addressing(I2C0, ubRdSlaveAddr, I2C_RECEIVER);
-                        state = (UBYTE)I2C_CLEAR_ADDRESS_FLAG;
-                    }
-                    timeout = 0;
-                } 
-                else 
-                {
-                    timeout = 0;
-                    state = (UBYTE)I2C_START;
-                    read_cycle = 0;
-                    
-                }
-                break;
-            case I2C_CLEAR_ADDRESS_FLAG:
-                /* address flag set means i2c slave sends ACK */
-                while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0) && (timeout < I2C_SHORT_TIMEOUT))
-                {
-                    timeout++;
-                }
-                if(timeout < I2C_SHORT_TIMEOUT) 
-                {
-                    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
-                    timeout = 0;
-                    state = (UBYTE)I2C_TRANSMIT_DATA;
-                } else 
-                {
-                    timeout = 0;
-                    state = (UBYTE)I2C_START;
-                    read_cycle = 0;
-                    
-                }
-                break;
-            case I2C_TRANSMIT_DATA:
-                if(RESET == read_cycle) 
-                {
-                    /* wait until the transmit data buffer is empty */
-                    while((i2c_flag_get(I2C0, I2C_FLAG_TBE) == 0) && (timeout < I2C_SHORT_TIMEOUT))
-                    {
-                        timeout++;
-                    }
-                    if(timeout < I2C_SHORT_TIMEOUT) 
-                    {
-                        /* send the EEPROM's internal address to write to : only one byte address */
-                        i2c_data_transmit(I2C0, ubRdAddr);
-                        timeout = 0;
-                    } 
-                    else 
-                    {
-                        timeout = 0;
-                        state = (UBYTE)I2C_START;
-                        read_cycle = 0;
-                        
-                    }
-                    /* wait until BTC bit is set */
-                    while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (timeout < I2C_SHORT_TIMEOUT))
-                    {
-                        timeout++;
-                    }
-                    if(timeout < I2C_SHORT_TIMEOUT) 
-                    {
-                        timeout = 0;
-                        state = (UBYTE)I2C_START;
-                        read_cycle++;
-                    } else 
-                    {
-                        timeout = 0;
-                        state = (UBYTE)I2C_START;
-                        read_cycle = 0;
-                        
-                    }
-                } 
-                else 
-                {
-                    /* one byte master reception procedure (polling) */
-                    if(ubRdNBytes < 2) 
-                    {
-                        /* disable acknowledge */
-                        i2c_ack_config(I2C0, I2C_ACK_DISABLE);
-                        /* clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register (I2C_STAT0 has already been read) */
-                        i2c_flag_get(I2C0, I2C_FLAG_ADDSEND);
-                        /* send a stop condition to I2C bus*/
-                        i2c_stop_on_bus(I2C0);
-                        /* wait for the byte to be received */
-                        while(i2c_flag_get(I2C0, I2C_FLAG_RBNE) == 0)
-                        {
-                        	// do nothing
-                        }
-                        /* read the byte received from the EEPROM */
-                        *p_buffer = i2c_data_receive(I2C0);
-                        /* decrement the read bytes counter */
-                        ubRdNBytes--;
-                        timeout = 0;
-                        state = (UBYTE)I2C_STOP;
-                    } 
-                    else 
-                    {  /* more than one byte master reception procedure (DMA) */                   
-                        dma_transfer_number_config(DMA0, DMA_CH6, ubRdNBytes);
-                        
-                        DMA_CH6MADDR(DMA0) = (ULONG)p_buffer;
+//          /* enable acknowledge */
+//          i2c_ack_config(I2C0, I2C_ACK_ENABLE);
+        
+//          while(i2c_timeout_flag ==0)
+//          {
+//              switch(state) 
+//              {
+//              case I2C_START:
+//                  if(RESET == read_cycle) 
+//                  {
+//                      /* disable I2C0 */
+//                      i2c_disable(I2C0);
+//                      /* enable I2C0 */
+//                      i2c_enable(I2C0);
+//                      /* enable acknowledge */
+//                      i2c_ack_config(I2C0, I2C_ACK_ENABLE);
+//                      /* i2c master sends start signal only when the bus is idle */
+//                      while((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) != 0) && (timeout < I2C_SHORT_TIMEOUT))
+//                      {
+//                          timeout++;
+//                      }
                     
-                        i2c_dma_last_transfer_config(I2C0, I2C_DMALST_ON);
-                        /* enable I2C0 DMA */
-                        i2c_dma_config(I2C0, I2C_DMA_ON);
-                        /* enable DMA0 channel5 */
-                        dma_channel_enable(DMA0, DMA_CH6);
-                        /* wait until BTC bit is set */
-                        while(dma_flag_get(DMA0, DMA_CH6, DMA_FLAG_FTF) == 0)
-                        {
-                        	// do nothing
-                        }
-
-                        state = (UBYTE)I2C_STOP;
-                    }
-                }
-                break;
-            case I2C_STOP:
-                /* send a stop condition to I2C bus */
-                i2c_stop_on_bus(I2C0);
-                /* i2c master sends STOP signal successfully */
-                while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_SHORT_TIMEOUT)) 
-                {
-                    timeout++;
-                }
-                if(timeout < I2C_SHORT_TIMEOUT)
-                {
-                    timeout = 0;                 
-                    i2c_timeout_flag = 1;
-                    state = (UBYTE)I2C_START;
+//                      if(timeout < I2C_SHORT_TIMEOUT) 
+//                      {
+//                          /* send the start signal */
+//                          i2c_start_on_bus(I2C0);
+//                          timeout = 0;
+//                          state = (UBYTE)I2C_SEND_ADDRESS;
+//                      } 
+//                      else 
+//                      {
+//                          i2c_bus_reset();
+//                          timeout = 0;
+//                          state = (UBYTE)I2C_START;
+//                      }
+//                  } 
+//                  else 
+//                  {
+//                      i2c_start_on_bus(I2C0);
+//                      timeout = 0;
+//                      state = (UBYTE)I2C_SEND_ADDRESS;
+//                  }
+//                  break;
+//              case I2C_SEND_ADDRESS:
+//                  /* i2c master sends START signal successfully */
+//                  while((i2c_flag_get(I2C0, I2C_FLAG_SBSEND) == 0) && (timeout < I2C_SHORT_TIMEOUT))
+//                  {
+//                      timeout++;
+//                  }
+//                  if(timeout < I2C_SHORT_TIMEOUT) 
+//                  {
+//                      if(RESET == read_cycle) 
+//                      {
+//                          i2c_master_addressing(I2C0, ubRdSlaveAddr, I2C_TRANSMITTER);
+//                          state = (UBYTE)I2C_CLEAR_ADDRESS_FLAG;
+//                      } 
+//                      else 
+//                      {
+//                          i2c_master_addressing(I2C0, ubRdSlaveAddr, I2C_RECEIVER);
+//                          state = (UBYTE)I2C_CLEAR_ADDRESS_FLAG;
+//                      }
+//                      timeout = 0;
+//                  } 
+//                  else 
+//                  {
+//                      timeout = 0;
+//                      state = (UBYTE)I2C_START;
+//                      read_cycle = 0;
+//                  }
+//                  break;
+//              case I2C_CLEAR_ADDRESS_FLAG:
+//                  /* address flag set means i2c slave sends ACK */
+//                  while((i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) == 0) && (timeout < I2C_SHORT_TIMEOUT))
+//                  {
+//                      timeout++;
+//                  }
+//                  if(timeout < I2C_SHORT_TIMEOUT) 
+//                  {
+//                      i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
+//                      timeout = 0;
+//                      state = (UBYTE)I2C_TRANSMIT_DATA;
+//                  } 
+//                  else 
+//                  {
+//                      timeout = 0;
+//                      state = (UBYTE)I2C_START;
+//                      read_cycle = 0;   
+//                  }
+//                  break;
+//              case I2C_TRANSMIT_DATA:
+//                  if(RESET == read_cycle) 
+//                  {
+//                      /* wait until the transmit data buffer is empty */
+//                      while((i2c_flag_get(I2C0, I2C_FLAG_TBE) == 0) && (timeout < I2C_SHORT_TIMEOUT))
+//                      {
+//                          timeout++;
+//                      }
+//                      if(timeout < I2C_SHORT_TIMEOUT) 
+//                      {
+//                          /* send the EEPROM's internal address to write to : only one byte address */
+//                          i2c_data_transmit(I2C0, ubRdAddr);
+//                          timeout = 0;
+//                      } 
+//                      else 
+//                      {
+//                          timeout = 0;
+//                          state = (UBYTE)I2C_START;
+//                          read_cycle = 0;    
+//                      }
+//                      /* wait until BTC bit is set */
+//                      while((i2c_flag_get(I2C0, I2C_FLAG_BTC) == 0) && (timeout < I2C_SHORT_TIMEOUT))
+//                      {
+//                          timeout++;
+//                      }
+//                      if(timeout < I2C_SHORT_TIMEOUT) 
+//                      {
+//                          timeout = 0;
+//                          state = (UBYTE)I2C_START;
+//                          read_cycle++;
+//                      }
+//                      else 
+//                      {
+//                          timeout = 0;
+//                          state = (UBYTE)I2C_START;
+//                          read_cycle = 0;
+//                      }
+//                  } 
+//                  else 
+//                  {
+//                      /* one byte master reception procedure (polling) */
+//                      if(ubRdNBytes < 2) 
+//                      {
+//                          /* disable acknowledge */
+//                          i2c_ack_config(I2C0, I2C_ACK_DISABLE);
+//                          /* clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register (I2C_STAT0 has already been read) */
+//                          i2c_flag_get(I2C0, I2C_FLAG_ADDSEND);
+//                          /* send a stop condition to I2C bus*/
+//                          i2c_stop_on_bus(I2C0);
+//                          /* wait for the byte to be received */
+//                          while(i2c_flag_get(I2C0, I2C_FLAG_RBNE) == 0)
+//                          {
+//                          	// do nothing
+//                          }
+//                          /* read the byte received from the EEPROM */
+//                          *p_buffer = i2c_data_receive(I2C0);
+//                          /* decrement the read bytes counter */
+//                          ubRdNBytes--;
+//                          timeout = 0;
+//                          state = (UBYTE)I2C_STOP;
+//                      } 
+//                      else 
+//                      {  /* more than one byte master reception procedure (DMA) */                   
+                      
+//                          dma_transfer_number_config(DMA0, DMA_CH6, ubRdNBytes);        
+//                          DMA_CH6MADDR(DMA0) = (ULONG)p_buffer;
+                      
+//                          i2c_dma_last_transfer_config(I2C0, I2C_DMALST_ON);
+//                          /* enable I2C0 DMA */
+//                          i2c_dma_config(I2C0, I2C_DMA_ON);
+//                          /* enable DMA0 channel5 */
+//                          dma_channel_enable(DMA0, DMA_CH6);
+//                          /* wait until BTC bit is set */
+//                          while(dma_flag_get(DMA0, DMA_CH6, DMA_FLAG_FTF) == 0)
+//                          {
+//                          	// do nothing
+//                          }
+
+//                          state = (UBYTE)I2C_STOP;
+//                      }
+//                  }
+//                  break;
+//              case I2C_STOP:
+//                  /* send a stop condition to I2C bus */
+//                  i2c_stop_on_bus(I2C0);
+//                  /* i2c master sends STOP signal successfully */
+//                  while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_SHORT_TIMEOUT)) 
+//                  {
+//                      timeout++;
+//                  }
+
+//                  if(timeout < I2C_SHORT_TIMEOUT)
+//                  {
+//                      timeout = 0;                 
+//                      i2c_timeout_flag = 1;
+//                      state = (UBYTE)I2C_START;
+//                      read_cycle = 0;
                    
-                    /* disable DMA0 CH6 */
-                    dma_channel_disable(DMA0, DMA_CH6);
-                    /* disable I2C0 DMA */
-                    i2c_dma_config(I2C0, I2C_DMA_OFF); 
-                    i2c_dma_last_transfer_config(I2C0, I2C_DMALST_OFF);
-                } 
-                else 
-                {
-                     timeout = 0;
-                    //state = I2C_START;
-                     state = (UBYTE)I2C_STOP;
-                     read_cycle = 0;
-                }
+//                      /* disable DMA0 CH6 */
+//                      dma_channel_disable(DMA0, DMA_CH6);
+//                      /* disable I2C0 DMA */
+//                      i2c_dma_config(I2C0, I2C_DMA_OFF); 
+//                      i2c_dma_last_transfer_config(I2C0, I2C_DMALST_OFF);
+//                  } 
+//                  else 
+//                  {
+//                       timeout = 0;
+//                      //state = I2C_START;
+//                       state = (UBYTE)I2C_STOP;
+//                       read_cycle = 0;
+//                  }
                                               
-                break;
-            default:
-                state = (UBYTE)I2C_START;
-                read_cycle = 0;
-                i2c_timeout_flag = 1;
-                timeout = 0;
+//                  break;
+//              default:
+//                  state = (UBYTE)I2C_START;
+//                  read_cycle = 0;
+//                  i2c_timeout_flag = 1;
+//                  timeout = 0;
                 
-                break;
-            }
-        }
+//                  break;
+//              }
+//          }
         
-     }
+//       }
     
+//      i2c_voReadBufferCRC(out);
+
+//      i2c_voGetValueFrmBuffer(out);
+
+//      out->ReadFinishFlg = TRUE;
+    
+//  }
+
+void i2c_voSysparaReadFromEE(I2C_RXCRC_OUT *out) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */
+{
+   UBYTE ubRdNBytes = 0, ubRdSlaveAddr = 0, ubRdAddr = 0;
+   UBYTE ubRdCnt = 2;
+   UBYTE *p_buffer;
+   
+    while(ubRdCnt != 0)
+    {
+   	 ubRdCnt--;
+
+       if (ubRdCnt == 1)
+       {
+           ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK1;
+           ubRdAddr = 0x00;
+           ubRdNBytes = I2C_RX1_NBYTES;           
+           p_buffer = I2C_ubReadBuffer[0];
+       }
+       else if (ubRdCnt == 0)
+       {
+           ubRdSlaveAddr = I2C_SLAVEADDR_BLOCK3;
+           ubRdAddr = 0x00;
+           ubRdNBytes = I2C_RX2_NBYTES;
+           p_buffer = I2C_ubReadBuffer[1];
+       }
+       else
+       {
+       	//do nothing
+       }
+
+       iI2C_Read(0, ubRdSlaveAddr, ubRdAddr, 8, p_buffer, ubRdNBytes);
+   }
+
     i2c_voReadBufferCRC(out);
 
     i2c_voGetValueFrmBuffer(out);
 
     out->ReadFinishFlg = TRUE;
-    
 }
 /*************************************************************************
  Function:

+ 4 - 4
User project/3.BasicFunction/Source/power.c

@@ -64,7 +64,7 @@ void power_voPowerManagement(ULONG ulAutoPowerOffDelayTime, ULONG SysTickCnt, UL
 {    
     switch(power_stPowStateOut.powerstate)
     {
-        case POWER_START: //��Դ�����£�����1s����POWER ON
+        case POWER_START: // 电源键按下,超过1s进入POWER ON
         {
             if(iGpio_Read(HW_GPIO_POWERSTATE_PIN) != 0)
             {
@@ -79,7 +79,7 @@ void power_voPowerManagement(ULONG ulAutoPowerOffDelayTime, ULONG SysTickCnt, UL
             AutoPowerOffTimeCnt = SysTickCnt;
             break;
         }
-        case POWER_ON: // 3s�󣬼��PC0�����Ƿ���PC0��������POWER_ON_END
+        case POWER_ON: // 3s后,检测PC0按键是否弹起,PC0弹起后进入POWER_ON_END
         {
             power_stPowStateOut.uwPowerOn2OffCnt++;
             if (power_stPowStateOut.uwPowerOn2OffCnt >= power_stPowStateCof.uwPowerOn2OffTimeCnt)
@@ -94,7 +94,7 @@ void power_voPowerManagement(ULONG ulAutoPowerOffDelayTime, ULONG SysTickCnt, UL
             }          
             break;
         }
-        case POWER_ON_END: //��Դ�����½���POWER_OFF��������趨ʱ����Զ�����POWER_OFF
+        case POWER_ON_END: // 电源键按下进入POWER_OFF,或待机设定时候后自动进入POWER_OFF
         {
             //The key pushed down for "uwPowerShutTouchTimeCnt" to POWER_OFF
             if (iGpio_Read(HW_GPIO_POWERSTATE_PIN) != 0)
@@ -137,7 +137,7 @@ void power_voPowerManagement(ULONG ulAutoPowerOffDelayTime, ULONG SysTickCnt, UL
             }  
             break;
         }  
-        case POWER_OFF: //�ػ������ȴ����ݴ洢��ɣ��ر�LOCK
+        case POWER_OFF: // 关机处理,等待数据存储完成,关闭LOCK
         { 
             //Finish save and wait 1s, or delay for 3s
             if (((EESaveFinishFlg == TRUE) && (ParaSaveEEFlg == FALSE) && ((SysTickCnt - PowerOffDTimeOut) > 1000)) || 

+ 83 - 175
User project/3.BasicFunction/Source/torquesensor.c

@@ -13,19 +13,23 @@
  Beginning of File, do not put anything above here except notes
  Compiler Directives:
 *************************************************************************/
+#include "torquesensor.h"
 #include "syspar.h"
-#include "typedefine.h"
 #include "mathtool.h"
 #include "torquesensor.h"
 #include "CodePara.h"
 #include "canAppl.h"
 #include "api_rt.h"
+
+#ifdef RUN_ARCH_SIM
+#include "test_user.h"
+#endif
 /******************************
  *
  * static  Parameter
  *
  ******************************/
-static LPF_OUT   scm_stTorSensorLpf;
+static LPF_OUT   torq_pvt_stTorSensorLpf;
 static volatile SWORD TorqOffsetReg[TORQ_OFFSET_NUM]= {
 640,    //-11 C
 718,    //8 C
@@ -91,8 +95,8 @@ TORQUESENSOR_OUT torsensor_stTorSensorOut = TORQUESENSOR_OUT_DEFAULT;
 void torsensor_voTorSensorCof(void)
 {
     ULONG ulLpfTm = 0;
-    UWORD i = 0;
-      
+    UWORD i = 0, uwAverageOffset = 0;
+
     // torsensor_stTorSensorCof.uwMaxSensorTorquePu = ((ULONG)TORQUE_MAX_RANGE << 14) / TORQUEBASE; // Q14
     torsensor_stTorSensorCof.uwMinSensorTorquePu = ((ULONG)TORQUE_MIN_RANGE << 14) / TORQUEBASE; // Q14
     torsensor_stTorSensorCof.uwMaxSensorVolOutputPu = (ULONG)TORQUE_VOLTAGE_MAX_RANGE << 14 / VBASE;
@@ -102,7 +106,7 @@ void torsensor_voTorSensorCof(void)
 
     if(torsensor_stTorSensorCof.uwTorqueOffsetConfirmFlg == FALSE)
     {
-        #if (TORSENSOR_USEMOL == TORSENSOR_USEDEFAULT)
+#if (TORSENSOR_USEMOL == TORSENSOR_USEDEFAULT)
         torsensor_stTorSensorCof.uwTorqueOffset = TORQUE_VOLTAGE_MIN_RANGE * 4096 / 3300;
         #elif (TORSENSOR_USEMOL == TORSENSOR_USEEE)
          torsensor_stTorSensorCof.uwTorqueOffsetPowerUp = iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH]; 
@@ -125,57 +129,21 @@ void torsensor_voTorSensorCof(void)
             MC_UpcInfo.stSensorInfo.uwSaveFlg = 1;
         }
         else
-        {
-            UWORD AverageOffset = 0;
-//            AverageOffset = ((SLONG)torsensor_stTorSensorCof.uwTorqueOffsetNow1 + torsensor_stTorSensorCof.uwTorqueOffsetNow2 + 
-//                            torsensor_stTorSensorCof.uwTorqueOffsetNow3 + torsensor_stTorSensorCof.uwTorqueOffsetNow4)>>2;
-//            if( ((SWORD)torsensor_stTorSensorCof.uwTorqueOffsetPowerUp - torsensor_stTorSensorCof.uwTorqueOffsetOrign) > 200 )
-//            {
-//            }
-//            else
-//            {
-//                torsensor_stTorSensorCof.uwTorqueOffsetNow1 = torsensor_stTorSensorCof.uwTorqueOffsetNow2;
-//                torsensor_stTorSensorCof.uwTorqueOffsetNow2 = torsensor_stTorSensorCof.uwTorqueOffsetNow3;
-//                torsensor_stTorSensorCof.uwTorqueOffsetNow3 = torsensor_stTorSensorCof.uwTorqueOffsetNow4;
-//                torsensor_stTorSensorCof.uwTorqueOffsetNow4 = torsensor_stTorSensorCof.uwTorqueOffsetPowerUp;
-//
-//                cp_stFlg.ParaSaveEEFlg = TRUE;
-//                cp_stFlg.ParaUpdateFlg = TRUE;
-//                //cp_stFlg.ParaSensorInfoUpdateFlg = TRUE;
-//                //cp_stFlg.ParaAssistUpdateFinishFlg = TRUE;
-//                MC_UpcInfo.stSensorInfo.uwSaveFlg = TRUE;
-//            }
-//
-//            if( torsensor_stTorSensorCof.uwTorqueNowAllHasValueFlg == TRUE )
-//            {
-//                if((AverageOffset - torsensor_stTorSensorCof.uwTorqueOffsetOrign)>400 || (AverageOffset - torsensor_stTorSensorCof.uwTorqueOffsetOrign)<-400)
-//                {
-//                    torsensor_stTorSensorCof.uwTorqueOffset = torsensor_stTorSensorCof.uwTorqueOffsetOrign;
-//                }
-//                else
-//                {
-//                    torsensor_stTorSensorCof.uwTorqueOffset = AverageOffset;       
-//                }
-//            }
-//            else
-//            {
-//                torsensor_stTorSensorCof.uwTorqueOffset = torsensor_stTorSensorCof.uwTorqueOffsetOrign;
-//            }
-            
-            
+        { 
             /* Compare with AvgOffset */ 
             if(torsensor_stTorSensorCof.uwTorqueNowAllHasValueFlg == TRUE)
             {
-                AverageOffset = (UWORD)(((ULONG)torsensor_stTorSensorCof.uwTorqueOffsetNow1 + torsensor_stTorSensorCof.uwTorqueOffsetNow2 +
+                uwAverageOffset = (UWORD)(((ULONG)torsensor_stTorSensorCof.uwTorqueOffsetNow1 + torsensor_stTorSensorCof.uwTorqueOffsetNow2 +
                                 torsensor_stTorSensorCof.uwTorqueOffsetNow3 + torsensor_stTorSensorCof.uwTorqueOffsetNow4)>>2);
             }
             else
             {
-                AverageOffset = torsensor_stTorSensorCof.uwTorqueOffsetOrign;
+                uwAverageOffset = torsensor_stTorSensorCof.uwTorqueOffsetOrign;
             }            
-            if(abs((SWORD)torsensor_stTorSensorCof.uwTorqueOffsetPowerUp - AverageOffset) > 200)   
+
+            if(abs((SWORD)torsensor_stTorSensorCof.uwTorqueOffsetPowerUp - (SWORD)uwAverageOffset) > 200)   
             {
-                torsensor_stTorSensorCof.uwTorqueOffset = AverageOffset;
+                torsensor_stTorSensorCof.uwTorqueOffset = uwAverageOffset;
             }
             else
             {
@@ -192,44 +160,25 @@ void torsensor_voTorSensorCof(void)
 
                 torsensor_stTorSensorCof.uwTorqueOffset = torsensor_stTorSensorCof.uwTorqueOffsetPowerUp;  
             }
-
         }
-        #endif
+#endif
         torsensor_stTorSensorCof.uwTorqueOffsetConfirmFlg = TRUE;
     }
-    torsensor_stTorSensorCof.uwSensorVolPerTorqDefault = TORQUE_VOLTAGE_PER_NM;
-    
-    torsensor_stTorSensorCof.uwSensorVolPerTorq1 =
-        (UWORD)((((ULONG)3300 * (torsensor_stTorSensorCof.uwBikeTorStep1ADC - torsensor_stTorSensorCof.uwTorqueOffset)) >> 12) *10 *10/
-        (torsensor_stTorSensorCof.uwBikeTorStep1RealNm - 0));
     
-    torsensor_stTorSensorCof.uwSensorVolPerTorq2 =
-    		(UWORD)((((ULONG)3300 * (torsensor_stTorSensorCof.uwBikeTorStep2ADC - torsensor_stTorSensorCof.uwBikeTorStep1ADC)) >> 12) *10 *10/
-        (torsensor_stTorSensorCof.uwBikeTorStep2RealNm - torsensor_stTorSensorCof.uwBikeTorStep1RealNm));
-    
-    torsensor_stTorSensorCof.uwSensorVolPerTorq3 =
-    		(UWORD)((((ULONG)3300 * (torsensor_stTorSensorCof.uwBikeTorStep3ADC - torsensor_stTorSensorCof.uwBikeTorStep2ADC)) >> 12) *10 *10/
-        (torsensor_stTorSensorCof.uwBikeTorStep3RealNm - torsensor_stTorSensorCof.uwBikeTorStep2RealNm));
-    
-    torsensor_stTorSensorCof.uwSensorVolPerTorq4 =
-    		(UWORD)((((ULONG)3300 * (torsensor_stTorSensorCof.uwBikeTorStep4ADC - torsensor_stTorSensorCof.uwBikeTorStep3ADC)) >> 12) *10*10 /
-        (torsensor_stTorSensorCof.uwBikeTorStep4RealNm - torsensor_stTorSensorCof.uwBikeTorStep3RealNm));
+    torsensor_stTorSensorCof.uwSensorVolPerTorqDefault = TORQUE_VOLTAGE_PER_NM;
 
     torsensor_stTorSensorCof.ulTorqueReg2PuDefault = (ULONG)((((UQWORD)33 << 24) / 10) / (1 << ADC_RESOLUTION_BIT) / TORQUE_VOLTAGE_SEN2MCUGAIN * 100 * 1000 /
                                                      torsensor_stTorSensorCof.uwSensorVolPerTorqDefault / TORQUEBASE *
                                                      10); // 3.3/4096/harwaregain/VolPerNm/TorqueBase;
-    torsensor_stTorSensorCof.ulTorqueReg2Pu1 = (ULONG)((((UQWORD)33 << 24) / 10) / (1 << ADC_RESOLUTION_BIT) / TORQUE_VOLTAGE_SEN2MCUGAIN * 100 * 1000 /
-                                               torsensor_stTorSensorCof.uwSensorVolPerTorq1 / TORQUEBASE *
-                                               10*10); // 3.3/4096/harwaregain/VolPerNm/TorqueBase;
-    torsensor_stTorSensorCof.ulTorqueReg2Pu2 = (ULONG)((((UQWORD)33 << 24) / 10) / (1 << ADC_RESOLUTION_BIT) / TORQUE_VOLTAGE_SEN2MCUGAIN * 100 * 1000 /
-                                               torsensor_stTorSensorCof.uwSensorVolPerTorq2 / TORQUEBASE *
-                                               10*10); // 3.3/4096/harwaregain/VolPerNm/TorqueBase;
-    torsensor_stTorSensorCof.ulTorqueReg2Pu3 = (ULONG)((((UQWORD)33 << 24) / 10) / (1 << ADC_RESOLUTION_BIT) / TORQUE_VOLTAGE_SEN2MCUGAIN * 100 * 1000 /
-                                               torsensor_stTorSensorCof.uwSensorVolPerTorq3 / TORQUEBASE *
-                                               10*10); // 3.3/4096/harwaregain/VolPerNm/TorqueBase;
-    torsensor_stTorSensorCof.ulTorqueReg2Pu4 = (ULONG)((((UQWORD)33 << 24) / 10) / (1 << ADC_RESOLUTION_BIT) / TORQUE_VOLTAGE_SEN2MCUGAIN * 100 * 1000 /
-                                               torsensor_stTorSensorCof.uwSensorVolPerTorq4 / TORQUEBASE *
-                                               10*10); // 3.3/4096/harwaregain/VolPerNm/TorqueBase;
+
+    torsensor_stTorSensorCof.ulTorqueReg2Pu1 = (ULONG)(((UQWORD)(torsensor_stTorSensorCof.uwBikeTorStep1RealNm - 0) << 24) / 
+                                               (torsensor_stTorSensorCof.uwBikeTorStep1ADC - torsensor_stTorSensorCof.uwTorqueOffset) /TORQUEBASE);
+    torsensor_stTorSensorCof.ulTorqueReg2Pu2 = (ULONG)(((UQWORD)(torsensor_stTorSensorCof.uwBikeTorStep2RealNm - torsensor_stTorSensorCof.uwBikeTorStep1RealNm) << 24) / 
+                                               (torsensor_stTorSensorCof.uwBikeTorStep2ADC - torsensor_stTorSensorCof.uwBikeTorStep1ADC) /TORQUEBASE);        
+    torsensor_stTorSensorCof.ulTorqueReg2Pu3 = (ULONG)(((UQWORD)(torsensor_stTorSensorCof.uwBikeTorStep3RealNm - torsensor_stTorSensorCof.uwBikeTorStep2RealNm) << 24) / 
+                                               (torsensor_stTorSensorCof.uwBikeTorStep3ADC - torsensor_stTorSensorCof.uwBikeTorStep2ADC) /TORQUEBASE);
+    torsensor_stTorSensorCof.ulTorqueReg2Pu4 = (ULONG)(((UQWORD)(torsensor_stTorSensorCof.uwBikeTorStep4RealNm - torsensor_stTorSensorCof.uwBikeTorStep3RealNm) << 24) / 
+                                               (torsensor_stTorSensorCof.uwBikeTorStep4ADC - torsensor_stTorSensorCof.uwBikeTorStep3ADC) /TORQUEBASE);
     
     torsensor_stTorSensorCof.uwBikeTorStep1NmPu = (UWORD)(((ULONG)torsensor_stTorSensorCof.uwBikeTorStep1RealNm << 14)/TORQUEBASE);
     torsensor_stTorSensorCof.uwBikeTorStep2NmPu = (UWORD)(((ULONG)torsensor_stTorSensorCof.uwBikeTorStep2RealNm << 14)/TORQUEBASE);
@@ -238,8 +187,9 @@ void torsensor_voTorSensorCof(void)
     
     /* Torque Sensor limit coef */
     ulLpfTm = 1000000 / torsensor_stTorSensorCof.uwTorSensorLPFFrq;
-    mth_voLPFilterCoef(ulLpfTm, torsensor_stTorSensorCof.uwTorVolLPFDisFrq, &scm_stTorSensorLpf.uwKx);
+    mth_voLPFilterCoef(ulLpfTm, torsensor_stTorSensorCof.uwTorVolLPFDisFrq, &torq_pvt_stTorSensorLpf.uwKx);
     
+    /* Torque Offset Correction Coef */
 //    for (i = 0; i < (TORQ_OFFSET_NUM - 1); i++)
 //    {
 //        TorqOffsetCof[i] =  (((SLONG)TorqOffsetReg[i+1] - (SLONG)TorqOffsetReg[i]) << 12) /(TorqOffsetTemp[i+1] - TorqOffsetTemp[i]); //Q12
@@ -272,9 +222,7 @@ void torsensor_voTorSensorInit(void)
     torsensor_stTorSensorOut.blTorqueErrorFlg = FALSE;
     mth_voLPFilterCoef(1000000 / 1, EVENT_1MS_HZ, &tst_dynOffsetLpf.uwKx); //25Hz  
     tstdynOffset= iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH]; 
-    tst_dynOffsetLpf.slY.sw.hi =  (SWORD)iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH]; 
-        /* Torque Sensor limit coef */
-   
+    tst_dynOffsetLpf.slY.sw.hi =  (SWORD)iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH];   
 }
 
 /*************************************************************************
@@ -378,8 +326,8 @@ void torsensor_voTorSensorInit(void)
 //            TorqValuePu = torsensor_stTorSensorCof.uwBikeTorStep4NmPu;
 //        }
 //        torsensor_stTorSensorOut.uwTorquePu=TorqValuePu;
-//        mth_voLPFilter(torsensor_stTorSensorOut.uwTorquePu, &scm_stTorSensorLpf);
-//        torsensor_stTorSensorOut.uwTorqueLPFPu = scm_stTorSensorLpf.slY.sw.hi;
+//        mth_voLPFilter(torsensor_stTorSensorOut.uwTorquePu, &torq_pvt_stTorSensorLpf);
+//        torsensor_stTorSensorOut.uwTorqueLPFPu = torq_pvt_stTorSensorLpf.slY.sw.hi;
 //        TorqValue = (ULONG)TorqValuePu * TORQUEBASE  >> 14;
 //        
 //    //TorqValue = ((torsensor_stTorSensorOut.uwTorqueReg - tstTorqOffset) << 12 )/tstSencitiveset;
@@ -395,7 +343,7 @@ void torsensor_voTorSensorInit(void)
 ****************************************************************/
 static UWORD tor_pvt_uwOffsetTarget = 0;
 static UWORD tor_pvt_uwOffsetMax = 0,tor_pvt_uwOffsetMin = 4096;
-static ULONG tor_pvt_ulCnt = 0;
+static ULONG tor_pvt_ulCnt = 0, tor_pvt_ulCnt2 = 0;
 void torsensor_voOffsetUpdate(void) 
 {
     SWORD swTorDelta;
@@ -405,7 +353,12 @@ void torsensor_voOffsetUpdate(void)
         swTorDelta = (SWORD)tor_pvt_uwOffsetMax - (SWORD)tor_pvt_uwOffsetMin;
         if(swTorDelta > 40)
         {   
-            tor_pvt_ulCnt = 0;              
+            tor_pvt_ulCnt = 0;   
+            tor_pvt_uwOffsetTarget = torsensor_stTorSensorCof.uwTorqueOffset;           
+        }
+        else 
+        {
+            tor_pvt_uwOffsetTarget = (tor_pvt_uwOffsetMax + tor_pvt_uwOffsetMin) >> 1;
         }
         tor_pvt_uwOffsetMax = 0;
         tor_pvt_uwOffsetMin = 4096; 
@@ -422,13 +375,11 @@ void torsensor_voOffsetUpdate(void)
             tor_pvt_uwOffsetMax = torsensor_stTorSensorOut.uwTorqueReg;
         }    
     }
-          
+   
     if(tor_pvt_ulCnt > TORQUE_90S_1MSCNT)
     {
-        swTorDelta = (SWORD)tor_pvt_uwOffsetMax - (SWORD)tor_pvt_uwOffsetMin;
-        if(swTorDelta < 40)
+        if(tor_pvt_uwOffsetTarget != torsensor_stTorSensorCof.uwTorqueOffset)
         {
-            tor_pvt_uwOffsetTarget = (tor_pvt_uwOffsetMax + tor_pvt_uwOffsetMin) >> 1;
             if(torsensor_stTorSensorCof.uwTorqueOffset < tor_pvt_uwOffsetTarget - 20)
             {
                 torsensor_stTorSensorCof.uwTorqueOffset += 20;
@@ -439,17 +390,13 @@ void torsensor_voOffsetUpdate(void)
             }
             else
             {
-               torsensor_stTorSensorCof.uwTorqueOffset = tor_pvt_uwOffsetTarget;
+                torsensor_stTorSensorCof.uwTorqueOffset = tor_pvt_uwOffsetTarget;
             }
             
-            torsensor_stTorSensorCof.uwSensorVolPerTorq1 =
-            		(UWORD)((((ULONG)3300 * (torsensor_stTorSensorCof.uwBikeTorStep1ADC - torsensor_stTorSensorCof.uwTorqueOffset)) >> 12) *10 *10/
-            (torsensor_stTorSensorCof.uwBikeTorStep1RealNm - 0));
-        
-            torsensor_stTorSensorCof.ulTorqueReg2Pu1 = (ULONG)((((SQWORD)33 << 24) / 10) / (1 << ADC_RESOLUTION_BIT) / TORQUE_VOLTAGE_SEN2MCUGAIN * 100 * 1000 /
-                                               torsensor_stTorSensorCof.uwSensorVolPerTorq1 / TORQUEBASE *
-                                               10*10); // 3.3/4096/harwaregain/VolPerNm/TorqueBase;
+            torsensor_stTorSensorCof.ulTorqueReg2Pu1 = (ULONG)(((UQWORD)(torsensor_stTorSensorCof.uwBikeTorStep1RealNm - 0) << 24) / 
+                                                (torsensor_stTorSensorCof.uwBikeTorStep1ADC - torsensor_stTorSensorCof.uwTorqueOffset) /TORQUEBASE);
         }
+
         tor_pvt_ulCnt = 0;   
     }       
 }
@@ -464,95 +411,56 @@ void torsensor_voOffsetUpdate(void)
 ****************************************************************/
 void torsensor_voTorADC(void) // need to match ADC_StartConversion(ADC1);
 {
+    torsensor_stTorSensorOut.uwTorqueReg = iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH];
+#if (TORSENSOR_USEMOL == TORSENSOR_USEDEFAULT)
+    torsensor_stTorSensorOut.uwTorquePu =
+        (((SQWORD)abs((SWORD)(torsensor_stTorSensorOut.uwTorqueReg) - torsensor_stTorSensorCof.uwTorqueOffset)) *
+            torsensor_stTorSensorCof.ulTorqueReg2PuDefault) >>
+        10; // Q14
 
-
-    if (torsensor_stTorSensorOut.blTorqueErrorFlg == TRUE)
+#elif (TORSENSOR_USEMOL == TORSENSOR_USEEE)      
+    if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwTorqueOffset)
     {
         torsensor_stTorSensorOut.uwTorquePu = 0;
-        torsensor_stTorSensorOut.uwTorqueReg = iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH];
-        if (torsensor_stTorSensorOut.uwTorqueReg < 4000 && torsensor_stTorSensorOut.uwTorqueReg > 10) // output 0mv - 3000mv
-        {
-            torsensor_stTorSensorOut.uwTorqueErrorCnt++;
-            if (torsensor_stTorSensorOut.uwTorqueErrorCnt > 1000)
-            {
-                torsensor_stTorSensorOut.blTorqueErrorFlg = FALSE;
-                torsensor_voTorSensorInit();
-            }
-        }
-        else
-        {
-            torsensor_stTorSensorOut.uwTorqueErrorCnt = 0;
-        }
     }
-    else
+    else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep1ADC)
     {
-        torsensor_stTorSensorOut.uwTorqueReg = iAdc_GetResultPointer(0)[HW_ADC_TORQ_CH]; // TorSensor_uwDMAReg;
-#if (TORSENSOR_USEMOL == TORSENSOR_USEDEFAULT)
-        torsensor_stTorSensorOut.uwTorquePu =
-            (((SQWORD)abs((SWORD)(torsensor_stTorSensorOut.uwTorqueReg) - torsensor_stTorSensorCof.uwTorqueOffset)) *
-             torsensor_stTorSensorCof.ulTorqueReg2PuDefault) >>
-            10; // Q14
-#elif (TORSENSOR_USEMOL == TORSENSOR_USEEE)
-        
-        if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwTorqueOffset)
-        {
-            torsensor_stTorSensorOut.uwTorquePu = 0;
-        }
-        else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep1ADC)
-        {
-            torsensor_stTorSensorOut.uwTorquePu = (UWORD)(0 +
-                ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwTorqueOffset)) *
-                 torsensor_stTorSensorCof.ulTorqueReg2Pu1) >> 10)); // Q14
-        }
-        else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep2ADC)
-        {
-            torsensor_stTorSensorOut.uwTorquePu = (UWORD)(torsensor_stTorSensorCof.uwBikeTorStep1NmPu +
-                ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwBikeTorStep1ADC)) *
-                 torsensor_stTorSensorCof.ulTorqueReg2Pu2) >> 10)); // Q14
+        torsensor_stTorSensorOut.uwTorquePu = (UWORD)(0 +
+            ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwTorqueOffset)) *
+                torsensor_stTorSensorCof.ulTorqueReg2Pu1) >> 10)); // Q14
+    }
+    else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep2ADC)
+    {
+        torsensor_stTorSensorOut.uwTorquePu = (UWORD)(torsensor_stTorSensorCof.uwBikeTorStep1NmPu +
+            ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwBikeTorStep1ADC)) *
+                torsensor_stTorSensorCof.ulTorqueReg2Pu2) >> 10)); // Q14
 
-        }
-        else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep3ADC)
-        {
-            torsensor_stTorSensorOut.uwTorquePu = (UWORD)(torsensor_stTorSensorCof.uwBikeTorStep2NmPu +
-                ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwBikeTorStep2ADC)) *
-                 torsensor_stTorSensorCof.ulTorqueReg2Pu3) >> 10)); // Q14
+    }
+    else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep3ADC)
+    {
+        torsensor_stTorSensorOut.uwTorquePu = (UWORD)(torsensor_stTorSensorCof.uwBikeTorStep2NmPu +
+            ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwBikeTorStep2ADC)) *
+                torsensor_stTorSensorCof.ulTorqueReg2Pu3) >> 10)); // Q14
 
-        }
-        else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep4ADC)
-        {
-            torsensor_stTorSensorOut.uwTorquePu = (UWORD)(torsensor_stTorSensorCof.uwBikeTorStep3NmPu +
-                ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwBikeTorStep3ADC)) *
-                 torsensor_stTorSensorCof.ulTorqueReg2Pu4) >> 10)); // Q14
+    }
+    else if (torsensor_stTorSensorOut.uwTorqueReg <= torsensor_stTorSensorCof.uwBikeTorStep4ADC)
+    {
+        torsensor_stTorSensorOut.uwTorquePu = (UWORD)(torsensor_stTorSensorCof.uwBikeTorStep3NmPu +
+            ((((UQWORD)abs((SWORD)torsensor_stTorSensorOut.uwTorqueReg - torsensor_stTorSensorCof.uwBikeTorStep3ADC)) *
+                torsensor_stTorSensorCof.ulTorqueReg2Pu4) >> 10)); // Q14
 
-        }
-        else
-        {
-            torsensor_stTorSensorOut.uwTorquePu = torsensor_stTorSensorCof.uwBikeTorStep4NmPu;
-        }
+    }
+    else
+    {
+        torsensor_stTorSensorOut.uwTorquePu = torsensor_stTorSensorCof.uwBikeTorStep4NmPu;
+    }
 
 #endif
-        mth_voLPFilter((SWORD)torsensor_stTorSensorOut.uwTorquePu, &scm_stTorSensorLpf);
-        torsensor_stTorSensorOut.uwTorqueLPFPu = (UWORD)scm_stTorSensorLpf.slY.sw.hi;
-        torsensor_stTorSensorOut.uwTorquePercent = (UWORD)(((ULONG)torsensor_stTorSensorOut.uwTorqueLPFPu << 14) /
-                (torsensor_stTorSensorCof.uwMaxSensorTorquePu - torsensor_stTorSensorCof.uwMinSensorTorquePu)); // Q15
+    mth_voLPFilter((SWORD)torsensor_stTorSensorOut.uwTorquePu, &torq_pvt_stTorSensorLpf);
+    torsensor_stTorSensorOut.uwTorqueLPFPu = (UWORD)torq_pvt_stTorSensorLpf.slY.sw.hi;
+    torsensor_stTorSensorOut.uwTorquePercent = (UWORD)(((ULONG)torsensor_stTorSensorOut.uwTorqueLPFPu << 14) /
+            (torsensor_stTorSensorCof.uwMaxSensorTorquePu - torsensor_stTorSensorCof.uwMinSensorTorquePu)); // Q15
 
-        if (torsensor_stTorSensorOut.uwTorqueReg > 4000 || torsensor_stTorSensorOut.uwTorqueReg < 10) // output 0mv - 3000mv
-        {
-            torsensor_stTorSensorOut.uwTorqueErrorCnt++;
-            if (torsensor_stTorSensorOut.uwTorqueErrorCnt > 5000)
-            {
-                torsensor_stTorSensorOut.blTorqueErrorFlg = TRUE;
-                torsensor_stTorSensorOut.uwTorquePu = 0;
-                torsensor_stTorSensorOut.uwTorqueErrorCnt = 0;
-                torsensor_stTorSensorOut.uwTorqueLPFPu = 0;
-                cp_stHistoryPara.uwTorSensorAlamTimes++;
-            }
-        }
-        else
-        {
-            torsensor_stTorSensorOut.uwTorqueErrorCnt = 0;
-        }
-    }
 }
 
 /***************************************************************

+ 0 - 68
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/app_tasks.h

@@ -1,68 +0,0 @@
-/**
- * @file tasks.h
- * @author Xiao, Lifan (xiaolf6@midea.com)
- * @brief
- * @version 0.1
- * @date 2021-08-06
- *
- * @copyright Copyright (c) 2021
- *
- */
-
-#ifndef _TASKS_H_
-#define _TASKS_H_
-
-/****************************************************************
- *
- *                     Standard Interface
- *
- * *************************************************************/
-
-/* Driver Layer Interface */
-/* The following function will be called by platfrom layer */
-
-/**
- * @brief Init pwm task
- *
- */
-void App_Task_InitTaskPwm();
-
-/**
- * @brief Pwm task called in pwm isr
- *
- */
-void App_Task_TaskPwm();
-
-/**
- * @brief Init adc task
- *
- */
-void App_Task_InitTaskAdcCplt();
-
-/**
- * @brief Adc task called in adc complete isr
- *
- */
-void App_Task_TaskAdcCplt();
-
-/**
- * @brief Init task 1
- *
- */
-void App_Task_InitTask1();
-
-/**
- * @brief Task 1 called by period timer
- *
- */
-void App_Task_Task1();
-
-void App_Task_InitTask2();
-
-void App_Task_Task2();
-
-void App_Task_InitTaskBg();
-
-void App_Task_TaskBg();
-
-#endif

+ 10 - 0
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/board_config.h

@@ -87,6 +87,16 @@
 
 #define HW_PWM_CAP_HZ 1600000L
 
+/* ---------------------------------- EEPROM参数 ---------------------------------- */
+
+#define HW_I2C_EE_PAGESIZE_BYTE 16
+#define HW_I2C_EE_ADDR_BLOCK1   0xA0
+#define HW_I2C_EE_ADDR_BLOCK2   0xA2
+#define HW_I2C_EE_ADDR_BLOCK3   0xA4
+#define HW_I2C_EE_ADDR_BLOCK4   0xA6
+
+
+
 /* ========================================================================== */
 /* ================================ API接口序号定义 =============================== */
 /* ========================================================================== */

+ 0 - 84
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_adc.h

@@ -1,84 +0,0 @@
-/**
- * @file hal_adc.h
- * @author Xiao, Lifan (xiaolf6@midea.com)
- * @brief
- * @version 0.1
- * @date 2021-08-09
- *
- * @copyright Copyright (c) 2021
- *
- */
-
-#ifndef _HAL_ADC_H_
-#define _HAL_ADC_H_
-
-#include "hal_config.h"
-
-/****************************************************************
- *
- *                     Standard Interface
- *
- * *************************************************************/
-
-/******************************/
-/* Global Interface Variables */
-/******************************/
-
-/* !!!Important!!! */
-/* Interface Variable Should Not Be Modified By Application */
-
-/**
- * @brief The raw sampling results
- *
- */
-extern uint16_t *Hal_Adc_RawResults;
-
-/**
- * @brief The scaled sampling results, calculated by y=a(x+b)
- *
- */
-extern int32_t *Hal_Adc_ScaledResults;
-
-/*************************/
-/* Global Interface Hook */
-/*************************/
-
-/**
- * @brief Function hook called at the end of the sampling
- *
- */
-extern void (*Hal_Adc_SamplingCompleteHook)();
-
-/**************************************/
-/* Platform Layer Interface Functions */
-/**************************************/
-
-/**
- * @brief Init adc module
- *
- */
-void Hal_Adc_Init();
-
-/**
- * @brief Read sampling results from the adc peripheral
- *
- */
-void Hal_Adc_Read();
-
-/**
- * @brief Set the scale of the specified channel
- *
- * @param scale in format q17.15
- * @param channel channel index
- */
-void Hal_Adc_SetScale(int32_t scale, uint8_t channel);
-
-/**
- * @brief Set the offset of the specified channel
- *
- * @param offset in range 0...4096
- * @param channel channel index
- */
-void Hal_Adc_SetOffset(int16_t offset, uint8_t channel);
-
-#endif

+ 0 - 65
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_dio.h

@@ -1,65 +0,0 @@
-/**
- * @file hal_dio.h
- * @author Wang, Tong (wangtong7@midea.com)
- * @brief
- * @version 0.1
- * @date 2021-10-10
- *
- * @copyright Copyright (c) 2021
- *
- */
-
-#ifndef _HAL_DIO_H_
-#define _HAL_DIO_H_
-
-#include "hal_config.h"
-
-/****************************************************************
- *
- *                     Standard Interface
- *
- * *************************************************************/
-
-/********************/
-/* Type definations */
-/********************/
-
-#define DIO_LEVEL_HIGH 1
-#define DIO_LEVEL_LOW  0
-
-/******************************/
-/* Global Interface Variables */
-/******************************/
-
-/* !!!Important!!! */
-/* Interface Variable Should Not Be Modified By Application */
-
-/**
- * @brief Activate pin (with pre-defined active level)
- *
- * @param index Pin number defined in hal_config.h
- */
-void Hal_Dio_ActivatePin(uint8_t index);
-
-/**
- * @brief Deactivate Pin (with pre-defined active level)
- *
- * @param index Pin number defined in hal_config.h
- */
-void Hal_Dio_DeactivatePin(uint8_t index);
-
-/**
- * @brief Set pin level
- *
- * @param index Pin index
- * @param level Pin level
- */
-void Hal_Dio_SetPinLevel(uint8_t index, uint8_t level);
-
-/**
- * @brief Init Dio module
- *
- */
-void Hal_Dio_Init();
-
-#endif

+ 0 - 108
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_harderr.h

@@ -1,108 +0,0 @@
-/**
- * @file hal_harderr.h
- * @author Xiao Lifan (xiaolf6@midea.com)
- * @brief
- * @version 0.1
- * @date 2021-09-26
- *
- * @copyright Copyright (c) 2021
- *
- * @details The interface of system hard error detect and handling
- *
- */
-
-#ifndef _HAL_HARDERR_H_
-#define _HAL_HARDERR_H_
-
-#include "hal_config.h"
-
-/****************************************************************
- *
- *                     Standard Interface
- *
- * *************************************************************/
-
-/********************/
-/* Type definations */
-/********************/
-
-// typedef union
-// {
-//     uint32_t all;
-//     struct bit
-//     {
-//         uint32_t bit0:1;
-//         uint32_t bit0:1;
-//     };
-
-// } Hal_Harderr_FlagType;
-
-/******************************/
-/* Global Interface Variables */
-/******************************/
-
-/* !!!Important!!! */
-/* Interface Variable Should Not Be Modified By Application */
-
-/**
- * @brief The flag of triggered hardware error
- *
- */
-extern uint32_t Hal_HardErr_Flags;
-
-/*************************/
-/* Global Interface Hook */
-/*************************/
-
-/**
- * @brief Function called when hardware error are triggered
- *
- */
-extern void (*Hal_HardErr_TriggerHook)();
-
-/**
- * @brief Function called when hardware error are cleared
- *
- * @note The clear of the hardware err may lag
- *
- */
-extern void (*Hal_HardErr_ClearHook)();
-
-/*****************************************/
-/* Application Layer Interface Functions */
-/*****************************************/
-
-/**
- * @brief Get specified bit of hardware error flags
- *
- * @param bit bit index
- * @return uint8_t error status 0 - no error, 1 - error occurs
- */
-uint8_t Hal_HardErr_GetFlagStatus(uint8_t bit);
-
-/**
- * @brief Try clear hardware error
- *
- * @return uint8_t result of clear action 0 - success, 1 - falied
- */
-uint8_t Hal_HardErr_TryClearHardErr();
-
-/**************************************/
-/* Platform Layer Interface Functions */
-/**************************************/
-
-/**
- * @brief Init hardware error detection
- *
- */
-void Hal_HardErr_Init();
-
-/**
- * @brief Set the specified bit of hardware error flag
- *
- * @param bit bit index
- * @param state flag state
- */
-void Hal_HardErr_SetFlagStatus(uint8_t bit, uint8_t state);
-
-#endif

+ 0 - 296
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hal_pwm.h

@@ -1,296 +0,0 @@
-/**
- * @file hal_pwm.h
- * @author Xiao, Lifan (xiaolf6@midea.com)
- * @brief
- * @version 0.1
- * @date 2021-08-09
- *
- * @copyright Copyright (c) 2021
- *
- * @details The interface of PWM module
- *
- */
-
-#ifndef _HAL_PWM_H_
-#define _HAL_PWM_H_
-
-#include "hal_config.h"
-
-/****************************************************************
- *
- *                     Standard Interface
- *
- * *************************************************************/
-
-/********************/
-/* Type definations */
-/********************/
-
-/**
- * @brief The PWM wave type
- * @note Four type of PWM wave is supported, as
- *
- * RightAligned:
- *       ┌──────
- *       │
- *       │
- * ──────┘
- *
- * LeftAligned:
- * ──────┐
- *       │
- *       │
- *       └──────
- *
- * CenterAligned:
- *     ┌───┐
- *     │   │
- *     │   │
- * ────┘   └────
- *
- * CenterAlignedInverse:
- * ────┐   ┌────
- *     │   │
- *     │   │
- *     └───┘
- *
- */
-
-typedef enum
-{
-    RightAligned,
-    LeftAligned,
-    CenterAligned,
-    CenterAlignedInverse,
-    EdgeAlignedAutoReverse,
-#if HAL_PWM_SUPPORT_CUSTOM_VECTOR_TYPE
-    Custom,
-#endif
-} Hal_Pwm_WaveModeEnum;
-
-typedef enum
-{
-    VectorTypeUp,
-    VectorTypeDown,
-    VectorTypeUpDown,
-    VectorTypeDownUp,
-} Hal_Pwm_VectorType;
-
-/******************************/
-/* Global Interface Variables */
-/******************************/
-
-/* !!!Important!!! */
-/* Interface Variable Should Not Be Modified By Application */
-
-/**
- * @brief The clock of the pwm module (in unit Hz)
- *
- */
-extern uint32_t Hal_Pwm_Clock;
-
-/**
- * @brief The period of the pwm module (in unit Ticks)
- *
- */
-extern uint32_t Hal_Pwm_PeriodTicks;
-
-/**
- * @brief The period of the pwm module (in unit us)
- *
- */
-extern uint32_t Hal_Pwm_PeriodUs;
-
-/**
- * @brief Avaliable pwm channel number
- *
- */
-extern const uint32_t Hal_Pwm_ChannelNum;
-
-/**
- * @brief Actual phase duty cycle (in unit ticks)
- *
- */
-extern uint32_t *Hal_Pwm_ActualDutyCycleTicks;
-
-/**
- * @brief Drive pwm output status
- *
- */
-extern int8_t Hal_Pwm_DriveOutputEnable;
-
-/*************************/
-/* Global Interface Hook */
-/*************************/
-
-/**
- * @brief Function hook called at Zero Interrupt
- *
- */
-extern void (*Hal_Pwm_ZeroIsrHook)();
-
-/**
- * @brief Function hook called at Period Interrupt
- *
- */
-extern void (*Hal_Pwm_PeriodIsrHook)();
-
-/*****************************************/
-/* Application Layer Interface Functions */
-/*****************************************/
-
-/**
- * @brief Set the duty cycle for all channel (in q15 format)
- *
- * @param da Pointer to the list of duty cycles
- * @param channels The number of channel to set duty cycle
- *
- * @note If current PWM mode is EdgeAlignedAutoReverse, the modulation mode will reverse after calling this function
- */
-void Hal_Pwm_SetDutyCycle(int32_t *da, int8_t channels);
-
-/**
- * @brief Set the duty cycle for specified channel (in q15 format)
- *
- * @param duty duty cycle
- * @param chindex The index of channel to set duty cycle
- *
- * @note Calling this function will not affect PWM mode
- */
-void Hal_Pwm_SetChannelDutyCycle(int32_t duty, int8_t chindex);
-
-/**
- * @brief Set the pwm period (in ticks)
- *
- * @param ticks Pwm period
- */
-void Hal_Pwm_SetPeriod(int32_t ticks);
-
-/**
- * @brief Set the Wave Mode
- *
- * @param mode Target mode
- */
-void Hal_Pwm_SetWaveMode(Hal_Pwm_WaveModeEnum mode);
-
-/**
- * @brief Set the pwm output deadband
- *
- * @param ticks Deadband length
- */
-void Hal_Pwm_SetDeadband(int32_t ticks);
-
-/**
- * @brief Enable drive pwm immediately
- *
- */
-void Hal_Pwm_EnableDriveOutput();
-
-/**
- * @brief Disable drive pwm output immediately
- *
- */
-void Hal_Pwm_DisableDriveOutput();
-
-/**
- * @brief Enable channel pwm immediately
- *
- * @param ch_index Channel index
- */
-void Hal_Pwm_EnableChannelOutput(uint8_t ch_index);
-
-/**
- * @brief Disable channel pwm immediately
- *
- * @param ch_index Channel index
- */
-void Hal_Pwm_DisableChannelOutput(uint8_t ch_index);
-
-/**
- * @brief Enable standard hooks, function address for enable, 0 for disable
- *
- * @param zeroHook Zero interrupt hook address
- * @param prdHook Period interrupt hook address
- */
-void Hal_Pwm_EnableStdHooks(void *zeroHook, void *prdHook);
-
-/**************************************/
-/* Platform Layer Interface Functions */
-/**************************************/
-
-/**
- * @brief Init pwm module
- *
- */
-void Hal_Pwm_Init();
-
-#if HAL_PWM_SUPPORT_CUSTOM_VECTOR_TYPE
-
-/****************************************************************
- *
- *                    Extended Interface
- *            Support Custom Modulation Like TSPWM
- *         Different Vector Type On Different Channel
- *
- * *************************************************************/
-
-void Hal_Pwm_Ext_SetCustomVectorType(Hal_Pwm_VectorType *type, uint8_t channels);
-
-#endif
-
-#if HAL_PWM_SUPPORT_SINGLE_RESISTOR_SAMPLING
-
-/****************************************************************
- *
- *                    Extended Interface
- *              Support Single Resistor Sampling
- *
- * *************************************************************/
-
-/*************************/
-/* Global Interface Hook */
-/*************************/
-
-/**
- * @brief Function hook for pwm sampling trigger
- *
- */
-void (*Hal_Pwm_Ext_SamplingTriggerHook)();
-
-/*****************************************/
-/* Application Layer Interface Functions */
-/*****************************************/
-
-/**
- * @brief Set the duty cycle of the extra channel, affect the
- * sampling trigger moment
- *
- * @param dutycycle Duty cycle in q15 format
- */
-void Hal_Pwm_Ext_SetSamplingDutyCycle(uint32_t dutycycle);
-
-/**************************************/
-/* Platform Layer Interface Functions */
-/**************************************/
-
-/**
- * @brief Extra init process to support single resistor sampling
- * @note
- * An extra channel will be used to trigger sampling at attribute time.
- * The counter of extra channel always runs counting up mode for
- * controlling the sampling trigger time
- *
- */
-void Hal_Pwm_Ext_Init();
-
-#endif
-
-#if HAL_PWM_SUPPORT_COMPLEMENTARY_PULSE_GENERATION
-
-#endif
-
-#if HAL_PWM_SUPPORT_HALF_PULSE_GENERATION
-
-#endif
-
-#endif

+ 12 - 4
User project/4.BasicHardwSoftwLayer/1.BasicHardwLayer/Include/hwsetup.h

@@ -21,10 +21,16 @@
 #ifndef HWSETUP_H
 #define HWSETUP_H
 
+#ifndef RUN_ARCH_SIM
 #include "gd32f30x_libopt.h"
+#endif
 #include "STLmain.h"
 #include "syspar.h"
 #include "board_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 ************************************************************************/
@@ -42,9 +48,9 @@
 #define APB1CLK_KHZ CLK_APB1_KHZ // APB1 Clock
 #define APB2CLK_KHZ CLK_APB2_KHZ // APB2 Clock
 #define TIM0CLK_KHZ CLK_TIM0_KHZ // TIM0 Clock
-#define TIM1CLK_KHZ CLK_TIM0_KHZ /100
+#define TIM1CLK_KHZ (CLK_TIM0_KHZ /100)
 #define TIM2CLK_KHZ CLK_TIM0_KHZ 
-#define TIM5CLK_KHZ CLK_TIM0_KHZ / 2 
+#define TIM5CLK_KHZ (CLK_TIM0_KHZ / 2 )
 /* Timer2 for switchhall */
 #define TIM2CNTCLK_KHZ 72    // not use
 /* Time task base use TIMER5 */
@@ -93,7 +99,7 @@
 //#define IO_POWERLOCK_OFF (GPIO_OCTL(GPIOC) &= ~0x0002)
 //#define IO_POWER_STATE  (GPIO_ISTAT(GPIOC) & 0x0001)
 /* TIMER1 capture value */
-#define TIMER1_CAP_BIKESPD  TIMER_CH3CV(TIMER1)
+//#define TIMER1_CAP_BIKESPD  TIMER_CH3CV(TIMER1)
 //#define TIMER1_CAP_CANDANCE  TIMER_CH2CV(TIMER1)
 /************************************************************************
  TypeDefs & Structure defines (N/A)
@@ -180,8 +186,10 @@ _HWSETUP_EXT void hw_voIWDGInit(UWORD prer, UWORD rlr);
 /************************************************************************
  Flag Define (N/A)
 ************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/***********************************************************************/
 #endif
 /************************************************************************
  Copyright (c) 2022 Welling Motor Technology(Shanghai) Co. Ltd.

+ 7 - 0
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/CodePara.h

@@ -21,6 +21,9 @@
 #ifndef CODE_PARA_H
 #define CODE_PARA_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Definitions & Macros
 *************************************************************************/
@@ -324,6 +327,10 @@ void CPHistoryInfoCalTiming(void);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 7 - 1
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/glbcof.h

@@ -22,6 +22,10 @@ Revising History (ECL of this file):
 #define GLBCOF_H
 
 #include "typedefine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 *************************************************************************/
@@ -212,8 +216,10 @@ _GLBCOF_EXT void cof_voSysInit(void);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/***********************************************************************/
 #endif
 /*************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 6 - 1
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/macroequ.h

@@ -21,6 +21,9 @@
 #ifndef MACROEQU_H
 #define MACROEQU_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 ************************************************************************/
@@ -76,8 +79,10 @@ _MACROEQU_EXT UWORD FUNCTION_BUFFER[0x20];
 /************************************************************************
  Flag Define (N/A)
 ************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/***********************************************************************/
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 6 - 1
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/mathtool.h

@@ -21,6 +21,9 @@ Revising History (ECL of this file):
 #ifndef MATHTOOL_H
 #define MATHTOOL_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Modules used (included header files)
 *************************************************************************/
@@ -106,8 +109,10 @@ _MATHTOOL_EXT UWORD mth_voArctan(const ARCTAN_IN *in);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/************************************************************************/
 #endif
 /*************************************************************************
  Copyright (c) 2011 Welling Motor Technology(Shanghai) Co. Ltd.

+ 9 - 3
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/syspar.h

@@ -14,6 +14,7 @@
 ************************************************************************/
 #ifndef SYSPAR_H
 #define SYSPAR_H
+
 /************************************************************************
  Compiler Directives
 *************************************************************************/
@@ -69,11 +70,16 @@ Update Time
 /*======================================================================*
    ADC Maximum Value
 *=======================================================================*/
-#if ((MOTOR_ID_SEL == MOTOR_WELLING_CITY_36V) || (MOTOR_ID_SEL == MOTOR_WELLING_MTB_36V))
+#define IPM_36V    0
+#define IPM_48V    1
+#define IPM_ID_SEL IPM_36V
+
+#if (IPM_ID_SEL == IPM_36V)
 #define ADC_IPHASE_CUR_MAX_AP  15600 //13400
-#elif ((MOTOR_ID_SEL == MOTOR_WELLING_CITY_48V) || (MOTOR_ID_SEL == MOTOR_WELLING_MTB_48V))
-#define ADC_IPHASE_CUR_MAX_AP  8888 //13400
+#else
+#define ADC_IPHASE_CUR_MAX_AP  7500 //13400
 #endif
+
 #define ADC_IDC_CUR_MAX_AP     9524//10476//11640//9524 //10476
 #define ADC_ISENSOR_CUR_MAX_AP 6005
 #define ADC_VDC_MAX_VT         605

+ 8 - 1
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/typedefine.h

@@ -20,6 +20,10 @@
 *************************************************************************/
 #ifndef TYPEDEFINE_H
 #define TYPEDEFINE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Definitions & Macros (N/A)
 ************************************************************************/
@@ -38,7 +42,7 @@ typedef unsigned long      _ULONG;
 typedef signed long long   _SQWORD;
 typedef unsigned long long _UQWORD;
 
-typedef void               VOID;
+// typedef void               VOID;
 typedef unsigned char      UBYTE; // One byte unsigned
 typedef signed char        SBYTE; // One byte signed
 typedef unsigned short     UWORD; // Two bytes unsigned
@@ -194,6 +198,9 @@ Local Function Call Prototypes (N/A)
 /************************************************************************
  Flag Define (N/A)
 ************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 #endif
 
 /************************************************************************

+ 13 - 7
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/user.h

@@ -18,6 +18,10 @@
  Compiler Directives
 *************************************************************************/
 #include "typedefine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Definitions & Macros
 *************************************************************************/
@@ -43,9 +47,7 @@ Update Time
 #define MOTOR_WELLING_CITY_48V    0x30
 #define MOTOR_WELLING_MTB_48V     0x31
 
-#define MOTOR_ID_SEL              MOTOR_WELLING_MTB_36V
-
-
+#define MOTOR_ID_SEL              MOTOR_WELLING_CITY_36V    ///< syspar.h中也需要选择36V/48V系统
 /*======================================================================*
     Motor Parameters
 *=======================================================================*/
@@ -247,11 +249,11 @@ Update Time
 /* Recover time of IPM OC */
 #define ALM_IPM_OC_REC_TM 200 // unit: ms, Time of duration(TBC)
 /* Recover time & value of over voltage */
-#define ALM_OVR_VLT_REC_VAL 450 // unit: 0.1V
+#define ALM_OVR_VLT_REC_VAL (ALM_OVR_VLT_LVL1_VAL - 30)  // unit: 0.1V
 #define ALM_OVR_VLT_REC_TM  100 // unit: ms, Time of duration(TBC)
 #define ALM_OVR_VLT_REC_TM1 150 // unit: ms, Time of duration(TBC)
 /* Recover time & value of under voltage */
-#define ALM_UNDR_VLT_REC_VAL 300 // unit: 0.1V
+#define ALM_UNDR_VLT_REC_VAL (ALM_UNDR_VLT_LVL1_VAL + 30) // unit: 0.1V
 #define ALM_UNDR_VLT_REC_TM  200 // unit: ms, Time of duration(TBC)
 #define ALM_UNDR_VLT_REC_TM1 400 // unit: ms, Time of duration(TBC)
 /* Recover time & value of IPM over heat */
@@ -367,8 +369,8 @@ Update Time
 /*======================================================================*
    Constant Voltage Braking Parameter define
 *=======================================================================*/
-#define CVB_CONSTANT_VOL_BRAKE_V 42   // unit:0.1V,Voltage limit of Constant Voltage Brake
-#define CVB_CONSTANT_SPD_LOW_RPM 1000 // unit:rpm,
+#define CVB_CONSTANT_VOL_BRAKE_V (ALM_OVR_VLT_LVL1_VAL - 30)   // unit:0.1V,Voltage limit of Constant Voltage Brake
+#define CVB_CONSTANT_SPD_LOW_RPM 4500 // unit:rpm,
 
 /*======================================================================*
    Power limit
@@ -569,6 +571,10 @@ Update Time
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /*************************************************************************
  Copyright (c) 2019 Welling Motor Technology(Shanghai) Co. Ltd.

+ 1 - 0
User project/5.Api_rt/api_rt.c

@@ -8,4 +8,5 @@ void iRt_Init()
     iRtUart_Init();
     iRtPwm_Init();
     iRtAdc_Init();
+    iRtI2C_Init();
 }

+ 1 - 0
User project/5.Api_rt/api_rt.h

@@ -8,6 +8,7 @@
 #include "api_rt_timer.h"
 #include "api_rt_pwm.h"
 #include "api_rt_adc.h"
+#include "api_rt_i2c.h"
 
 #ifndef _API_RT_H_
 #define _API_RT_H_

+ 597 - 0
User project/5.Api_rt/api_rt_i2c.c

@@ -0,0 +1,597 @@
+#include "api_rt_i2c.h"
+#include "api_rt_dbg.h"
+#include "board_config.h"
+#include "gd32f30x.h"
+#include <stdint.h>
+
+ApiRtI2C_Handle I2Cs[1];
+
+/* ========================================================================== */
+/* ============================ Api RT Functions ============================ */
+/* ========================================================================== */
+
+void iRtI2C_Init()
+{
+    I2Cs[0].I2CBase = I2C0;
+}
+
+
+int iRtI2C_BusReset(uint8_t devIndex)
+{
+    i2c_deinit(I2Cs[devIndex].I2CBase);
+    /* Configure SDA/SCL for GPIO */
+    GPIO_BC(GPIOB) |= GPIO_PIN_6;
+    GPIO_BC(GPIOB) |= GPIO_PIN_7;
+    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
+    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
+    __NOP();
+    __NOP();
+    __NOP();
+    __NOP();
+    __NOP();
+    GPIO_BOP(GPIOB) |= GPIO_PIN_6;
+    __NOP();
+    __NOP();
+    __NOP();
+    __NOP();
+    __NOP();
+    GPIO_BOP(GPIOB) |= GPIO_PIN_7;
+    /* Connect I2C_SCL_PIN to I2C_SCL */
+    /* Connect I2C_SDA_PIN to I2C_SDA */
+    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
+    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
+
+    /* configure I2Cs[devIndex].I2CBase clock */
+    i2c_clock_config(I2Cs[devIndex].I2CBase, 100000, I2C_DTCY_2);
+    
+    /* Configure I2C address */
+    i2c_mode_addr_config(I2Cs[devIndex].I2CBase, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, HW_I2C_EE_ADDR_BLOCK1);
+    
+    /* Enable acknowledge */
+    i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_ENABLE);
+    
+    /* Enable I2C_DMA */
+//    i2c_dma_config(I2Cs[devIndex].I2CBase, I2C_DMA_ON); 
+       
+    /* Enable I2C */
+    i2c_enable(I2Cs[devIndex].I2CBase);
+
+    return 1;
+}
+
+void iRtI2C_WaitEEReady()
+{
+    uint16_t cnt1 = 0, cnt2 = 0;
+
+    /* Wait at least 5ms after writing a page */
+    while (cnt2 < 2)
+    {
+        cnt1++;
+        if (cnt1 == 10000)
+        {
+            cnt2++;
+            cnt1 = 0;
+        }
+    }
+}
+
+int iRtI2C_PageWrite2EE(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t *data, uint8_t count)
+{
+    uint8_t state = (uint8_t)I2C_START;
+    uint16_t timeoutCnt = 0;
+    uint8_t i2c_timeout_flag = 0;
+    uint8_t i2cBusResetCnt = 0;
+
+    /* Write to EEPROM enable*/
+    GPIO_OCTL(GPIOC) &= ~0x1000;
+
+    /* Enable acknowledge */
+    i2c_ack_config(I2Cs[devIndex].I2CBase , I2C_ACK_ENABLE);
+
+    while(!(i2c_timeout_flag)) 
+    {
+        /* I2C process */
+        switch(state) 
+        {
+        case I2C_START:
+            /* I2C master sends start signal only when the bus is idle */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_I2CBSY) != 0)  && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT)
+            {
+                i2c_start_on_bus(I2Cs[devIndex].I2CBase);
+                timeoutCnt = 0;
+                state = I2C_SEND_ADDRESS;
+            } 
+            else 
+            {
+                i2cBusResetCnt += iRtI2C_BusReset(devIndex);
+                timeoutCnt = 0;
+                state = I2C_START;
+                //printf("i2c bus is busy in WRITE!\n");
+            }
+            break;
+
+        case I2C_SEND_ADDRESS:
+            /* I2C master sends START signal successfully */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_SBSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT)
+            {
+                i2c_master_addressing(I2Cs[devIndex].I2CBase, devAddr, I2C_TRANSMITTER);
+                timeoutCnt = 0;
+                state = I2C_CLEAR_ADDRESS_FLAG;
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = I2C_START;
+                printf("i2c master sends start signal timeoutCnt in WRITE!\n");
+            }
+            break;
+
+        case I2C_CLEAR_ADDRESS_FLAG:
+            /* address flag set means i2c slave sends ACK */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT)
+            {
+                i2c_flag_clear(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND);
+                timeoutCnt = 0;
+                state = I2C_TRANSMIT_DATA;
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = I2C_START;
+                //printf("i2c master clears address flag timeoutCnt in WRITE!\n");
+            }
+            break;
+
+        case I2C_TRANSMIT_DATA:
+            /* wait until the transmit data buffer is empty */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_TBE) == 0) && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT) {
+                /* send the EEPROM's internal address to write to : only one byte address */
+                i2c_data_transmit(I2Cs[devIndex].I2CBase, memAddr);
+                timeoutCnt = 0;
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = I2C_START;
+                //printf("i2c master sends EEPROM's internal address timeoutCnt in WRITE!\n");
+            }
+
+            /* wait until BTC bit is set */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_BTC) == 0) && (timeoutCnt < I2C_TIME_OUT)){
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT) 
+            {
+                timeoutCnt = 0;
+            }
+            else 
+            {
+                timeoutCnt = 0;
+                state = I2C_START;
+                //printf("i2c master sends data timeoutCnt in WRITE!\n");
+            }
+
+            while(count != 0)
+            {
+                count --;
+                i2c_data_transmit(I2Cs[devIndex].I2CBase, *data);
+                /* Point to the next byte to be written */
+                data++;
+                /* wait until BTC bit is set */
+                while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_BTC) == 0) && (timeoutCnt < I2C_TIME_OUT))
+                {
+                    timeoutCnt++;
+                }
+
+                if(timeoutCnt < I2C_TIME_OUT) 
+                {
+                    timeoutCnt = 0;
+                } 
+                else 
+                {
+                    timeoutCnt = 0;
+                    state = I2C_START;
+                    //printf("i2c master sends data timeoutCnt in WRITE!\n");
+                }
+            }
+
+            timeoutCnt = 0;
+            state = I2C_STOP;
+            break;
+
+        case I2C_STOP:
+            /* send a stop condition to I2C bus */
+            i2c_stop_on_bus(I2Cs[devIndex].I2CBase);
+
+            /* I2C master sends STOP signal successfully */
+            while((I2C_CTL0(I2Cs[devIndex].I2CBase) & I2C_CTL0_STOP) && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT) 
+            {
+                timeoutCnt = 0;
+                state = I2C_COMPLETE;
+                i2c_timeout_flag = 1;
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = I2C_START;
+                //printf("i2c master sends stop signal timeoutCnt in WRITE!\n");
+            }
+            break;
+
+        default:
+            state = I2C_START;
+            i2c_timeout_flag = 1;
+            timeoutCnt = 0;
+            //printf("i2c master sends start signal in WRITE.\n");
+            break;
+        }
+
+        if(i2cBusResetCnt > 2 )
+        {
+            break;
+        }
+    }
+
+    /* Write to EEPROM disable */
+    GPIO_OCTL(GPIOC) |= 0x1000;
+
+    if(state == I2C_COMPLETE)
+    {
+        return count;
+    }
+    else 
+    {
+        return 0;
+    }
+}
+
+/* ========================================================================== */
+/* ============================== API Functions ============================= */
+/* ========================================================================== */
+
+int iI2C_Write(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t memAddrSize, uint8_t* data, uint16_t count)
+{
+    uint8_t addr = 0, misalignedDataCnt = 0, pageCnt = 0, singleDataCnt = 0;
+    uint16_t writeCompCnt = 0;
+    
+    if(memAddrSize == 0x8)
+    {
+        memAddr = memAddr & 0xFF;
+    }
+    addr = memAddr % HW_I2C_EE_PAGESIZE_BYTE;
+    misalignedDataCnt = HW_I2C_EE_PAGESIZE_BYTE - addr; 
+    pageCnt = count / HW_I2C_EE_PAGESIZE_BYTE;
+    singleDataCnt = count % HW_I2C_EE_PAGESIZE_BYTE;    
+
+    /* If memAddr is HW_I2C_EE_PAGESIZE_BYTE aligned */
+    if (addr == 0)
+    {
+        while (pageCnt != 0)
+        {
+            pageCnt--;
+            writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, HW_I2C_EE_PAGESIZE_BYTE);
+            iRtI2C_WaitEEReady();
+            memAddr += HW_I2C_EE_PAGESIZE_BYTE;
+            data += HW_I2C_EE_PAGESIZE_BYTE;  
+        }
+
+        if (singleDataCnt != 0)
+        {
+            writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, singleDataCnt);
+            iRtI2C_WaitEEReady();
+        }
+    }
+    else
+    {
+        /* If memAddr is not HW_I2C_EE_PAGESIZE_BYTE aligned */
+        if(count < misalignedDataCnt)
+        {
+            writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, count);
+            iRtI2C_WaitEEReady();
+        }
+        else 
+        {
+            count -= misalignedDataCnt;
+            pageCnt = count / HW_I2C_EE_PAGESIZE_BYTE;
+            singleDataCnt = count % HW_I2C_EE_PAGESIZE_BYTE;
+
+            /* Write misaligned data */
+            if(misalignedDataCnt != 0)  
+            {
+                writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, misalignedDataCnt);
+                iRtI2C_WaitEEReady();
+                memAddr += misalignedDataCnt;
+                data += misalignedDataCnt; 
+            }
+
+            /* Write page data */
+            while(pageCnt != 0)
+            {
+                pageCnt --;
+                writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, HW_I2C_EE_PAGESIZE_BYTE);
+                iRtI2C_WaitEEReady();
+                memAddr += HW_I2C_EE_PAGESIZE_BYTE;
+                data += HW_I2C_EE_PAGESIZE_BYTE; 
+            }
+
+            /* Write single data */
+            if (singleDataCnt != 0)
+            {
+                writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, singleDataCnt);
+                iRtI2C_WaitEEReady();
+            }
+        }
+    }
+
+    return writeCompCnt;
+}
+
+int iI2C_Read(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t memAddrSize, uint8_t* data, uint16_t count)
+{
+    uint8_t state = (uint8_t)I2C_START;
+    uint8_t read_cycle = 0;
+    uint16_t timeoutCnt = 0;
+    uint8_t i2c_timeout_flag = 0;
+    uint8_t i2cBusResetCnt = 0;
+
+    /* enable acknowledge */
+    i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_ENABLE);
+    
+    while(i2c_timeout_flag ==0)
+    {
+        switch(state) 
+        {
+        case I2C_START:
+            if(RESET == read_cycle) 
+            {
+                /* Disable I2C0 */
+                i2c_disable(I2Cs[devIndex].I2CBase);
+                /* Enable I2C0 */
+                i2c_enable(I2Cs[devIndex].I2CBase);
+                /* Enable acknowledge */
+                i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_ENABLE);
+                /* I2C master sends start signal only when the bus is idle */
+                while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_I2CBSY) != 0) && (timeoutCnt < I2C_TIME_OUT))
+                {
+                    timeoutCnt++;
+                }
+                
+                if(timeoutCnt < I2C_TIME_OUT) 
+                {
+                    /* Send the start signal */
+                    i2c_start_on_bus(I2Cs[devIndex].I2CBase);
+                    timeoutCnt = 0;
+                    state = (uint8_t)I2C_SEND_ADDRESS;
+                } 
+                else 
+                {
+                    i2cBusResetCnt += i2c_bus_reset();
+                    timeoutCnt = 0;
+                    state = (uint8_t)I2C_START;
+                }
+            } 
+            else 
+            {
+                i2c_start_on_bus(I2Cs[devIndex].I2CBase);
+                timeoutCnt = 0;
+                state = (uint8_t)I2C_SEND_ADDRESS;
+            }
+            break;
+        case I2C_SEND_ADDRESS:
+            /* I2C master sends START signal successfully */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_SBSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+            if(timeoutCnt < I2C_TIME_OUT) 
+            {
+                if(RESET == read_cycle) 
+                {
+                    i2c_master_addressing(I2Cs[devIndex].I2CBase, devAddr, I2C_TRANSMITTER);
+                    state = (uint8_t)I2C_CLEAR_ADDRESS_FLAG;
+                } 
+                else 
+                {
+                    i2c_master_addressing(I2Cs[devIndex].I2CBase, devAddr, I2C_RECEIVER);
+                    state = (uint8_t)I2C_CLEAR_ADDRESS_FLAG;
+                }
+                timeoutCnt = 0;
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = (uint8_t)I2C_START;
+                read_cycle = 0;
+            }
+            break;
+        case I2C_CLEAR_ADDRESS_FLAG:
+            /* Address flag set means i2c slave sends ACK */
+            while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
+            {
+                timeoutCnt++;
+            }
+            if(timeoutCnt < I2C_TIME_OUT) 
+            {
+                i2c_flag_clear(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND);
+                timeoutCnt = 0;
+                state = (uint8_t)I2C_TRANSMIT_DATA;
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = (uint8_t)I2C_START;
+                read_cycle = 0;   
+            }
+            break;
+        case I2C_TRANSMIT_DATA:
+            if(RESET == read_cycle) 
+            {
+                /* Wait until the transmit data buffer is empty */
+                while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_TBE) == 0) && (timeoutCnt < I2C_TIME_OUT))
+                {
+                    timeoutCnt++;
+                }
+                if(timeoutCnt < I2C_TIME_OUT) 
+                {
+                    /* Send the EEPROM's internal address to write to : only one byte address */
+                    i2c_data_transmit(I2Cs[devIndex].I2CBase, memAddr);
+                    timeoutCnt = 0;
+                } 
+                else 
+                {
+                    timeoutCnt = 0;
+                    state = (uint8_t)I2C_START;
+                    read_cycle = 0;    
+                }
+                /* Wait until BTC bit is set */
+                while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_BTC) == 0) && (timeoutCnt < I2C_TIME_OUT))
+                {
+                    timeoutCnt++;
+                }
+                if(timeoutCnt < I2C_TIME_OUT) 
+                {
+                    timeoutCnt = 0;
+                    state = (uint8_t)I2C_START;
+                    read_cycle++;
+                }
+                else 
+                {
+                    timeoutCnt = 0;
+                    state = (uint8_t)I2C_START;
+                    read_cycle = 0;
+                }
+            } 
+            else 
+            {
+                /* One byte master reception procedure (polling) */
+                if(count < 2) 
+                {
+                    /* Disable acknowledge */
+                    i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_DISABLE);
+                    /* Clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register (I2C_STAT0 has already been read) */
+                    i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND);
+                    /* Send a stop condition to I2C bus*/
+                    i2c_stop_on_bus(I2Cs[devIndex].I2CBase);
+                    /* Wait for the byte to be received */
+                    while(i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_RBNE) == 0)
+                    {
+                        // do nothing
+                    }
+                    /* Read the byte received from the EEPROM */
+                    *data = i2c_data_receive(I2Cs[devIndex].I2CBase);
+                    /* Decrement the read bytes counter */
+                    count--;
+                    timeoutCnt = 0;
+                    state = (uint8_t)I2C_STOP;
+                } 
+                else 
+                {  /* More than one byte master reception procedure (DMA) */                   
+                    
+                    dma_transfer_number_config(DMA0, DMA_CH6, count);        
+                    DMA_CH6MADDR(DMA0) = (uint32_t)data;
+                    
+                    i2c_dma_last_transfer_config(I2Cs[devIndex].I2CBase, I2C_DMALST_ON);
+                    /* Enable I2Cs[devIndex].I2CBase DMA */
+                    i2c_dma_config(I2Cs[devIndex].I2CBase, I2C_DMA_ON);
+                    /* Enable DMA0 channel5 */
+                    dma_channel_enable(DMA0, DMA_CH6);
+                    /* Wait until BTC bit is set */
+                    while(dma_flag_get(DMA0, DMA_CH6, DMA_FLAG_FTF) == 0 && (timeoutCnt < I2C_TIME_OUT))
+                    {
+                        timeoutCnt++;
+                    }
+
+                    if(timeoutCnt < I2C_TIME_OUT) 
+                    {
+                        timeoutCnt = 0;
+                        state = (uint8_t)I2C_STOP;
+                    } 
+                    else 
+                    {
+                        i2c_timeout_flag = 1;
+                        break;
+                    }
+                }
+            }
+            break;
+        case I2C_STOP:
+            /* Send a stop condition to I2C bus */
+            i2c_stop_on_bus(I2Cs[devIndex].I2CBase);
+            /* I2C master sends STOP signal successfully */
+            while((I2C_CTL0(I2Cs[devIndex].I2CBase) & I2C_CTL0_STOP) && (timeoutCnt < I2C_TIME_OUT)) 
+            {
+                timeoutCnt++;
+            }
+
+            if(timeoutCnt < I2C_TIME_OUT)
+            {
+                timeoutCnt = 0;                 
+                i2c_timeout_flag = 1;
+                state = (uint8_t)I2C_COMPLETE;
+                read_cycle = 0;
+                
+                /* Disable DMA0 CH6 */
+                dma_channel_disable(DMA0, DMA_CH6);
+                /* Disable I2Cs[devIndex].I2CBase DMA */
+                i2c_dma_config(I2Cs[devIndex].I2CBase, I2C_DMA_OFF); 
+                i2c_dma_last_transfer_config(I2Cs[devIndex].I2CBase, I2C_DMALST_OFF);
+            } 
+            else 
+            {
+                timeoutCnt = 0;
+                state = (uint8_t)I2C_START;
+                read_cycle = 0;
+            }
+                                            
+            break;
+        default:
+            state = (uint8_t)I2C_START;
+            read_cycle = 0;
+            i2c_timeout_flag = 1;
+            timeoutCnt = 0;
+            
+            break;
+        }
+
+        if(i2cBusResetCnt > 1)
+        {
+            break;
+        }
+    }
+
+    if(state == I2C_COMPLETE)
+    {
+        return count;
+    }
+    else 
+    {
+        return 0;
+    }
+}
+

+ 58 - 0
User project/5.Api_rt/api_rt_i2c.h

@@ -0,0 +1,58 @@
+#ifndef _API_I2C_LOW_H_
+#define _API_I2C_LOW_H_
+
+#include <stdint.h>
+#include "api_i2c.h"
+#include "api_rt_common.h"
+#include "gd32f30x.h"
+
+#define I2C_TIME_OUT    (uint16_t)(10000)
+
+typedef struct
+{
+    uint32_t I2CBase;
+} ApiRtI2C_Handle;
+
+extern ApiRtI2C_Handle I2Cs[1];
+
+typedef enum
+{
+    I2C_START = 0,
+    I2C_SEND_ADDRESS,
+    I2C_CLEAR_ADDRESS_FLAG,
+    I2C_TRANSMIT_DATA,
+    I2C_STOP,
+    I2C_COMPLETE
+} ApiRtI2C_Process;
+
+/**
+ * @brief I2C初始化
+ */
+void iRtI2C_Init();
+
+/**
+ * @brief I2C等待EE可写入
+ */
+void iRtI2C_WaitEEReady();
+
+/**
+ * @brief I2C总线复位
+ *
+ * @return 总线复位次数
+ */
+int iRtI2C_BusReset(uint8_t devIndex);
+
+/**
+ * @brief I2C同步页写入EE
+ * 
+ * @param devIndex 外设序号
+ * @param devAddr 设备地址
+ * @param memAddr 内存地址
+ * @param memAddrSize 内存地址宽度
+ * @param data 写入数据Buffer
+ * @param count 写入数据长度
+ * @return 写入结果
+ */
+int iRtI2C_PageWrite2EE(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t *data, uint8_t count);
+
+#endif

+ 0 - 1
User project/5.Api_rt/api_rt_pwm.c

@@ -43,7 +43,6 @@ void iRtPwm_Init()
 #endif
 
 }
-
 void iRtPwm_CountZeroIsr(uint8_t devIndex)
 {
     if (Pwms[devIndex].CountZeroISR.Enable)

+ 11 - 0
tests/sim/.gitignore

@@ -0,0 +1,11 @@
+# Matlab Autosave File
+*.original
+*.autosave
+*.asv
+*.slxc
+*.mex*
+
+# Simulink Build File
+slprj/
+*_rtw/
+

BIN
tests/sim/FanPlatformAuto.slx


BIN
tests/sim/FanPlatform_Debug.slx


+ 0 - 0
unit_test/STLmain.h → tests/sim/automation/.gitignore


+ 7 - 0
tests/sim/automation/ApplyInit.m

@@ -0,0 +1,7 @@
+function ApplyInit(initvars, connections)
+% 设置模型初始化变量
+    [t, n] = SelectConnection(initvars.tag, connections);
+    if (t == 'v')
+        assignin('base', n, initvars.value);
+    end
+end

+ 34 - 0
tests/sim/automation/ApplyInjection.m

@@ -0,0 +1,34 @@
+function ApplyInjection(injection, connection, modelPorts)
+%SET_INJ 设置注入信号
+%   
+    [conn_type, conn_name] = SelectConnection(injection.tag, connection);
+    if conn_type == 's' || conn_type == 'p'
+        if conn_type == 's'
+            ch = SelectPort(modelPorts.Software, conn_name);
+        elseif conn_type == 'p'
+            ch = SelectPort(modelPorts.Physical, conn_name);
+        end
+        SetPortSignal(ch, ConstructSignal(injection.time, injection.value));
+        SetPortEnable(ch, injection.enable');
+        if isfield(injection.option, 'through')
+            SetPortThrough(ch, injection.option.through);
+        end
+        if isfield(injection.option, 'interpolation')
+            SetPortInterpolation(ch, injection.option.interpolation);
+        end
+    end
+end
+
+function Signal = ConstructSignal(time, value)
+    if length(time) == 1
+        if time == 0
+            Signal = value;
+        else
+           Signal = [0 0; time value]; 
+        end
+    else
+        Signal = [time value];
+    end
+end
+
+

BIN
tests/sim/automation/AutomationPortLib.slx


+ 13 - 0
tests/sim/automation/CommentBlocks.m

@@ -0,0 +1,13 @@
+function CommentBlocks(handles, out)
+%COMMENTOUTBLOCKS 此处显示有关此函数的摘要
+%   此处显示详细说明
+for i = 1:length(handles)
+    if out == 1
+        set_param(handles(i), 'Commented', 'on');
+    else
+        set_param(handles(i), 'Commented', 'off');
+    end
+end
+
+end
+

+ 100 - 0
tests/sim/automation/ConditionCheck.m

@@ -0,0 +1,100 @@
+function [result, msg] = ConditionCheck(check)
+
+result = 0;
+msg = '';
+
+if check.fdb.Length < 2
+    msg = 'Not enough data to verify condition';
+    return;
+end
+
+if check.tolerance <= 0
+    msg = 'Invalid tolerance setting';
+    return;
+end
+
+if check.ref.Time(1) > 0
+    check.ref = addsample(check.ref, 'Data', 0, 'Time', 0);
+end
+
+if check.ref.Time(end) < check.fdb.Time(end)
+    check.ref = addsample(check.ref, 'Data', check.ref.Data(end), 'Time', check.fdb.Time(end));
+end
+
+if check.preprocess == 0
+    % 不需要对数据进行预处理
+    if isa(check.time, 'double') || isa(check.time, 'char')
+        if isa(check.time, 'char')
+            test_time = check.fdb.Time(end);
+        else
+            test_time = check.time;
+        end
+        
+        if max(test_time) > check.fdb.Time(end)
+            msg = 'Check time out of range';
+            return;
+        end
+        if check.refIntp
+            check.ref_cmp = resample(check.ref, test_time);
+        else
+            check.ref_cmp = resample(check.ref, test_time, 'zoh');
+        end
+        if check.fdbIntp
+            check.fdb_cmp = resample(check.fdb, test_time);
+        else
+            check.fdb_cmp = resample(check.fdb, test_time, 'zoh');
+        end
+        res = check.condition.Test(check.ref_cmp.Data, check.fdb_cmp.Data, check.tolerance);
+        if all(res)
+            result = 1;
+            msg = sprintf('[%s]: [%s] [%s] check passed', check.tag, check.fdb_name, check.condition.Name);
+            return;
+        else
+            fail = not(res);
+            fail_index = find(fail);
+            result = 0;
+            msg = sprintf('[%s]: [%s] [%s] check failed at time {%s}: Expected {%s}; Get {%s}', check.tag, check.fdb_name, check.condition.Name, mat2str(test_time(fail_index)), mat2str(check.ref_cmp.Data(fail_index)),  mat2str(check.fdb_cmp.Data(fail_index)));
+            return;
+        end
+    else
+        result = 0;
+        msg = 'Invalid check time setting';
+        return;
+    end
+else
+    % 需要对数据进行预处理,即检查时间段内的情况
+    test_time = check.fdb.time(find(and(check.fdb.Time > check.time(1), check.fdb.Time > check.time(1))));
+    if check.refIntp
+        check.ref_cmp = resample(check.ref, test_time);
+    else
+        check.ref_cmp = resample(check.ref, test_time, 'zoh');
+    end
+    if check.fdbIntp
+        check.fdb_cmp = resample(check.fdb, test_time);
+    else
+        check.fdb_cmp = resample(check.fdb, test_time, 'zoh');
+    end
+    switch (check.adv)
+        case {'A', 'Always'}
+            res = check.condition.Test(check.ref_cmp.Data, check.fdb_cmp.Data, check.tolerance);
+        case {'R', 'RMS'}
+        case {'M', 'Mean'}
+            res = check.condition.Test(mean(check.ref_cmp), mean(check.fdb_cmp), check.tolerance);
+        case {'P', 'Peak2Peak'}
+            res = check.condition.Test(check.ref_cmp.Data(1), max(check.fdb_cmp) - min(check.fdb_cmp), check.tolerance);
+    end
+    if all(res)
+        result = 1;
+        msg = sprintf('[%s]: [%s] [%s] check passed', check.tag, check.fdb_name, check.condition.Name);
+        return;
+    else
+        fail = not(res);
+        fail_index = find(fail);
+        result = 0;
+        msg = sprintf('[%s]: [%s] [%s-%s] check failed in duration {%s}: Expected {%s}; Get {%s}', check.tag, check.fdb_name, check.adv, check.condition.Name, mat2str(check.time), mat2str(check.ref_cmp.Data(fail_index(1))),  mat2str(check.fdb_cmp.Data(fail_index(1))));
+        return;
+    end     
+end
+
+
+end

+ 18 - 0
tests/sim/automation/LoadModelPorts.m

@@ -0,0 +1,18 @@
+function ModelPorts = LoadModelPorts(model)
+%LOADMODELPORT 此处显示有关此函数的摘要
+%   此处显示详细说明
+ModelPorts.Physical = get_phy_channels(model);
+ModelPorts.Software = get_sw_channels(model);
+end
+
+function channels = get_sw_channels(model)
+% 获取模型的软件信号注入接口
+% 返回注入接口模型句柄
+    channels = find_system(model, 'FindAll', 'on', 'MaskType', 'InjectionChannel', 'InjectionType', 'Software');
+end
+
+function channels = get_phy_channels(model)
+% 获取模型的物理信号注入接口
+% 返回注入接口模型句柄
+    channels = find_system(model, 'FindAll', 'on', 'MaskType', 'InjectionChannel', 'InjectionType', 'Physical');
+end

+ 54 - 0
tests/sim/automation/LoadTest.m

@@ -0,0 +1,54 @@
+function LoadTest(case_name)
+
+evalin('base', 'clear all');
+caseFile = [case_name '_Case.json'];
+
+test_case = jsondecode(fileread(caseFile));   %读取测试用例文件
+target_model = test_case.Model.name;
+connectionFile = test_case.Model.connection_file;
+
+% 初始化模型
+load_system(target_model);
+% scopes = find_system(target_model, 'FindAll', 'on', 'BlockType', 'Scope');
+% CommentBlocks(scopes, 1);
+evalin('base', test_case.Model.init);
+
+% 获取模型测试接口
+ports = LoadModelPorts(target_model);
+
+% 初始化注入信号
+% 默认物理信号为0,使能直通
+for i = 1:length(ports.Physical)
+    SetPortSignal(ports.Physical(i), 0);
+    SetPortThrough(ports.Physical(i), 1);
+    SetPortEnable(ports.Physical(i), 1);
+end
+
+% 默认软件信号为0,关闭直通
+for i = 1:length(ports.Software)
+    SetPortSignal(ports.Software(i), 0);
+    SetPortThrough(ports.Software(i), 0);
+    SetPortEnable(ports.Software(i), 0);
+end
+
+% 加载注入信号
+test_connection = jsondecode(fileread(connectionFile));   %读取连接文件
+
+% 应用模型注入信号
+for i = 1:length(test_case.Injections)
+    ApplyInjection(test_case.Injections(i), test_connection, ports);
+end
+
+% 应用模型初始化信号
+for i = 1:length(test_case.Initializations)
+    ApplyInit(test_case.Initializations(i), test_connection)
+end
+
+%% 运行模型
+if isfield(test_case.Model, 'config')
+    for i = 1:length(test_case.Model.config)
+        set_param(target_model, test_case.Model.config(i).name, test_case.Model.config(i).value);
+    end
+end
+
+end

+ 138 - 0
tests/sim/automation/ParseCheck.m

@@ -0,0 +1,138 @@
+function check = ParseCheck(check_in, case_in, connections)
+%PARSE_CASE 此处显示有关此函数的摘要
+%   此处显示详细说明
+check.id = check_in.id;
+check.tag = check_in.tag;
+check.condition_str = check_in.condition;
+check.condition.Name = '';
+check.condition.Test = @() 0;
+check.ref_name = '';
+check.ref = timeseries(0, 0);
+check.refIntp = 1;  %默认使能插值
+check.fdb_name = '';
+check.fdb = timeseries(0, 0);
+check.fdbIntp = 1;  %默认使能插值
+
+tmp.ref.time = 0;
+tmp.ref.value = 0;
+tmp.fdb.time = 0;
+tmp.fdb.value = 0;
+
+if isa(check_in.time, 'struct')
+    check.preprocess = 1;
+    check.time = check_in.time.duration;
+    check.adv = check_in.time.adv;
+else
+    check.preprocess = 0;
+    check.time = check_in.time;
+    check.adv = 'None';
+end
+
+check.tolerance = check_in.tolerance;
+if check.tolerance == 0
+    check.tolerance = 1e-10;
+end
+check.test = @() 0;
+
+if isa(check_in.ref, 'char')
+    check.ref_name = check_in.ref;
+    [tmp.ref.time, tmp.ref.value, check.refIntp] = GetSignal(check_in.ref, case_in, connections);
+elseif isa(check_in.ref, 'double')
+    tmp.ref.time = check.time;
+    if (check.preprocess == 1)  
+        tmp.ref.value = [check_in.ref; check_in.ref];
+    else
+        tmp.ref.value = check_in.ref;
+    end
+end
+
+if isa(check_in.fdb, 'char')
+    check.fdb_name = check_in.fdb;
+    [tmp.fdb.time, tmp.fdb.value, check.fdbIntp] = GetSignal(check_in.fdb, case_in, connections);
+elseif isa(check_in.fdb, 'double')
+    tmp.fdb.time = check.time;
+    if (check.preprocess == 1)   
+        tmp.fdb.value = [check_in.fdb; check_in.fdb];
+    else
+        tmp.fdb.value = check_in.fdb;
+    end
+end
+
+check.ref = timeseries(tmp.ref.value, tmp.ref.time);
+check.fdb = timeseries(tmp.fdb.value, tmp.fdb.time);
+
+switch(check_in.condition)
+    case 'eq'
+        check.condition.Name = 'Equal';
+        check.condition.Test = @(ref, fdb, tor) and(fdb <= ref + tor, fdb >= ref - tor);
+    case 'ne'
+        check.condition.Name = 'NotEqual';
+        check.condition.Test = @(ref, fdb, tor) or(fdb > ref + tor, fdb < ref - tor);
+    case 'gt'
+        check.condition.Name = 'GreaterThan';
+        check.condition.Test = @(ref, fdb, tor) (fdb > ref);
+    case 'ge'
+        check.condition.Name = 'GreaterOrEqual';
+        check.condition.Test = @(ref, fdb, tor) (fdb >= ref);
+    case 'lt'
+        check.condition.Name = 'LessThan';
+        check.condition.Test = @(ref, fdb, tor) (fdb >= ref);
+    case 'le'
+        check.condition.Name = 'LessOrEqual';
+        check.condition.Test = @(ref, fdb, tor) (fdb >= ref);
+    case 'EqAngle'
+        check.condition.Name = 'EqualAngle';
+        check.condition.Test = @(ref, fdb, tor) ((mod(fdb - ref, 2*pi) < tor) || (mod(fdb - ref, 2*pi) > (2*pi - tor)));
+    case 'In'
+        check.condition.Name = 'In';
+        check.condition.Test = @(ref, fdb, tor) and(fdb <= ref + tor, fdb >= ref - tor);
+    case 'NotIn'
+        check.condition.Name = 'NotIn';
+        check.condition.Test = @(ref, fdb, tor) or(fdb > ref + tor, fdb < ref - tor);
+end
+check.test = @ConditionCheck;
+
+end
+
+function [time, value, intp] = GetSignal(tag, test, connections)
+
+time = 0;
+value = 0;
+intp = 0;
+
+for i = 1:length(test.Initializations)
+    if strcmp(tag, test.Initializations(i).tag)
+        time = 0;
+        value = test.Initializations(i).value;
+        return;
+    end
+end
+
+for i = 1:length(test.Injections)
+    if strcmp(tag, test.Injections(i).tag)
+        time = test.Injections(i).time;
+        value = test.Injections(i).value;
+        if isfield(test.Injections(i), 'option')
+            if isfield(test.Injections(i).option, 'interpolation')
+                if test.Injections(i).option.interpolation
+                    intp = 1;
+                end
+            end
+        end
+        return;
+    end
+end
+
+for i = 1:length(test.Feedbacks)
+    if strcmp(tag, test.Feedbacks(i).tag)
+        [t, n, c] = SelectConnection(test.Feedbacks(i).tag, connections);
+        if t == 'v' || t == 'a'
+            time = evalin('base', n).Time;
+            value = evalin('base', n).Data(:,c + 1);
+            return;
+        end
+    end
+end
+
+end
+

+ 75 - 0
tests/sim/automation/RunTest.m

@@ -0,0 +1,75 @@
+function result = RunTest(case_name)
+%RUNTEST 运行测试用例
+
+%% 初始化/加载
+evalin('base', 'clear all');
+caseFile = [case_name '_Case.json'];
+
+test_case = jsondecode(fileread(caseFile));   %读取测试用例文件
+target_model = test_case.Model.name;
+connectionFile = test_case.Model.connection_file;
+
+% 初始化模型
+load_system(target_model);
+scopes = find_system(target_model, 'FindAll', 'on', 'BlockType', 'Scope');
+CommentBlocks(scopes, 1);
+evalin('base', test_case.Model.init);
+
+% 获取模型测试接口
+ports = LoadModelPorts(target_model);
+
+% 初始化注入信号
+% 默认物理信号为0,使能直通
+for i = 1:length(ports.Physical)
+    SetPortSignal(ports.Physical(i), 0);
+    SetPortThrough(ports.Physical(i), 1);
+    SetPortEnable(ports.Physical(i), 1);
+end
+
+% 默认软件信号为0,关闭直通
+for i = 1:length(ports.Software)
+    SetPortSignal(ports.Software(i), 0);
+    SetPortThrough(ports.Software(i), 0);
+    SetPortEnable(ports.Software(i), 0);
+end
+
+% 加载注入信号
+test_connection = jsondecode(fileread(connectionFile));   %读取连接文件
+
+% 应用模型注入信号
+for i = 1:length(test_case.Injections)
+    ApplyInjection(test_case.Injections(i), test_connection, ports);
+end
+
+% 应用模型初始化信号
+for i = 1:length(test_case.Initializations)
+    ApplyInit(test_case.Initializations(i), test_connection)
+end
+
+%% 运行模型
+if isfield(test_case.Model, 'config')
+    for i = 1:length(test_case.Model.config)
+        set_param(target_model, test_case.Model.config(i).name, test_case.Model.config(i).value);
+    end
+end
+out = sim(target_model);
+assignin('base', 'out', out); 
+% s = load('matlab.mat');
+% assignin('base', 'out', s.out); 
+close_system(target_model, 0); %仿真完成后必须关闭模型,否则在Accelerator模式下再次仿真将导致Matlab崩溃,原因暂时不明
+
+%% 获取模型输出
+
+%% 验证测试结果
+test_check = test_case.Checks;
+check_result = {};
+for i = 1:length(test_check)
+    check = ParseCheck(test_check(i), test_case, test_connection);
+    [res, msg] = ConditionCheck(check);
+    check_result{i} = {check.id, check.tag, res, msg};
+end
+
+result = check_result;
+
+end
+

+ 35 - 0
tests/sim/automation/SelectConnection.m

@@ -0,0 +1,35 @@
+function [Type, Name, Column] = SelectConnection(tag, map)
+%GET_CONNECTION 读取信号连接信息
+%   type为信号连接类型:
+%   's'-连接至软件注入点
+%   'p'-连接至物理注入点
+%   'v'-连接至变量
+%   'a'-连接至数组
+%   'n'-无效连接
+Type = 'n';
+Name = '';
+Column = 0;
+for i = 1:length(map)
+    if strcmp(tag, map(i).from)
+        if isa(map(i).to, 'char')
+            Type = 'v';
+            Name = map(i).to;
+        elseif isa(map(i).to, 'struct')
+            if strcmp(map(i).to.type, 'port')
+                if strcmp(map(i).to.spec, 'software')
+                    Type = 's';
+                    Name = map(i).to.channel;
+                elseif strcmp(map(i).to.spec, 'physical')
+                    Type = 'p';
+                    Name = map(i).to.channel;
+                end
+            elseif strcmp(map(i).to.type, "array")
+                Type = 'a';
+                Name = map(i).to.name;
+                Column = map(i).to.column;
+            end
+        end
+        break;
+    end
+end
+

+ 20 - 0
tests/sim/automation/SelectPort.m

@@ -0,0 +1,20 @@
+function Port = SelectPort(handles, hints)
+%SELECTPORT 根据序号选择端口,接受字符串或者数字
+%   此处显示详细说明
+Port = 0;    
+if isa(hints, 'char')
+    for i = 1:length(handles)
+        if strcmp(get_param(handles(i), 'Index'), hints)
+            Port = handles(i);
+        end
+    end 
+elseif isa(hints, 'double')
+    for i = 1:length(handles)
+        if str2double(get_param(handles(i), 'Index')) == hints
+            Port = handles(i);
+        end
+    end
+end
+
+end
+

+ 16 - 0
tests/sim/automation/SetPortEnable.m

@@ -0,0 +1,16 @@
+function SetPortEnable(handle, en)
+% 使能或关闭注入信号
+% handle 信号注入模块句柄或全名
+% en 使能
+    if en == 0
+        set_param(handle, 'enableVar', '[0 0]');
+    elseif en == 1
+        set_param(handle, 'enableVar', '[0 1]');  
+    else
+        if length(inputname(2)) > 0
+            set_param(handle, 'enableVar', inputname(2));
+        else
+            set_param(handle, 'enableVar', mat2str(en));
+        end
+    end
+end

+ 8 - 0
tests/sim/automation/SetPortInterpolation.m

@@ -0,0 +1,8 @@
+function SetPortInterpolation(handle, en)
+% 使能或关闭注入信号曲线插值
+    if en
+        set_param(handle, 'interpolation', 1);
+    else
+        set_param(handle, 'interpolation', 0);
+    end
+end

+ 12 - 0
tests/sim/automation/SetPortSignal.m

@@ -0,0 +1,12 @@
+function SetPortSignal(handle, sig)
+% 设置注入信号
+    if length(sig) == 1
+        set_param(handle, 'dataVar', mat2str([0, sig]));
+    else
+        if length(inputname(2)) > 0
+            set_param(handle, 'dataVar', inputname(2));
+        else
+            set_param(handle, 'dataVar', mat2str(sig));
+        end
+    end
+end

+ 4 - 0
tests/sim/automation/SetPortThrough.m

@@ -0,0 +1,4 @@
+function SetPortThrough(handle, en)
+% 使能或关闭注入信号直通
+    set_param(handle, 'through', double(en));
+end

BIN
tests/sim/automation/injection_dtype.mat


+ 25 - 0
tests/sim/automation/slblocks.m

@@ -0,0 +1,25 @@
+function blkStruct = slblocks
+
+% This function specifies that the library should appear
+
+% in the Library Browser
+
+% and be cached in the browser repository
+
+
+
+Browser.Library = 'AutomationPortLib';
+
+% 'mylib' is the name of the library
+
+
+
+Browser.Name = 'AutomationMidea';
+
+% 'My Library' is the library name that appears
+
+% in the Library Browser
+
+
+
+blkStruct.Browser = Browser;

+ 26 - 0
tests/sim/init_model.m

@@ -0,0 +1,26 @@
+% Motor Parameter 
+Ls=0.17050;
+Ld=0.17050;
+Lq=0.21500;
+Rs=18.25;
+Ra=Rs;
+P=5;
+Psif=0.31344;
+J=2620e-7;
+InerRate=1;
+
+% AC Voltage 
+Vac=310;
+
+% Control Speed 
+Rpm=1620;
+Freq=Rpm/60*P;
+w=Rpm/60*2*pi;
+we=Freq*2*pi;
+
+% Sample Parameter 
+MaxIphase = 8.25;
+MaxVdc = 641.9;
+
+load('injection_dtype.mat');
+

+ 3 - 0
tests/sim/prepare_test.m

@@ -0,0 +1,3 @@
+addpath('./automation/');
+addpath('./test_cases/');
+load('injection_dtype.mat');

+ 2 - 0
tests/sim/pytest/.gitignore

@@ -0,0 +1,2 @@
+__pycache__
+.pytest_cache

+ 17 - 0
tests/sim/pytest/base_case.py

@@ -0,0 +1,17 @@
+import pytest
+from matlab_wrapper import *
+
+class TestBase:
+    case_name = ''
+    res = 0
+
+    @pytest.fixture(scope='class')
+    def Sim(self):
+        res = run_sim(self.case_name)
+        return res
+
+    def test_Sim(self, Sim):
+        assert Sim != None
+
+    def test_Result(self, Sim, index):
+        assert Sim[index][2] == 1, Sim[index][3]

+ 11 - 0
tests/sim/pytest/conftest.py

@@ -0,0 +1,11 @@
+import matlab_wrapper as mw
+
+def pytest_generate_tests(metafunc):
+    if "index" in metafunc.fixturenames:
+        case_name = metafunc.cls.case_name
+        if case_name == '':
+            case_name = metafunc.cls.__name__[4:]
+            metafunc.cls.case_name = case_name
+        print(case_name)
+        checks_name = mw.load_checks(case_name)
+        metafunc.parametrize("index", range(len(checks_name)), ids=checks_name)

+ 28 - 0
tests/sim/pytest/matlab_wrapper.py

@@ -0,0 +1,28 @@
+import os
+import matlab.engine
+import json
+from pathlib import Path
+
+def load_checks(case_name):
+    tmp = []
+    print('Load Check of Case [{0}]'.format(case_name))
+    case_path = '../test_cases/'+case_name+'_Case.json'
+    if (os.path.exists(case_path)):
+        fo = open(case_path)
+        checks_data = fo.read()
+        checks = json.loads(checks_data)['Checks']
+        for check in checks:
+            tmp.append(check['tag'])
+        print('{0} Checks Loaded'.format(len(tmp)))
+    else:
+        print('Case File Not Found')
+    return tmp
+
+def run_sim(case_name):
+    eng = matlab.engine.start_matlab()
+    eng.cd(Path().absolute().parent.as_posix())
+    eng.prepare_test(nargout=0)
+    res = eng.RunTest(case_name)
+    eng.quit()
+    return res
+

+ 15 - 0
tests/sim/pytest/test_Sim.py

@@ -0,0 +1,15 @@
+import base_case as base
+import os
+import re
+
+exist_testcases_path = os.path.exists("../test_cases")
+
+if exist_testcases_path:
+    var_dict = locals()
+    for dirpath, dnames, fnames in os.walk("../test_cases"):
+        for fname in fnames:
+            m = re.match('^(.+)_Case.json$', fname)
+            if m != None:
+                var_dict['Test'+m.group(1)] = type('Test'+m.group(1),(base.TestBase,),{})
+else:
+    print("No Test Cases Found!")

+ 363 - 0
tests/sim/sim_board/.gitignore

@@ -0,0 +1,363 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Oo]ut/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd

+ 12 - 0
tests/sim/sim_board/api_rt/api_rt.c

@@ -0,0 +1,12 @@
+#include "api_rt.h"
+
+void iRt_Init()
+{
+    iRtPwm_Init();
+    iRtAdc_Init();
+    iRtGpioLow_Init();
+    iRtTimer_Init();
+    iRtCap_Init();
+    iRtUart_Init();
+    iRtProbe_Init();
+}

+ 17 - 0
tests/sim/sim_board/api_rt/api_rt.h

@@ -0,0 +1,17 @@
+#ifndef _API_RT_H_
+#define _API_RT_H_
+
+#include "api_config.h"
+#include "api_board_support.h"
+#include "api_rt_adc.h"
+#include "api_rt_pwm.h"
+#include "api_rt_gpio.h"
+#include "api_rt_timer.h"
+#include "api_rt_cap.h"
+#include "api_rt_delay.h"
+#include "api_rt_uart.h"
+#include "api_rt_test_probe.h"
+
+void iRt_Init();
+
+#endif

+ 81 - 0
tests/sim/sim_board/api_rt/api_rt_adc.c

@@ -0,0 +1,81 @@
+#include "api_adc.h"
+#include "api_rt_adc.h"
+#include "api_rt_dbg.h"
+#include "board.h"
+#include <stdint.h>
+
+ApiRtAdc_Handle Adcs[2];
+
+void iRtAdc_Init()
+{
+    Adcs[0].AdcBase = &adc;
+    Adcs[1].AdcBase = &adc2;
+}
+
+uint16_t iAdc_GetResult(uint8_t devIndex, uint8_t channelIndex)
+{
+    if (devIndex == 0)
+    {
+        Adcs[devIndex].Results[channelIndex] = Adcs[0].AdcBase->SamplingOutput[channelIndex];
+    }
+    return Adcs[devIndex].Results[channelIndex];
+}
+
+uint16_t *iAdc_GetResultPointer(uint8_t devIndex)
+{
+    if (devIndex == 0)
+    {
+        for (int i = 0; i < 8; i++)
+        {
+            Adcs[devIndex].Results[i] = Adcs[0].AdcBase->SamplingOutput[i];
+        }
+    }
+    return Adcs[devIndex].Results;
+}
+
+void iAdc_Enable(uint8_t devIndex)
+{
+    Adcs[devIndex].AdcBase->Base.Enable = 1;
+}
+
+void iAdc_Disable(uint8_t devIndex)
+{
+    Adcs[devIndex].AdcBase->Base.Enable = 0;
+}
+
+ApiAdc_Status iAdc_GetStatus(uint8_t devIndex)
+{
+    return ApiAdc_End;
+}
+
+void iAdc_Convert(uint8_t devIndex)
+{
+    Adcs[devIndex].AdcBase->Sample(&Adcs[0].AdcBase->Base);
+}
+
+int8_t iAdc_ChannelGroupSwitch(uint8_t devIndex, uint8_t groupIndex)
+{
+    return 0;
+}
+
+void iAdc_EnableConversionInterrupt(uint8_t devIndex)
+{
+    Adcs[devIndex].AdcBase->InterruptOutputFlag = 0;
+    Adcs[devIndex].AdcBase->EnableInterrupt     = 1;
+}
+
+void iAdc_DisableConversionInterrupt(uint8_t devIndex)
+{
+    Adcs[devIndex].AdcBase->EnableInterrupt = 0;
+}
+
+void iAdc_BindConversionInterrupt(uint8_t devIndex, void (*action)())
+{
+    scheduler.InterruptBind(&scheduler, &Adcs[devIndex].AdcBase->Base, AdcInterruptOutEOC, action);
+}
+
+void iAdc_EnableHardwareTrigger(uint8_t devIndex)
+{}
+
+void iAdc_DisableHardwareTrigger(uint8_t devIndex)
+{}

+ 29 - 0
tests/sim/sim_board/api_rt/api_rt_adc.h

@@ -0,0 +1,29 @@
+#ifndef _API_RT_ADC_H_
+#define _API_RT_ADC_H_
+
+#include <stdint.h>
+#include "api_rt_common.h"
+#include "sim_mcu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define API_RT_ADC_DEVICE_COUNT 1
+#define API_RT_ADC_RESULT_SIZE  16
+
+typedef struct
+{
+    struct Sim_Adc *AdcBase;
+    uint16_t        Results[API_RT_ADC_RESULT_SIZE];
+} ApiRtAdc_Handle;
+
+extern ApiRtAdc_Handle Adcs[2];
+
+extern void iRtAdc_Init();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 109 - 0
tests/sim/sim_board/api_rt/api_rt_cap.c

@@ -0,0 +1,109 @@
+#include "api_cap.h"
+#include "api_rt_cap.h"
+#include "api_rt_dbg.h"
+#include "board.h"
+
+ApiRtCap_Handle Caps[1];
+
+void iRtCap_Init()
+{
+    Caps[0].CapBase                 = &inputCap;
+    Caps[0].CapBase->Base.Prescaler = 1;
+}
+
+uint32_t iCap_GetClock(uint8_t devIndex)
+{
+    return HW_PWM_CAP_HZ;
+}
+
+void iCap_SetEdgeType(uint8_t devIndex, uint8_t channelIndex, ApiCap_EdgeType edge)
+{
+
+    switch (edge)
+    {
+    case ApiCap_NoneEdge:
+        Caps[devIndex].CapBase->Channel[channelIndex].Enable = 0;
+        break;
+    case ApiCap_RisingEdge:
+        Caps[devIndex].CapBase->Channel[channelIndex].Enable = 1;
+        Caps[devIndex].CapBase->Channel[channelIndex].Edge   = CaptureRisingEdge;
+        break;
+    case ApiCap_FallingEdge:
+        Caps[devIndex].CapBase->Channel[channelIndex].Enable = 1;
+        Caps[devIndex].CapBase->Channel[channelIndex].Edge   = CaptureFallingEdge;
+        break;
+    case ApiCap_BothEdge:
+        Caps[devIndex].CapBase->Channel[channelIndex].Enable = 1;
+        Caps[devIndex].CapBase->Channel[channelIndex].Edge   = CaptureRisingFallingEdge;
+        break;
+    default:
+        break;
+    }
+}
+
+void iCap_Enable(uint8_t devIndex)
+{
+    Caps[devIndex].CapBase->Base.Enable = 1;
+}
+
+void iCap_Disable(uint8_t devIndex)
+{
+    Caps[devIndex].CapBase->Base.Enable = 0;
+}
+
+void iCap_SetPeriod(uint8_t devIndex, uint32_t prd)
+{
+    Caps[devIndex].CapBase->CountMax = TICK_TRANS2(prd, iCap_GetClock(devIndex));
+}
+
+uint32_t iCap_GetPeriod(uint8_t devIndex)
+{
+    return INV_TICK_TRANS2(Caps[devIndex].CapBase->CountMax, iCap_GetClock(devIndex));
+}
+
+uint32_t iCap_GetCaptureValue(uint8_t devIndex, uint8_t channelIndex)
+{
+    return INV_TICK_TRANS2(Caps[devIndex].CapBase->Channel[channelIndex]._CapturedValue, iCap_GetClock(devIndex));
+}
+
+void iCap_EnableCaptureReset(uint8_t devIndex, uint8_t channelIndex)
+{
+    Caps[devIndex].CapBase->TimerResetEnable = 1;
+}
+
+void iCap_DisableCaptureReset(uint8_t devIndex, uint8_t channelIndex)
+{
+    Caps[devIndex].CapBase->TimerResetEnable = 0;
+}
+
+void iCap_EnableDeviceInterrupt(uint8_t devIndex)
+{
+    Caps[devIndex].CapBase->_CounterInterruptFlag  = 0;
+    Caps[devIndex].CapBase->CounterInterruptEnable = 1;
+}
+
+void iCap_DisableDeviceInterrupt(uint8_t devIndex)
+{
+    Caps[devIndex].CapBase->CounterInterruptEnable = 0;
+}
+
+void iCap_BindDeviceInterrupt(uint8_t devIndex, void (*action)())
+{
+    scheduler.InterruptBind(&scheduler, &Caps[devIndex].CapBase->Base, CaptureInterruptCounter, action);
+}
+
+void iCap_EnableChannelInterrupt(uint8_t devIndex, uint8_t channelIndex)
+{
+    Caps[devIndex].CapBase->Channel[channelIndex]._InterruptFlag  = 0;
+    Caps[devIndex].CapBase->Channel[channelIndex].InterruptEnable = 1;
+}
+
+void iCap_DisableChannelInterrupt(uint8_t devIndex, uint8_t channelIndex)
+{
+    Caps[devIndex].CapBase->Channel[channelIndex].InterruptEnable = 0;
+}
+
+void iCap_BindChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, void (*action)())
+{
+    scheduler.InterruptBind(&scheduler, &Caps[devIndex].CapBase->Base, CaptureInterruptOut1 + channelIndex, action);
+}

+ 25 - 0
tests/sim/sim_board/api_rt/api_rt_cap.h

@@ -0,0 +1,25 @@
+#ifndef _API_RT_CAP_H_
+#define _API_RT_CAP_H_
+
+#include <stdint.h>
+#include "api_rt_common.h"
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+typedef struct
+{
+    struct Sim_Capture *CapBase;
+} ApiRtCap_Handle;
+
+extern ApiRtCap_Handle Caps[1];
+
+void iRtCap_Init();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 21 - 0
tests/sim/sim_board/api_rt/api_rt_common.h

@@ -0,0 +1,21 @@
+#ifndef _API_RT_COMMON_H_
+#define _API_RT_COMMON_H_
+
+#include <stdint.h>
+#include "board_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+typedef struct
+{
+    uint8_t Enable;
+    void (*Action)();
+} ApiRt_Interrupt;
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 10 - 0
tests/sim/sim_board/api_rt/api_rt_dbg.c

@@ -0,0 +1,10 @@
+#include "api_rt_dbg.h"
+
+AssertFailRecord AssertRecord;
+
+void assert_fail(char *fileName, int lineNo)
+{
+    AssertRecord.LastFileName = fileName;
+    AssertRecord.LastLineNo   = lineNo;
+    AssertRecord.FailCount += 1;
+}

+ 47 - 0
tests/sim/sim_board/api_rt/api_rt_dbg.h

@@ -0,0 +1,47 @@
+#ifndef _API_RT_DBG_H_
+#define _API_RT_DBG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+// #define USE_ASSERT
+
+#ifdef USE_ASSERT
+#define ASSERT_EQ(X, Y)                      \
+    do                                       \
+    {                                        \
+        if (((X) != (Y)))                    \
+        {                                    \
+            assert_fail(__FILE__, __LINE__); \
+        }                                    \
+    } while (0)
+#define ASSERT_LESS(X, Y)                    \
+    do                                       \
+    {                                        \
+        if (((X) >= (Y)))                    \
+        {                                    \
+            assert_fail(__FILE__, __LINE__); \
+        }                                    \
+    } while (0)
+#else
+#define ASSERT_EQ(X, Y)
+#define ASSERT_LESS(X, Y)
+#endif
+
+typedef struct
+{
+    int   FailCount;
+    char *LastFileName;
+    int   LastLineNo;
+} AssertFailRecord;
+
+extern AssertFailRecord AssertRecord;
+
+void assert_fail(char *fileName, int lineNo);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 7 - 0
tests/sim/sim_board/api_rt/api_rt_delay.c

@@ -0,0 +1,7 @@
+#include "api_delay.h"
+
+void iDelay_Ms(uint32_t time)
+{}
+
+void iDelay_Us(uint32_t time)
+{}

+ 14 - 0
tests/sim/sim_board/api_rt/api_rt_delay.h

@@ -0,0 +1,14 @@
+#ifndef _API_RT_DELAY_H_
+#define _API_RT_DELAY_H_
+
+#include "api_delay.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 78 - 0
tests/sim/sim_board/api_rt/api_rt_fault.c

@@ -0,0 +1,78 @@
+#include "api_rt_common.h"
+#include "api_fault.h"
+#include "api_rt_fault.h"
+
+uint32_t FaultCode;
+uint8_t  NvmLockFlag;
+
+uint8_t SimNonVolatileMemory[0x1000];
+
+void iRtFaultLow_Init()
+{
+    FaultCode   = 0;
+    NvmLockFlag = 1;
+}
+
+uint32_t iFault_GetAll()
+{
+    return FaultCode;
+}
+
+void iFault_ClearAll()
+{
+    FaultCode = 0;
+}
+
+uint32_t iFault_GetBits(uint32_t mask)
+{
+    return FaultCode & mask;
+}
+
+void iFault_SetBits(uint32_t mask)
+{
+    FaultCode |= mask;
+}
+
+void iFault_ClearBits(uint32_t mask)
+{
+    FaultCode &= ~mask;
+}
+
+void iFault_UnlockNonVolatileMemory()
+{
+    NvmLockFlag = 0;
+}
+
+void iFault_LockNonVolatileMemory()
+{
+    NvmLockFlag = 1;
+}
+
+void iFault_WriteNonVolatileMemory(uint32_t offset, uint8_t length, void *ptr)
+{
+    if (!NvmLockFlag)
+    {
+        if (length == 8)
+        {
+            if (NVM_BASE_ADDRESS + offset + length <= NVM_MAX_ADDRESS)
+            {
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset]     = *(uint8_t *)ptr;
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 1] = *((uint8_t *)ptr + 1);
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 2] = *((uint8_t *)ptr + 2);
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 3] = *((uint8_t *)ptr + 3);
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 4] = *((uint8_t *)ptr + 4);
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 5] = *((uint8_t *)ptr + 5);
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 6] = *((uint8_t *)ptr + 6);
+                SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + 7] = *((uint8_t *)ptr + 7);
+            }
+        }
+    }
+}
+
+void iFault_ReadNonVolatileMemory(uint32_t offset, uint8_t length, uint8_t *buffer)
+{
+    for (int i = 0; i < length; i++)
+    {
+        *(buffer + i) = SimNonVolatileMemory[NVM_BASE_ADDRESS + offset + i];
+    }
+}

+ 17 - 0
tests/sim/sim_board/api_rt/api_rt_fault.h

@@ -0,0 +1,17 @@
+#ifndef _API_RT_FAULT_H_
+#define _API_RT_FAULT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define NVM_BASE_ADDRESS 0x0UL
+#define NVM_MAX_ADDRESS  0x400UL
+
+void iRtFaultLow_Init();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 65 - 0
tests/sim/sim_board/api_rt/api_rt_gpio.c

@@ -0,0 +1,65 @@
+#include "api_gpio.h"
+#include "api_rt_gpio.h"
+#include "api_rt_dbg.h"
+
+#include "board.h"
+
+ApiRtGpio_Handle Gpios[GPIO_PIN_COUNT];
+
+void iRtGpioLow_Init()
+{
+    Gpios[0].GpioBase = &ledPin;
+    Gpios[1].GpioBase = &capPin;
+    Gpios[2].GpioBase = &ledPin;
+}
+
+void iGpio_SetMode(uint16_t pin, ApiGpio_PinMode mode)
+{
+    ASSERT_LESS(pin, GPIO_PIN_COUNT);
+    ApiRtGpio_Handle *gpio = &Gpios[pin];
+
+    switch (mode)
+    {
+    case ApiGpio_Input:
+        gpio->GpioBase->Mode = GPIO_MODE_IN;
+        break;
+    case ApiGpio_Output:
+        gpio->GpioBase->Mode = GPIO_MODE_OUT;
+        break;
+    case ApiGpio_AlternateFunction:
+        gpio->GpioBase->Mode = GPIO_MODE_IN;
+        break;
+    default:
+        break;
+    }
+}
+
+ApiGpio_Level iGpio_Read(uint16_t pin)
+{
+    ASSERT_LESS(pin, GPIO_PIN_COUNT);
+    ApiRtGpio_Handle *gpio = &Gpios[pin];
+
+    ApiGpio_Level level = ApiGpio_LowLevel;
+
+    if (gpio->GpioBase->IORead == 1)
+    {
+        level = ApiGpio_HighLevel;
+    }
+
+    return level;
+}
+
+void iGpio_Write(uint16_t pin, ApiGpio_Level level)
+{
+    ASSERT_LESS(pin, GPIO_PIN_COUNT);
+    ApiRtGpio_Handle *gpio = &Gpios[pin];
+
+    if (level == ApiGpio_HighLevel)
+    {
+        gpio->GpioBase->IOWrite = 1;
+    }
+    else
+    {
+        gpio->GpioBase->IOWrite = 0;
+    }
+}

+ 27 - 0
tests/sim/sim_board/api_rt/api_rt_gpio.h

@@ -0,0 +1,27 @@
+#ifndef _API_RT_GPIO_H_
+#define _API_RT_GPIO_H_
+
+#include <stdint.h>
+#include "api_gpio.h"
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define GPIO_PIN_COUNT 3
+
+typedef struct
+{
+    struct Sim_Gpio *GpioBase;
+} ApiRtGpio_Handle;
+
+extern ApiRtGpio_Handle Gpios[GPIO_PIN_COUNT];
+
+void iRtGpioLow_Init();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 439 - 0
tests/sim/sim_board/api_rt/api_rt_pwm.c

@@ -0,0 +1,439 @@
+#include "api_rt_pwm.h"
+#include "api_rt_adc.h"
+#include "api_rt_dbg.h"
+
+#include "board.h"
+
+#include "isr.h"
+
+ApiRtPwm_Handle Pwms[1];
+
+void iRtPwm_AdcEocIsr()
+{
+    if (Pwms[0].PwmBase->CntDir == ApiPwm_CountUp)
+    {
+        Adcs[1].Results[Pwms[0].AdcTriggerIndex] = Pwms[0].AdcTriggerAdcBase->SamplingOutput[0];
+        Pwms[0].AdcTriggerIndex += 1;
+        if (Pwms[0].AdcTriggerIndex < Pwms[0].AdcTriggerUpCounts)
+        {
+            Pwms[0].AdcTriggerTimerBase->CompareReloadInput = Pwms[0].AdcTriggerUpTicks[Pwms[0].AdcTriggerIndex];
+        }
+        else
+        {
+            Pwms[0].AdcTriggerAdcBase->Base.Enable = 0;
+        }
+    }
+    else
+    {
+        Adcs[1].Results[Pwms[0].AdcTriggerIndex] = Pwms[0].AdcTriggerAdcBase->SamplingOutput[0];
+        Pwms[0].AdcTriggerIndex += 1;
+        if (Pwms[0].AdcTriggerIndex < Pwms[0].AdcTriggerDownCounts)
+        {
+            Pwms[0].AdcTriggerTimerBase->CompareReloadInput = Pwms[0].AdcTriggerDownTicks[Pwms[0].AdcTriggerIndex];
+        }
+        else
+        {
+            Pwms[0].AdcTriggerAdcBase->Base.Enable = 0;
+        }
+    }
+}
+
+void iRtPwm_Init()
+{
+    Pwms[0].PwmBase = &pwm;
+    for (int i = 0; i < 6; i++)
+    {
+        Pwms[0].CompareValues[i]       = 0;
+        Pwms[0].ActiveCompareValues[i] = 0;
+    }
+    Pwms[0].CountZeroISR.Enable = 0;
+    Pwms[0].CountZeroISR.Action = 0;
+    Pwms[0].CountMaxISR.Enable  = 0;
+    Pwms[0].CountMaxISR.Action  = 0;
+    Pwms[0].BreakISR.Enable     = 0;
+    Pwms[0].BreakISR.Action     = 0;
+    Pwms[0].OutputEnable        = 0;
+    for (int i = 0; i < 4; i++)
+    {
+        Pwms[0].ChannelISR[i].Enable = 0;
+        Pwms[0].ChannelISR[i].Action = 0;
+        // Pwms[0].ChannelOutputEnable[i] = 0;
+    }
+
+    scheduler.InterruptBind(&scheduler, &pwm.Base, PwmInterruptOutUpdate, iRtPwm_UpdateIsr);
+
+    Pwms[0].MultiSyncEnable                    = 0;
+    Pwms[0].AdcTriggerTimerBase                = &sampleTrigTimer2;
+    Pwms[0].AdcTriggerAdcBase                  = &adc2;
+    Pwms[0].AdcTriggerIndex                    = 0;
+    Pwms[0].AdcTriggerUpCounts                 = 1;
+    Pwms[0].AdcTriggerDownCounts               = 0;
+    Pwms[0].AdcTriggerUpTicks[0]               = HW_INIT_HHPWM_PERIOD;
+    Pwms[0].AdcTriggerDownTicks[0]             = 0;
+    Pwms[0].AdcTriggerAdcBase->EnableInterrupt = 1;
+    scheduler.InterruptBind(&scheduler, &Pwms[0].AdcTriggerAdcBase->Base, AdcInterruptOutEOC, iRtPwm_AdcEocIsr);
+
+    pwmLoadDma.SourceSize          = DMASixteenBit;
+    pwmLoadDma.SourceLength        = 6;
+    pwmLoadDma.SourceAddress       = Pwms[0].ActiveCompareValues;
+    pwmLoadDma.TargetSize          = DMAThirtytwoBit;
+    pwmLoadDma.TargetLength        = 3;
+    pwmLoadDma.TargetAddress       = Pwms[0].PwmBase->CmpValueInput;
+    pwmLoadDma.TransNum            = 3;
+    pwmLoadDma.SourceIncrementMode = 1;
+    pwmLoadDma.TargetIncrementMode = 1;
+    pwmLoadDma.Reset(&pwmLoadDma.Base);
+    pwmLoadDma.Transfer(&pwmLoadDma.Base);
+    scheduler.TriggerBind(&scheduler, &pwm.Base, PwmTriggerOutUpdate, &pwmLoadDma.Base, DMATriggerInTrans);
+}
+
+uint32_t iPwm_GetClock(uint8_t devIndex)
+{
+    return 64000000UL;
+}
+
+void iPwm_EnableCount(uint8_t devIndex)
+{}
+
+void iPwm_DisableCount(uint8_t devIndex)
+{}
+
+uint32_t iPwm_GetCountMax(uint8_t devIndex)
+{
+    return INV_TICK_TRANS(Pwms[devIndex].PwmBase->TotalCntNumCurrent);
+}
+
+void iPwm_SetCountMax(uint8_t devIndex, uint32_t countMax)
+{
+    Pwms[devIndex].PwmBase->TotalCntNumInput = TICK_TRANS(countMax);
+    sampleTrigTimer.CountReloadInput         = TICK_TRANS(countMax);
+    sampleTrigTimer2.CountReloadInput        = TICK_TRANS(countMax);
+}
+
+uint32_t iPwm_GetCount(uint8_t devIndex)
+{
+    return INV_TICK_TRANS(Pwms[devIndex].PwmBase->CntValue);
+}
+
+void iPwm_SetCount(uint8_t devIndex, uint32_t count)
+{
+    Pwms[devIndex].PwmBase->CntValue = TICK_TRANS(count);
+}
+
+ApiPwm_CountMode iPwm_GetCountMode(uint8_t devIndex)
+{
+    struct Sim_Pwm *base = Pwms[devIndex].PwmBase;
+
+    ApiPwm_CountMode res = ApiPwm_CountUp;
+
+    switch (base->CntMode)
+    {
+    case SIM_PWM_UP:
+        res = ApiPwm_CountUp;
+        break;
+#if API_FUNCTION_PWM_COUNTDOWN == API_SUPPORT
+    case SIM_PWM_DOWN:
+        res = ApiPwm_CountDown;
+        break;
+#endif
+    case SIM_PWM_UP_DOWN:
+        res = ApiPwm_CountUpDown;
+        break;
+    }
+
+    return res;
+}
+
+void iPwm_SetCountMode(uint8_t devIndex, ApiPwm_CountMode mode)
+{
+    struct Sim_Pwm *base = Pwms[devIndex].PwmBase;
+    switch (mode)
+    {
+    case ApiPwm_CountUp:
+        base->CntMode = SIM_PWM_UP;
+        break;
+#if API_FUNCTION_PWM_COUNTDOWN == API_SUPPORT
+    case ApiPwm_CountDown:
+        base->CntMode = SIM_PWM_DOWN;
+        break;
+#endif
+    case ApiPwm_CountUpDown:
+        base->CntMode = SIM_PWM_UP_DOWN;
+        break;
+    }
+}
+
+ApiPwm_CompareMode iPwm_GetCompareMode(uint8_t devIndex, uint8_t channelIndex)
+{
+    struct Sim_Pwm *base = Pwms[devIndex].PwmBase;
+
+    ApiPwm_CompareMode mode = ApiPwm_NoAction;
+    switch (base->PwmMode)
+    {
+    case SIM_PWM_PWMMODE1:
+        mode = ApiPwm_HigherClear;
+        break;
+    case SIM_PWM_PWMMODE2:
+        mode = ApiPwm_HigherSet;
+        break;
+    default:
+        mode = ApiPwm_NoAction;
+        break;
+    }
+    return mode;
+}
+
+void iPwm_SetCompareMode(uint8_t devIndex, uint8_t channelIndex, ApiPwm_CompareMode mode)
+{
+    struct Sim_Pwm *base = Pwms[devIndex].PwmBase;
+
+    switch (mode)
+    {
+    case ApiPwm_HigherSet:
+        base->PwmMode = SIM_PWM_PWMMODE2;
+        break;
+    case ApiPwm_HigherClear:
+        base->PwmMode = SIM_PWM_PWMMODE1;
+        break;
+    default:
+        break;
+    }
+}
+
+uint32_t iPwm_GetCompareValue(uint8_t devIndex, uint8_t channelIndex)
+{
+    struct Sim_Pwm *base = Pwms[devIndex].PwmBase;
+
+    uint32_t value = 0;
+
+    value = base->CmpValueCurrent[channelIndex];
+
+    return INV_TICK_TRANS(value);
+}
+
+void iPwm_SetCompareValue(uint8_t devIndex, uint8_t channelIndex, uint32_t value)
+{
+    ASSERT_LESS(devIndex, 1);
+    ASSERT_LESS(channelIndex, 3);
+    Pwms[devIndex].CompareValues[channelIndex] = TICK_TRANS(value);
+    Pwms[devIndex].CompareValues[channelIndex + 3] = TICK_TRANS(value);
+}
+
+void iPwm_SetCompareValueDelay(uint8_t devIndex, uint8_t channelIndex, uint32_t value)
+{
+    ASSERT_LESS(devIndex, 1);
+    ASSERT_LESS(channelIndex, 3);
+    Pwms[devIndex].CompareValues[channelIndex + 3] = TICK_TRANS(value);
+}
+
+void iPwm_SetCompareGroupValues16(uint8_t devIndex, uint16_t* values)
+{
+    for (int i = 0; i < 6; i++)
+    {
+        Pwms[devIndex].CompareValues[i] = TICK_TRANS(values[i]);
+    }
+}
+
+void iPwm_SetCompareValueImmediate(uint8_t devIndex, uint8_t channelIndex, uint32_t value)
+{
+    ASSERT_LESS(devIndex, 1);
+    ASSERT_LESS(channelIndex, 4);
+
+    Pwms[devIndex].PwmBase->CmpValueCurrent[channelIndex] = TICK_TRANS(value);
+}
+
+int8_t iPwm_GetEnableState(uint8_t devIndex)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    return Pwms[devIndex].OutputEnable;
+}
+
+void iPwm_EnableOutput(uint8_t devIndex)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    Pwms[devIndex].PwmBase->BridgeOffFlag[0] = 0;
+    Pwms[devIndex].PwmBase->BridgeOffFlag[1] = 0;
+    Pwms[devIndex].PwmBase->BridgeOffFlag[2] = 0;
+
+    Pwms[devIndex].OutputEnable = 1;
+}
+
+void iPwm_DisableOutput(uint8_t devIndex)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    Pwms[devIndex].PwmBase->BridgeOffFlag[0] = 1;
+    Pwms[devIndex].PwmBase->BridgeOffFlag[1] = 1;
+    Pwms[devIndex].PwmBase->BridgeOffFlag[2] = 1;
+
+    Pwms[devIndex].OutputEnable = 0;
+}
+
+void iPwm_EnableDeviceInterrupt(uint8_t devIndex, ApiPwm_DeviceInterrupt interrupt)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    switch (interrupt)
+    {
+    case ApiPwm_CountZeroInt:
+        Pwms[devIndex].CountZeroISR.Enable = 1;
+        break;
+    case ApiPwm_CountMaxInt:
+        Pwms[devIndex].CountMaxISR.Enable = 1;
+        break;
+    case ApiPwm_BreakInt:
+        Pwms[devIndex].BreakISR.Enable = 1;
+        break;
+    default:
+        break;
+    }
+}
+
+void iPwm_DisableDeviceInterrupt(uint8_t devIndex, ApiPwm_DeviceInterrupt interrupt)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    switch (interrupt)
+    {
+    case ApiPwm_CountZeroInt:
+        Pwms[devIndex].CountZeroISR.Enable = 0;
+        break;
+    case ApiPwm_CountMaxInt:
+        Pwms[devIndex].CountMaxISR.Enable = 0;
+        break;
+    case ApiPwm_BreakInt:
+        Pwms[devIndex].BreakISR.Enable = 0;
+        break;
+    default:
+        break;
+    }
+}
+
+void iPwm_EnableChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, ApiPwm_ChannelInterrupt interrupt)
+{
+    ASSERT_LESS(devIndex, 1);
+    ASSERT_LESS(channelIndex, 4);
+
+    Pwms[devIndex].ChannelISR[channelIndex].Enable = 1;
+}
+
+void iPwm_DisableChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, ApiPwm_ChannelInterrupt interrupt)
+{
+    ASSERT_LESS(devIndex, 1);
+    ASSERT_LESS(channelIndex, 4);
+
+    Pwms[devIndex].ChannelISR[channelIndex].Enable = 0;
+}
+
+void iPwm_BindDeviceInterrupt(uint8_t devIndex, ApiPwm_DeviceInterrupt interrupt, void (*action)())
+{
+    ASSERT_LESS(devIndex, 1);
+
+    switch (interrupt)
+    {
+    case ApiPwm_CountZeroInt:
+        Pwms[devIndex].CountZeroISR.Action = action;
+        break;
+    case ApiPwm_CountMaxInt:
+        Pwms[devIndex].CountMaxISR.Action = action;
+        break;
+    case ApiPwm_BreakInt:
+        Pwms[devIndex].BreakISR.Action = action;
+        break;
+    default:
+        break;
+    }
+}
+
+void iPwm_BindChannelInterrupt(uint8_t devIndex, uint8_t channelIndex, ApiPwm_DeviceInterrupt interrupt, void (*action)())
+{
+    ASSERT_LESS(devIndex, 1);
+    ASSERT_LESS(channelIndex, 4);
+
+    Pwms[devIndex].ChannelISR[channelIndex].Action = action;
+}
+
+int8_t iPwm_GetBreakState(uint8_t devIndex)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    return Pwms[devIndex].PwmBase->BreakFlag;
+}
+
+void iPwm_ClearBreak(uint8_t devIndex)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    Pwms[devIndex].PwmBase->BreakFlag = 0;
+}
+
+void iPwm_EnableSyncMultiSampling(uint8_t devIndex)
+{
+    Pwms[devIndex].MultiSyncEnable = 1;
+}
+
+void iPwm_DisableSyncMultiSampling(uint8_t devIndex)
+{
+    Pwms[devIndex].MultiSyncEnable = 0;
+}
+
+void iPwm_SyncMultiSamplingCountUp(uint8_t devIndex, uint32_t samplingTicks[], uint8_t samplingCounts)
+{
+    Pwms[devIndex].AdcTriggerUpCounts = samplingCounts;
+    for (int i = 0; i < samplingCounts; i++)
+    {
+        Pwms[devIndex].AdcTriggerUpTicks[i] = TICK_TRANS(samplingTicks[i]);
+    }
+}
+
+void iPwm_SyncMultiSamplingCountDown(uint8_t devIndex, uint32_t samplingTicks[], uint8_t samplingCounts)
+{
+    Pwms[devIndex].AdcTriggerDownCounts = samplingCounts;
+    for (int i = 0; i < samplingCounts; i++)
+    {
+        Pwms[devIndex].AdcTriggerDownTicks[i] = TICK_TRANS(samplingTicks[i]);
+    }
+}
+
+void iRtPwm_ActivateCompareValues(uint8_t devIndex)
+{
+    ASSERT_LESS(devIndex, 1);
+
+    for (int i = 0; i < 6; i++)
+    {
+        Pwms[devIndex].ActiveCompareValues[i] = Pwms[devIndex].CompareValues[i];
+    }
+}
+
+void iRtPwm_UpdateIsr()
+{
+    if (Pwms[0].PwmBase->CntDir == SIM_PWM_DIR_UP)
+    {
+        if (Pwms[0].MultiSyncEnable == 1 && Pwms[0].AdcTriggerUpCounts > 0)
+        {
+            Pwms[0].AdcTriggerIndex                         = 0;
+            Pwms[0].AdcTriggerTimerBase->CompareReloadInput = Pwms[0].AdcTriggerUpTicks[0];
+            Pwms[0].AdcTriggerAdcBase->Base.Enable          = 1;
+        }
+        if (Pwms[0].CountZeroISR.Enable && Pwms[0].CountZeroISR.Action != 0)
+        {
+            Pwms[0].CountZeroISR.Action();
+        }
+    }
+    else if (Pwms[0].PwmBase->CntDir == SIM_PWM_DIR_DOWN)
+    {
+        if (Pwms[0].MultiSyncEnable == 1 && Pwms[0].AdcTriggerDownCounts > 0)
+        {
+            Pwms[0].AdcTriggerIndex                         = 0;
+            Pwms[0].AdcTriggerTimerBase->CompareReloadInput = Pwms[0].AdcTriggerDownTicks[0];
+            Pwms[0].AdcTriggerAdcBase->Base.Enable          = 1;
+        }
+        if (Pwms[0].CountMaxISR.Enable && Pwms[0].CountMaxISR.Action != 0)
+        {
+            Pwms[0].CountMaxISR.Action();
+        }
+        iRtPwm_ActivateCompareValues(0);
+    }
+}

+ 43 - 0
tests/sim/sim_board/api_rt/api_rt_pwm.h

@@ -0,0 +1,43 @@
+#ifndef _API_RT_PWM_H_
+#define _API_RT_PWM_H_
+
+#include <stdint.h>
+#include "api_rt_common.h"
+#include "api_pwm.h"
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+typedef struct
+{
+    struct Sim_Pwm   *PwmBase;
+    uint16_t          CompareValues[6];
+    uint16_t          ActiveCompareValues[6];
+    ApiRt_Interrupt   CountZeroISR;
+    ApiRt_Interrupt   CountMaxISR;
+    ApiRt_Interrupt   BreakISR;
+    ApiRt_Interrupt   ChannelISR[4];
+    int8_t            OutputEnable;
+    uint8_t           MultiSyncEnable;
+    struct Sim_Timer *AdcTriggerTimerBase;
+    uint8_t           AdcTriggerIndex;
+    uint8_t           AdcTriggerUpCounts;
+    uint32_t          AdcTriggerUpTicks[8];
+    uint8_t           AdcTriggerDownCounts;
+    uint32_t          AdcTriggerDownTicks[8];
+    struct Sim_Adc   *AdcTriggerAdcBase;
+} ApiRtPwm_Handle;
+
+extern ApiRtPwm_Handle Pwms[1];
+
+void iRtPwm_Init();
+
+void iRtPwm_ActivateCompareValues(uint8_t devIndex);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 153 - 0
tests/sim/sim_board/api_rt/api_rt_test_probe.c

@@ -0,0 +1,153 @@
+#include "api_rt_common.h"
+#include "api_rt_test_probe.h"
+
+ApiRtProbe_Handle Probe;
+
+void iRtProbe_Init()
+{
+    for (int i = 0; i < INJ_POINT_MAX; i++)
+    {
+        Probe.InjectionPoints[i].Enable   = 0;
+        Probe.InjectionPoints[i].HasValue = 0;
+        Probe.InjectionPoints[i].Value    = 0;
+    }
+
+    for (int i = 0; i < TEST_POINT_MAX; i++)
+    {
+        Probe.TestPoints[i].HasValue = 0;
+        Probe.TestPoints[i].Value    = 0;
+    }
+}
+
+void iRtProbe_TransInjectionData(uint16_t index, double value)
+{
+    Probe.InjectionPoints[index].HasValue = 1;
+    Probe.InjectionPoints[index].Value    = value;
+}
+
+void iRtProbe_ControlInjectionPoint(uint16_t index, uint32_t en)
+{
+    Probe.InjectionPoints[index].Enable = en;
+}
+
+double iRtProbe_TransTestData(uint16_t index)
+{
+    if (Probe.TestPoints[index].HasValue)
+    {
+        return Probe.TestPoints[index].Value;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+void iProbe_InjectInt8(void *p, uint16_t id, uint8_t sign)
+{
+    int8_t  val;
+    uint8_t uval;
+
+    if (!(Probe.InjectionPoints[id].Enable && Probe.InjectionPoints[id].HasValue))
+    {
+        return;
+    }
+
+    if (sign)
+    {
+        val          = (int8_t)(Probe.InjectionPoints[id].Value);
+        *(int8_t *)p = val;
+    }
+    else
+    {
+        uval          = (uint8_t)(Probe.InjectionPoints[id].Value);
+        *(uint8_t *)p = uval;
+    }
+}
+
+void iProbe_InjectInt16(void *p, uint16_t id, uint8_t sign)
+{
+    int16_t  val;
+    uint16_t uval;
+
+    if (!(Probe.InjectionPoints[id].Enable && Probe.InjectionPoints[id].HasValue))
+    {
+        return;
+    }
+
+    if (sign)
+    {
+        val           = (int16_t)(Probe.InjectionPoints[id].Value);
+        *(int16_t *)p = val;
+    }
+    else
+    {
+        uval           = (uint16_t)(Probe.InjectionPoints[id].Value);
+        *(uint16_t *)p = uval;
+    }
+}
+
+void iProbe_InjectInt32(void *p, uint16_t id, uint8_t sign)
+{
+    int32_t  val;
+    uint32_t uval;
+
+    if (!(Probe.InjectionPoints[id].Enable && Probe.InjectionPoints[id].HasValue))
+    {
+        return;
+    }
+
+    if (sign)
+    {
+        val           = (int32_t)(Probe.InjectionPoints[id].Value);
+        *(int32_t *)p = val;
+    }
+    else
+    {
+        uval           = (uint32_t)(Probe.InjectionPoints[id].Value);
+        *(uint32_t *)p = uval;
+    }
+}
+
+void iProbe_InjectFloat32(float *p, uint16_t id)
+{
+    float val;
+
+    if (!(Probe.InjectionPoints[id].Enable && Probe.InjectionPoints[id].HasValue))
+    {
+        return;
+    }
+
+    val = Probe.InjectionPoints[id].Value;
+    *p  = val;
+}
+
+void iProbe_InjectFloat64(float *p, uint16_t id)
+{
+    double val;
+
+    if (!(Probe.InjectionPoints[id].Enable && Probe.InjectionPoints[id].HasValue))
+    {
+        return;
+    }
+
+    val = Probe.InjectionPoints[id].Value;
+    *p  = val;
+}
+
+void iProbe_ReadInt32(int32_t v, uint16_t id)
+{
+    Probe.TestPoints[id].Value    = v;
+    Probe.TestPoints[id].HasValue = 1;
+}
+
+void iProbe_ReadUint32(uint32_t v, uint16_t id)
+{
+    Probe.TestPoints[id].Value    = v;
+    Probe.TestPoints[id].HasValue = 1;
+}
+
+void iProbe_ReadFloat64(double v, uint16_t id)
+{
+    Probe.TestPoints[id].Value    = v;
+    Probe.TestPoints[id].HasValue = 1;
+}

+ 49 - 0
tests/sim/sim_board/api_rt/api_rt_test_probe.h

@@ -0,0 +1,49 @@
+#ifndef _API_RT_TEST_PROBE_H_
+#define _API_RT_TEST_PROBE_H_
+
+#include <stdint.h>
+#include "api_rt_common.h"
+#include "api_test_probe.h"
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define INJ_POINT_MAX  256
+#define TEST_POINT_MAX 256
+
+typedef struct
+{
+    uint8_t Enable;
+    uint8_t HasValue;
+    double  Value;
+} ApiRtProbe_InjectionPoint;
+
+typedef struct
+{
+    uint8_t HasValue;
+    double  Value;
+} ApiRtProbe_TestPoint;
+
+typedef struct
+{
+    ApiRtProbe_InjectionPoint InjectionPoints[INJ_POINT_MAX];
+    ApiRtProbe_TestPoint      TestPoints[TEST_POINT_MAX];
+} ApiRtProbe_Handle;
+
+extern ApiRtProbe_Handle Probe;
+
+void iRtProbe_Init();
+
+void iRtProbe_TransInjectionData(uint16_t index, double value);
+
+void iRtProbe_ControlInjectionPoint(uint16_t index, uint32_t en);
+
+double iRtProbe_TransTestData(uint16_t index);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 69 - 0
tests/sim/sim_board/api_rt/api_rt_timer.c

@@ -0,0 +1,69 @@
+#include "api_rt_timer.h"
+#include "api_rt_dbg.h"
+
+#include "board.h"
+
+ApiRtTimer_Handle Timers[GENERAL_TIMER_COUNT + 1];
+
+void iRtTimer_Init()
+{
+    Timers[0].TimerBase = &tbsTick;
+
+    Timers[1].TimerBase = &sysTick;
+}
+
+uint32_t iTimer_GetClock(uint8_t devIndex)
+{
+    return 64000000UL;
+}
+
+void iTimer_Start(uint8_t devIndex)
+{
+    Timers[devIndex].TimerBase->Base.Enable = 1;
+}
+
+void iTimer_Stop(uint8_t devIndex)
+{
+    Timers[devIndex].TimerBase->Base.Enable = 0;
+}
+
+void iTimer_EnableAutoReload(uint8_t devIndex)
+{}
+
+void iTimer_DisableAutoReload(uint8_t devIndex)
+{}
+
+uint32_t iTimer_GetPeriod(uint8_t devIndex)
+{
+    return INV_TICK_TRANS(Timers[devIndex].TimerBase->_CountReloadValue);
+}
+
+void iTimer_SetPeriod(uint8_t devIndex, uint32_t ticks)
+{
+    Timers[devIndex].TimerBase->_CountReloadValue = TICK_TRANS(ticks);
+}
+
+uint32_t iTimer_GetCount(uint8_t devIndex)
+{
+    return INV_TICK_TRANS(Timers[devIndex].TimerBase->_CountValue);
+}
+
+void iTimer_Reset(uint8_t devIndex)
+{
+    Timers[devIndex].TimerBase->TimerReset(&Timers[devIndex].TimerBase->Base);
+}
+
+void iTimer_BindInterrupt(uint8_t devIndex, void (*action)())
+{
+    scheduler.InterruptBind(&scheduler, &Timers[devIndex].TimerBase->Base, TimerInterruptOutUIF, action);
+}
+
+void iTimer_EnableInterrupt(uint8_t devIndex)
+{
+
+}
+
+void iTimer_DisableInterrupt(uint8_t devIndex)
+{
+
+}

+ 29 - 0
tests/sim/sim_board/api_rt/api_rt_timer.h

@@ -0,0 +1,29 @@
+#ifndef _API_RT_TIMER_H_
+#define _API_RT_TIMER_H_
+
+#include <stdint.h>
+#include "api_rt_common.h"
+#include "api_timer.h"
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define GENERAL_TIMER_COUNT     1
+#define SYSTEM_TICK_TIMER_INDEX GENERAL_TIMER_COUNT
+
+typedef struct
+{
+    struct Sim_Timer *TimerBase;
+} ApiRtTimer_Handle;
+
+extern ApiRtTimer_Handle Timers[GENERAL_TIMER_COUNT + 1];
+
+void iRtTimer_Init();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 50 - 0
tests/sim/sim_board/api_rt/api_rt_uart.c

@@ -0,0 +1,50 @@
+#include "api_rt_uart.h"
+#include "api_rt_dbg.h"
+
+ApiRtUart_Handle Uarts[1];
+
+uint8_t rxBuffer[UART_BUFFER_LENGTH];
+uint8_t txBuffer[UART_BUFFER_LENGTH];
+
+void iRtUart_Init()
+{}
+
+void iUart_Open(uint8_t devIndex, uint32_t baudrate)
+{}
+
+void iUart_Close(uint8_t devIndex)
+{}
+
+ApiUart_Status iUart_GetStatus(uint8_t devIndex)
+{
+    return ApiUart_Idle;
+}
+
+int16_t iUart_Available(uint8_t devIndex)
+{
+    return 0;
+}
+
+int16_t iUart_GetWriteBufferSpace(uint8_t devIndex)
+{
+    return 0;
+}
+
+int16_t iUart_Read(uint8_t devIndex, uint8_t *data, int16_t count)
+{
+    return 0;
+}
+
+int16_t iUart_Write(uint8_t devIndex, uint8_t *data, int16_t count)
+{
+    return 0;
+}
+
+void iUart_ReadAsync(uint8_t devIndex, uint8_t *data, uint8_t count, void (*cplt)(uint8_t *data, int16_t count), void (*error)())
+{}
+
+void iUart_WriteAsync(uint8_t devIndex, uint8_t *data, uint8_t count, void (*cplt)(), void (*error)())
+{}
+
+void iRtUart0_RxISR()
+{}

+ 43 - 0
tests/sim/sim_board/api_rt/api_rt_uart.h

@@ -0,0 +1,43 @@
+#ifndef _API_RT_UART_H_
+#define _API_RT_UART_H_
+
+#include <stdint.h>
+#include "api_rt_common.h"
+#include "api_uart.h"
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define UART_BUFFER_LENGTH 64
+
+typedef struct
+{
+    ApiUart_Status Status;
+    uint8_t       *RxBuffer;
+    uint16_t       RxBufferHead;
+    uint16_t       RxBufferTail;
+    uint8_t       *TxBuffer;
+    uint16_t       TxBufferCount;
+
+    void (*AsyncWriteCompleteCallback)();
+    void (*AsyncWriteErrorCallback)();
+    void (*AsyncReadCompleteCallback)(uint8_t *data, int16_t count);
+    void (*AsyncReadErrorCallback)();
+
+    int16_t  AsyncReadCount;
+    uint8_t *AsyncReadAddr;
+} ApiRtUart_Handle;
+
+extern ApiRtUart_Handle Uarts[1];
+
+void iRtUart_Init();
+
+void iRtUart0_RxISR();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif

+ 18 - 0
tests/sim/sim_board/include/board.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#define TICK_TRANS(X)     ((X) / BoardSampleTimeFactor)
+#define INV_TICK_TRANS(X) ((X)*BoardSampleTimeFactor)
+
+#define TICK_TRANS2(X, CLOCK)     ((long)((X) / ((CLOCK) / BoardSampleRate)))
+#define INV_TICK_TRANS2(X, CLOCK) ((long)((X) * ((CLOCK) / BoardSampleRate)))
+
+#include "mcu_instance.h"
+
+extern double WatchBuffer[16];
+extern double ControlBuffer[4];
+
+extern double BoardSampleTime;
+extern double BoardSampleRate;
+extern int    BoardSampleTimeFactor;
+
+void BoardInit(double ts);

+ 15 - 0
tests/sim/sim_board/include/isr.h

@@ -0,0 +1,15 @@
+#pragma once
+
+void iRtPwm_UpdateIsr();
+
+void TbsTimerIsr();
+
+void CapIsr();
+
+void UartIsr();
+
+void DmaIsr();
+
+void SystickIsr();
+
+void CaptureIsr();

+ 16 - 0
tests/sim/sim_board/include/mcu_instance.h

@@ -0,0 +1,16 @@
+#pragma once
+#include "sim_mcu.h"
+
+extern struct Sim_Scheduler scheduler;
+extern struct Sim_Pwm       pwm;
+extern struct Sim_Adc       adc;
+extern struct Sim_Adc       adc2;
+extern struct Sim_Gpio      ledPin;
+extern struct Sim_Gpio      capPin;
+extern struct Sim_Gpio      breakPin;
+extern struct Sim_Timer     sysTick;
+extern struct Sim_Timer     tbsTick;
+extern struct Sim_Timer     sampleTrigTimer;
+extern struct Sim_Timer     sampleTrigTimer2;
+extern struct Sim_DMA       pwmLoadDma;
+extern struct Sim_Capture   inputCap;

+ 12 - 0
tests/sim/sim_board/include/sfun_wrapper.h

@@ -0,0 +1,12 @@
+#pragma once
+
+#include "sim_mcu.h"
+
+typedef struct
+{
+    double  data;
+    int32_t enable;
+} injection_dtype;
+
+void McuInit(double ts);
+void McuRun(const double *ain, const int32_t *din, const injection_dtype *ctrl, double *aout, int *dout, double *watchOut);

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott