From 7a3dd9fb891260ee5426d619e9fb78b643c675b4 Mon Sep 17 00:00:00 2001 From: Janosch Date: Tue, 11 Oct 2022 11:45:51 +0100 Subject: [PATCH] moving definition to charger.cpp --- Makefile | 5 +- include/charger.h | 143 +++------------------------------------- libopeninv/libopeninv.a | Bin 40872 -> 47178 bytes src/charger.cpp | 136 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 2 +- test/test.out | Bin 53696 -> 51480 bytes test/test_logic.h | 1 + 7 files changed, 150 insertions(+), 137 deletions(-) create mode 100644 src/charger.cpp diff --git a/Makefile b/Makefile index 44ce955..67d1481 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ LDFLAGS = -Llibopencm3/lib -T$(LDSCRIPT) -march=armv7 -nostartfiles -Wl,--gc- OBJSL = main.o hwinit.o stm32scheduler.o params.o terminal.o terminal_prj.o \ my_string.o digio.o sine_core.o my_fp.o printf.o anain.o \ param_save.o errormessage.o stm32_can.o \ - picontroller.o terminalcommands.o chargercan.o + picontroller.o terminalcommands.o chargercan.o charger.o OBJS = $(patsubst %.o,obj/%.o, $(OBJSL)) vpath %.c src/ libopeninv/src @@ -125,10 +125,11 @@ Test: g++ -c -Ilibopeninv/include/ -Iinclude -o params.o libopeninv/src/params.cpp g++ -c -Ilibopeninv/include/ -Iinclude -o errormessage.o libopeninv/src/errormessage.cpp g++ -c -Ilibopeninv/include/ -Iinclude -o printf.o libopeninv/src/printf.cpp + g++ -c -Ilibopeninv/include/ -Iinclude -o charger.o src/charger.cpp -D TEST_COMMON_H g++ -c -Ilibopeninv/include/ -Iinclude -o digio_mock.o test/digio_mock.cpp g++ -c -Ilibopeninv/include/ -Iinclude -o timer_mock.o test/timer_mock.cpp ar rcs libopeninv/libopeninv.a *.o - rm -f my_fp.o my_string.o params.o errormessage.o printf.o digio_mock.o timer_mock.o chademo.o terminal.o + rm -f my_fp.o my_string.o params.o errormessage.o printf.o digio_mock.o timer_mock.o terminal.o g++ -gdwarf-2 -g test/test.c -Llibopeninv -Iinclude -lopeninv -o test/test.out && gdb -ex='set confirm on' -ex=run -ex=quit --args ./test/test.out cleanTest: cd test && $(MAKE) clean diff --git a/include/charger.h b/include/charger.h index 73d6477..3e3e47b 100644 --- a/include/charger.h +++ b/include/charger.h @@ -1,136 +1,11 @@ +#ifndef CHARGER_H +#define CHARGER_H #include "../libopeninv/include/params.h" -#ifdef TEST_COMMON_H -#include "../test/digio_mock.h" -#include "../test/timer_mock.h" -#else -#include -#include +extern uint32_t startTime; +bool IsEvseInput(); +bool CheckUnplugged(); +bool CheckTimeout(); +void CalcTotals(); +void DisableAll(); +void EvseRead(); #endif - -static bool IsEvseInput(); -static void DisableAll(); - -static bool IsEvseInput() -{ - enum inputs input = (enum inputs)Param::GetInt(Param::inputype); - return input == INP_TYPE1 || input == INP_TYPE2 || input == INP_TYPE2_3P || input == INP_TYPE2_AUTO; -} - -static bool CheckUnplugged() -{ - return IsEvseInput() && !Param::GetBool(Param::proximity); -} - -static void DisableAll() -{ - DigIo::hvena_out.Clear(); - DigIo::acpres_out.Clear(); - DigIo::evseact_out.Clear(); - DigIo::ch1act_out.Clear(); - DigIo::ch2act_out.Clear(); - DigIo::ch2act_out.Clear(); - DigIo::ch1ena_out.Clear(); - DigIo::ch2ena_out.Clear(); - DigIo::ch3ena_out.Clear(); -} - -static void CalcTotals() -{ - s32fp totalCurrent = Param::Get(Param::c1idc) + Param::Get(Param::c2idc) + Param::Get(Param::c3idc); - - Param::SetFixed(Param::idc, totalCurrent); - s32fp u1 = Param::Get(Param::c1udc); - s32fp u2 = Param::Get(Param::c2udc); - s32fp u3 = Param::Get(Param::c3udc); - - s32fp udcmax = MAX(u1, MAX(u2, u3)); - Param::SetFixed(Param::udc, udcmax); -} - -static uint32_t startTime; -static bool CheckTimeout() -{ - uint32_t now = rtc_get_counter_val(); - uint32_t timeout = Param::GetInt(Param::timelim); - - timeout *= 60; - - return timeout > 0 && (now - startTime) > timeout; -} - -static void EvseRead() -{ - const int threshProxType1 = 2200; - const int threshProx = 3700; - const int thresh13A = 3200; - const int thresh20A = 2800; - const int thresh32A = 1800; - const int thresh63A = 1000; - int val = AnaIn::cablelim.Get(); - - if (timer_get_flag(TIM3, TIM_SR_CC2IF)) - { - //The relationship between duty cycle and maximum current is linear - //until 85% = 51A. Above that it becomes non-linear but that is not - //relevant for our 10kW charger. - float evselim = timer_get_ic_value(TIM3, TIM_IC2) / 10; - evselim *= 0.666666f; - Param::SetFloat(Param::evselim, evselim); - } - else - { - //If no PWM detected, set limit to 0 - Param::SetInt(Param::evselim, 0); - } - - if (Param::GetInt(Param::inputype) == INP_TYPE2 || - Param::GetInt(Param::inputype) == INP_TYPE2_3P || - Param::GetInt(Param::inputype) == INP_TYPE2_AUTO) - { - if (val > threshProx) - { - Param::SetInt(Param::proximity, 0); - Param::SetInt(Param::cablelim, 0); - } - else - { - Param::SetInt(Param::proximity, 1); - - if (val > thresh13A) - { - Param::SetInt(Param::cablelim, 13); - } - else if (val > thresh20A) - { - Param::SetInt(Param::cablelim, 20); - } - else if (val > thresh32A) - { - Param::SetInt(Param::cablelim, 32); - } - else if (val > thresh63A) - { - Param::SetInt(Param::cablelim, 63); - } - } - } - else if (Param::GetInt(Param::inputype) == INP_TYPE1) - { - if (val > threshProxType1) - { - Param::SetInt(Param::proximity, 0); - Param::SetInt(Param::cablelim, 0); - } - else - { - Param::SetInt(Param::proximity, 1); - Param::SetInt(Param::cablelim, 40); - } - } - else - { - Param::SetInt(Param::proximity, 0); - Param::SetInt(Param::cablelim, 32); - } -} - diff --git a/libopeninv/libopeninv.a b/libopeninv/libopeninv.a index 6dcafb097fa7a2ee9a2966a610b85ef5212f1a21..b70a1ca31336101d1d6638c8cd8d4e6121c1dc40 100644 GIT binary patch delta 4364 zcmcIneQZ-z6uM;2xp_;K6Yr_Bv-Ko+MSWW+*r{!0 zgw%zDf$*Xgp$H#WR|mSZtzDr&xMNF%2-S=0H;0<;S|9Fc+tSh!YUWr~Lu*&?_O?)6 zTbnVi54JU}YmWrmy7>5VZnLiS?ohiiOAXGMA8HH*(VjK8wzRgxt9$34m}TpED!*xS zu(Ku9S=qi2!vqwY*RrIlrV0l4R_VSAF=R~f@z%!*Spie9KMf1DIatOW?qAmXqhI-Z zMx6-)hOw}yHrca%QjHX1%_4bNE0Juhty`wOPL?Cq*NOJ_8DY+?cJ@U|5-!At8O9Fl z8B-8RGuW6k@IQ7n&A{#chrZ6_N#m(?ug8PVNz4{YN6#b{ioS9tQIqU{6xBY9X`e;U zCW-`>m?e5qZ7@-p8Vn_trUt_?ZRjdZAMUndXCy184PT`VZY$)d3FaV3n!%_x8q-E` zjp@QZ?(cbP&dsUq(zTd3GLgs@EWDnWHhEWHt#MB*QW~?Oj>Xnb%sm|)Sf)+tU1@$# zT@+5}>DLDL8_zK2seA6&Wy|57 zMf0I*PQ!*`oQr98=PtEAKYLZ)G~6+pfu)vk6mnEjzcQu2g>V$|L{h&srQZfy)|Bhd zkQU`$s>CX4nA1E6y+Jt2%Tx)y){~_kO3gG#I+V3k368oVIR}3aQRP-8eb#gp3Gk+^ z3p4g0s!Z-9T>GM_Z8uTw8SJ0pGYs(h8(yF1bupZ~-lZ(y zbpx+&rnAod^PoaZ>_w8?prJ`oh|L2N(dobRYE`^n@CnH=s#v$waQ!9Vvz8S6F7?8_)|vU$a`J`R zyd~gN%i!z01#l?uO4LfJ7`{K?fj6vPM|FBahQxu3=5|Gboe@gWxJ63OW_C{gB&cbk z4ByszH{?ED58qfT;E1(EC+DHJ4WWmW`jh7k@k_W@pu!su?l(~ zaeVxe{9QaFBR~f9&IyAU_DQB1JYm3`UxIzX-)rJi`3EI_slWM!wVD6zZ> zluHIy^Q$2P8866y&ysMDG|xf_m*=VFxNe+4Rs=E_?3QqOfx{ABAuar}gv&vF*2F31 zytsbSMP-DbP(weegzG9yoIK%>@Wm2NKivd>g@j)!;q?lu)`Qj2jSHcfSxO~8)8SvLK;KK&4^H`D>_(?L5@e9l>K@O2|ZwB0#0pFO0<5h?g zcc&>*_#+Z7pZFySmp61O1ODzG;VbbbKK&yF;-eYxUo+q^e|If(xGmtBms79<-9$p( zq_P}>EiR=Up55)bT;#YRBA^J4$ZHlUSV=deK)9x6aU^tKr1JNF|0i;N!>V*+kY= z;aqD?5&kwMxsm^-HfUK;?U|=GS}@xdL)=~j$M+P8q0{b!<9Fu3k9(Z9Msvkt$d8vR z0r+l@OWkaNgPvlT5qBz^pw8=3w^?A#iegx6cPcG#*zQtyTEJZ~Tj_u=ad6yN1ZP!t zz$Fe29ITiPzGp4a;4R7>FqiNsV1L4`0Q}JEvJDg%d+vi--Wr>^@v$tp!@I;bXft#G RtM)Fn#VOuUUI4{j{u>5z&p-eG delta 360 zcmX^0foa8lrU{nyMn)zIV35GYz`zj5z`*f^d@P{Az(5+VhiFh?VPHVU`W6ff#9$j0 g1_p|7DA0i157fca*Dx?Z@a8p)>Fk?la&Dal01!7sfB*mh diff --git a/src/charger.cpp b/src/charger.cpp new file mode 100644 index 0000000..018ad5e --- /dev/null +++ b/src/charger.cpp @@ -0,0 +1,136 @@ +#include "my_math.h" +#include "charger.h" +#ifdef TEST_COMMON_H +#include "../test/test_common.h" +#include "../test/digio_mock.h" +#include "../test/timer_mock.h" +#else +#include "digio.h" +#include "anain.h" +#include +#include +#endif + +bool IsEvseInput() +{ + enum inputs input = (enum inputs)Param::GetInt(Param::inputype); + return input == INP_TYPE1 || input == INP_TYPE2 || input == INP_TYPE2_3P || input == INP_TYPE2_AUTO; +} + +bool CheckUnplugged() +{ + return IsEvseInput() && !Param::GetBool(Param::proximity); +} + +void DisableAll() +{ + DigIo::hvena_out.Clear(); + DigIo::acpres_out.Clear(); + DigIo::evseact_out.Clear(); + DigIo::ch1act_out.Clear(); + DigIo::ch2act_out.Clear(); + DigIo::ch2act_out.Clear(); + DigIo::ch1ena_out.Clear(); + DigIo::ch2ena_out.Clear(); + DigIo::ch3ena_out.Clear(); +} + +void CalcTotals() +{ + s32fp totalCurrent = Param::Get(Param::c1idc) + Param::Get(Param::c2idc) + Param::Get(Param::c3idc); + + Param::SetFixed(Param::idc, totalCurrent); + s32fp u1 = Param::Get(Param::c1udc); + s32fp u2 = Param::Get(Param::c2udc); + s32fp u3 = Param::Get(Param::c3udc); + + s32fp udcmax = MAX(u1, MAX(u2, u3)); + Param::SetFixed(Param::udc, udcmax); +} + +bool CheckTimeout() +{ + uint32_t now = rtc_get_counter_val(); + uint32_t timeout = Param::GetInt(Param::timelim); + + timeout *= 60; + + return timeout > 0 && (now - startTime) > timeout; +} + +void EvseRead() +{ + const int threshProxType1 = 2200; + const int threshProx = 3700; + const int thresh13A = 3200; + const int thresh20A = 2800; + const int thresh32A = 1800; + const int thresh63A = 1000; + int val = AnaIn::cablelim.Get(); + + if (timer_get_flag(TIM3, TIM_SR_CC2IF)) + { + //The relationship between duty cycle and maximum current is linear + //until 85% = 51A. Above that it becomes non-linear but that is not + //relevant for our 10kW charger. + float evselim = timer_get_ic_value(TIM3, TIM_IC2) / 10; + evselim *= 0.666666f; + Param::SetFloat(Param::evselim, evselim); + } + else + { + //If no PWM detected, set limit to 0 + Param::SetInt(Param::evselim, 0); + } + + if (Param::GetInt(Param::inputype) == INP_TYPE2 || + Param::GetInt(Param::inputype) == INP_TYPE2_3P || + Param::GetInt(Param::inputype) == INP_TYPE2_AUTO) + { + if (val > threshProx) + { + Param::SetInt(Param::proximity, 0); + Param::SetInt(Param::cablelim, 0); + } + else + { + Param::SetInt(Param::proximity, 1); + + if (val > thresh13A) + { + Param::SetInt(Param::cablelim, 13); + } + else if (val > thresh20A) + { + Param::SetInt(Param::cablelim, 20); + } + else if (val > thresh32A) + { + Param::SetInt(Param::cablelim, 32); + } + else if (val > thresh63A) + { + Param::SetInt(Param::cablelim, 63); + } + } + } + else if (Param::GetInt(Param::inputype) == INP_TYPE1) + { + if (val > threshProxType1) + { + Param::SetInt(Param::proximity, 0); + Param::SetInt(Param::cablelim, 0); + } + else + { + Param::SetInt(Param::proximity, 1); + Param::SetInt(Param::cablelim, 40); + } + } + else + { + Param::SetInt(Param::proximity, 0); + Param::SetInt(Param::cablelim, 32); + } +} + diff --git a/src/main.cpp b/src/main.cpp index b771b3e..e9765f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,7 +46,7 @@ static Stm32Scheduler* scheduler; static Can* can; static PiController dcCurController; - +uint32_t startTime; static bool CheckStartCondition() { diff --git a/test/test.out b/test/test.out index f5636e0d921d6ae3415a30055b8c3c8fe63587d3..9f24529113931dbffd4e9a3895f34e5069bde65d 100755 GIT binary patch delta 18118 zcmZ{L34B!5_5Xb@Gf7_7nQTK6APFHMfv{vjc4P}A3YeInvKfXXkjP}81W@RJpb`QY zytIN!D=w`TL_(-_`$14dP*egIu%$NCZLDZPQBi60`<{32o0-i2_kW*H-Z}St&vwsU z-ZtraI$-A`0qq&;T}L{GP7a7+`~Fh3@qNqM;T!K9xj5jRUw?JS!@Zqr0=5LGFOK3N zLBCgz=ktR>Bb1r^QqU3CvLQ@AcCHgNSP=Gwlwa_ZC#MR9e(U?{KbRrfclpVyGlhJo zpFDr4E{|ee_xE*lf@fCcMVvD~nZI}3=CwMW?#8MHj-VaUX>wy|MxBH=KyaQ;ev_0U5p5T{& zW=XWm56$D&P@86W?%_(PjTeMk;`5|F+vs0`hEQAl42fF&&?3GEsNrptANmOI2D)3? z7WttkxDsZIe_oFqA9|J_1^QQsUhqSE z_*J0&=7}n>2l`eciKm3y;!`AA;D=`NVxY#j)cc_$_H^#T!Pu?r_clyZ<|1bN=&3EYe@s(DqXNL6n>4fqn_7 zA3C021!~kGd2`=hOyMcfUfTjcbS5tbYV0BPe&}qz9;i`)oqlKu?*M9yc$Xi#fM4=K z-F~Q@TVuSombSh*SM#YrjUJ8lL+f}0P@@`4{Lp5;$H#V)A9^3}_OU(Shpy*JtSvrC z&a?}DXdBN4`nZ@^jBV+g^KNdBwJDExu8!Rss_qEsOiu|=U0WwDs%Fd`tT9%wby6|$ zH-dG37V%dEe>3r)3OVR5#J^FaN-XMUM2oH!C$EY{~-8{UCl`aTffS*{Zo)9otsHNPUzn%^zSGAB|?7!xqrv2ZXtD>Q136)9i*Nu)Wb>r zaj*KNVNmZU)V~Ig{>`KQyH%n8@pAAEul_;Oj~Dufg?>7zpZ!Iz&0bQUIp*q zVWA#L>dy%EwWJ>5RWBv=M3>NCBJ{6=xSNIkZKVH?Ku>MbNWZ^O&lc*`A@@wEyHAAb z-H9cey|CGEMUf-?%}|&n3$vfWqtkDYS)_>K`eYdztNWO|P9`bBkU42a6Ad_@q@;-Q!i>l`StPY8=kWYHlkHj_nSAB(%mB12fX?hz(bXSYk3%qNpCO}>54A`|>k zwZ;mI7s+A{EZP^p`Ca6|pXU{{epayIvgLSwFXS3yoAP_tt?gy{I)5C>uZ9cz=fR^} zhsZvB8XO!B0B{7WmbrgKqHe1&j(jP<*E^3EkO!;qP$fL9BoC*q^G}B*yPk&OVTJtA zdUWp~KVQQolIZIvi~I}_e$2v84Ed?Pjzl1q4ob+uKHeyDtrjy9)8`0 zGMwyFhQndxi$>BNOu13#kBp?|PpItSP->2)=D*N%{|k|h(7xs#iDqm5^|t)$N3WYV zTp#SDZE^<%mb>JWBJf@c{HGt0bPc-gI+8}lza!TUw2zFSW;-=&sX2z4>nYNDibPwY z`#8$pnt!7${{|vWA~ii$CdHBk8ZBa#Qmk7L%dd}bo6Y5nQCD1t3*ha@IP#lFQT6Ty zQZtOAzUo)WL<)kk(|qdA(C5Qe5clUlphKrs!_{dxb^l7(_8rE*Li<%JCmghA=*xIg z5qWqP9^N+BEoE#r1)e61Jwy03+2skl`QR}TW67)*WS};;{f6DArN=Y2)Gmp?DA@tlJ>1a`wCV9?Pa8G z{+{n0IYAv;%H1QA6aN9zm!ZT8+U8xaD9DXTLypX8cJIE%Q%6nWn@8QOj=6)sJ8G~R zdk4QdD#7}9JQKF%yIW1xw*1SjZ@XXP{j)RFXG;0Z>_O_fQhrZ%nsq+unAGnghjx7z zX$c>n$)C(lRntoOTiG|MUzhOzWT&fdmGHEj!Ro^q{MMXA_5KoGl`}}ayOeLqNmpM9 z=7(~|sy9mbH#zgwJte#_H!G+OFA3VhR6Z&wC)x(jv|Y>oZZB0f8B;Mlvp=#Qs$JVoI705*kLd^Xe8wX`;M zR-_Gam!SnL|JQtaMi%AKC!`Knn z5oTgj+@Wx>vCCN~t{J*05h9u^yHa^WTFe~}rBZYL(eEOy`X;$7vbO68RG9k}MEojJ zTr70K909Qdl?I!Rg0R{)@V6q2XN8m03`9tY8OBtG9 z-6s-z7uP<%KYif5YzTc48$>#jeX_C=PRmooQwbmFbJe^`7g2A>f1=rbl9!Ci)x>0O zHGjw#k4|u%ypz_5$)aE0osDhg=O94csxXSJ=0Bj(X5NK!YgfV6u(uEo^Embd_9nuy z>|@vHDvhLa1}cA%D$hej-xkEOSql8P$)dEGXM@|&rEKU4Xf;o{lm9R}#g!>Qwjuw9 z^3~@)>#i*}5Kx=>2Aqw1!&%&B{(;;gl^B_dIfYV*QQOQHC1NCL4kg5-w4TGh)Pbzp z%&$OVgnj}1SHII^Wr#bbHuG;G>pQ>O%*XM3_dr*3G*<7+{P0afN47(N?F=OvM|*-d zlO_U?2?;$(EakQ_W0kjf(U`cjm-2N>+D1I-4~0>IuxdSy7(aHljhP&%-uelDchWfJ z32vU8seIl!a&nQPM)m7le{*qwI_+cr;j|VtXFQ)hy;>>jd}(^Pq84A|Z_PNXtl_)z zQ~KTWH~k9Q?ztCiU3(p)_9j1*pRL%rX=YKTxIg&u^WI+EarEso=0|Ju^&{g^GWWU9 zdD`d{^M9dtlHWSBSv`K0zcJIUly?rE^;B5r`z2S@z~rgF`{U4?pML!g#dQo@(!W0F z?fn#V#p&K&6IOXhcW>`t(62#ffSx?l+gkye^I>oAM$jps&w&0Bv;uZrBnLf5a?q=w z$AGW@3;cpU3u-bmb_#SbC_4wgpu^Agx_T?XEQVks=qAu-Ku>@k108uD4nWs}ny_Cz z2RazE7jy>bZ5NOLXfx_KxuO<2;iK`TJpKsSQE_7N`q&w$DK zD-1w;K;59DFdV_SsL%a70-{|3Is(;qa9@QAuY*&-kDlg#T$tdx47MAp!+cejdR4=)HZB66 z;)}2J;#t6N0AKElt0GywufV5cP2!^L%~j3U9RQ!j98hS0!v8OUEx^|R#}4h|V6NeS z?E~J~%_9~ixK4rn1gh!2s*An3UIzXp@G-u4trw>U7lwU<9%?*wt@q+tz~g}@`{H+c z@LBo;2r1CBn8!h-M}axuU7 zG;o1o*kdBk@OQvwfn9cn|7+pEz#_0$&Y&7`A<2kQk7n{&K4MXv!uYdg!<30Udr6}C zLx>OYVsO{Mb@2vpG1zm$_;zr4;BN2^aHZgu@osQVaGm@rxE#s2^C58YJR97H z;KuM`aM!@)^9FD+*m@T5?cnmjS$PMzQgF+8H#jG_EBq?B9pK`)bt(LTYvI}8J_L6! zF9vrF+$!DxE(VL|H+(y|Ja7ki2e?vj&+=|?PHp>i5G*r z2F}hK$`cpFV23(}oyz7r7GhfIYbX!+Yrs=|@de(oDg}NR_&{HL9^su2mJikFP)_% zVX~S(wDYlsbj50XdplhsT%G6Ljka-y^dmzmsjh=u85TPBN@nO8-%ii-lqRpWTUr@k zN0VXEBmXe>Jl4kdQQSHESf}9`j1J>1`4r5Cb=al4vKa&Gu{OSe;u}Jf&C{QW(wd~v zv2i~7##hcFZgqO~ACdZa%k7MgjquSozFl?#@%HUKsc(E)fB|FwG_hom82lNPF}_cp z&G;VK!;71v`DJIAW_*K8;!1OplEPD(hiI9&!J;D-T1nan**eenz-CKxn3m@w zNzx|yw4(V%;Q1cORoEBG7I};2SuJ7O94RU0Q(Ka>64~0V<7*^$}pKRePI^xe>9i}CDBzEBGo)+Ox03RVGsk{Sto@|N!Uj{zjgDdwYX;b>( z6YmYvW=aV%0zO-|M18gZFOiZSz6baMPmAJT1a9|8t^%)?Ejj-8g=uwCa-L7UFG*|e zgRcR8p9kL#e7$VZ48`~ZZkA;k z^wKWKL?I$K1_qPThd43qQRJj(?|@ge1_%PQcX2jpe?kUk77~DNM!pz>i!D=>z~JYA z1yLjP2lOm7A@n1VuppQ2I5f%h58#I&(&ppDv_ZH%QMA9~tZHN6DL|tQ%S3xOGi&3Z z6R1%xLE1K?5vU#K<{=P)e;I^o(w(23BNQAXPPNYA3B!n0NDHlzPh z+6JgbhgVmWvzYK^oMXeA>dIN1_9BdJS_RO4njPnO?Y9V=pxp`MM6DToe~mt14A5SL z(}CK{kSA%kLz1k`$2mpYgMmnE)(Tpm-rXJNO{_Vy%E~cy7>g0BS0;rhu*SBG(gTbFB4OnL(PGvs?%B-Au}JqUfVWKj-kVC>~1-4xUu3G1Sw=da?nj z&nea=)V^EWrQ07+tPRxHvJhHk0jV!5*6|c@iJpEyYL{XyB!5d?!GXF%%#?s@(1-|% z{|pvUpON;ki0A?|uzHUpi@;z)V)h^aB^^5x3`yy|V)Sp2E%d%2ei%H0{~5fl9f!8A z9nC^Y;KI@xF_=`KbI=8)kSPde*(`-2e?;PzHlt;SrZpjq%BLtX{Sl@Nk~kLfG+1k5 zLaFX4WC^JalxiVQ5tbw|+Z4qVISZ0MkhKD zFEE%|0R^yEg7E$fy8z8Mn@!k-#tx&S~?5@w+%-qzRXiMMqO>fTnE&~!<| zus*755W%bZTpy<^kck(g+Im~N`gmE@r*+2HOJa-N!PM9g)kR6Avi{1fN+(loAs47S zkSX-~k$OLdvChIHYMM-%SEpuRq7O-)PuE_=|os^u#OqQ?f58c?D<<%Qk23UOq zo75xV0;9r-57^$bhQ*vhYX3z`pCo2Bn0Dv=(%$g1gv_&W2ay(yIUX32MSH5c-NDk8 zS_sTz0wbXze=6#+?joxySPgMCAiyecilPO4aXaL6#5{)+N%hdNEQoZ|mAj#9P6>Pk zc^N-SH9RL%l}cXzP61ZR0IBqlZSF619HKv@r1!_hg2++2 z@<0%FW>ZYyU!iUMTGxo%L-8J^c+??NT%Qj8LB?Cyr$Z#w10=E_vP@TwVBk$bfzvP& z#;=5pI8!iA%8wexUjzv06Tqlgx)C5t-8H}Wzq`W0WISe)bO(eDJf4G z=8@8zWzyby3}WLJc7lx8Mfzv@=(`XPg~}u(Dli`|>IUgadpb#1EM*yPZ_{XjC{g{0 zSGV7l_A`x8RGP@LG)>=fqekmD1KSIRJtExGA87Z!#)I?e#@qN+?NtbC2yCH4vkP#`5P?-n9@NsPu zqas--`h=Al8d?~QT_v4$KGgPr5U|b zlqrFaP770DmuB`;N#`ls`rSs*5V9_e&I@ydk!=Q=!M@Hi$yr5TcSFe?*^tGsP=#XA zi=LEiiAnFF=K-vPMnL%`A{=K0JfpU=vdPI$ZcF74ZmS8Zt}S;oS5)$Ew`KB-hi`VN zcq`FXs>A!JS;0Jmw`v{CTC-FxwC9$;p}_} zFi>7jHz})cyaxa#BE_o%i>cL=xVovVva!)o-QvCFIMjms+=Nt2t}_bCqE{K(%F z6EEf^0p@_^{13b<;Jhi2-?L*#k};bD;uLfItLA}DRYku|syT#d>clL5U`L|MSQ!C> z6?4+3<{|BB0CaG-@2IX}Wo32CmX$eK*@Emms!~~HOH*Z8W2L>Kg_RZFrgLTW&PG;- zw5n@aQ*O?(dRARq-|TE+m9_Szj>`Hv2P@C5wwE*bY^uk@S-HKoysp;S2%xO#=Bm0z z=hEh7tZ;5o*_^3!=S`i>D2N@Us%u7ML;+m3)ZSFd%Cno{XGZn%!aDHIn)+(|FuBW? zM5#52!u$9s%PnH%If%?tcE-5MbD*CM!7_(^IV)RM?WnA+W6tWD$_mG7Z)YlND_GIg z+o#Scn?1Fp6hmQmR-*fJM^CM_7uM$DVxM2l9CfwJlj%8gY$+m7r_}W7khjLN>T=vf zG{cG_HDSPVP>H+r-snl7PDZaNT3LB>V_A8fqq#=N%j+sC%UjU%ChyR*`o_9d)iu@5 z)y!E{4WHRm(DGcAly^KH=PIMAn45!<((@>{JIc$PbxymZiPbjOl$9gHCf^ig4H_#e zv5Az?8!==qpJpeOhnRG^DS)Qwp z4XdlKL1!L$BF2RR>cgfNu!WV^H#_R==sQMtWn;CoQlCWSIrNZOYp@;8_PiaXi3gANa(g}XljhUXI+}Kly7Cna zC8VA;HrMI}lH-LwQqt5t(sx#&U-eW8Og{K(scdYju0vgDHB?kL(G)MUI~=_0NUCcb z`D$uLe~LUaqZ$(+8xuf}UPFtdJXK026vNP5Pg70o9jogr^>ti2zbHS4ma$lobLY*$h&DN$Y*}+{ zIluLAd~i9{AEU@mKauFd_|(`}K}Ae&6jiK=id?akP(5zSLnVc~!nt=$on1IX?*wgW zVhT~0^a(|46Lnir&8An`YnN9t&upXu(k_O2AiAzpkF9cgy}e>IEq7xKset+}>Y3%_ z6Vt&^zyiiH#!RD{m*=2oeEP02nT|>fow4`X%U3kl%hZgyKU!Z4`7M0g6E>T^*s!tD zn#-XLtI=7CO7h)rB=Ad*Mn{*G72Td+S~|aM=DfMnOABwCTUN%)>f^8>QgD3)^%W?0 zSSl~=#iI68=at^Zs#=VZZ?-qD@;ne6l{fY(TN!Nd$GkF&!4H=AQYve)7<^h5|7CZ= zOyk+0(`y!N@Gp5~7K4AyBWtl3{OiMXSH^AqEknf}4`pTWbG$N(!N1_+%Ha14SH=x| zZKl_i!8dqi7K5MRao=Jw`23-IR>r+~TZY$_!Ef`*ECyfYao=JwczoHRS{b+Dmxp*= z8T`M!GK;}K;Bnt#G57~FbXUe*_zJICu))`QWfp_~+#_qT7(Bj4-S^Zjag{!h!Q*=s zC2ZVT-02zrmB9wTz$>#DJpD+X4w@$hUnAy;aT`C?qp~vC;AePc7K1PL$XYB0f4gvH z+!GD+sH_Y&_z_;2#o)(#WGxnhpOD30d*+`x#uKsO(s*bvvNZ}|P;_RhZFJ}0-zS^+ zp?$HuW1r2XKZ3Ia&woTN!BZF=@8M4&`Fg#{t_Z?0KQT z{p&L5Al%@R{6#5`*HQe!1acF*%7gY=m4#f{Yr~D?(Y?0#`{{-laf_sX`o{!1w&*%L z>1?MrOyrYI5LhhQbo`H$$I7IZO8EsTUrBGwaa0Pzu1fhuDW{*_(9w@yMLt9H^GLpH z-$-Q|Ke=yYd=YMc@fwZM&%At(2yT7B7GDljVg1-9`SH}yaPX->*Xp*h>^XXcCLK@C97pEAQY0~Ysgaf$ zctRlkEq?kpLr#$f)329t7+s_X)>C3Z#QP349^t=f?@b^HP2r=4vua;BW7@j{Y}vtmpxgC6YtQ z{;SIq*c2HHFHQ6#0t$ol3JwKFJ%53|t>7?bbe@#|Crii&3&M(}+<2c~1M9pDqLua&YS)Phn9}tX|d{&y4!9mUp~pb8VJpGvrEIF3~?gP6PO<>=2sz zaYE{67KpY(%1=xA2zqUVL;ooN=(kcne3mX|Hw0nyb{ORt>Um#vQ36qTWTZM}$dxPy zgMLYIz*b1_c?q>kaf`I7lJaYEFl|!45pwEAo9u=$<9G4y12%Ifq59}#10cUOaunL7 z{n{|dRVypFMG7SOOvd|Cj^<=3|F@JMr{D77kc3@_oaXmE`9eNG5T@Zd7;#=%S>gxre7k*pVnzuyt! zYByBnEklGxCRMKtGfqy#@0C{2YPnXVE3 z5q{~QZS?aJeb}!vT{6~QxjyE~+|H4lrcU;^Qp312tCn*t5PJZ{+wSLa0B`8DxrPy{ z{=b{k7|8#xiBbSL_1SpCI8&y7x0DZ&+ks4z(R*RiH*TkXC-c5v$cM7&vTFB8V2d>P zNqUfzfW64G583SW-;dSIBaD>8~d%wq9&Logu1fU@lY&R3e3+0=W2YtHkic!y z;29~;lJXkJsi2$W`j+<$>;Zo1Pqxw9rPcHD(q)wIptL$Jt&Cal0qN_r^pdpvNLm`h zYYG*KpDq*$RLVSJc*9FJ*ASq%c(5gR3NhBAeoT;7*JM1Kl$T2RK6xWC5CcSqUCL8r z^dUmb)=RlbCOk#TpMe}(#WePe-(GP@8myZpG>xs|4c#D-ZStFM=Xv&@ZT7E#Qc;aN z)I=HP7io1-S{b8k3;VwZVI<@<%Ep6*OpeXsDKF#BOrm4t++Hc8H1VTt&90>UGI@+HedGork{o^O8b5i4Gq z=1i}uEMGwn<9M2H=}dfmT0nSqc41RK-U}4cJ5oOX$f5`+j+%}acBT6Jy3Woc&#Kn! zJl%9&ZM~y;`SQw&7C!HdLz?H=zBBkuyP}OHKeyw>MQ7zPvl0O}GsOF-sSZa=XVqKh z)XpgDna9(4q2wqS??Un%yQo==4q6w06-v%lDkN zZ9ib*YfkqMiQOrLJtqDXbiRK=G>iD9(_>-_c8gXpUft7?hQC|*@a|z+(E(k+HgJ3Q Q813x;h}JrO>15LX0;!W!Z2$lO literal 53696 zcmeIb3wTu3xj(%3Om;E@xlAD36$SyhCgdg;1xAuOQeJehdH8YCE5}#1HZGi zOSM$MDfll@WP5nrAqgD16rU3z$xWn4lJFu4YaFtL6q4LXhkt^kaHx4?n&b?Mdg%v; zSNxh`%{-ar&?+bLt5W>7a957RIkd`=Zysrp^ha(@4EwTV+OO~2Gx_83$|DF7*l-#Y?Nj>)P%c^`F za(*9$9QozHdazs9s{BT(2YY#`ozStcCAeu(@xqq++?HTlWNYr$C5v(w73YQ8^9lu> z?4mrVOd5tA5&#~OaFS_-AkKmGt{%=xhP<_I`hk)4G9;0XMm7=iz_5%`@b zNHTj4jKDt)xEKHSW7G(Gs7}0gW~3j+f3ke90Pe-V{WuHY5<5s~w2M%j0WDBgT@k2n=xk^ThQbY<)fFpS+S?kcYd5ttNLq5r_0`u_7UTy4 zbz8UAZVGl46f8!(r8X1_gtv7x1cGgi?LIAF=PHCmD42v1dTIk5k!iUQk#GoB!{EBjfx70+fyUZkiw3l=xwaDoWZHnDNVGH97H$Mc`Wl06wJpJqH)x@7 zXI*OtP*SQ&-dY=M(^jruU%H|!P>@%oU0q(bVr8H(uh@(g=3PeabKuX3-r*E6YTfi7 zZ}mD_I;vLmEib}fKE4@U%&A>OAPyb;KSap=J0}>-ppkDj=!8Wk2i>HzK=Jdq%j4a^ zbkd?}PpI*j@i&SkzR!m5Rs4N6yzg4c-*3YYD15+%A657n8~(b&U22?Xd;BWxvEfr! z%Y3~ye4|RwvEdK;B>xf{zE!2GYQ%S|HQwZTRL~i9cY&ug;Tr-zO9G^skfY!#4c5 z!uxIbn+lKFaMp9ihQFowhio|O@pLD*XQB;{DLq~r&U%*EaJHw!hM!S-{5D*xmUe8k z;jE|GhR;y^9X5Qv!gtwl*0aZk=PLdOY&h$A!iKY+eKx#U>FKlK%M^axhO?dl8@@{M z$80$3(e6lIUoIP7uJm|p_ zdu{k!h5K!Ifx@e7IJeIZ8@@>KZ?)mvPam-1%M|}!8_xWFHr%K958H6&kJ<1F#ec?z zGr#AqME`tL@lUkjT;3%%yhibt*zgSs-)O^cPUK{?T;(x@3?^F0;8~&EU`)znk;b(04X@w8jaOR)5E76}HD1NUEXZ{i!{x`+% zx8dAAn{BwR=3^Z;oc+1ShNmh12W&X&-)F-!6n~!$XZ-^J8eS2WQ-lN7(l zhI4)8+i2=C;E-`du_O1@z1g0tlw|LD;0m04d?pmu;JB;f2$4W`g*{I-=O&S+Hm$~ zpAFxn_z&A~=8xI%pyEGc!xzUDiSNzR3ob~Ur z;oXXVj}2%2PuTFN;@@Y(`MiJJhJRM^57_XpDO}r~=%24E+-1X=zr=fz&~G4^L3;h=j%DbofiK7+mXPLihsIK#m8|A z?q(3-fCV3A!DAMDv;{w7!EvE)9(xs@283+l;}Hw)U=ZOG7Cgm*@3Y`k20r>MIOV~| zVGHhJ@IrXO0~b7S!2=gOaKQr?JaEAS{~z+e2U%19>hC`7^7k082QVG;+I47QBC1%D`u z9=q8eecRuC@=R5Ad9QKlT)3h)^{rW-wv44bfprAo1a19SM zigL0%`FF?iS0JlJ=GXYUmrn+#=8wJ;PWSgLUyVfU$UlaMWA$*}LF3!t({F;TnLo*& z+5#d)Y9NQo_WGmSW6{XTL%wrlYLD;S6~2?(KZ4Nzfd9Zisz3UIzsDEz>;3+ok|o3a z$q3OGfJP6ZcrV}y%0AK)tAZijzH|EEw|jgi1?`|oD+X=Pkrypi^CDPd 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 diff --git a/test/test_logic.h b/test/test_logic.h index 8b84690..68872b2 100644 --- a/test/test_logic.h +++ b/test/test_logic.h @@ -3,6 +3,7 @@ #endif #include #include "test_common.h" +uint32_t startTime; void test_calc_totals() {