12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719 |
- #include "Module_PsuComm.h"
- #include "Config.h"
- #include "Common.h"
- #define DERATING_COUNT 30
- #define DERATING_GAP 30
- #define ELEMENT_NOT_FIND 255
- #define CHK_VOL_RANGE 50
- #define CHK_CUR_RANGE 10
- #define DERATING_RANGE 100
- #define ZERO_CURRENT 10 // 該值須保持最小為 1A
- #define ZERO_VOLTAGE 50
- #define STOP_CURRENT 30
- #define PSU_MAX_CUR 1000 // unit: 0.1A
- #define PSU_MIN_VOL 1000 // unit: 0.1V
- #define PRE_CHARG_STEP_CUR 30
- #define PRE_CHARG_RANGE 50
- #define PSU_TASK_CHECK_TIME 1
- #define PSU_COMM_CHECK_TIME 1
- #define GET_PSU_COUNT_INTERVAL 1 // unit: second
- #define GET_PSU_COUNT_TIME 13 // unit: second
- #define GET_PSU_LOCATION_INTERVAL 200 // unit: millisecond
- #define PSU_COUNT_CONFIRM_INTERVAL 200 // unit: millisecond
- #define PSU_COUNT_CONFIRM_TIME 1 // unit: second
- #define GET_PSU_VERSION_INTERVAL 200 // unit: millisecond
- #define GET_PSU_CAP_INTERVAL 200 // unit: millisecond
- #define GET_PSU_CAP_TIME 1 // unit: second
- #define STABLE_CURRENT_TOLERANCE 10 // unit: 0.1A, 1A
- #define MAX_STABLE_COUNT 24
- #define WAIT_EV_DERATING_TIMEOUT 5 // unit: second
- #define WAIT_SLAVE_POWER_OFF_TIMEOUT 5 // unit: second
- #define WAIT_PARALLEL_RELAY_DELAY 1 // unit: second
- #define WAIT_RELAY_CONFIRMED_TIME 3 // unit: second
- #define MAX_PREPARE_SWITCH_OFF_TIME 10 // unit: second
- #define MIN_POWER_OFF_TIME 1 // unit: second
- #define WAIT_SLAVE_TO_CHARGING 1 // unit: second
- #define WAIT_SLAVE_TIMEOUT 5 // unit: second
- #define WAIT_GRAB_TIME 15 // unit: second
- #define MAX_PSU_POWER_OFF_CURRENT 50 // unit: 0.1A, 5A
- #define MAX_PSU_POWER_OFF_VOLTAGE 100 // unit: 0.1A, 10V
- #define PRECHARGE_OFFSET_VOLTAGE 20 // unit: 0.1V, 2V
- #define PRECHARGE_RANGE_VOLTAGE 200 // unit: 0.1V, 10V
- #define WAIT_PRECHARGE_TIME 10 // unit: second
- #define EXTEND_CAPABILITY_DELAY 30 // unit: second
- #define EXTEND_AFTER_DERATING_DELAY 3 // unit: second
- #define EXTEND_LOADING 8000 // unit: 0.01%, 80%
- #define RELEASE_LOADING 5000 // unit: 0.01%, 50%
- #define RELEASE_LOADING_OFFSET 1000 // unit: 0.01%, 10%
- #define BALANCE_CURRENT_INTERVAL 100 // unit: 1ms, 100ms
- #define SMOOTH_DERATING_INTERVAL 100 // unit: 1ms, 100ms
- #define CURRENT_REACH_TARGET_TIME 5 // unit: 1s, 5s
- #define CURRENT_STABLE_TIME 10 // unit: 1s, 10s
- #define REACH_CURRENT_TOLERANCE 10 // unit: 0.1A, 1A
- #define MAX_ADJ_BALANCE_CURRENT 30 // unit: 0.1A, 3A
- #define START_BALANCE_CRITERIA 100 // unit: 0.01%, 1%
- #define STOP_BALANCE_CRITERIA 10 // unit: 0.01%, 0.1%
- #define EV_MAX_CURRENT_DELAY 60 // unit: second
- #define EV_MAX_STAGE_CURRENT_DELAY 30 // unit: second
- #define WAIT_SLAVE_READY_TIME 15 // unit: second
- #define WAIT_SLAVE_DELAY 1 // unit: second
- #define SHOW_OUTPUT_DELAY 1
- #define CURRENT_BALANCE_CRITERIA 400 // unit: 0.1A, 40A
- #define SAFETY_PRECHARGE_OFFSET 200 // unit: 0.1V, 20V
- #define CHARGING_DELAY_INTERVAL 200 // unit: 1ms, 400ms
- #define MAX_CHARGING_DELAY_COUNT 15
- #define VOLTAGE_RESUME_STEP 10 // unit: 0.1V, 1V
- #define POWER_ONOFF_RESEND_INTERVAL 1 // unit: 1s, 1s
- #define COMM_LOST_CRITICAL 0
- #define LOST_CNT_CRITICAL 10
- #define PSU_CLEAN_ERR_INTERVAL 3 // unit: 1s, 3s
- #if SAFETY_TEST_ENABLE
- #define PRECHARGE_OFFSET 1 // 0: normal output, 1: precharge voltage offset enable
- #define ONE_MODULE_OUTPUT 1 // 0: normal output, 1: only one module output enable
- #define MASTER_OUTPUT_FIRST 0 // 0: normal output, 1: master output first enable
- #else
- #define PRECHARGE_OFFSET 0 // 0: normal output, 1: precharge voltage offset enable
- #define ONE_MODULE_OUTPUT 0 // 0: normal output, 1: only one module output enable
- #define MASTER_OUTPUT_FIRST 0 // 0: normal output, 1: master output first enable
- #endif
- #define MIN_RELEASE_POWER 30 // unit: 1kw
- #define MAX_DIFF_POWER_TO_DERATING 5 // unit: 1kw
- #define MAX_DIFF_POWER_TO_EXTEND 3 // unit: 1kw
- #define MIN_DIFF_PHYSICAL_POWER 3 // unit: 1kw
- #define MIN_DIFF_CONFIG_POWER 3 // unit: 1kw
- #define PSU_DEBUG_MSG 0
- #define ENABLE_SMOOTH_DERATING 1
- #define PSU_INDICATION_TIME 10 // unit: 1s
- struct SysConfigAndInfo *ShmSysConfigAndInfo;
- struct StatusCodeData *ShmStatusCodeData;
- struct PsuData *ShmPsuData;
- ChargerInfoData *ShmChargerInfo;
- PsuPositionInfoData *ShmPsuPosition;
- PsuGroupingInfoData *ShmPsuGrouping;
- bool libInitialize = false;
- byte _gunCount = 0;
- byte _maxGroupCount = 0;
- byte getAvailableCapOffset = 5;
- byte deratingKeepCount = 0;
- byte psuCmdSeq = _PSU_CMD_CAP;
- bool psuReceiveRecovery = false;
- bool isCommStart = false;
- int lostCnt = 0;
- bool _isTriggerShutdown = false;
- bool _isShutdownCompleted = false;
- pid_t _RxPsuPid = 0;
- unsigned short evseOutVol[CONNECTOR_QUANTITY] = {0, 0, 0, 0};
- unsigned short evseOutCur[CONNECTOR_QUANTITY] = {0, 0, 0, 0};
- unsigned short evseOutputDelay[CONNECTOR_QUANTITY] = {0, 0, 0, 0};
- struct timespec _PsuReceiveRecoveryCheck_time;
- struct timespec _PsuWorkStep_time;
- struct timespec _cmdSubPriority_time;
- struct timespec _PsuGroupRole_time[CONNECTOR_QUANTITY];
- struct timespec _ChargingRequest_time[CONNECTOR_QUANTITY];
- struct timespec _PsuGroupDerating_time[CONNECTOR_QUANTITY];
- struct timespec _StopCharging_time[CONNECTOR_QUANTITY];
- struct timespec _ExtendCapability_time[CONNECTOR_QUANTITY];
- struct timespec _ReachCurrent_time[CONNECTOR_QUANTITY];
- struct timespec _BalanceCurrent_time[CONNECTOR_QUANTITY];
- struct timespec _MaxCurrent_time[CONNECTOR_QUANTITY];
- struct timespec _StageCurrent_time[CONNECTOR_QUANTITY];
- struct timespec _CheckSlaveReady_time[CONNECTOR_QUANTITY];
- struct timespec _ChargingDelay_time[CONNECTOR_QUANTITY];
- struct timespec _PoweOnOff_time[CONNECTOR_QUANTITY];
- struct timespec _PsuCommCheck_time;
- struct timespec _SmoothDerating_time[CONNECTOR_QUANTITY];
- struct timespec _CleanPsuAlarm_time[CONNECTOR_QUANTITY];
- unsigned short GCTargetVoltage[CONNECTOR_QUANTITY];
- unsigned short GCTargetCurrent[CONNECTOR_QUANTITY];
- unsigned short StableOutputCurrent[CONNECTOR_QUANTITY];
- unsigned short MaxCurrentDemand[CONNECTOR_QUANTITY];
- unsigned short StageMaxCurrent[CONNECTOR_QUANTITY];
- GroupOutputConfigInfo PreGroupOutput[MAX_GROUP_QUANTITY];
- unsigned char OutputConfigStep[MAX_GROUP_QUANTITY];
- unsigned char _preOutputConfigStep[MAX_GROUP_QUANTITY];
- unsigned char _GfdStep[MAX_GROUP_QUANTITY];
- unsigned char _VoltageResumeCnt[MAX_GROUP_QUANTITY];
- unsigned char _GunIndexOfPrioritySequence[MAX_GROUP_QUANTITY];
- PsuStatusInfo _LocalPsuStatus[MAX_PSU_MODULE_QUANTITY];
- bool _Psu_Indication_Enable[MAX_PSU_MODULE_QUANTITY];
- int _Psu_Indication_Count[MAX_PSU_MODULE_QUANTITY];
- int GetPsuModuleQuantity(unsigned char group);
- //=================================
- // Common routine
- //=================================
- bool Is_OutputK1K2_Ready(int gunIndex)
- {
- bool ready = false;
- if(gunIndex < CONNECTOR_QUANTITY)
- {
- if(chargingInfo[gunIndex]->RelayK1K2Status || ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
- {
- ready = true;
- }
- }
- return ready;
- }
- // default is return enable
- bool Is_EnableReleaseAndExtendWhenForceCharging(int gunIndex)
- {
- if(ShmChargerInfo->Control.FCharging[gunIndex].FCtrl.bits.EnableForceCharging)
- {
- return ShmChargerInfo->Control.FCharging[gunIndex].FCtrl.bits.EnableReleaseAndExtend;
- }
- return true;
- }
- // return psu group number
- // return -1 when out of TotalPsuQuantity
- int FindTargetGroup(byte address)
- {
- return address < ShmPsuPosition->TotalPsuQuantity ? ShmPsuPosition->PsuAddressInfo[address].GroupNo : -1;
- }
- // return psu index in the group
- // return -1 when out of TotalPsuQuantity
- int FindGroupIndex(byte address)
- {
- return address < ShmPsuPosition->TotalPsuQuantity ? ShmPsuPosition->PsuAddressInfo[address].GIndex : -1;
- }
- int FindPsuIndex(byte group, byte gIndex)
- {
- int psuIndex = 0;
- for(int i = 0; i < _maxGroupCount; i++)
- {
- if(i < group)
- {
- psuIndex += ShmChargerInfo->Control.PsuInitQuantity[i];
- }
- else
- {
- break;
- }
- }
- psuIndex += gIndex;
- return psuIndex;
- }
- void PsuGroupOnOff(byte group, byte on_off)
- {
- if(on_off == _PSU_ON)
- {
- SwitchPower_On(group);
- }
- else
- {
- SwitchPower_Off(group);
- }
- }
- void PsuSingleOnOff(byte address, byte on_off)
- {
- if(on_off == _PSU_ON)
- {
- SinglePsuPower_On(address);
- }
- else
- {
- SinglePsuPower_Off(address);
- }
- }
- void LedGroupOnOff(byte group, byte on_off)
- {
- if(on_off == _PSU_ON)
- {
- FlashLed_Blinking(group);
- }
- else
- {
- FlashLed_Static(group);
- }
- }
- void LedSingleOnOff(byte address, byte on_off)
- {
- if(on_off == _PSU_ON)
- {
- SingleFlashLed_Blinking(address);
- }
- else
- {
- SingleFlashLed_Static(address);
- }
- }
- //=================================
- // Save data to share memory Function
- //=================================
- bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
- {
- if(GENERAL_GUN_QUANTITY > 0 && target < GENERAL_GUN_QUANTITY)
- {
- chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ConnectorInfo[target].GeneralChargingData;
- return true;
- }
- return false;
- }
- //=================================
- // Alarm code mapping to share memory Function
- //=================================
- // 檢查 Byte 中某個 Bit 的值
- // _byte : 欲改變的 byte
- // _bit : 該 byte 的第幾個 bit
- unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
- unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit)
- {
- return ( _byte & mask_table[_bit] ) != 0x00;
- }
- void AbnormalStopAnalysis(byte gun_index, int errCode)
- {
- for (char i = 0; i < 4; i++)
- {
- unsigned char byteIndex = (errCode >> (8 * i)) & 0xff;
- for (char bitIndex = 0; bitIndex < 8; bitIndex++)
- {
- if(DetectBitValue(byteIndex , bitIndex) == 1)
- {
- switch(i)
- {
- case 0:
- {
- // err 1
- if (bitIndex == 2)
- {
- // 012307
- // fuse burn-out
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES;
- }
- else if (bitIndex == 3)
- {
- // 012308
- // Communication fault between PFC and DCDC
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES;
- }
- else if (bitIndex == 6)
- {
- // 012309
- // Unbalance positive and negative BUS voltage
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES;
- }
- else if (bitIndex == 7)
- {
- // 012310
- // BUS over voltage
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = YES;
- }
- }
- break;
- case 1:
- {
- // err 2
- if (bitIndex == 0)
- {
- // 012311
- // BUS voltage abnormal
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = YES;
- }
- else if (bitIndex == 1)
- {
- // 012270
- // Over voltage of any phase
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
- }
- else if (bitIndex == 2)
- {
- // 012263
- // ID number repetition
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
- }
- else if (bitIndex == 3)
- {
- // 012312
- // BUS under voltage
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = YES;
- }
- else if (bitIndex == 4)
- {
- // 012313
- // Phase loss
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = YES;
- }
- else if (bitIndex == 6)
- {
- // 012271
- // Under voltage of any phase
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
- }
- }
- break;
- case 2:
- {
- // err3
- if (bitIndex == 0)
- {
- // 012240
- // CAN communication fault
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCommunicationFail = YES;
- }
- else if (bitIndex == 1)
- {
- // 012275
- // DCDC uneven current sharing
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = YES;
- }
- else if (bitIndex == 3)
- {
- // 012278
- // PFC power off
- //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = YES;
- }
- else if (bitIndex == 5)
- {
- // 012314
- // Full speed of fan
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = YES;
- }
- else if (bitIndex == 6)
- {
- // 012266
- // DCDC power off
- //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
- }
- else if (bitIndex == 7)
- {
- // 012273
- // Module unders power limiting status
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
- }
- }
- break;
- case 3:
- {
- // err 4
- if (bitIndex == 0)
- {
- // 012315
- // Temperature power limiting
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = YES;
- }
- else if (bitIndex == 1)
- {
- // 012316
- // AC power limiting
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = YES;
- }
- else if (bitIndex == 2)
- {
- // 012317
- // DCDC eeprom faults
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = YES;
- }
- else if (bitIndex == 3)
- {
- // 012269
- // Fan faults
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
- }
- else if (bitIndex == 4)
- {
- // 012264
- // DCDC short circuit
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
- }
- else if (bitIndex == 5)
- {
- // 012318
- // PFC eeprom faults
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
- }
- else if (bitIndex == 6)
- {
- // 012226
- // DCDC over temperature
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
- }
- else if (bitIndex == 7)
- {
- // 012319
- // DCDC output over voltage
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
- }
- }
- break;
- }
- }
- // else
- // {
- // switch (byteIndex) {
- // case 0: {
- // if (bitIndex == 0)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO;
- // else if (bitIndex == 5)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
- // }
- // break;
- // case 1: {
- // if (bitIndex == 1)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = NO;
- // else if (bitIndex == 2)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = NO;
- // else if (bitIndex == 3)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO;
- // else if (bitIndex == 4)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
- // else if (bitIndex == 5)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
- // }
- // break;
- // case 2: {
- // if (bitIndex == 1)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = NO;
- // if (bitIndex == 2)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = NO;
- // else if (bitIndex == 3)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO;
- // else if (bitIndex == 4)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO;
- // else if (bitIndex == 5)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
- // else if (bitIndex == 6)
- // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = NO;
- // }
- // break;
- // }
- // }
- }
- }
- }
- // return single psu alarm status: PsuStatusInfo
- unsigned int InfyPwrStateAnalysis(int psu_index, unsigned char state_0, unsigned char state_1, unsigned char state_2)
- {
- bool _changed = false;
- PsuStatusInfo _alarmStatus;
- _alarmStatus.StatusVal = 0;
- if(ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[0] != state_0 ||
- (ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[1] & 0xFE) != (state_1 & 0xFE) ||
- (ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[2] & 0x7F) != (state_2 & 0x7F))
- {
- _changed = true;
- }
- InfyPsuStateFlagInfo _infyState;
- _infyState.StateVal[0] = state_0;
- _infyState.StateVal[1] = state_1;
- _infyState.StateVal[2] = state_2;
- if(_infyState.bits.OutputShort ||
- _infyState.bits.PsuFault ||
- _infyState.bits.FanFault ||
- _infyState.bits.PsuProtect ||
- _infyState.bits.FanFault ||
- _infyState.bits.OverTemperature ||
- _infyState.bits.OutputOverVoltage ||
- _infyState.bits.CanCommInterrupt ||
- _infyState.bits.PsuIdRepetition ||
- _infyState.bits.InputPhaseLost ||
- _infyState.bits.InputUnderVoltage ||
- _infyState.bits.InputOverVoltage)
- {
- _alarmStatus.bits.Fault = true;
- }
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrStateFlag.bits.Changed = _changed;
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[0] = state_0;
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[1] = state_1;
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[2] = state_2;
- return _alarmStatus.StatusVal;
- }
- //=================================
- // Callback Function
- //=================================
- // 0x04: PSU_RCmd_ModuleStatus
- void GetGroupCallback(byte group, byte psu_index, unsigned short full_address)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(ShmPsuData->Work_Step < Get_PSU_LOCATION)
- {
- return;
- }
- if(group >= _maxGroupCount || psu_index >= MAX_PSU_MODULE_QUANTITY)
- {
- return;
- }
- ShmPsuPosition->PsuAddressInfo[psu_index].Full_Address = full_address;
- ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo = group;
- if(!ShmPsuPosition->PsuAddressInfo[psu_index].CheckIn)
- {
- ShmPsuPosition->PsuAddressInfo[psu_index].CheckIn = true;
- ShmPsuPosition->TotalPsuQuantity++;
- //LOG_INFO("SN = %d At Group %02X", SN, group);
- }
- if(ShmPsuPosition->TotalPsuQuantity == ShmPsuData->SystemInitialPsuQuantity)
- {
- byte groupNo = 0, quantity = 0;
- if(!ShmPsuPosition->PsuLocationInit)
- {
- memset(ShmPsuPosition->GroupLocationInfo, 0x00, sizeof(ShmPsuPosition->GroupLocationInfo));
- for(int i = 0; i < MAX_PSU_MODULE_QUANTITY; i++)
- {
- if(ShmPsuPosition->PsuAddressInfo[i].CheckIn)
- {
- groupNo = ShmPsuPosition->PsuAddressInfo[i].GroupNo;
- quantity = ShmPsuPosition->GroupLocationInfo[groupNo].GroupPsuQuantity;
- ShmPsuPosition->PsuAddressInfo[i].GIndex = quantity;
- ShmPsuPosition->GroupLocationInfo[groupNo].PsuIndex[quantity] = i;
- ShmPsuPosition->GroupLocationInfo[groupNo].GroupPsuQuantity++;
- //LOG_INFO("Psu %d Assign To Group %02X At %d", index, group, ShmPsuPosition->PsuAddressInfo[index].GIndex);
- }
- }
- bool match = true;
- for(int i = 0; i < _maxGroupCount; i++)
- {
- if(ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity != ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity)
- {
- match = false;
- }
- }
- if(match)
- {
- ShmPsuPosition->PsuLocationInit = true;
- }
- else
- {
- // try to re-initial psu location
- ShmPsuPosition->ReInitPsuLocation = true;
- }
- }
- }
- }
- // 0x04: PSU_RCmd_ModuleStatus_alarm_flag
- void GetAlarmFlagCallback(byte address, unsigned int alarm1, unsigned int alarm2)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(ShmPsuData->Work_Step < Get_PSU_LOCATION)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- if(ShmPsuPosition->PsuLocationInit)
- {
- }
- }
- void UpdatePsuGroupAlarmStatus(byte group)
- {
- int psu_index = 0;
- unsigned int status_or = 0, status_and = 0xFFFFFFFF;
- if(ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity > 0)
- {
- for(int i = 0; i < ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity; i++)
- {
- psu_index = ShmPsuPosition->GroupLocationInfo[group].PsuIndex[i];
- status_or |= ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal;
- status_and &= ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal;
- }
- ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal = status_or;
- ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal = status_and;
- }
- else
- {
- ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal = 0;
- ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal = 0;
- }
- }
- // 0x04: PSU_RCmd_ModuleStatus_alarm_status
- void GetAlarmStatusCallback(byte address, unsigned int status)
- {
- bool _update = false;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(ShmPsuData->Work_Step < Get_PSU_LOCATION)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- if(ShmPsuPosition->PsuLocationInit)
- {
- if(ShmPsuPosition->SinglePsuStatus[address].StatusVal != status)
- {
- _update = true;
- }
- ShmPsuPosition->SinglePsuStatus[address].StatusVal = status;
- if(_update)
- {
- UpdatePsuGroupAlarmStatus(group);
- }
- }
- }
- void GetInfyPwrAlarmFlagCallback(byte address, byte state_2, byte state_1, byte state_0)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(ShmPsuData->Work_Step < Get_PSU_LOCATION || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- unsigned int _alarmStatus = 0;
- _alarmStatus = InfyPwrStateAnalysis(address, state_0, state_1, state_2);
- GetAlarmStatusCallback(address, _alarmStatus);
- }
- void GetPhPwrAlarmFlagCallback(byte address, unsigned int status, unsigned int alarm_1, unsigned int alarm_0)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(ShmPsuData->Work_Step < Get_PSU_LOCATION)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- if(ShmPsuPosition->PsuLocationInit)
- {
- GetAlarmStatusCallback(address, status);
- }
- }
- // 0x04: PSU_RCmd_ModuleStatus_ambient
- void GetAmbientCallback(byte address, byte temp)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(ShmPsuData->Work_Step < Get_PSU_LOCATION)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- if(ShmPsuPosition->PsuLocationInit)
- {
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp1 = temp;
- }
- }
- // 0x02: PSU_RCmd_SysModuleCount
- void GetModuleCountCallback(byte group, byte count, bool summation)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if(group < _maxGroupCount)
- {
- ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity = count;
- }
- if(summation)
- {
- int total = 0;
- for(int i = 0; i < _maxGroupCount; i++)
- {
- total += ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity;
- }
- if(ShmPsuData->Work_Step == GET_PSU_COUNT)
- {
- ShmPsuData->SystemInitialPsuQuantity = total;
- }
- ShmPsuData->SystemPresentPsuQuantity = total;
- }
- }
- // 0x02: PSU_RCmd_SysModuleCount_SystemPresentPsuQuantity
- void GetSysModuleCountCallback(byte group, byte count)
- {
- if(ShmPsuData->Work_Step == GET_PSU_COUNT)
- {
- ShmPsuData->SystemInitialPsuQuantity = count;
- }
- ShmPsuData->SystemPresentPsuQuantity = count;
- }
- void UpdateGunAvailableCapability(unsigned char group)
- {
- int _availableCurrent = 0, _availablePower = 0, _realPower = 0;
- unsigned char master = 0;
- master = ShmChargerInfo->PsuGrouping.GroupCollection[group].TargetGroup;
- // calculate output group capability
- if(master == 0)
- {
- chargingInfo[group]->AvailableChargingCurrent = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
- chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
- chargingInfo[group]->RealRatingPower = ShmPsuData->PsuGroup[group].GroupRealOutputPower * 10;
- }
- else
- {
- if(ShmPsuGrouping->GroupCollection[master - 1].Role == _GROLE_MASTER)
- {
- _availableCurrent = ShmPsuData->PsuGroup[master - 1].GroupAvailableCurrent;
- _availablePower = ShmPsuData->PsuGroup[master - 1].GroupAvailablePower;
- _realPower = ShmPsuData->PsuGroup[master - 1].GroupRealOutputPower * 10;
- for(byte i = 0; i < ShmPsuGrouping->GroupCollection[master - 1].Partner.Quantity; i++)
- {
- byte slave = ShmPsuGrouping->GroupCollection[master - 1].Partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE ||
- ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PREPARE_SWITCH_OFF)
- {
- _availableCurrent += ShmPsuData->PsuGroup[slave].GroupAvailableCurrent;
- _availablePower += ShmPsuData->PsuGroup[slave].GroupAvailablePower;
- _realPower += ShmPsuData->PsuGroup[slave].GroupRealOutputPower * 10;
- }
- }
- if(ShmPsuGrouping->GroupCollection[master - 1].GroupCtrl.bits.DeratingConfirmed)
- {
- chargingInfo[master - 1]->AvailableChargingCurrent = ShmPsuGrouping->GroupCollection[master - 1].ReAssignAvailableCurrent;
- }
- else
- {
- chargingInfo[master - 1]->AvailableChargingCurrent = _availableCurrent;
- }
- chargingInfo[master - 1]->AvailableChargingPower = _availablePower;
- chargingInfo[master - 1]->RealRatingPower = _realPower;
- // if((master - 1) != group)
- // {
- // chargingInfo[group]->AvailableChargingCurrent = 0;;
- // chargingInfo[group]->AvailableChargingPower = 0;
- // chargingInfo[group]->RealRatingPower = 0;
- // }
- }
- }
- }
- void UpdateSystemAvailable(void)
- {
- int _sysCurrent = 0, _sysPower = 0;
- // summation of system current & power
- for(byte i = 0; i < _maxGroupCount; i++)
- {
- _sysCurrent += ShmPsuData->PsuGroup[i].GroupAvailableCurrent;
- _sysPower += ShmPsuData->PsuGroup[i].GroupAvailablePower;
- }
- ShmPsuData->SystemAvailableCurrent = _sysCurrent;
- ShmPsuData->SystemAvailablePower = _sysPower;
- }
- // maxVol, minVol unit: 0.1V
- // maxCur unit: 0.1A
- // totalPow unit: 0.1kW
- // 0x0A: PSU_RCmd_ModuleCapability
- void GetAvailableCapCallback(byte address, short maxVol, short minVol, short maxCur, short totalPow)
- {
- int _groupCurrent = 0, _groupPower = 0;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- byte master = 0;
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- // calculate psu module available power
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].AvailablePower = totalPow;
- //if(ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage >= PSU_MIN_VOL)
- if(ShmPsuGrouping->GroupOutput[group].GTargetVoltage >= PSU_MIN_VOL)
- {
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].AvailableCurrent =
- ((ShmPsuData->PsuGroup[group].PsuModule[gIndex].AvailablePower * 100) * 10) / (ShmPsuGrouping->GroupOutput[group].GTargetVoltage / 10);
- }
- else
- {
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].AvailableCurrent = maxCur > PSU_MAX_CUR ? PSU_MAX_CUR : maxCur;
- }
- // summation of psu group current & power
- for(byte i = 0; i < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; i++)
- {
- _groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[i].AvailableCurrent;
- _groupPower += ShmPsuData->PsuGroup[group].PsuModule[i].AvailablePower;
- }
- if(ShmPsuData->PsuGroup[group].StableIAvailableCurrent != 0)
- {
- ShmPsuData->PsuGroup[group].GroupAvailableCurrent = ShmPsuData->PsuGroup[group].StableIAvailableCurrent;
- }
- else
- {
- if(ShmPsuData->PsuGroup[group].GroupRealOutputPower != 0 &&
- ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage >= PSU_MIN_VOL)
- {
- ShmPsuData->PsuGroup[group].GroupAvailableCurrent = ((ShmPsuData->PsuGroup[group].GroupRealOutputPower * 1000) * 10) / (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10);
- }
- else
- {
- ShmPsuData->PsuGroup[group].GroupAvailableCurrent = _groupCurrent;
- }
- }
- ShmPsuData->PsuGroup[group].GroupAvailablePower = _groupPower;
- // update MaximumChargingVoltage
- master = ShmChargerInfo->PsuGrouping.GroupCollection[group].TargetGroup;
- if(master == 0)
- {
- chargingInfo[group]->MaximumChargingVoltage = maxVol;
- }
- else
- {
- if(ShmPsuGrouping->GroupCollection[master - 1].Role == _GROLE_MASTER)
- {
- chargingInfo[master - 1]->MaximumChargingVoltage = maxVol;
- // if((master - 1) != group)
- // {
- // chargingInfo[group]->MaximumChargingVoltage = 0;
- // }
- }
- }
- UpdateGunAvailableCapability(group);
- UpdateSystemAvailable();
- //LOG_INFO("address = %d, maxVol = %d, minVol = %d, maxCur = %d, totalPow = %d", address, maxVol, minVol, maxCur, totalPow);
- }
- // 0x07: PSU_RCmd_ModuleVersion
- void GetFwCallback(byte address, short dcSwVer, short pfcSwVer, short hwVer)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step != Get_PSU_VERSION || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- sprintf((char *)ShmPsuData->PsuVersion[address].FwPrimaryVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
- sprintf((char *)ShmPsuData->PsuVersion[address].FwSecondVersion, "PFC %d.%02d", (pfcSwVer & 0xFF00) >> 8, pfcSwVer & 0xFF);
- sprintf((char *)ShmPsuData->PsuGroup[group].PsuModule[gIndex].FwVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
- //LOG_INFO("Psu %d %s %s", address, ShmPsuData->PsuVersion[address].FwPrimaryVersion, ShmPsuData->PsuVersion[address].FwSecondVersion);
- }
- // 0x07: PSU_RCmd_ModuleVersion_dc
- void GetDcFwCallback(byte address, char *dcSwVer)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step != Get_PSU_VERSION || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- strcpy((char *)ShmPsuData->PsuVersion[address].FwPrimaryVersion, dcSwVer);
- strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[gIndex].FwVersion, dcSwVer);
- }
- // 0x07: PSU_RCmd_ModuleVersion_pfc
- void GetPfcFwCallback(byte address, char *pfcSwVer)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step != Get_PSU_VERSION || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- strcpy((char *)ShmPsuData->PsuVersion[address].FwSecondVersion, pfcSwVer);
- }
- // no using -- GetInputVoltageCallback
- void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL1 = vol1;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL2 = vol2;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL3 = vol3;
- }
- // no using -- GetInputVoltageCallback End
- // no using -- GetPresentOutputCallback
- void GetPresentOutputCallback(byte group, unsigned short outVol, unsigned short outCur)
- {
- }
- // no using -- GetPresentOutputCallback End
- // type 1: FAN_SPEED_CMD
- // type 2: TEMP_DC_CMD
- // type 3: TEMP_PFC_CMD
- // 0x0E: PSU_RCmd_ModuleMiscInfo
- void GetMisCallback(byte address, unsigned int value, byte type)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- if (type == 1)
- {
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_1 = value;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_2 = value;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_3 = value;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_4 = value;
- }
- else if (type == 2)
- {
- //ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp1 = value;
- //ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp2 = value;
- //ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp3 = value;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].ExletTemp = value;
- }
- else if (type == 3)
- {
- //printf("PFC - group = %d, index = %d, value = %d \n", group, address, value);
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp = value;
- }
- }
- // 0x0E: PSU_RCmd_ModuleMiscInfo_FanSpeed
- void GetFanSpeedCallback(byte address, unsigned int speed)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_1 = speed;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_2 = speed;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_3 = speed;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].FanSpeed_4 = speed;
- }
- // 0x0E: PSU_RCmd_ModuleMiscInfo_InletTemp
- void GetInletTempCallback(byte address, char temp)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp = temp;
- }
- // 0x0E: PSU_RCmd_ModuleMiscInfo_ExletTemp
- void GetExletTempCallback(byte address, char temp)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].ExletTemp = temp;
- }
- // 0x0E: PSU_RCmd_ModuleMiscInfo_OutletTemp
- void GetOutletTempCallback(byte address, char temp)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].OutletTemp = temp;
- }
- // temp1: dd in 1
- // temp2: dd in 2
- // temp3: dd out 1
- // temp4: dd out 2
- // 0x0E: PSU_RCmd_ModuleMiscInfo_OtherTemp
- void GetOtherTempCallback(byte address, char temp1, char temp2, char temp3, char temp4)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp_1 = temp1;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InletTemp_2 = temp2;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp2 = temp3;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp3 = temp4;
- }
- // Iavail unit: 0.1A
- // Vext unit: 0.1V
- // 0x0C: PSU_RCmd_ModuleIAvailable
- // 0x02CCF0XX
- void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- byte master = 0;
- unsigned short diffIAvailable = 0;
- int totalCurrent = 0;
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].IAvailableCurrent = Iavail;
- // summation of psu group i available current
- for (byte i = 0; i < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; i++)
- {
- totalCurrent += ShmPsuData->PsuGroup[group].PsuModule[i].IAvailableCurrent;
- }
- ShmPsuData->PsuGroup[group].TotalIAvailableCurrent = totalCurrent;
- diffIAvailable = totalCurrent >= ShmPsuData->PsuGroup[group].TempIAvailableCurrent ?
- totalCurrent - ShmPsuData->PsuGroup[group].TempIAvailableCurrent : ShmPsuData->PsuGroup[group].TempIAvailableCurrent - totalCurrent;
- if(diffIAvailable > STABLE_CURRENT_TOLERANCE)
- {
- ShmPsuData->PsuGroup[group].StableCurrentCounter = 0;
- ShmPsuData->PsuGroup[group].StableIAvailableCurrent = 0;
- }
- ShmPsuData->PsuGroup[group].TempIAvailableCurrent = ShmPsuData->PsuGroup[group].TotalIAvailableCurrent;
- ShmPsuData->PsuGroup[group].StableCurrentCounter++;
- if(ShmPsuData->PsuGroup[group].StableCurrentCounter >= MAX_STABLE_COUNT)
- {
- // get stable StableIAvailableCurrent
- ShmPsuData->PsuGroup[group].StableIAvailableCurrent = ShmPsuData->PsuGroup[group].TotalIAvailableCurrent;
- // get stable GroupRealOutputPower
- ShmPsuData->PsuGroup[group].GroupRealOutputPower = (ShmPsuData->PsuGroup[group].StableIAvailableCurrent * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage) / 100 / 1000;
- ShmPsuData->PsuGroup[group].StableCurrentCounter = 0;
- }
- master = ShmChargerInfo->PsuGrouping.GroupCollection[group].TargetGroup;
- if(master == 0)
- {
- // unit: 0.1A
- chargingInfo[group]->DeratingChargingCurrent = ShmPsuData->PsuGroup[group].StableIAvailableCurrent;
- chargingInfo[group]->DeratingChargingPower = (chargingInfo[group]->DeratingChargingCurrent * chargingInfo[group]->PresentChargingVoltage) / 10 / 100;
- }
- else
- {
- // calculate DeratingChargingCurrent of master group
- totalCurrent = ShmPsuData->PsuGroup[master - 1].StableIAvailableCurrent;
- for(byte i = 0; i < ShmPsuGrouping->GroupCollection[master - 1].Partner.Quantity; i++)
- {
- byte slave = ShmPsuGrouping->GroupCollection[master - 1].Partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE)
- {
- totalCurrent += ShmPsuData->PsuGroup[slave].StableIAvailableCurrent;
- }
- }
- chargingInfo[master - 1]->DeratingChargingCurrent = totalCurrent;
- chargingInfo[master - 1]->DeratingChargingPower = (chargingInfo[master - 1]->DeratingChargingCurrent * chargingInfo[master - 1]->PresentChargingVoltage) / 10 / 100;
- if((master - 1) != group)
- {
- chargingInfo[group]->DeratingChargingCurrent = 0;
- chargingInfo[group]->DeratingChargingPower = 0;
- }
- }
- }
- // outVol unit: 1V
- // outCur unit: 1A
- // 0x01: PSU_RCmd_SysOutputVolCur_F
- void GetPresentOutputFCallback(byte group, float outVol, float outCur)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || group >= _maxGroupCount ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- byte master = 0;
- unsigned short pVoltage = 0, pCurrent = 0;
- unsigned short gVoltage = 0, gCurrent = 0;
- pVoltage = isinf(outVol) == 0 ? (unsigned short)(outVol * 10) : 0;
- pCurrent = isinf(outCur) == 0 ? (unsigned short)(outCur * 10) : 0;
- ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = pVoltage;
- ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = pCurrent;
- ShmPsuData->PsuGroup[group].GroupPresentOutputPower = (pVoltage * pCurrent) / 100 / 100;
- master = ShmChargerInfo->PsuGrouping.GroupCollection[group].TargetGroup;
- if(master == 0)
- {
- // calculate PresentChargingVoltage and PresentChargingCurrent of self group
- chargingInfo[group]->PresentChargingVoltage = (float)ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10;
- chargingInfo[group]->PresentChargingCurrent = (float)ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent / 10;
- }
- else
- {
- // calculate PresentChargingVoltage and PresentChargingCurrent of master group
- gVoltage = ShmPsuData->PsuGroup[master - 1].GroupPresentOutputVoltage;
- gCurrent = ShmPsuData->PsuGroup[master - 1].GroupPresentOutputCurrent;
- for(byte i = 0; i < ShmPsuGrouping->GroupCollection[master - 1].Partner.Quantity; i++)
- {
- byte slave = ShmPsuGrouping->GroupCollection[master - 1].Partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE ||
- ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PREPARE_SWITCH_OFF ||
- ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE_POWER_OFF)
- {
- if(ShmPsuData->PsuGroup[slave].GroupPresentOutputVoltage > gVoltage)
- {
- gVoltage = ShmPsuData->PsuGroup[slave].GroupPresentOutputVoltage;
- }
- gCurrent += ShmPsuData->PsuGroup[slave].GroupPresentOutputCurrent;
- }
- }
- chargingInfo[master - 1]->PresentChargingVoltage = (float)gVoltage / 10;
- chargingInfo[master - 1]->PresentChargingCurrent = (float)gCurrent / 10;
- if((master - 1) != group)
- {
- chargingInfo[group]->PresentChargingVoltage = 0;
- chargingInfo[group]->PresentChargingCurrent = 0;
- }
- }
- }
- // outVol unit: 1V
- // outCur unit: 1A
- void GetModuleOutputCallback(byte address, float outVol, float outCur)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- unsigned short voltage = isinf(outVol) == 0 ? (unsigned short)(outVol * 10) : 0;
- unsigned short current = isinf(outCur) == 0 ? (unsigned short)(outCur * 10) : 0;
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].PresentOutputVoltage = voltage;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].PresentOutputCurrent = current;
- }
- // phihong pwr only
- void GetErrorRecordCallback(byte psu_index, byte count_down, byte *error_record)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int err_cnt = 0;
- bool _change = false;
- for(int i = 0; i < 7; i++)
- {
- if(error_record[i] != 0)
- {
- err_cnt++;
- if(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError[i] != error_record[i] || _change)
- {
- _change = true;
- }
- }
- else
- {
- break;
- }
- }
- if(_change)
- {
- memset(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError, 0x00, sizeof(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError));
- memcpy(ShmPsuPosition->SinglePhPsuError[psu_index].PsuError, error_record, err_cnt);
- }
- else
- {
- _change = ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount != err_cnt ? true : false;
- }
- ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount = err_cnt;
- ShmPsuPosition->SinglePhPsuError[psu_index].PhPwrStateFlag.bits.Changed |= _change;
- }
- //==========================================
- // 特規用指令
- //==========================================
- // 0x1901: Nexton_PSU_DcOutputValue
- void GetOutputAndTempCallback(byte address, unsigned short outputVol_s,
- unsigned short outputCur_s, unsigned short outputPower, unsigned char Temperature)
- {
- return;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- //ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp1 = Temperature;
- //ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp2 = Temperature;
- //ShmPsuData->PsuGroup[group].PsuModule[gIndex].CriticalTemp3 = Temperature;
- }
- // 0x1902: Nexton_PSU_StatusEvent
- void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status,
- unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4)
- {
- return;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- int alarm = (err4 << 24) | (err3 << 16) | (err2 << 8) | err1;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].AlarmCode = alarm;
- AbnormalStopAnalysis(group, alarm);
- if(isErr)
- {
- // 012267
- //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
- ShmPsuData->PsuGroup[group].GroupErrorFlag.bits.PsuFailure = true;
- }
- }
- // 0x1903: Nexton_PSU_AcInputValue
- void GetModuleInputCallback(byte address, unsigned short inputR,
- unsigned short inputS, unsigned short inputT)
- {
- return;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt++;
- if (ShmPsuData->Work_Step < GET_SYS_CAP || address >= ShmPsuData->SystemInitialPsuQuantity ||
- !ShmPsuPosition->PsuLocationInit)
- {
- return;
- }
- int group = FindTargetGroup(address);
- int gIndex = FindGroupIndex(address);
- if(group < 0 || gIndex < 0)
- {
- return;
- }
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL1 = inputR;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL2 = inputS;
- ShmPsuData->PsuGroup[group].PsuModule[gIndex].InputVoltageL3 = inputT;
- }
- //==========================================
- // Init all share memory
- //==========================================
- int InitShareMemory()
- {
- int result = PASS;
- int MeterSMId;
- //creat ShmSysConfigAndInfo
- if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmget ShmSysConfigAndInfo NG %d");
- #endif
- result = FAIL;
- }
- else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmat ShmSysConfigAndInfo NG");
- #endif
- result = FAIL;
- }
- else
- {}
- //creat ShmStatusCodeData
- if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmget ShmStatusCodeData NG");
- #endif
- result = FAIL;
- }
- else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmat ShmStatusCodeData NG");
- #endif
- result = FAIL;
- }
- else
- {}
- //creat ShmPsuData
- if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmget ShmPsuData NG");
- #endif
- result = FAIL;
- }
- else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmat ShmPsuData NG");
- #endif
- result = FAIL;
- }
- if ((MeterSMId = shmget(SM_ChargerInfoKey, sizeof(ChargerInfoData), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmat ChargerInfoData NG");
- #endif
- result = FAIL;
- }
- else if ((ShmChargerInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("shmat ChargerInfoData NG");
- #endif
- result = FAIL;
- }
- if(result == PASS)
- {
- ShmPsuPosition = &ShmChargerInfo->PsuPosition;
- ShmPsuGrouping = &ShmChargerInfo->PsuGrouping;
- }
- return result;
- }
- //================================================
- // Main process
- //================================================
- void InitialPsuData(void)
- {
- ShmPsuData->SystemInitialPsuQuantity = 0;
- ShmPsuData->SystemPresentPsuQuantity = 0;
- ShmPsuData->SystemAvailablePower = 0;
- LOG_INFO("************ psu Group = %d", ShmPsuData->GroupCount);
- for (byte _groupCount = 0; _groupCount < ShmPsuData->GroupCount; _groupCount++)
- {
- ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
- ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
- ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
- ShmPsuData->PsuGroup[_groupCount].GroupErrorFlag.PsuGroupErrorValue = 0;
- }
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCommunicationFail = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFault = NO;
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = NO;
- memset(_LocalPsuStatus, 0x00, sizeof(_LocalPsuStatus));
- memset(_Psu_Indication_Enable, 0x00, sizeof(_Psu_Indication_Enable));
- memset(_Psu_Indication_Count, 0x00, sizeof(_Psu_Indication_Count));
- memset(&ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR, 0x00, sizeof(ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR));
- memset(&ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND, 0x00, sizeof(ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND));
- }
- void Initialization()
- {
- bool isPass = false;
- while(!isPass)
- {
- isPass = true;
- for (byte _index = 0; _index < _maxGroupCount; _index++)
- {
- if (!FindChargingInfoData(_index, &chargingInfo[0]))
- {
- LOG_ERROR("Module_PsuComm : FindChargingInfoData false");
- isPass = false;
- break;
- }
- }
- sleep(1);
- }
- ShmPsuData->GroupCount = _maxGroupCount;
- }
- bool Is_PsuRxComm_Alive(void)
- {
- if(_RxPsuPid > 0)
- {
- if(kill(_RxPsuPid, 0) == 0)
- {
- // Process exists.
- return true;
- }
- }
- return false;
- }
- void Run_PsuRxCommProcess(void)
- {
- _RxPsuPid = InitialCommunication();
- LOG_INFO("Create PsuRx PID = %d", _RxPsuPid);
- }
- void PsuReceiveRecoveryCheck(void)
- {
- char *ptrSave, *ptrToken;
- int fd, psuTaskCount = 0;
- char pathBuffer[64], psuTaskPidString[64];
- system("pidof Module_PsuComm > /tmp/Module_PsuTask");
- snprintf(pathBuffer, sizeof(pathBuffer), "/tmp/Module_PsuTask");
- fd = open(pathBuffer, O_RDWR);
- if(fd < 0)
- {
- close(fd);
- return;
- }
- if(read(fd, psuTaskPidString, 64) < 0)
- {
- close(fd);
- return;
- }
- ptrToken = strtok_r(psuTaskPidString, " ", &ptrSave);
- while(ptrToken != NULL)
- {
- int psuPid = atoi(ptrToken);
- if(psuPid > 0)
- {
- psuTaskCount++;
- }
- ptrToken = strtok_r(NULL, " ", &ptrSave);
- }
- close(fd);
- if(psuTaskCount == 1)
- {
- LOG_INFO("************ PSU Receive Task Need Recovery ************\n");
- Run_PsuRxCommProcess();
- psuReceiveRecovery = true;
- }
- }
- void ShowGroupMember(unsigned char group)
- {
- if(group < MAX_GROUP_QUANTITY)
- {
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- for(byte psu = 0; psu < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; psu++)
- {
- LOG_INFO("Group %d - Number = %d, SN = %02X", group + 1, psu,
- ShmPsuPosition->GroupLocationInfo[group].PsuIndex[psu]);
- }
- }
- }
- }
- void ShowPsuVersion(unsigned char group)
- {
- if(group < MAX_GROUP_QUANTITY)
- {
- if(ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity > 0)
- {
- LOG_INFO("Group %d PSU Version Info", group + 1);
- for(int i = 0; i < ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity; i++)
- {
- int psuIndex = ShmPsuPosition->GroupLocationInfo[group].PsuIndex[i];
- LOG_INFO("PSU Primary: %s, Second: %s",
- ShmPsuData->PsuVersion[psuIndex].FwPrimaryVersion,
- ShmPsuData->PsuVersion[psuIndex].FwSecondVersion);
- }
- }
- }
- }
- void ShowGroupAvailableCurrentPower(unsigned char group)
- {
- if(group < MAX_GROUP_QUANTITY)
- {
- LOG_INFO("Group %d Available Current = %3d.%dA, Power = %3d.%dkW", group + 1,
- (ShmPsuData->PsuGroup[group].GroupAvailableCurrent / 10), (ShmPsuData->PsuGroup[group].GroupAvailableCurrent % 10),
- (ShmPsuData->PsuGroup[group].GroupAvailablePower / 10), (ShmPsuData->PsuGroup[group].GroupAvailablePower % 10));
- }
- }
- unsigned char _TempType = 0;
- void PsuGroupRoutineQuery(void)
- {
- for(byte group = 0; group < GENERAL_GUN_QUANTITY; group++)
- {
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- if (psuCmdSeq == _PSU_CMD_CAP)
- {
- // 取系統總輸出能力
- GetModuleCap(group);
- }
- else if (psuCmdSeq == _PSU_CMD_OUTPUT)
- {
- // 取各群輸出電壓電流 (float)
- GetModuleOutputF(group);
- }
- else if (psuCmdSeq == _PSU_CMD_IVAILIABLE)
- {
- // 取得模塊輸出額定電流能力
- unsigned short voltage = 0;
- if(ShmPsuGrouping->GroupCollection[group].TargetGroup == 0)
- {
- voltage = (unsigned short)(chargingInfo[group]->FireChargingVoltage);
- }
- else
- {
- voltage = (unsigned short)(chargingInfo[ShmPsuGrouping->GroupCollection[group].TargetGroup - 1]->FireChargingVoltage);
- }
- GetModuleIavailable(group, voltage);
- }
- else if (psuCmdSeq == _PSU_CMD_TEMP)
- {
- // 取得模塊溫度
- if(_TempType == _PSU_TMP_DCDC)
- {
- GetDcTemperature(group);
- }
- else
- {
- GetPfcTemperature(group);
- }
- }
- }
- }
- if(psuCmdSeq == _PSU_CMD_CAP)
- {
- psuCmdSeq = _PSU_CMD_OUTPUT;
- }
- else if(psuCmdSeq == _PSU_CMD_OUTPUT)
- {
- psuCmdSeq = _PSU_CMD_IVAILIABLE;
- }
- else if(psuCmdSeq == _PSU_CMD_IVAILIABLE)
- {
- psuCmdSeq = _PSU_CMD_TEMP;
- _TempType = _TempType == _PSU_TMP_DCDC ? _PSU_TMP_PFC : _PSU_TMP_DCDC;
- }
- else
- {
- psuCmdSeq = _PSU_CMD_CAP;
- }
- }
- void SetPsuGroupRole(byte group, byte role)
- {
- if(group < GENERAL_GUN_QUANTITY)
- {
- ShmPsuGrouping->GroupCollection[group].Role = role;
- }
- }
- void SetPsuGroupToIdle(byte group)
- {
- if(group < GENERAL_GUN_QUANTITY)
- {
- SetPsuGroupRole(group, _GROLE_IDLE);
- memset(&ShmPsuGrouping->GroupCollection[group].Partner, 0x00, sizeof(PsuGroupPartner));
- memset(&ShmPsuGrouping->GroupCollection[group].PossibleMember, 0x00, sizeof(PsuGroupPartner));
- ShmPsuGrouping->GroupCollection[group].TargetGroup = 0;
- ShmPsuGrouping->GroupCollection[group].ReservedTarget = 0;
- //LOG_INFO("Reset Group[%02X] To Idle", group);
- }
- }
- // group: self group index
- void SetPsuGroupToMaster(byte group)
- {
- if(group < GENERAL_GUN_QUANTITY)
- {
- SetPsuGroupRole(group, _GROLE_MASTER);
- ShmPsuGrouping->GroupCollection[group].TargetGroup = group + 1;
- //LOG_INFO("Set Group[%02X] As Master To Gun %d", group, group + 1);
- }
- }
- // group: self group index
- // target: target group index + 1
- void SetPsuGroupToSlave(byte group, byte target)
- {
- if(group < GENERAL_GUN_QUANTITY && target <= GENERAL_GUN_QUANTITY)
- {
- SetPsuGroupRole(group, _GROLE_SLAVE);
- ShmPsuGrouping->GroupCollection[group].TargetGroup = target;
- ShmPsuGrouping->GroupCollection[group].ReservedTarget = 0;
- memset(&ShmPsuGrouping->GroupCollection[group].PossibleMember, 0x00, sizeof(PsuGroupPartner));
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.SlaveCtrlValue = 0;
- //LOG_INFO("Set Group[%02X] As Slave To Gun %d", group, target);
- }
- }
- // target: target group index + 1
- // tPartner: set member to power off
- void PrepareToPowerOff(byte target, PsuGroupPartner *tPartner)
- {
- unsigned char master = 0, slave = 0;
- char strMember[64];
- bool find = false;
- sprintf(strMember, "Set Member:");
- for(int i = 0; i < tPartner->Quantity; i++)
- {
- slave = tPartner->Member[i];
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- SetPsuGroupRole(slave, _GROLE_PREPARE_SWITCH_OFF);
- ShmPsuGrouping->GroupCollection[slave].ReservedTarget = target;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedDerating = true;
- char strSlave[8];
- sprintf(strSlave, " [%02X]", slave);
- strcat(strMember, strSlave);
- find = true;
- }
- if(find)
- {
- char strTemp[32];
- if(target != 0)
- {
- sprintf(strTemp, " Prepare To Change To Gun %d", target);
- }
- else
- {
- sprintf(strTemp, " Prepare To Power Of");
- }
- strcat(strMember, strTemp);
- LOG_INFO("%s", strMember);
- }
- }
- // target: target group index + 1
- // tPartner: set member to prepare to attach on
- void PrepareToExtendCapability(byte target, PsuGroupPartner *tPartner)
- {
- char strMember[64];
- sprintf(strMember, "Set Member:");
- for(int i = 0; i < tPartner->Quantity; i++)
- {
- SetPsuGroupRole(tPartner->Member[i], _GROLE_PREPARE_ATTACH_ON);
- ShmPsuGrouping->GroupCollection[tPartner->Member[i]].ReservedTarget = target;
- char strSlave[8];
- sprintf(strSlave, " [%02X]", tPartner->Member[i]);
- strcat(strMember, strSlave);
- }
- if(tPartner->Quantity > 0)
- {
- char strTemp[32];
- sprintf(strTemp, " Prepare To Attach To Gun %d", target);
- strcat(strMember, strTemp);
- LOG_INFO("%s", strMember);
- }
- }
- void FindPsuGroupPartner(byte master, int condition, PsuGroupPartner *tPartner, int type, int quantityLimit)
- {
- int slave = 0, location = 0;
- PsuGroupPartner partner;
- int extendPower = 0;
- bool done = false;
- int parallelRelay = 0;
- unsigned short parallelFlag = 0;
- memset(&partner, 0x00, sizeof(PsuGroupPartner));
- // search from left
- location = ShmPsuGrouping->GroupCollection[master].Location - 1;
- for(int i = location; i >= 0; i--)
- {
- switch(type)
- {
- case _EXTEND_TYPE_QUANTITY:
- if(partner.Quantity >= condition)
- {
- done = true;
- }
- break;
- case _EXTEND_TYPE_POWER:
- if(extendPower >= condition)
- {
- done = true;
- }
- break;
- default:
- done = true;
- break;
- }
- if(done || partner.Quantity >= quantityLimit)
- {
- break;
- }
- slave = ShmPsuGrouping->Layout[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_IDLE ||
- (ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_WAIT_SLAVE && (ShmPsuGrouping->GroupCollection[slave].ReservedTarget - 1) == master))
- {
- parallelRelay = ShmPsuGrouping->GroupCollection[master].ParallelConfig[slave];
- parallelFlag |= parallelRelay != 0 ? (1 << (parallelRelay - 1)) : 0;
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity > 0)
- {
- partner.Member[partner.Quantity] = slave;
- partner.ParallelFlag[partner.Quantity] = parallelFlag;
- partner.Quantity++;
- extendPower += (ShmPsuData->PsuGroup[slave].GroupAvailablePower / 10);
- parallelFlag = 0;
- }
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay)
- {
- parallelFlag = 0;
- }
- }
- else
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- // Enable6ParallelRelay = 0, need to check slave is the same target or not
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE && master == (ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1))
- {
- continue;
- }
- break;
- }
- }
- }
- parallelFlag = 0;
- // search from right
- location = ShmPsuGrouping->GroupCollection[master].Location + 1;
- for(int i = location; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- switch(type)
- {
- case _EXTEND_TYPE_QUANTITY:
- if(partner.Quantity >= condition)
- {
- done = true;
- }
- break;
- case _EXTEND_TYPE_POWER:
- if(extendPower >= condition)
- {
- done = true;
- }
- break;
- default:
- done = true;
- break;
- }
- if(done || partner.Quantity >= quantityLimit)
- {
- break;
- }
- slave = ShmPsuGrouping->Layout[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_IDLE ||
- (ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_WAIT_SLAVE && (ShmPsuGrouping->GroupCollection[slave].ReservedTarget - 1) == master))
- {
- parallelRelay = ShmPsuGrouping->GroupCollection[master].ParallelConfig[slave];
- parallelFlag |= parallelRelay != 0 ? (1 << (parallelRelay - 1)) : 0;
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity > 0)
- {
- partner.Member[partner.Quantity] = slave;
- partner.ParallelFlag[partner.Quantity] = parallelFlag;
- partner.Quantity++;
- extendPower += (ShmPsuData->PsuGroup[slave].GroupAvailablePower / 10);
- parallelFlag = 0;
- }
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay)
- {
- parallelFlag = 0;
- }
- }
- else
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- // Enable6ParallelRelay = 0, need to check slave is the same target or not
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE && master == (ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1))
- {
- continue;
- }
- break;
- }
- }
- }
- memcpy(tPartner, &partner, sizeof(PsuGroupPartner));
- }
- int GetPsuGroupAvailable(byte group)
- {
- PsuGroupPartner partner;
- FindPsuGroupPartner(group, MAX_GROUP_QUANTITY, &partner, _EXTEND_TYPE_QUANTITY, MAX_GROUP_QUANTITY);
- return partner.Quantity;
- }
- // return quantity which role is _GROLE_MASTER
- int FindChargingMasterQuantity(void)
- {
- int quantity = 0;
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- if(ShmPsuGrouping->GroupCollection[i].Role == _GROLE_MASTER)
- {
- quantity++;
- }
- }
- return quantity;
- }
- // return total psu group quantity
- int FindTotalPsuGroupQuantity(void)
- {
- int quantity = 0;
- for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
- {
- if(ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity > 0)
- {
- quantity++;
- }
- }
- return quantity;
- }
- void ShowGunPrioritySequence(unsigned char *sequence, int quantity)
- {
- char strSequence[256];
- sprintf(strSequence, "Priority Sequence:");
- for(int i = 0; i < quantity; i++)
- {
- char strGun[32];
- sprintf(strGun, " [Gun %d: %d kW]",
- sequence[i] + 1,
- (int)ShmPsuGrouping->GroupCollection[sequence[i]].DiffPower_PhysicalLimit);
- strcat(strSequence, strGun);
- }
- PSU_LOG("%s", strSequence);
- }
- void CheckExtendConflictPriority(unsigned char *sequence, int quantity)
- {
- bool done = true;
- int temp = 0;
- for(int i = 0; i < quantity - 1; i++)
- {
- done = true;
- for(int j = 0; j < quantity - i - 1; j++)
- {
- if(ShmPsuGrouping->GroupCollection[sequence[j + 1]].DiffPower_PhysicalLimit > ShmPsuGrouping->GroupCollection[sequence[j]].DiffPower_PhysicalLimit)
- {
- temp = sequence[j];
- sequence[j] = sequence[j + 1];
- sequence[j + 1] = temp;
- done = false;
- }
- }
- //ShowGunPrioritySequence(sequence, quantity);
- if(done)
- {
- break;
- }
- }
- }
- // return conflict reason
- int IsExtendConflict(byte master)
- {
- int available = 0, conflictMasterCnt = 0, conflictGroupCnt = 0, average = 0, remainder = 0;
- available = GetPsuGroupAvailable(master);
- if(available == 0)
- {
- return _CONFLICT_AVAILABLE;
- }
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- if(ShmPsuGrouping->GroupCollection[i].GroupCtrl.bits.ExtendAvailable ||
- ShmPsuGrouping->GroupCollection[i].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue != 0)
- {
- conflictMasterCnt++;
- conflictGroupCnt += ShmPsuGrouping->GroupCollection[i].Partner.Quantity + 1;
- }
- }
- average = conflictMasterCnt != 0 ? ((conflictGroupCnt + available) / conflictMasterCnt) : 0;
- remainder = conflictMasterCnt != 0 ? ((conflictGroupCnt + available) % conflictMasterCnt) : 0;
- if(ShmPsuGrouping->GroupCollection[master].Partner.Quantity + 1 < average)
- {
- ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit = average - ShmPsuGrouping->GroupCollection[master].Partner.Quantity - 1;
- #if PSU_DEBUG_MSG
- LOG_INFO("Gun %d Extend Average First, Quantity Limit: %d", master + 1, ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit);
- #endif
- return _CONFLICT_NONE;
- }
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- if(ShmPsuGrouping->GroupCollection[i].GroupCtrl.bits.ExtendAvailable ||
- ShmPsuGrouping->GroupCollection[i].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue != 0)
- {
- if(ShmPsuGrouping->GroupCollection[i].Partner.Quantity + 1 < average)
- {
- return _CONFLICT_AVERAGE;
- }
- }
- }
- if(remainder > 0)
- {
- int find = 0;
- CheckExtendConflictPriority(_GunIndexOfPrioritySequence, MAX_GROUP_QUANTITY);
- ShowGunPrioritySequence(_GunIndexOfPrioritySequence, MAX_GROUP_QUANTITY);
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- if(find >= remainder)
- {
- break;
- }
- if(ShmPsuGrouping->GroupCollection[_GunIndexOfPrioritySequence[i]].GroupCtrl.bits.ExtendAvailable)
- {
- find++;
- if(master == _GunIndexOfPrioritySequence[i])
- {
- ShmPsuGrouping->GroupCollection[_GunIndexOfPrioritySequence[i]].ExtendQuantityLimit = 1;
- #if PSU_DEBUG_MSG
- LOG_INFO("Gun %d Extend Via Priority First, Quantity Limit: %d", master + 1, ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit);
- #endif
- return _CONFLICT_NONE;
- }
- }
- }
- }
- return _CONFLICT_PRIORITY;
- }
- void FindGrabPartner(byte group, byte GrabMaster, PsuGroupPartner *tPartner)
- {
- bool find = false;
- int location = 0, master = 0, slave = 0;
- // find other group in the same direction
- if(ShmPsuGrouping->Location[group] < ShmPsuGrouping->Location[GrabMaster])
- {
- // find other group far to GrabMaster in the same direction
- location = ShmPsuGrouping->GroupCollection[group].Location - 1;
- for(int i = location; i >= 0; i--)
- {
- slave = ShmPsuGrouping->Layout[i];
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(master == GrabMaster)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- find = true;
- #if PSU_DEBUG_MSG
- LOG_INFO("Find Priority Partner [%02X] Far To GrabMaster At Right Side", slave);
- #endif
- break;
- }
- }
- if(!find)
- {
- // find other group near to GrabMaster in the same direction
- location = ShmPsuGrouping->GroupCollection[group].Location + 1;
- for(int i = location; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave == GrabMaster)
- {
- break;
- }
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(master == GrabMaster)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- find = true;
- #if PSU_DEBUG_MSG
- LOG_INFO("Find Priority Partner [%02X] Near To GrabMaster At Right Side", slave);
- #endif
- break;
- }
- }
- if(!find)
- {
- for(int i = ShmChargerInfo->Control.MaxConnector - 1; i >= 0; i--)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave == GrabMaster)
- {
- break;
- }
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(master == GrabMaster)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- find = true;
- #if PSU_DEBUG_MSG
- LOG_INFO("Find Priority Partner [%02X] At Right Side At Ring Mode", slave);
- #endif
- break;
- }
- }
- }
- }
- }
- if(ShmPsuGrouping->Location[group] > ShmPsuGrouping->Location[GrabMaster])
- {
- // find other group far to GrabMaster in the same direction
- location = ShmPsuGrouping->GroupCollection[group].Location + 1;
- for(int i = location; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- slave = ShmPsuGrouping->Layout[i];
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(master == GrabMaster)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- find = true;
- #if PSU_DEBUG_MSG
- LOG_INFO("Find Priority Partner [%02X] Far To GrabMaster At Left Side", slave);
- #endif
- break;
- }
- }
- if(!find)
- {
- // find other group near to GrabMaster in the same direction
- location = ShmPsuGrouping->GroupCollection[group].Location - 1;
- for(int i = location; i >= 0; i--)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave == GrabMaster)
- {
- break;
- }
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(master == GrabMaster)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- find = true;
- #if PSU_DEBUG_MSG
- LOG_INFO("Find Priority Partner [%02X] Near To GrabMaster At Left Side", slave);
- #endif
- break;
- }
- }
- if(!find)
- {
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave == GrabMaster)
- {
- break;
- }
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(master == GrabMaster)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- find = true;
- #if PSU_DEBUG_MSG
- LOG_INFO("Find Priority Partner [%02X] At Left Side At Ring Mode", slave);
- #endif
- break;
- }
- }
- }
- }
- }
- }
- // return grab success or fail
- // return tPartner with possible member
- bool PsuGroupGrabCheck(byte group, PsuGroupPartner *tPartner)
- {
- int slave = 0, target = 0, location = 0, average = 0, total = 0;
- if(ShmPsuGrouping->GroupCollection[group].Role != _GROLE_SLAVE && ShmPsuGrouping->GroupCollection[group].Role != _GROLE_REQUEST_TO_CHARGING)
- {
- return false;
- }
- memset(tPartner, 0x00, sizeof(PsuGroupPartner));
- total = GetPsuGroupAvailable(group) + 1;
- average = FindTotalPsuGroupQuantity() / (1 + FindChargingMasterQuantity());
- if(total < average)
- {
- // search from left
- location = ShmPsuGrouping->GroupCollection[group].Location - 1;
- for(int i = location; i >= 0; i--)
- {
- if(total + tPartner->Quantity < average)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE &&
- (ShmPsuGrouping->GroupCollection[group].Role == _GROLE_REQUEST_TO_CHARGING ||
- ShmPsuGrouping->GroupCollection[slave].TargetGroup == ShmPsuGrouping->GroupCollection[group].TargetGroup))
- {
- target = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if((ShmPsuGrouping->GroupCollection[target].Partner.Quantity + 1) > average)
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- }
- else
- {
- FindGrabPartner(group, target, tPartner);
- }
- }
- }
- else
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- break;
- }
- }
- }
- }
- // search from right
- location = ShmPsuGrouping->GroupCollection[group].Location + 1;
- for(int i = location; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- if(total + tPartner->Quantity < average)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE &&
- (ShmPsuGrouping->GroupCollection[group].Role == _GROLE_REQUEST_TO_CHARGING ||
- ShmPsuGrouping->GroupCollection[slave].TargetGroup == ShmPsuGrouping->GroupCollection[group].TargetGroup))
- {
- target = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if((ShmPsuGrouping->GroupCollection[target].Partner.Quantity + 1) > average)
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- tPartner->Member[tPartner->Quantity] = slave;
- tPartner->Quantity++;
- }
- else
- {
- FindGrabPartner(group, target, tPartner);
- }
- }
- }
- else
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- break;
- }
- }
- }
- }
- }
- return tPartner->Quantity > 0 ? true : false;
- }
- // return tPartner with possible member when group power off
- void PsuGroupPowerOffCheck(byte group, PsuGroupPartner *tPartner)
- {
- int master = 0, quantity = 0, location = 0;
- memset(tPartner, 0x00, sizeof(PsuGroupPartner));
- if(ShmPsuGrouping->GroupCollection[group].Role != _GROLE_SLAVE)
- {
- return;
- }
- master = ShmPsuGrouping->GroupCollection[group].TargetGroup - 1;
- quantity = ShmPsuGrouping->GroupCollection[master].Partner.Quantity;
- for(int i = 0; i < quantity; i++)
- {
- if(tPartner->Quantity == 0)
- {
- if(group == ShmPsuGrouping->GroupCollection[master].Partner.Member[i])
- {
- location = i;
- tPartner->Member[tPartner->Quantity] = group;
- tPartner->Quantity++;
- }
- }
- else
- {
- // find other group in the same direction
- if(ShmPsuGrouping->Location[ShmPsuGrouping->GroupCollection[master].Partner.Member[location]] < ShmPsuGrouping->Location[master])
- {
- if(ShmPsuGrouping->Location[ShmPsuGrouping->GroupCollection[master].Partner.Member[i]] < ShmPsuGrouping->Location[master])
- {
- tPartner->Member[tPartner->Quantity] = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- tPartner->Quantity++;
- //printf("\r\n Find Other Group %02X In The Same Direction", ShmPsuGrouping->GroupCollection[master].Partner.Member[i]);
- }
- }
- if(ShmPsuGrouping->Location[ShmPsuGrouping->GroupCollection[master].Partner.Member[location]] > ShmPsuGrouping->Location[master])
- {
- if(ShmPsuGrouping->Location[ShmPsuGrouping->GroupCollection[master].Partner.Member[i]] > ShmPsuGrouping->Location[master])
- {
- tPartner->Member[tPartner->Quantity] = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- tPartner->Quantity++;
- //printf("\r\n Find Other Group %02X In The Same Direction", ShmPsuGrouping->GroupCollection[master].Partner.Member[i]);
- }
- }
- }
- }
- }
- void UpdateGunTotalPsuQuantity(int master)
- {
- ShmPsuGrouping->GroupCollection[master].GunPsuQuantity = GetPsuModuleQuantity(master);
- }
- // group: group index, target: target index
- // master: master group index
- void AddMember(byte group, byte master, unsigned short flag)
- {
- if(group < GENERAL_GUN_QUANTITY && master < GENERAL_GUN_QUANTITY)
- {
- if(ShmPsuGrouping->GroupCollection[master].Role != _GROLE_MASTER &&
- ShmPsuGrouping->GroupCollection[master].Role != _GROLE_REQUEST_TO_CHARGING)
- {
- return;
- }
- if(ShmPsuGrouping->GroupCollection[group].Role != _GROLE_IDLE &&
- ShmPsuGrouping->GroupCollection[group].Role != _GROLE_WAIT_SLAVE &&
- ShmPsuGrouping->GroupCollection[group].Role != _GROLE_PRECHARGE_READY)
- {
- return;
- }
- SetPsuGroupToSlave(group, master + 1);
- ShmPsuGrouping->GroupCollection[master].Partner.Member[ShmPsuGrouping->GroupCollection[master].Partner.Quantity] = group;
- ShmPsuGrouping->GroupCollection[master].Partner.ParallelFlag[ShmPsuGrouping->GroupCollection[master].Partner.Quantity] = flag;
- ShmPsuGrouping->GroupCollection[master].Partner.Quantity++;
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity++;
- //ShmPsuGrouping->GroupCollection[master].GunPsuQuantity += ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity;
- UpdateGunTotalPsuQuantity(master);
- #if PSU_DEBUG_MSG
- LOG_INFO("Gun %d Add Group [%02X], Quantity: %d (%d), Flag: %04X",
- master + 1, group, ShmPsuGrouping->GroupCollection[master].Partner.Quantity,
- ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity, flag);
- #endif
- }
- //printf("\r\n Add Group %02X To Gun %d (Quantity %d), Set Parallel Relay %d On", group, target + 1, ShmPsuGrouping->GroupCollection[target].Partner.Quantity, ParallelConfig);
- }
- }
- // master: master group index
- void AddAvailableMember(unsigned char master)
- {
- PsuGroupPartner partner;
- char strMember[64];
- FindPsuGroupPartner(master, MAX_GROUP_QUANTITY, &partner, _EXTEND_TYPE_QUANTITY, MAX_GROUP_QUANTITY);
- sprintf(strMember, "Gun %d Add Available Member:", master + 1);
- for(int i = 0; i < partner.Quantity; i++)
- {
- AddMember(partner.Member[i], master, partner.ParallelFlag[i]);
- char strSlave[8];
- sprintf(strSlave, " [%02X]", partner.Member[i]);
- strcat(strMember, strSlave);
- }
- if(partner.Quantity > 0)
- {
- LOG_INFO("%s", strMember);
- }
- }
- // master: master group index
- // slave: slave group index
- void RemoveMember(unsigned char master, unsigned char slave)
- {
- bool find = false;
- int location = 0;
- unsigned char other = 0;
- unsigned short parallelFlag = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- if(slave == ShmPsuGrouping->GroupCollection[master].Partner.Member[i])
- {
- ShmPsuGrouping->GroupCollection[master].Partner.Member[i] = 0;
- location = i;
- find = true;
- break;
- }
- }
- if(find)
- {
- for(int i = location + 1; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- other = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- parallelFlag = ShmPsuGrouping->GroupCollection[master].Partner.ParallelFlag[i];
- ShmPsuGrouping->GroupCollection[master].Partner.Member[i] = 0;
- ShmPsuGrouping->GroupCollection[master].Partner.Member[i - 1] = other;
- ShmPsuGrouping->GroupCollection[master].Partner.ParallelFlag[i - 1] = parallelFlag;
- }
- ShmPsuGrouping->GroupCollection[master].Partner.Quantity--;
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity > 0)
- {
- ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity--;
- //ShmPsuGrouping->GroupCollection[master].GunPsuQuantity -= ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity;
- UpdateGunTotalPsuQuantity(master);
- }
- #if PSU_DEBUG_MSG
- LOG_INFO("Gun %d Remove Group [%02X], Quantity: %d (%d)",
- master + 1, slave, ShmPsuGrouping->GroupCollection[master].Partner.Quantity,
- ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity);
- #endif
- }
- }
- // master: master group index
- void RemoveNonGroupMember(unsigned char master)
- {
- unsigned char slave = 0;
- char strMember[64];
- PsuGroupPartner partner;
- bool find = false;
- if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER)
- {
- sprintf(strMember, "Gun %d Remove Member:", master + 1);
- memcpy(&partner, &ShmPsuGrouping->GroupCollection[master].Partner, sizeof(PsuGroupPartner));
- for(int i = 0; i < partner.Quantity; i++)
- {
- slave = partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_SLAVE)
- {
- RemoveMember(master, slave);
- if(ShmPsuGrouping->GroupCollection[slave].ReservedTarget == 0)
- {
- SetPsuGroupToIdle(slave);
- }
- else
- {
- SetPsuGroupRole(slave, _GROLE_WAIT_SLAVE);
- }
- char strSlave[8];
- sprintf(strSlave, " [%02X]", slave);
- strcat(strMember, strSlave);
- find = true;
- }
- }
- if(find)
- {
- LOG_INFO("%s", strMember);
- }
- }
- }
- void SetPsuGroupPowerOnOff(unsigned char group, unsigned char power_on_off)
- {
- if(group < CONNECTOR_QUANTITY)
- {
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- #if ONE_MODULE_OUTPUT
- // for safety test (inrush current)
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.InPrechargeMode)
- {
- PsuSingleOnOff(ShmPsuPosition->GroupLocationInfo[group].PsuSN[0], power_on_off);
- }
- else
- {
- PsuGroupOnOff(group, power_on_off);
- }
- #else
- PsuGroupOnOff(group, power_on_off);
- #endif
- LedGroupOnOff(group, power_on_off);
- }
- isStartOutputSwitch[group] = power_on_off == _PSU_ON ? true : false;
- }
- }
- // master: master group index
- unsigned short GetPresentTargetCurrent(unsigned char master, unsigned char role_condition)
- {
- unsigned char slave = 0;
- unsigned short current = 0;
- current = ShmPsuGrouping->GroupOutput[master].GTargetCurrent;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(role_condition == _GROLE_MASTER || ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE)
- {
- current += ShmPsuGrouping->GroupOutput[slave].GTargetCurrent;
- }
- }
- return current;
- }
- // group: group index
- int GetPsuModuleQuantity(unsigned char group)
- {
- int quantity = 0;
- unsigned char slave = 0;
- quantity = ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[group].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[group].Partner.Member[i];
- quantity += ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity;
- }
- return quantity;
- }
- // group: group index
- bool IsAvailableGroup(unsigned char group)
- {
- return ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0 ? true : false;
- }
- // master: master group index
- int GetMasterAvailableGroup(unsigned char master)
- {
- int quantity = 0;
- unsigned char slave = 0;
- quantity = IsAvailableGroup(master) ? quantity + 1 : quantity;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- quantity = IsAvailableGroup(slave) ? quantity + 1 : quantity;
- }
- return quantity;
- }
- // group: group index
- void UpdateGunLoading(unsigned char group)
- {
- if(ShmChargerInfo->PsuGrouping.GroupCollection[group].TargetGroup != 0 &&
- group == ShmChargerInfo->PsuGrouping.GroupCollection[group].TargetGroup - 1)
- {
- unsigned short TargetCurrent = (int)(chargingInfo[group]->EvBatterytargetCurrent * 10);
- ShmPsuGrouping->GroupCollection[group].GunLoading = chargingInfo[group]->AvailableChargingCurrent != 0 ?
- (TargetCurrent * 10000 / (int)chargingInfo[group]->AvailableChargingCurrent) : 0;
- if(chargingInfo[group]->PresentChargingVoltage >= (PSU_MIN_VOL / 10))
- {
- // unit: 1kW
- float _diffPowerByCurrent = 0, _diffPowerByPower = 0, _presentTargerPower = 0;
- _presentTargerPower = ((((float)ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000);
- // DiffPower_Available
- ShmPsuGrouping->GroupCollection[group].DiffPower_Available = (((float)(chargingInfo[group]->AvailableChargingCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
- // DiffPower_Capability
- _diffPowerByCurrent = (((float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].CapabilityCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
- _diffPowerByPower = (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].CapabilityPower / 10) - _presentTargerPower;
- ShmPsuGrouping->GroupCollection[group].DiffPower_Capability = _diffPowerByPower < _diffPowerByCurrent ? _diffPowerByPower : _diffPowerByCurrent;
- // DiffPower_PhysicalLimit
- ShmPsuGrouping->GroupCollection[group].DiffPower_PhysicalLimit = (((float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[group].RemoteMaxPhysicalCurrent - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
- // DiffPower_ConfigLimit
- _diffPowerByCurrent = (((float)(ShmChargerInfo->OutputLimit.GunLimitCurrent[group] - ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent) / 10) * chargingInfo[group]->PresentChargingVoltage) / 1000;
- _diffPowerByPower = (ShmChargerInfo->OutputLimit.GunLimitPower[group] / 10) - _presentTargerPower;
- ShmPsuGrouping->GroupCollection[group].DiffPower_ConfigLimit = _diffPowerByPower < _diffPowerByCurrent ? _diffPowerByPower : _diffPowerByCurrent;
- }
- else
- {
- ShmPsuGrouping->GroupCollection[group].DiffPower_Available = 0;
- ShmPsuGrouping->GroupCollection[group].DiffPower_Capability = 0;
- ShmPsuGrouping->GroupCollection[group].DiffPower_PhysicalLimit = 0;
- ShmPsuGrouping->GroupCollection[group].DiffPower_ConfigLimit = 0;
- }
- }
- else
- {
- ShmPsuGrouping->GroupCollection[group].GunLoading = 0;
- }
- }
- // group: group index
- void UpdatePsuGroupLoading(unsigned char group)
- {
- ShmPsuGrouping->GroupOutput[group].OutputLoading = ShmPsuData->PsuGroup[group].GroupAvailableCurrent != 0 ?
- (ShmPsuGrouping->GroupOutput[group].GTargetCurrent * 10000 / ShmPsuData->PsuGroup[group].GroupAvailableCurrent) : 0;
- }
- // master: master group index
- void UpdateMasterPsuGroupLoading(unsigned char master)
- {
- unsigned char slave = 0;
- UpdatePsuGroupLoading(master);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- UpdatePsuGroupLoading(slave);
- }
- }
- void PsuGroupIncreaseCurrent(unsigned char group, unsigned short needIncrease, unsigned short *realIncreaseCurrent)
- {
- unsigned short increase = needIncrease;
- if((ShmPsuGrouping->GroupOutput[group].GTargetCurrent + increase) <= ShmPsuData->PsuGroup[group].GroupAvailableCurrent)
- {
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent += increase;
- }
- else
- {
- increase = ShmPsuData->PsuGroup[group].GroupAvailableCurrent - ShmPsuGrouping->GroupOutput[group].GTargetCurrent;
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
- }
- *realIncreaseCurrent += increase;
- }
- void PsuGroupDecreaseCurrent(unsigned char group, unsigned short needDecrease, unsigned short *realDecreaseCurrent)
- {
- unsigned short decrease = needDecrease;
- if(ShmPsuGrouping->GroupOutput[group].GTargetCurrent >= (decrease + ZERO_CURRENT))
- {
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent -= decrease;
- }
- else
- {
- decrease = ShmPsuGrouping->GroupOutput[group].GTargetCurrent - ZERO_CURRENT;
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent = ZERO_CURRENT;
- }
- *realDecreaseCurrent += decrease;
- }
- void IncreaseCurrentByGunLoading(unsigned char group, unsigned short loading, unsigned short *realIncrease, unsigned short MaxIncrease)
- {
- unsigned short target = 0, need = 0;
- if(*realIncrease >= MaxIncrease)
- {
- return;
- }
- target = (loading * ShmPsuData->PsuGroup[group].GroupAvailableCurrent) / 10000;
- need = target >= ShmPsuGrouping->GroupOutput[group].GTargetCurrent ?
- (target - ShmPsuGrouping->GroupOutput[group].GTargetCurrent) : 0;
- need = need > (MaxIncrease - *realIncrease) ? (MaxIncrease - *realIncrease) : need;
- //LOG_INFO("Group [%02X] Target Current %d.%d A, Increase Current: %d.%d A",
- // group, (target / 10), (target % 10), (need / 10), (need % 10));
- if(need > 0)
- {
- PsuGroupIncreaseCurrent(group, need, realIncrease);
- }
- }
- void DecreaseCurrentByGunLoading(unsigned char group, unsigned short loading, unsigned short *realDecrease, unsigned short MaxDecrease)
- {
- unsigned short target = 0, need = 0;
- if(*realDecrease >= MaxDecrease)
- {
- return;
- }
- target = (loading * ShmPsuData->PsuGroup[group].GroupAvailableCurrent) / 10000;
- need = ShmPsuGrouping->GroupOutput[group].GTargetCurrent >= target ?
- (ShmPsuGrouping->GroupOutput[group].GTargetCurrent - target) : 0;
- need = need > (MaxDecrease - *realDecrease) ? (MaxDecrease - *realDecrease) : need;
- //LOG_INFO("Group [%02X] Target Current %d.%d A, Decrease Current: %d.%d A",
- // group, (target / 10), (target % 10), (need / 10), (need % 10));
- if(need > 0)
- {
- PsuGroupDecreaseCurrent(group, need, realDecrease);
- }
- }
- // master: master group index
- void AverageIncreaseCurrent(unsigned char master, unsigned short NeedIncreaseCurrent)
- {
- unsigned char availableGroup = 0, slave = 0;
- unsigned short avgGroupCurrent = 0, excessCurrent = 0, realIncrease = 0;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Increase By GunLoading %d.%02d Percent",
- master + 1, (ShmPsuGrouping->GroupCollection[master].GunLoading / 100), (ShmPsuGrouping->GroupCollection[master].GunLoading % 100));
- #endif
- IncreaseCurrentByGunLoading(master, ShmPsuGrouping->GroupCollection[master].GunLoading, &realIncrease, NeedIncreaseCurrent);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- IncreaseCurrentByGunLoading(slave, ShmPsuGrouping->GroupCollection[master].GunLoading, &realIncrease, NeedIncreaseCurrent);
- }
- availableGroup = GetMasterAvailableGroup(master);
- if(NeedIncreaseCurrent > realIncrease && availableGroup > 0)
- {
- // increase current by group quantity
- avgGroupCurrent = (NeedIncreaseCurrent - realIncrease) / availableGroup;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Increase By Group, AvgGroupCurrent %d.%d A",
- master + 1, (avgGroupCurrent / 10), (avgGroupCurrent % 10));
- #endif
- PsuGroupIncreaseCurrent(master, avgGroupCurrent, &realIncrease);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- PsuGroupIncreaseCurrent(slave, avgGroupCurrent, &realIncrease);
- }
- }
- if(NeedIncreaseCurrent > realIncrease)
- {
- // increase excess current to master group
- excessCurrent = NeedIncreaseCurrent - realIncrease;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Increase, ExcessCurrent %d.%d A", master + 1, (excessCurrent / 10), (excessCurrent % 10));
- #endif
- PsuGroupIncreaseCurrent(master, excessCurrent, &realIncrease);
- }
- }
- // master: master group index
- void AverageDecreaseCurrent(unsigned char master, unsigned short NeedDecreaseCurrent)
- {
- unsigned char availableGroup = 0, slave = 0;
- unsigned short avgGroupCurrent = 0, excessCurrent = 0, realDecrease = 0;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Decrease By GunLoading %d.%02d Percent",
- master + 1, (ShmPsuGrouping->GroupCollection[master].GunLoading / 100), (ShmPsuGrouping->GroupCollection[master].GunLoading % 100));
- #endif
- DecreaseCurrentByGunLoading(master, ShmPsuGrouping->GroupCollection[master].GunLoading, &realDecrease, NeedDecreaseCurrent);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- DecreaseCurrentByGunLoading(slave, ShmPsuGrouping->GroupCollection[master].GunLoading, &realDecrease, NeedDecreaseCurrent);
- }
- availableGroup = GetMasterAvailableGroup(master);
- if(NeedDecreaseCurrent > realDecrease)
- {
- // decrease current by group quantity
- avgGroupCurrent = (NeedDecreaseCurrent - realDecrease) / availableGroup;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Decrease By Group, AvgGroupCurrent %d.%d A",
- master + 1, (avgGroupCurrent / 10), (avgGroupCurrent % 10));
- #endif
- PsuGroupDecreaseCurrent(master, avgGroupCurrent, &realDecrease);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- PsuGroupDecreaseCurrent(slave, avgGroupCurrent, &realDecrease);
- }
- }
- if(NeedDecreaseCurrent > realDecrease)
- {
- // decrease excess current
- excessCurrent = NeedDecreaseCurrent - realDecrease;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Decrease, ExcessCurrent %d.%d A", master + 1, (excessCurrent / 10), (excessCurrent % 10));
- #endif
- PsuGroupDecreaseCurrent(master, excessCurrent, &realDecrease);
- }
- }
- void MasterIncreaseCurrent(unsigned char master, unsigned short NeedIncreaseCurrent)
- {
- unsigned short excessCurrent = 0, realIncrease = 0;
- PsuGroupIncreaseCurrent(master, NeedIncreaseCurrent, &realIncrease);
- if(NeedIncreaseCurrent > realIncrease)
- {
- excessCurrent = NeedIncreaseCurrent - realIncrease;
- AverageIncreaseCurrent(master, excessCurrent);
- }
- }
- void MasterDecreaseCurrent(unsigned char master, unsigned short NeedDecreaseCurrent)
- {
- unsigned char slave = 0;
- unsigned short avgGroupCurrent = 0, excessCurrent = 0, realDecrease = 0;
- if(ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity > 0)
- {
- // decrease current by group quantity
- avgGroupCurrent = NeedDecreaseCurrent / ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity;
- #if PSU_DEBUG_MSG
- PSU_LOG("Gun %d Decrease By Group, AvgGroupCurrent %d.%d A",
- master + 1, (avgGroupCurrent / 10), (avgGroupCurrent % 10));
- #endif
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity > 0)
- {
- PsuGroupDecreaseCurrent(slave, avgGroupCurrent, &realDecrease);
- }
- }
- }
- if(NeedDecreaseCurrent > realDecrease)
- {
- excessCurrent = NeedDecreaseCurrent - realDecrease;
- PsuGroupDecreaseCurrent(master, excessCurrent, &realDecrease);
- }
- }
- void UpdateMaxCurrent(unsigned char master, unsigned short current)
- {
- int time = 0;
- // update max stage current
- if(current > StageMaxCurrent[master])
- {
- StageMaxCurrent[master] = current;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxStageCurrent = false;
- GetClockTime(&_StageCurrent_time[master]);
- }
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxStageCurrent)
- {
- time = GetTimeoutValue(_StageCurrent_time[master]) / uSEC_VAL;
- if(time >= EV_MAX_STAGE_CURRENT_DELAY)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxStageCurrent = true;
- LOG_INFO("Gun %d Reach Max Stage Current", master + 1);
- }
- }
- // update max target current and reset max current time
- if(current > MaxCurrentDemand[master])
- {
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxCurrentDemand)
- {
- LOG_INFO("Gun %d Max Current Demand Timer Reset", master + 1);
- }
- MaxCurrentDemand[master] = current;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxCurrentDemand = false;
- GetClockTime(&_MaxCurrent_time[master]);
- }
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxCurrentDemand)
- {
- time = GetTimeoutValue(_MaxCurrent_time[master]) / uSEC_VAL;
- if(time >= EV_MAX_CURRENT_DELAY)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxCurrentDemand = true;
- LOG_INFO("Gun %d Reach Max Current Demand", master + 1);
- }
- }
- }
- // master: master group index
- bool IsMasterOutputCurrentStable(unsigned char master)
- {
- int time = 0;
- bool stable = false, reachTarget = false;
- unsigned short presentOutput = (int)chargingInfo[master]->PresentChargingCurrent * 10;
- unsigned short TargetCurrent = 0;
- TargetCurrent = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- reachTarget = presentOutput > (TargetCurrent - REACH_CURRENT_TOLERANCE) && presentOutput < (TargetCurrent + REACH_CURRENT_TOLERANCE);
- if((presentOutput >= StableOutputCurrent[master] && presentOutput - StableOutputCurrent[master] > REACH_CURRENT_TOLERANCE) ||
- (presentOutput < StableOutputCurrent[master] && StableOutputCurrent[master] - presentOutput > REACH_CURRENT_TOLERANCE))
- {
- GetClockTime(&_ReachCurrent_time[master]);
- StableOutputCurrent[master] = presentOutput;
- }
- time = GetTimeoutValue(_ReachCurrent_time[master]) / uSEC_VAL;
- if(reachTarget || time >= CURRENT_STABLE_TIME ||
- (ShmChargerInfo->Control.FCharging[master].FCtrl.bits.EnableForceCharging && time >= CURRENT_REACH_TARGET_TIME))
- {
- stable = true;
- }
- return stable;
- }
- // master: master group index
- void MasterBalanceCurrent(unsigned char master)
- {
- int time = 0;
- unsigned char slave = 0;
- unsigned short realBalance = 0, grabCurrent = 0;
- time = GetTimeoutValue(_BalanceCurrent_time[master]) / mSEC_VAL;
- if(time >= BALANCE_CURRENT_INTERVAL)
- {
- //LOG_INFO("Gun %d Start Balance Current", master + 1);
- DecreaseCurrentByGunLoading(master, ShmPsuGrouping->GroupCollection[master].GunLoading, &grabCurrent, MAX_ADJ_BALANCE_CURRENT);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- DecreaseCurrentByGunLoading(slave, ShmPsuGrouping->GroupCollection[master].GunLoading, &grabCurrent, MAX_ADJ_BALANCE_CURRENT);
- }
- //LOG_INFO("Gun %d Grab Balance Current %d.%d A", master + 1, (grabCurrent / 10), (grabCurrent % 10));
- IncreaseCurrentByGunLoading(master, ShmPsuGrouping->GroupCollection[master].GunLoading, &realBalance, grabCurrent);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- IncreaseCurrentByGunLoading(slave, ShmPsuGrouping->GroupCollection[master].GunLoading, &realBalance, grabCurrent);
- }
- //LOG_INFO("Gun %d Increase Balance Current %d.%d A", master + 1, (realBalance / 10), (realBalance % 10));
- UpdateMasterPsuGroupLoading(master);
- GetClockTime(&_BalanceCurrent_time[master]);
- }
- }
- unsigned short GetLoadingDiff(unsigned char master)
- {
- unsigned char slave = 0;
- unsigned short maxLoading = 0, minLoading = 0, diffLoading = 0;
- maxLoading = ShmPsuGrouping->GroupOutput[master].OutputLoading;
- minLoading = ShmPsuGrouping->GroupOutput[master].OutputLoading;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity == 0 || ShmPsuData->PsuGroup[slave].GroupAvailableCurrent == 0)
- {
- continue;
- }
- maxLoading = ShmPsuGrouping->GroupOutput[slave].OutputLoading > maxLoading ?
- ShmPsuGrouping->GroupOutput[slave].OutputLoading : maxLoading;
- minLoading = ShmPsuGrouping->GroupOutput[slave].OutputLoading < minLoading ?
- ShmPsuGrouping->GroupOutput[slave].OutputLoading : minLoading;
- }
- diffLoading = maxLoading - minLoading;
- return diffLoading;
- }
- void CheckCurrentBalance(unsigned char master)
- {
- unsigned short diffLoading = 0;
- diffLoading = GetLoadingDiff(master);
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance)
- {
- if(diffLoading >= START_BALANCE_CRITERIA)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance = true;
- PSU_LOG("Gun %d Output Current Is Unbalance, diffLoading = %d.%02d", master + 1, (diffLoading / 100), (diffLoading % 100));
- GetClockTime(&_BalanceCurrent_time[master]);
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance)
- {
- MasterBalanceCurrent(master);
- diffLoading = GetLoadingDiff(master);
- if(diffLoading <= STOP_BALANCE_CRITERIA)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance = false;
- PSU_LOG("Gun %d Output Current Is Balance", master + 1);
- }
- }
- }
- // master: master group index
- // slave: slave group index
- bool IsGroupPartner(unsigned char master, unsigned char slave)
- {
- bool find = false;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- if(slave == ShmPsuGrouping->GroupCollection[master].Partner.Member[i])
- {
- find = true;
- break;
- }
- }
- return find;
- }
- void CleanSmoothDerating(unsigned char master)
- {
- ShmPsuGrouping->GroupCollection[master].SmoothDeratingTarget = 0;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.SmoothDerating = false;
- }
- void SetSmoothDerating(unsigned char master, unsigned char slave)
- {
- ShmPsuGrouping->GroupCollection[master].SmoothDeratingTarget = slave + 1;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.SmoothDerating = true;
- GetClockTime(&_SmoothDerating_time[master]);
- }
- // master: master group index
- void CheckSmoothBalance(unsigned char master)
- {
- int time = 0;
- unsigned char slave = 0;
- unsigned short realBalance = 0, grabCurrent = 0;
- unsigned char _ReleaseSlave = 0;
- if(ShmPsuGrouping->GroupCollection[master].SmoothDeratingTarget == 0 ||
- !IsGroupPartner(master, ShmPsuGrouping->GroupCollection[master].SmoothDeratingTarget - 1))
- {
- CleanSmoothDerating(master);
- LOG_INFO("Gun %d Smooth Derating Target Is Not Available!", master + 1);
- return;
- }
- unsigned short _CapCurrent = 0; // unit: 0.1A
- unsigned short _ReleaseCurrent = 0; // unit: 0.1A
- unsigned short _ReleaseLoading = 0; // unit: 0.01%
- unsigned short TargetCurrent = 0; // unit: 0.1A
- PsuGroupPartner ReleaseMember;
- _CapCurrent = (int)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[master].CapabilityCurrent;
- TargetCurrent = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- _ReleaseSlave = ShmPsuGrouping->GroupCollection[master].SmoothDeratingTarget - 1;
- _ReleaseCurrent = (int)chargingInfo[master]->AvailableChargingCurrent > (int)ShmPsuData->PsuGroup[_ReleaseSlave].GroupAvailableCurrent ?
- (int)chargingInfo[master]->AvailableChargingCurrent - (int)ShmPsuData->PsuGroup[_ReleaseSlave].GroupAvailableCurrent : 0;
- _ReleaseLoading = _ReleaseCurrent != 0 ? (TargetCurrent * 10000 / _ReleaseCurrent) : 0;
- if(ShmPsuGrouping->GroupOutput[_ReleaseSlave].GTargetCurrent <= MAX_ADJ_BALANCE_CURRENT)
- {
- float originalPower = 0, capabilityPower = 0, releasePower = 0;
- memset(&ReleaseMember, 0x00, sizeof(PsuGroupPartner));
- ReleaseMember.Member[0] = _ReleaseSlave;
- ReleaseMember.Quantity = 1;
- PrepareToPowerOff(0, &ReleaseMember);
- originalPower = ((chargingInfo[master]->AvailableChargingCurrent / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- capabilityPower = ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[master].CapabilityCurrent / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- releasePower = (((float)(_ReleaseCurrent) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- LOG_INFO("Gun %d Smooth Release [%02X]", master + 1, ReleaseMember.Member[0]);
- LOG_INFO("Gun %d Available %d A (%d kW) >> %d A (%d kW)",
- master + 1,
- ((int)chargingInfo[master]->AvailableChargingCurrent / 10), (int)originalPower,
- (_ReleaseCurrent / 10), (int)releasePower);
- LOG_INFO("Gun %d Capability %d A (%d kW) >> %d A (%d kW)",
- master + 1,
- ((int)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[master].CapabilityCurrent / 10), (int)capabilityPower,
- _ReleaseCurrent >= _CapCurrent ? (_CapCurrent / 10) : (_ReleaseCurrent / 10), (int)releasePower);
- CleanSmoothDerating(master);
- return;
- }
- time = GetTimeoutValue(_SmoothDerating_time[master]) / mSEC_VAL;
- if(time >= SMOOTH_DERATING_INTERVAL)
- {
- DecreaseCurrentByGunLoading(master, _ReleaseLoading, &grabCurrent, MAX_ADJ_BALANCE_CURRENT);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(slave != _ReleaseSlave)
- {
- DecreaseCurrentByGunLoading(slave, _ReleaseLoading, &grabCurrent, MAX_ADJ_BALANCE_CURRENT);
- }
- else
- {
- DecreaseCurrentByGunLoading(slave, 0, &grabCurrent, MAX_ADJ_BALANCE_CURRENT);
- }
- }
- //LOG_INFO("Gun %d Grab Balance Current %d.%d A", master + 1, (grabCurrent / 10), (grabCurrent % 10));
- IncreaseCurrentByGunLoading(master, _ReleaseLoading, &realBalance, grabCurrent);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(slave != _ReleaseSlave)
- {
- IncreaseCurrentByGunLoading(slave, _ReleaseLoading, &realBalance, grabCurrent);
- }
- }
- //LOG_INFO("Gun %d Increase Balance Current %d.%d A", master + 1, (realBalance / 10), (realBalance % 10));
- UpdateMasterPsuGroupLoading(master);
- GetClockTime(&_SmoothDerating_time[master]);
- }
- }
- bool IsOtherCharging(unsigned char group)
- {
- bool find = false;
- int other = 0, selfTarget = 0, location = 0;
- if(ShmPsuGrouping->GroupCollection[group].TargetGroup == 0)
- {
- return find;
- }
- selfTarget = ShmPsuGrouping->GroupCollection[group].TargetGroup - 1;
- // search from left
- location = ShmPsuGrouping->GroupCollection[group].Location - 1;
- for(int i = location; i >= 0; i--)
- {
- other = ShmPsuGrouping->Layout[i];
- if(ShmPsuGrouping->GroupCollection[other].Role == _GROLE_MASTER)
- {
- find = other != selfTarget ? true : false;
- break;
- }
- }
- if(!find)
- {
- // search from right
- location = ShmPsuGrouping->GroupCollection[group].Location + 1;
- for(int i = location; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- other = ShmPsuGrouping->Layout[i];
- if(ShmPsuGrouping->GroupCollection[other].Role == _GROLE_MASTER)
- {
- find = other != selfTarget ? true : false;
- break;
- }
- }
- }
- return find;
- }
- // master: master group index
- void MasterReleasePsuGroup(unsigned char master)
- {
- bool findOtherInCharging = false;
- unsigned char slave = 0, member = 0, releaseTarget = 0;
- unsigned char otherCharging[MAX_GROUP_QUANTITY] = {0};
- unsigned char releaseList[MAX_GROUP_QUANTITY] = {0};
- float releasePower[MAX_GROUP_QUANTITY] = {0};
- unsigned short releaseCurrent[MAX_GROUP_QUANTITY] = {0};
- PsuGroupPartner ReleaseMember;
- unsigned short target = 0, oriAvailableCurrent = 0, oriCapabilityCurrent = 0, maxReleaseCurrent = 0;
- float targetPower = 0, oriAvailablePower = 0, capabilityPower = 0, maxReleasePower = 0;
- if(ShmChargerInfo->PsuGrouping.GroupCollection[master].Role != _GROLE_MASTER ||
- ShmPsuGrouping->GroupCollection[master].Partner.Quantity == 0)
- {
- return;
- }
- target = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- targetPower = (((float)(target) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- oriAvailableCurrent = (int)chargingInfo[master]->AvailableChargingCurrent;
- oriAvailablePower = (((float)oriAvailableCurrent / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- oriCapabilityCurrent = (int)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[master].CapabilityCurrent;
- capabilityPower = (((float)oriCapabilityCurrent / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- unsigned short current = 0;
- PsuGroupPowerOffCheck(slave, &ReleaseMember);
- otherCharging[i] = IsOtherCharging(slave);
- findOtherInCharging = otherCharging[i] ? otherCharging[i] : findOtherInCharging;
- releaseList[i] = slave;
- for(int j = 0; j < ReleaseMember.Quantity; j++)
- {
- member = ReleaseMember.Member[j];
- current += ShmPsuData->PsuGroup[member].GroupAvailableCurrent;
- }
- releaseCurrent[i] = current;
- float power = (((float)(oriAvailableCurrent - releaseCurrent[i]) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- if(power >= (targetPower + MAX_DIFF_POWER_TO_DERATING) ||
- (oriAvailableCurrent - releaseCurrent[i]) >= oriCapabilityCurrent)
- {
- releasePower[i] = power;
- }
- else
- {
- releasePower[i] = 0;
- }
- //LOG_INFO("Gun %d Release [%02X], Total Release %d Group, Gun Loading %d.%02d >> %d.%02d", master + 1, slave, ReleaseMember.Quantity,
- // (originalLoading / 100), (originalLoading % 100),
- // (releaseLoading[i] / 100), (releaseLoading[i] % 100));
- }
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- if((otherCharging[i] || !findOtherInCharging) &&
- releasePower[i] > maxReleasePower && releasePower[i] != 0)
- {
- maxReleasePower = releasePower[i];
- maxReleaseCurrent = releaseCurrent[i];
- releaseTarget = releaseList[i];
- }
- }
- if(maxReleasePower > 0)
- {
- unsigned short _current = 0;
- _current = oriAvailableCurrent - maxReleaseCurrent;
- ShmPsuGrouping->GroupCollection[releaseTarget].GroupCtrl.bits.SlavePowerOffRequest = true;
- LOG_INFO("Gun %d Set [%02X] Release(%s)",
- master + 1, releaseTarget, findOtherInCharging ? "Other In Charging" : "Normal");
- LOG_INFO("Gun %d Available %d A (%d kW) >> %d A (%d kW)",
- master + 1,
- (oriAvailableCurrent / 10), (int)oriAvailablePower, (_current / 10), (int)maxReleasePower);
- LOG_INFO("Gun %d Capability %d A (%d kW) >> %d A (%d kW)",
- master + 1,
- (oriCapabilityCurrent / 10), (int)capabilityPower,
- _current >= oriCapabilityCurrent ? (oriCapabilityCurrent / 10) : (_current / 10), (int)maxReleasePower);
- }
- }
- // master: master group index
- void MasterDynamicRelease(unsigned char master)
- {
- unsigned char slave = 0;
- PsuGroupPartner ReleaseMember;
- unsigned short target = 0, releaseCurrent = 0, originalAvailable = 0, originalCapability = 0;
- float targetPower = 0, originalPower = 0, capabilityPower = 0, releasePower = 0;
- if(ShmChargerInfo->PsuGrouping.GroupCollection[master].Role != _GROLE_MASTER ||
- ShmPsuGrouping->GroupCollection[master].Partner.Quantity == 0)
- {
- return;
- }
- target = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- targetPower = (((float)(target) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- originalAvailable = (int)chargingInfo[master]->AvailableChargingCurrent;
- originalCapability = (int)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[master].CapabilityCurrent;
- releaseCurrent = 0;
- memset(&ReleaseMember, 0x00, sizeof(PsuGroupPartner));
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- releasePower = (((float)(originalAvailable - releaseCurrent - ShmPsuData->PsuGroup[slave].GroupAvailableCurrent) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- if(releasePower >= (targetPower + MAX_DIFF_POWER_TO_DERATING) ||
- (originalAvailable - releaseCurrent - ShmPsuData->PsuGroup[slave].GroupAvailableCurrent) >= originalCapability)
- {
- releaseCurrent += ShmPsuData->PsuGroup[slave].GroupAvailableCurrent;
- ReleaseMember.Member[ReleaseMember.Quantity] = slave;
- ReleaseMember.Quantity++;
- }
- }
- if(ReleaseMember.Quantity > 0)
- {
- char strMember[64];
- memset(strMember, 0x00, sizeof(strMember));
- for(int i = 0; i < ReleaseMember.Quantity; i++)
- {
- char strTemp[16];
- sprintf(strTemp, " [%02X]", ReleaseMember.Member[i]);
- strcat(strMember, strTemp);
- }
- PrepareToPowerOff(0, &ReleaseMember);
- originalPower = (((float)originalAvailable / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- capabilityPower = (((float)originalCapability / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- releasePower = (((float)(originalAvailable - releaseCurrent) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- LOG_INFO("Gun %d Direct Release%s", master + 1, strMember);
- LOG_INFO("Gun %d Available %d A (%d kW) >> %d A (%d kW)",
- master + 1,
- (originalAvailable / 10), (int)originalPower,
- ((originalAvailable - releaseCurrent) / 10), (int)releasePower);
- LOG_INFO("Gun %d Capability %d A (%d kW) >> %d A (%d kW)",
- master + 1,
- (originalCapability / 10), (int)capabilityPower,
- ((originalAvailable - releaseCurrent) / 10), (int)releasePower);
- }
- }
- void FindDeratingPriority(unsigned char master, PsuGroupPartner *tPartner)
- {
- unsigned char slave = 0;
- memset(tPartner, 0x00, sizeof(PsuGroupPartner));
- if((ShmChargerInfo->Control.MaxConnector - 1 - ShmPsuGrouping->GroupCollection[master].Location) > ShmPsuGrouping->GroupCollection[master].Location - 0)
- {
- for(int i = ShmChargerInfo->Control.MaxConnector - 1; i >= 0; i--)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave != master)
- {
- if((ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1) == master)
- {
- tPartner->Member[tPartner->Quantity++] = slave;
- }
- }
- else
- {
- break;
- }
- }
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave != master)
- {
- if((ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1) == master)
- {
- tPartner->Member[tPartner->Quantity++] = slave;
- }
- }
- else
- {
- break;
- }
- }
- }
- else
- {
- for(int i = 0; i < ShmChargerInfo->Control.MaxConnector; i++)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave != master)
- {
- if((ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1) == master)
- {
- tPartner->Member[tPartner->Quantity++] = slave;
- }
- }
- else
- {
- break;
- }
- }
- for(int i = ShmChargerInfo->Control.MaxConnector - 1; i >= 0; i--)
- {
- slave = ShmPsuGrouping->Layout[i];
- if(slave != master)
- {
- if((ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1) == master)
- {
- tPartner->Member[tPartner->Quantity++] = slave;
- }
- }
- else
- {
- break;
- }
- }
- }
- }
- // master: master group index
- void CheckSmoothDerating(unsigned char master)
- {
- unsigned char slave = 0;
- unsigned short target = 0, originalAvailable = 0, originalCapability = 0;
- float targetPower = 0, releasePower = 0;
- PsuGroupPartner releasePriority;
- if(ShmChargerInfo->PsuGrouping.GroupCollection[master].Role != _GROLE_MASTER ||
- ShmPsuGrouping->GroupCollection[master].Partner.Quantity == 0 ||
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.SmoothDerating)
- {
- return;
- }
- target = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- targetPower = (((float)(target) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- originalAvailable = (int)chargingInfo[master]->AvailableChargingCurrent;
- originalCapability = (int)ShmSysConfigAndInfo->SysInfo.ConnectorInfo[master].CapabilityCurrent;
- FindDeratingPriority(master, &releasePriority);
- for(int i = 0; i < releasePriority.Quantity; i++)
- {
- slave = releasePriority.Member[i];
- releasePower = (((float)(originalAvailable - ShmPsuData->PsuGroup[slave].GroupAvailableCurrent) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- if(releasePower >= (targetPower + MAX_DIFF_POWER_TO_DERATING) ||
- (originalAvailable - ShmPsuData->PsuGroup[slave].GroupAvailableCurrent) >= originalCapability)
- {
- SetSmoothDerating(master, slave);
- LOG_INFO("Gun %d Set Smooth Derating Member: [%02X]", master + 1, slave);
- break;
- }
- }
- /*
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- releasePower = (((float)(originalAvailable - ShmPsuData->PsuGroup[slave].GroupAvailableCurrent) / 10) * chargingInfo[master]->PresentChargingVoltage) / 1000;
- if(releasePower >= (targetPower + MAX_DIFF_POWER_TO_DERATING) ||
- (originalAvailable - ShmPsuData->PsuGroup[slave].GroupAvailableCurrent) >= originalCapability)
- {
- SetSmoothDerating(master, slave);
- LOG_INFO("Gun %d Set Smooth Derating Member: [%02X]", master + 1, slave);
- break;
- }
- }
- */
- }
- void CheckReleaseOrExtend(unsigned char master)
- {
- int time = 0;
- if((ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation || Is_EnableReleaseAndExtendWhenForceCharging(master)) &&
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.DeratingCtrlValue == 0 &&
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue == 0)
- {
- if(ShmPsuGrouping->GroupCollection[master].DiffPower_Available >= MIN_RELEASE_POWER)
- {
- if(ShmPsuGrouping->GroupCollection[master].Partner.Quantity > 0 &&
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxStageCurrent &&
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxCurrentDemand)
- {
- #if ENABLE_SMOOTH_DERATING == 0
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- MasterReleasePsuGroup(master);
- }
- else
- {
- MasterDynamicRelease(master);
- }
- #else
- CheckSmoothDerating(master);
- #endif
- }
- }
- else if(ShmPsuGrouping->GroupCollection[master].DiffPower_Available < MAX_DIFF_POWER_TO_EXTEND &&
- ShmPsuGrouping->GroupCollection[master].DiffPower_Capability < MAX_DIFF_POWER_TO_EXTEND &&
- ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit >= MIN_DIFF_PHYSICAL_POWER &&
- ShmPsuGrouping->GroupCollection[master].DiffPower_ConfigLimit >= MIN_DIFF_CONFIG_POWER)
- {
- time = GetTimeoutValue(_ExtendCapability_time[master]) / uSEC_VAL;
- if(time >= EXTEND_AFTER_DERATING_DELAY)
- {
- int available = GetPsuGroupAvailable(master);
- if(available > 0)
- {
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendAvailable)
- {
- LOG_INFO("Gun %d Extend Capability Available, DifPcap: %.1f kW, DiffConfig: %.1f kW, DifPphy: %.1f kW",
- master + 1,
- ShmPsuGrouping->GroupCollection[master].DiffPower_Capability,
- ShmPsuGrouping->GroupCollection[master].DiffPower_ConfigLimit,
- ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit);
- GetClockTime(&_ExtendCapability_time[master]);
- }
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendAvailable = true;
- }
- }
- }
- }
- }
- bool IsPsuGroupOutputConfigDifferent(unsigned char group)
- {
- bool different = false;
- if(ShmPsuGrouping->GroupOutput[group].GTargetVoltage != PreGroupOutput[group].GTargetVoltage ||
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent != PreGroupOutput[group].GTargetCurrent)
- {
- different = true;
- }
- PreGroupOutput[group].GTargetVoltage = ShmPsuGrouping->GroupOutput[group].GTargetVoltage;
- PreGroupOutput[group].GTargetCurrent = ShmPsuGrouping->GroupOutput[group].GTargetCurrent;
- return different;
- }
- // Gun X Demand Change -> Voltage: XXXX.X V, Current: XXXX.X A, Available: XXXX.X A, Loading: XXX.XX
- // Master [XX] -> Voltage: XXXX.X V, Current: XXXX.X A, Available: XXXX.X A, Loading: XXX.XX
- // Member [XX] -> Voltage: XXXX.X V, Current: XXXX.X A, Available: XXXX.X A, Loading: XXX.XX
- void ShowPsuGroupOutputConfig(unsigned char master)
- {
- unsigned char slave = 0;
- PSU_LOG("Gun %d Demand Change -> Voltage: %4d V, Current: %4d.%d A, Available: %4d.%d A, Loading: %3d.%02d",
- master + 1, (ShmPsuGrouping->GroupOutput[master].GTargetVoltage / 10),
- ((int)chargingInfo[master]->EvBatterytargetCurrent), (((int)(chargingInfo[master]->EvBatterytargetCurrent * 10)) % 10),
- ((int)chargingInfo[master]->AvailableChargingCurrent / 10), ((int)chargingInfo[master]->AvailableChargingCurrent % 10),
- (ShmPsuGrouping->GroupCollection[master].GunLoading / 100), (ShmPsuGrouping->GroupCollection[master].GunLoading % 100));
- PSU_LOG(" Master [%02X] -> Voltage: %4d V, Current: %4d.%d A, Available: %4d.%d A, Loading: %3d.%02d",
- master, (ShmPsuGrouping->GroupOutput[master].GTargetVoltage / 10),
- (ShmPsuGrouping->GroupOutput[master].GTargetCurrent / 10), (ShmPsuGrouping->GroupOutput[master].GTargetCurrent % 10),
- (ShmPsuData->PsuGroup[master].GroupAvailableCurrent / 10), (ShmPsuData->PsuGroup[master].GroupAvailableCurrent % 10),
- (ShmPsuGrouping->GroupOutput[master].OutputLoading / 100), (ShmPsuGrouping->GroupOutput[master].OutputLoading % 100));
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- PSU_LOG(" Member [%02X] -> Voltage: %4d V, Current: %4d.%d A, Available: %4d.%d A, Loading: %3d.%02d",
- slave, (ShmPsuGrouping->GroupOutput[slave].GTargetVoltage / 10),
- (ShmPsuGrouping->GroupOutput[slave].GTargetCurrent / 10), (ShmPsuGrouping->GroupOutput[slave].GTargetCurrent % 10),
- (ShmPsuData->PsuGroup[slave].GroupAvailableCurrent / 10), (ShmPsuData->PsuGroup[slave].GroupAvailableCurrent % 10),
- (ShmPsuGrouping->GroupOutput[slave].OutputLoading / 100), (ShmPsuGrouping->GroupOutput[slave].OutputLoading % 100));
- }
- }
- void PsuGroupOutputConfigCheck(unsigned char master)
- {
- unsigned char slave = 0;
- bool show = false;
- show = IsPsuGroupOutputConfigDifferent(master);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(IsPsuGroupOutputConfigDifferent(slave))
- {
- show = true;
- }
- }
- if(show)
- {
- ShowPsuGroupOutputConfig(master);
- }
- }
- void StepRecognition(unsigned char master, unsigned short voltage)
- {
- if(_GfdStep[master] == PREPARE_STEP_NONE && voltage > 0)
- {
- // gfd step
- _GfdStep[master] = PREPARE_STEP_CABLE_CHECK;
- LOG_INFO("Gun %d GFD Start Step", master + 1);
- }
- else if(_GfdStep[master] == PREPARE_STEP_CABLE_CHECK && voltage == 0)
- {
- // gfd done step
- _GfdStep[master] = PREPARE_STEP_GFD_DONE;
- LOG_INFO("Gun %d GFD Stop Step", master + 1);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.CableCheckDone = true;
- }
- else if(_GfdStep[master] == PREPARE_STEP_GFD_DONE && voltage >= SAFETY_PRECHARGE_OFFSET)
- {
- // precharge step
- _GfdStep[master] = PREPARE_STEP_PRECHARGE;
- LOG_INFO("Gun %d PreCharge Step", master + 1);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.InPrechargeMode = true;
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AlreadyInChargingMode)
- {
- // charging step
- if(_GfdStep[master] != PREPARE_STEP_CHARGING)
- {
- LOG_INFO("Gun %d Charging Step", master + 1);
- }
- _GfdStep[master] = PREPARE_STEP_CHARGING;
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.InPrechargeMode)
- {
- if(_VoltageResumeCnt[master] < MAX_CHARGING_DELAY_COUNT)
- {
- int time = GetTimeoutValue(_ChargingDelay_time[master]) / mSEC_VAL;
- if(time >= CHARGING_DELAY_INTERVAL)
- {
- GetClockTime(&_ChargingDelay_time[master]);
- _VoltageResumeCnt[master]++;
- }
- }
- else
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.InPrechargeMode = false;
- }
- }
- }
- }
- // master: master group index
- // voltage: target voltage, unit: 0.1V
- void UpdateOutputGroupVoltage(unsigned char master, unsigned short voltage)
- {
- unsigned char slave = 0;
- ShmPsuGrouping->TotalGroupOutput[master].GTargetVoltage = voltage;
- // set master group output voltage
- ShmPsuGrouping->GroupOutput[master].GTargetVoltage = voltage;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- // set slave group output voltage
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- #if ONE_MODULE_OUTPUT
- // for safety test (inrush current)
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.InPrechargeMode)
- {
- ShmPsuGrouping->GroupOutput[slave].GTargetVoltage = 0;
- }
- else
- {
- ShmPsuGrouping->GroupOutput[slave].GTargetVoltage = voltage;
- }
- #else
- ShmPsuGrouping->GroupOutput[slave].GTargetVoltage = voltage;
- #endif
- }
- }
- // master: master group index
- // group: self group index
- void UpdatePsuGroupOutputConfig(unsigned char master)
- {
- unsigned char slave = 0;
- unsigned short TargetVoltage = 0, TargetCurrent = 0, PresentTargetCurrent = 0;
- unsigned short current = 0;
- TargetVoltage = (int)(chargingInfo[master]->EvBatterytargetVoltage * 10);
- TargetCurrent = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- if(Is_OutputK1K2_Ready(master) || ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.CableCheckDone)
- {
- // update target voltage
- StepRecognition(master, TargetVoltage);
- #if PRECHARGE_OFFSET
- // for safety test (inrush current)
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AlreadyInChargingMode)
- {
- GCTargetVoltage[master] = _GfdStep[master] == PREPARE_STEP_PRECHARGE ?
- TargetVoltage - SAFETY_PRECHARGE_OFFSET : TargetVoltage;
- }
- else
- {
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.InPrechargeMode)
- {
- GCTargetVoltage[master] = TargetVoltage > (GCTargetVoltage[master] + VOLTAGE_RESUME_STEP) ?
- (GCTargetVoltage[master] + VOLTAGE_RESUME_STEP) : TargetVoltage;
- }
- else
- {
- GCTargetVoltage[master] = TargetVoltage;
- }
- }
- #else
- GCTargetVoltage[master] = TargetVoltage;
- #endif
- UpdateOutputGroupVoltage(master, GCTargetVoltage[master]);
- // update target current
- if(((ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity + 1) * ZERO_CURRENT) > TargetCurrent ||
- !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AlreadyInChargingMode)
- {
- current = ZERO_CURRENT;
- #if PSU_DEBUG_MSG
- if(ShmPsuGrouping->GroupOutput[master].GTargetCurrent != current)
- {
- LOG_INFO("Gun %d Need Minimum Target Current = %d", master + 1, current);
- }
- #endif
- ShmPsuGrouping->TotalGroupOutput[master].GTargetCurrent = current;
- ShmPsuGrouping->GroupOutput[master].GTargetCurrent = current;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE || ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PREPARE_SWITCH_OFF)
- {
- #if ONE_MODULE_OUTPUT
- // for safety test (inrush current)
- ShmPsuGrouping->GroupOutput[slave].GTargetCurrent = 0;
- #else
- ShmPsuGrouping->GroupOutput[slave].GTargetCurrent =
- ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity > 0 ? ZERO_CURRENT : 0;
- #endif
- ShmPsuGrouping->TotalGroupOutput[master].GTargetCurrent += ShmPsuGrouping->GroupOutput[slave].GTargetCurrent;
- }
- }
- unsigned short diffCurrent = 0;
- diffCurrent = ShmPsuGrouping->TotalGroupOutput[master].GTargetCurrent < TargetCurrent ? (TargetCurrent - ShmPsuGrouping->TotalGroupOutput[master].GTargetCurrent) : 0;
- ShmPsuGrouping->GroupOutput[master].GTargetCurrent += diffCurrent;
- }
- else
- {
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed)
- {
- // master in normal output mode
- PresentTargetCurrent = GetPresentTargetCurrent(master, _GROLE_MASTER);
- current = TargetCurrent <= (int)chargingInfo[master]->AvailableChargingCurrent ?
- TargetCurrent : (int)chargingInfo[master]->AvailableChargingCurrent;
- #if PSU_DEBUG_MSG
- if(GCTargetCurrent[master] != current)
- {
- LOG_INFO("Gun %d Need Normal Target Current = %d.%d A", master + 1, (current / 10), (current % 10));
- }
- #endif
- ShmPsuGrouping->TotalGroupOutput[master].GTargetCurrent = current;
- GCTargetCurrent[master] = current;
- UpdateMaxCurrent(master, GCTargetCurrent[master]);
- if(GCTargetCurrent[master] > PresentTargetCurrent)
- {
- // increase current
- OutputConfigStep[master] = _CURRENT_MODE_INCREASE;
- PSU_LOG("Gun %d Increase Current: %d.%d A, %d.%d A -> %d.%d A", master + 1,
- ((GCTargetCurrent[master] - PresentTargetCurrent) / 10), ((GCTargetCurrent[master] - PresentTargetCurrent) % 10),
- (PresentTargetCurrent / 10), (PresentTargetCurrent % 10), (GCTargetCurrent[master] / 10), (GCTargetCurrent[master] % 10));
- #if MASTER_OUTPUT_FIRST
- // for safety test
- if(GCTargetCurrent[master] <= CURRENT_BALANCE_CRITERIA)
- {
- MasterIncreaseCurrent(master, GCTargetCurrent[master] - PresentTargetCurrent);
- }
- else
- {
- AverageIncreaseCurrent(master, GCTargetCurrent[master] - PresentTargetCurrent);
- }
- #else
- AverageIncreaseCurrent(master, GCTargetCurrent[master] - PresentTargetCurrent);
- #endif
- }
- else if(GCTargetCurrent[master] < PresentTargetCurrent)
- {
- // decrease current
- OutputConfigStep[master] = _CURRENT_MODE_DECREASE;
- PSU_LOG("Gun %d Decrease Current: %d.%d A, %d.%d A -> %d.%d A", master + 1,
- ((PresentTargetCurrent - GCTargetCurrent[master]) / 10), ((PresentTargetCurrent - GCTargetCurrent[master]) % 10),
- (PresentTargetCurrent / 10), (PresentTargetCurrent % 10), (GCTargetCurrent[master] / 10), (GCTargetCurrent[master] % 10));
- #if MASTER_OUTPUT_FIRST
- // for safety test
- if(GCTargetCurrent[master] <= ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity * CURRENT_BALANCE_CRITERIA)
- {
- MasterDecreaseCurrent(master, PresentTargetCurrent - GCTargetCurrent[master]);
- }
- else
- {
- AverageDecreaseCurrent(master, PresentTargetCurrent - GCTargetCurrent[master]);
- }
- #else
- AverageDecreaseCurrent(master, PresentTargetCurrent - GCTargetCurrent[master]);
- #endif
- }
- else
- {
- // balance current or do not change
- OutputConfigStep[master] = _CURRENT_MODE_BALANCE;
- if(OutputConfigStep[master] != _preOutputConfigStep[master])
- {
- GetClockTime(&_ReachCurrent_time[master]);
- PSU_LOG("Gun %d In Balance Mode", master + 1);
- StableOutputCurrent[master] = (int)chargingInfo[master]->PresentChargingCurrent * 10;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.OutputCurrentStable = false;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance = false;
- }
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.OutputCurrentStable)
- {
- if(IsMasterOutputCurrentStable(master))
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.OutputCurrentStable = true;
- LOG_INFO("Gun %d Output Current = %5.1f A Stable", master + 1, chargingInfo[master]->PresentChargingCurrent);
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.OutputCurrentStable ||
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.SmoothDerating)
- {
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.SmoothDerating)
- {
- CheckSmoothBalance(master);
- }
- else
- {
- #if MASTER_OUTPUT_FIRST
- // for safety test
- if(GCTargetCurrent[master] > ShmPsuGrouping->GroupCollection[master].Partner.RealQuantity * CURRENT_BALANCE_CRITERIA)
- {
- CheckCurrentBalance(master);
- }
- else
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance = false;
- }
- #else
- CheckCurrentBalance(master);
- #endif
- }
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedCurrentBalance &&
- !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.SmoothDerating)
- {
- CheckReleaseOrExtend(master);
- }
- }
- }
- }
- else
- {
- // master in derating mode
- OutputConfigStep[master] = _CURRENT_MODE_DERATING;
- if(OutputConfigStep[master] != _preOutputConfigStep[master])
- {
- LOG_INFO("Gun %d In Derating Mode", master + 1);
- }
- }
- _preOutputConfigStep[master] = OutputConfigStep[master];
- }
- }
- else
- {
- ShmPsuGrouping->GroupOutput[master].GTargetVoltage = 0;
- ShmPsuGrouping->GroupOutput[master].GTargetCurrent = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- ShmPsuGrouping->GroupOutput[slave].GTargetVoltage = 0;
- ShmPsuGrouping->GroupOutput[slave].GTargetCurrent = 0;
- }
- }
- }
- // group: self group index
- void SetPsuGroupOutput(unsigned char group)
- {
- int time = 0;
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- if(ShmPsuGrouping->GroupOutput[group].GTargetVoltage >= PSU_MIN_VOL)
- {
- #if ONE_MODULE_OUTPUT
- // for safety test (inrush current)
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.InPrechargeMode)
- {
- SingleOutputVol(ShmPsuPosition->GroupLocationInfo[group].PsuSN[0], ShmPsuGrouping->GroupOutput[group].GTargetVoltage, ShmPsuGrouping->GroupOutput[group].GTargetCurrent);
- }
- else
- {
- PresentOutputVol(group, ShmPsuGrouping->GroupOutput[group].GTargetVoltage, ShmPsuGrouping->GroupOutput[group].GTargetCurrent);
- }
- #else
- PresentOutputVol(group, ShmPsuGrouping->GroupOutput[group].GTargetVoltage, ShmPsuGrouping->GroupOutput[group].GTargetCurrent);
- #endif
- if(!isStartOutputSwitch[group])
- {
- SetPsuGroupPowerOnOff(group, _PSU_ON);
- GetClockTime(&_PoweOnOff_time[group]);
- }
- }
- else
- {
- if(isStartOutputSwitch[group])
- {
- SetPsuGroupPowerOnOff(group, _PSU_OFF);
- GetClockTime(&_PoweOnOff_time[group]);
- }
- #if ONE_MODULE_OUTPUT
- // for safety test (inrush current)
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.InPrechargeMode)
- {
- SingleOutputVol(ShmPsuPosition->GroupLocationInfo[group].PsuSN[0], ShmPsuGrouping->GroupOutput[group].GTargetVoltage, ShmPsuGrouping->GroupOutput[group].GTargetCurrent);
- }
- else
- {
- PresentOutputVol(group, ShmPsuGrouping->GroupOutput[group].GTargetVoltage, ShmPsuGrouping->GroupOutput[group].GTargetCurrent);
- }
- #else
- PresentOutputVol(group, ShmPsuGrouping->GroupOutput[group].GTargetVoltage, ShmPsuGrouping->GroupOutput[group].GTargetCurrent);
- #endif
- }
- }
- time = GetTimeoutValue(_PoweOnOff_time[group]) / uSEC_VAL;
- if(time > POWER_ONOFF_RESEND_INTERVAL)
- {
- SetPsuGroupPowerOnOff(group, isStartOutputSwitch[group] ? _PSU_ON : _PSU_OFF);
- GetClockTime(&_PoweOnOff_time[group]);
- }
- //UpdatePsuGroupLoading(group);
- UpdateGunLoading(group);
- }
- // master: master group index
- bool CanMasterStartDerating(unsigned char master)
- {
- bool start = false;
- unsigned short TargetCurrent = 0;
- TargetCurrent = (int)(chargingInfo[master]->EvBatterytargetCurrent * 10);
- if(TargetCurrent <= ShmPsuGrouping->GroupCollection[master].ReAssignAvailableCurrent)
- {
- start = true;
- }
- return start;
- }
- // master: master group index
- // role_condition: when role_condition = _GROLE_MASTER, stop all member
- void SetMemberStartPowerOff(unsigned char master, unsigned char role_condition)
- {
- unsigned char slave = 0;
- char strMember[64];
- bool find = false;
- if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER)
- {
- sprintf(strMember, "Gun %d Set Member:", master + 1);
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(role_condition == _GROLE_MASTER || ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PREPARE_SWITCH_OFF)
- {
- SetPsuGroupRole(slave, _GROLE_SLAVE_POWER_OFF);
- char strSlave[8];
- sprintf(strSlave, " [%02X]", slave);
- strcat(strMember, strSlave);
- find = true;
- }
- }
- if(find)
- {
- strcat(strMember, " Power Off");
- LOG_INFO("%s", strMember);
- }
- }
- }
- // master: master group index
- bool IsMemberPowerOffOK(unsigned char master)
- {
- bool done = true;
- unsigned char slave = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_SLAVE && ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_SWITCH_OFF_OK)
- {
- done = false;
- }
- }
- return done;
- }
- // master: master group index
- void SetMemberPowerOffDone(unsigned char master)
- {
- unsigned char slave = 0;
- if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER)
- {
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].Partner.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].Partner.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SWITCH_OFF_OK)
- {
- SetPsuGroupRole(slave, _GROLE_WAIT_IDLE);
- }
- else if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE_POWER_OFF)
- {
- // can not power off normally
- SetPsuGroupRole(slave, _GROLE_TERMINATE);
- }
- }
- }
- }
- unsigned char _ParallelRelay[MAX_GROUP_QUANTITY];
- void SetPCabinetParallelRelay(unsigned short parallelConfig)
- {
- bool change = false;
- if(ShmChargerInfo->Control.CabinetRole == _CROLE_MASTER)
- {
- for(int i = 0; i < MAX_SLAVE_CABINET_QUANTITY; i++)
- {
- change = false;
- if(ShmChargerInfo->ParallelCabinet.PCabinet[i].LocalStatus == _DeviceStatus_Idle ||
- ShmChargerInfo->ParallelCabinet.PCabinet[i].LocalStatus == _DeviceStatus_Alarm ||
- ShmChargerInfo->ParallelCabinet.PCabinet[i].LocalStatus == _DeviceStatus_Charging)
- {
- for(int j = 0; j < GENERAL_GUN_QUANTITY; j++)
- {
- _ParallelRelay[j] = (parallelConfig & (1 << j)) > 0 ? YES : NO;
- if(_ParallelRelay[i] != ShmChargerInfo->ParallelCabinet.PCabinet[i].ParallelRelaySetting[i])
- {
- change = true;
- }
- }
- if(change)
- {
- char strParallel[128];
- sprintf(strParallel, "Set PCabinet %d Parallel Relay:", i + 1);
- for(int j = 0; j < GENERAL_GUN_QUANTITY; j++)
- {
- char strState[8];
- sprintf(strState, " %3s", _ParallelRelay[j] ? "ON" : "OFF");
- strcat(strParallel, strState);
- }
- LOG_INFO("%s", strParallel);
- }
- ShmChargerInfo->ParallelCabinet.PCabinet[i].ParallelRelaySetting[i] = _ParallelRelay[i];
- }
- }
- }
- }
- // master: master group index
- // Yes_No: Yes: relay on, No: relay off
- // role_condition: when role_condition = _GROLE_MASTER, parallel relay of all member do the action(on or off)
- void SetParallelRelayOnOff(unsigned char master, unsigned char Yes_No, unsigned char role_condition)
- {
- //int ParallelConfig = 0;
- unsigned char slave = 0;
- PsuGroupPartner *partner;
- if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER ||
- (ShmPsuGrouping->GroupCollection[master].Role == _GROLE_REQUEST_TO_CHARGING && Yes_No))
- {
- ShmPsuGrouping->GroupCollection[master].ParallelCheck = 0;
- partner = role_condition == _GROLE_PRECHARGE_READY ? &ShmPsuGrouping->GroupCollection[master].PossibleMember : &ShmPsuGrouping->GroupCollection[master].Partner;
- for(int i = 0; i < partner->Quantity; i++)
- {
- slave = partner->Member[i];
- if(role_condition == _GROLE_MASTER || ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_SLAVE)
- {
- //ParallelConfig = ShmPsuGrouping->GroupCollection[master].ParallelConfig[slave];
- //if(ParallelConfig != 0)
- //{
- // ShmPsuGrouping->GroupCollection[master].ParallelCheck |= (1 << (ParallelConfig - 1));
- //}
- ShmPsuGrouping->GroupCollection[master].ParallelCheck |= partner->ParallelFlag[i];
- }
- }
- if(Yes_No)
- {
- ShmPsuGrouping->ParallelRelayConfig.CtrlValue |= ShmPsuGrouping->GroupCollection[master].ParallelCheck;
- }
- else
- {
- ShmPsuGrouping->ParallelRelayConfig.CtrlValue &= ~ShmPsuGrouping->GroupCollection[master].ParallelCheck;
- }
- SetPCabinetParallelRelay(ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
- }
- }
- // master: master group index
- bool IsParallelRelayConfirmed(unsigned char master)
- {
- bool confirmed = true;
- for(int i = 0; i < CONNECTOR_QUANTITY; i++)
- {
- if((1 << i) & ShmPsuGrouping->GroupCollection[master].ParallelCheck)
- {
- if((ShmPsuGrouping->ParallelRelayConfig.CtrlValue & (1 << i)) != (ShmPsuGrouping->ParallelRelayConfirmed.CtrlValue & (1 << i)))
- {
- confirmed = false;
- break;
- }
- }
- }
- return confirmed;
- }
- // master: master group index
- bool IsPossibleMemberReady(unsigned char master)
- {
- bool ready = true;
- unsigned char slave = 0;
- if(ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity > 0)
- {
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].PossibleMember.Member[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_WAIT_SLAVE)
- {
- ready = false;
- }
- }
- }
- return ready;
- }
- // master: master group index
- bool IsExtendPrechargeReady(unsigned char master)
- {
- bool ready = true;
- unsigned char slave = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].PossibleMember.Member[i];
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity == 0 || ShmPsuData->PsuGroup[slave].GroupAvailableCurrent == 0)
- {
- continue;
- }
- if(ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_PREPARE_ATTACH_ON ||
- ShmPsuData->PsuGroup[slave].GroupPresentOutputVoltage > (ShmPsuData->PsuGroup[master].GroupPresentOutputVoltage + PRECHARGE_RANGE_VOLTAGE) ||
- ShmPsuData->PsuGroup[slave].GroupPresentOutputVoltage < (ShmPsuData->PsuGroup[master].GroupPresentOutputVoltage - PRECHARGE_OFFSET_VOLTAGE - PRECHARGE_RANGE_VOLTAGE))
- {
- ready = false;
- }
- }
- return ready;
- }
- // master: master group index
- void SetExtendPrechargeCompleted(unsigned char master)
- {
- unsigned char slave = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].PossibleMember.Member[i];
- SetPsuGroupRole(slave, _GROLE_PRECHARGE_READY);
- }
- }
- // master: master group index
- void SetExtendPrechargeStop(unsigned char master)
- {
- unsigned char slave = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].PossibleMember.Member[i];
- SetPsuGroupRole(slave, _GROLE_EXTEND_STOP);
- }
- memset(&ShmPsuGrouping->GroupCollection[master].PossibleMember, 0x00, sizeof(PsuGroupPartner));
- }
- // master: master group index
- void AddExtendMember(unsigned char master)
- {
- unsigned char slave = 0;
- unsigned short parallelFlag = 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity; i++)
- {
- slave = ShmPsuGrouping->GroupCollection[master].PossibleMember.Member[i];
- parallelFlag = ShmPsuGrouping->GroupCollection[master].PossibleMember.ParallelFlag[i];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PRECHARGE_READY)
- {
- AddMember(slave, master, parallelFlag);
- }
- }
- }
- // group: self group index
- void CheckChargingRequest(unsigned char group)
- {
- if(ShmPsuGrouping->GroupCollection[group].Role != _GROLE_IDLE)
- {
- return;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ChargingRequest)
- {
- SetPsuGroupRole(group, _GROLE_REQUEST_TO_CHARGING);
- }
- }
- // group: self group index
- void ChargingRequestProcess(unsigned char group)
- {
- int time = 0;
- PsuGroupPartner partner;
- if(ShmPsuGrouping->GroupCollection[group].Role != _GROLE_REQUEST_TO_CHARGING)
- {
- return;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ChargingRequest && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ChargingRequestConfirmed)
- {
- GetClockTime(&_ChargingRequest_time[group]);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ChargingRequest = false;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ChargingRequestConfirmed = true;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GroupShareCheck = true;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GroupShareCheck && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ShareConfirmed)
- {
- // check is there psu group to grab
- if(PsuGroupGrabCheck(group, &partner))
- {
- GetClockTime(&_ChargingRequest_time[group]);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GrabGroupWait = true;
- PrepareToPowerOff(group + 1, &partner);
- memcpy(&ShmPsuGrouping->GroupCollection[group].PossibleMember, &partner, sizeof(PsuGroupPartner));
- }
- else
- {
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ShareCheckDone = true;
- LOG_INFO("Gun %d Grab Nothing", group + 1);
- }
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ShareConfirmed = true;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GrabGroupWait && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ShareCheckDone)
- {
- // wait until grab psu ready or timeout
- bool ready = IsPossibleMemberReady(group);
- time = GetTimeoutValue(_ChargingRequest_time[group]) / uSEC_VAL;
- if(ready || time >= WAIT_GRAB_TIME)
- {
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ShareCheckDone = true;
- LOG_INFO("Gun %d Grab %s", group + 1, ready ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ShareCheckDone && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.FindGroupPartner)
- {
- GetClockTime(&_ChargingRequest_time[group]);
- AddAvailableMember(group);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.FindGroupPartner = true;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.FindGroupPartner && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ParallelRelayOn)
- {
- // after a little delay, set parallel relay on
- time = GetTimeoutValue(_ChargingRequest_time[group]) / uSEC_VAL;
- if(time >= WAIT_PARALLEL_RELAY_DELAY)
- {
- unsigned short original = ShmPsuGrouping->ParallelRelayConfig.CtrlValue;
- GetClockTime(&_ChargingRequest_time[group]);
- SetParallelRelayOnOff(group, YES, _GROLE_MASTER);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ParallelRelayOn = true;
- LOG_INFO("Gun %d Charging Request Set All Member Parallel Relay On 0x%02X -> 0x%02X", group + 1, original, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
- }
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ParallelRelayOn && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ParallelRelayConfirmed)
- {
- // wait until parallel relay on confirmed
- bool confirmed = IsParallelRelayConfirmed(group);
- time = GetTimeoutValue(_ChargingRequest_time[group]) / uSEC_VAL;
- //if(confirmed || time >= WAIT_RELAY_CONFIRMED_TIME)
- if(time >= WAIT_RELAY_CONFIRMED_TIME)
- {
- GetClockTime(&_ChargingRequest_time[group]);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ParallelRelayConfirmed = true;
- LOG_INFO("Gun %d Charging Request Parallel Relay Confirmed %s", group + 1, confirmed ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ParallelRelayConfirmed && !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GroupingDone)
- {
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GroupingDone = true;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.GroupingDone)
- {
- SetPsuGroupToMaster(group);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.IdleCtrlValue = 0;
- LOG_INFO("Gun %d Grouping Completed", group + 1);
- }
- }
- // master: master group index
- void PsuGroupDeratingProcess(unsigned char master)
- {
- int time = 0;
- // slave group set NeedDerating flag to start re-assign
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedDerating)
- {
- // reduce output current capability start
- GetClockTime(&_PsuGroupDerating_time[master]);
- unsigned short ReAssignCurrent = GetPresentTargetCurrent(master, _GROLE_SLAVE);
- ShmPsuGrouping->GroupCollection[master].ReAssignAvailableCurrent = ReAssignCurrent;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.NeedDerating = false;
- LOG_INFO("Gun %d DeratingConfirmed%s, ReAssignAvailableCurrent = %d.%d A",
- master + 1,
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed ? " Again" : "",
- (ReAssignCurrent / 10), (ReAssignCurrent % 10));
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.DeratingCtrlValue = 0;
- }
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed = true;
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingStart)
- {
- // wait until derating from ev or timeout
- bool start = CanMasterStartDerating(master);
- bool bypass = ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AlreadyInChargingMode ? false : true;
- time = GetTimeoutValue(_PsuGroupDerating_time[master]) / uSEC_VAL;
- if(start || time >= WAIT_EV_DERATING_TIMEOUT || bypass)
- {
- GetClockTime(&_PsuGroupDerating_time[master]);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingStart = true;
- LOG_INFO("Gun %d %s Start Derating%s", master + 1, start ? "Normal" : "Force", bypass ? " (Bypass)" : "");
- SetMemberStartPowerOff(master, _GROLE_PREPARE_SWITCH_OFF);
- if(!bypass)
- {
- // update stage max current and reset max current time
- StageMaxCurrent[master] = start ?
- (int)(chargingInfo[master]->EvBatterytargetCurrent * 10) :
- ShmPsuGrouping->GroupCollection[master].ReAssignAvailableCurrent;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxStageCurrent = false;
- GetClockTime(&_StageCurrent_time[master]);
- }
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingStart && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingPowerOffDone)
- {
- // wait until psu member power off ok or timeout
- bool power_off_ok = IsMemberPowerOffOK(master);
- time = GetTimeoutValue(_PsuGroupDerating_time[master]) / uSEC_VAL;
- if(power_off_ok || time >= WAIT_SLAVE_POWER_OFF_TIMEOUT)
- {
- GetClockTime(&_PsuGroupDerating_time[master]);
- SetMemberPowerOffDone(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingPowerOffDone = true;
- LOG_INFO("Gun %d Set Derating Member Power Off %s", master + 1, power_off_ok ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingPowerOffDone && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingRelayOff)
- {
- // after a little delay, set parallel relay off
- time = GetTimeoutValue(_PsuGroupDerating_time[master]) / uSEC_VAL;
- if(time >= WAIT_PARALLEL_RELAY_DELAY)
- {
- unsigned short original = ShmPsuGrouping->ParallelRelayConfig.CtrlValue;
- GetClockTime(&_PsuGroupDerating_time[master]);
- SetParallelRelayOnOff(master, NO, _GROLE_SWITCH_OFF_OK);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingRelayOff = true;
- LOG_INFO("Gun %d Set Parallel Relay Off 0x%02X -> 0x%02X", master + 1, original, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingRelayOff && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingRelayConfirmed)
- {
- // wait until parallel relay off confirmed
- bool confirmed = IsParallelRelayConfirmed(master);
- time = GetTimeoutValue(_PsuGroupDerating_time[master]) / uSEC_VAL;
- //if(confirmed || time >= WAIT_RELAY_CONFIRMED_TIME)
- if(time >= WAIT_RELAY_CONFIRMED_TIME)
- {
- GetClockTime(&_PsuGroupDerating_time[master]);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingRelayConfirmed = true;
- LOG_INFO("Gun %d Parallel Relay Confirmed %s", master + 1, confirmed ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingRelayConfirmed && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingCompleted)
- {
- // remove all non group member
- RemoveNonGroupMember(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingCompleted = true;
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingCompleted)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.DeratingCtrlValue = 0;
- UpdateGunAvailableCapability(master);
- GetClockTime(&_ExtendCapability_time[master]);
- LOG_INFO("Gun %d Derating Completed", master + 1);
- }
- }
- void MasterStopChargingProcess(unsigned char master)
- {
- int time = 0;
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingRequest && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingConfirmed)
- {
- // set all member to power off
- GetClockTime(&_StopCharging_time[master]);
- SetMemberStartPowerOff(master, _GROLE_MASTER);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingConfirmed = true;
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingConfirmed && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllPowerOffDone)
- {
- // wait until psu member power off ok or timeout
- bool power_off_ok = IsMemberPowerOffOK(master);
- time = GetTimeoutValue(_StopCharging_time[master]) / uSEC_VAL;
- if(power_off_ok || time >= WAIT_SLAVE_POWER_OFF_TIMEOUT)
- {
- GetClockTime(&_StopCharging_time[master]);
- SetMemberPowerOffDone(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllPowerOffDone = true;
- LOG_INFO("Gun %d Set All Member Power Off %s", master + 1, power_off_ok ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllPowerOffDone && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllParallelRelayOff)
- {
- // after a little delay, set all member parallel relay off
- time = GetTimeoutValue(_StopCharging_time[master]) / uSEC_VAL;
- if(time >= WAIT_PARALLEL_RELAY_DELAY)
- {
- unsigned short original = ShmPsuGrouping->ParallelRelayConfig.CtrlValue;
- GetClockTime(&_StopCharging_time[master]);
- SetParallelRelayOnOff(master, NO, _GROLE_MASTER);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllParallelRelayOff = true;
- LOG_INFO("Gun %d Set All Member Parallel Relay Off 0x%02X -> 0x%02X", master + 1, original, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllParallelRelayOff && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllParallelRelayConfirmed)
- {
- // wait until parallel relay off confirmed
- bool confirmed = IsParallelRelayConfirmed(master);
- time = GetTimeoutValue(_StopCharging_time[master]) / uSEC_VAL;
- //if(confirmed || time >= WAIT_RELAY_CONFIRMED_TIME)
- if(time >= WAIT_RELAY_CONFIRMED_TIME)
- {
- GetClockTime(&_StopCharging_time[master]);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllParallelRelayConfirmed = true;
- LOG_INFO("Gun %d All Member Parallel Relay Confirmed %s", master + 1, confirmed ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllParallelRelayConfirmed && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllMemberStopCompleted)
- {
- // remove all non group member
- RemoveNonGroupMember(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllMemberStopCompleted = true;
- LOG_INFO("Gun %d All Member Stop Completed", master + 1);
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.AllMemberStopCompleted && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingCompleted)
- {
- // check self group power down or not
- if(ShmPsuData->PsuGroup[master].GroupPresentOutputCurrent <= MAX_PSU_POWER_OFF_CURRENT)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingCompleted = true;
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingCompleted)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.MasterCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.StopChargingCtrlValue = 0;
- SetPsuGroupToIdle(master);
- LOG_INFO("Gun %d Stop Charging Completed", master + 1);
- }
- }
- void SlaveStopChargingProcess(unsigned char slave)
- {
- int time = 0;
- unsigned char master = 0;
- PsuGroupPartner PowerOffMember, GrabMember;
- if(ShmPsuGrouping->GroupCollection[slave].Role != _GROLE_SLAVE)
- {
- return;
- }
- master = ShmPsuGrouping->GroupCollection[slave].TargetGroup - 1;
- if(ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlaveChargingRequest && !ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.CheckSlaveReady)
- {
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.CheckSlaveReady = true;
- if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_REQUEST_TO_CHARGING)
- {
- LOG_INFO("Gun %d Need Wait Gun %d Grouping Completed", slave + 1, master + 1);
- GetClockTime(&_CheckSlaveReady_time[slave]);
- }
- else if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER && ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed)
- {
- LOG_INFO("Gun %d Need Wait Gun %d Derating Completed", slave + 1, master + 1);
- GetClockTime(&_CheckSlaveReady_time[slave]);
- }
- else
- {
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlavePowerOffRequest = true;
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.WaitSlaveReady = true;
- LOG_INFO("Gun %d Need Power Off And Request To Charging", slave + 1);
- }
- }
- // wait until master derating completed
- if(ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.CheckSlaveReady && !ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.WaitSlaveReady)
- {
- time = GetTimeoutValue(_CheckSlaveReady_time[slave]) / uSEC_VAL;
- if(time >= WAIT_SLAVE_READY_TIME ||
- (ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed))
- {
- if(!(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.DeratingConfirmed))
- {
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.RoleCtrl.SlaveCtrlValue = 0;
- LOG_INFO("Gun %d Wait Gun %d Timeout", slave + 1);
- }
- else
- {
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.WaitSlaveReady = true;
- LOG_INFO("Gun %d Is Ready", slave + 1);
- GetClockTime(&_CheckSlaveReady_time[slave]);
- }
- }
- }
- if(ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.WaitSlaveReady && !ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlavePowerOffRequest)
- {
- time = GetTimeoutValue(_CheckSlaveReady_time[slave]) / uSEC_VAL;
- if(time >= WAIT_SLAVE_DELAY)
- {
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlavePowerOffRequest = true;
- }
- }
- // self group, other slave or master set SlavePowerOffRequest flag to power off
- if(ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlavePowerOffRequest && !ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlavePowerOffConfirmed)
- {
- if(ShmChargerInfo->Control.SysCtrl.bits.Enable6ParallelRelay == 0)
- {
- PsuGroupPowerOffCheck(slave, &PowerOffMember);
- }
- else
- {
- PowerOffMember.Quantity = 1;
- PowerOffMember.Member[0] = slave;
- }
- if(PowerOffMember.Quantity == 1 && ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlaveChargingRequest)
- {
- // grab here
- if(PsuGroupGrabCheck(slave, &GrabMember))
- {
- for(int i = 0; i < GrabMember.Quantity; i++)
- {
- PowerOffMember.Member[PowerOffMember.Quantity++] = GrabMember.Member[i];
- }
- }
- }
- if(PowerOffMember.Quantity > 0)
- {
- unsigned char target = ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlaveChargingRequest ? (slave + 1) : 0;
- PrepareToPowerOff(target, &PowerOffMember);
- if(PowerOffMember.Quantity > 1 && ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlaveChargingRequest)
- {
- ShmPsuGrouping->GroupCollection[slave].PossibleMember.Quantity = PowerOffMember.Quantity - 1;
- memcpy(ShmPsuGrouping->GroupCollection[slave].PossibleMember.Member, &PowerOffMember.Member[1], PowerOffMember.Quantity - 1);
- }
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.bits.SlavePowerOffConfirmed = true;
- }
- else
- {
- ShmPsuGrouping->GroupCollection[slave].GroupCtrl.RoleCtrl.SlaveCtrlValue = 0;
- }
- }
- }
- void MasterExtendCapabilityProcess(unsigned char master)
- {
- int time = 0;
- // stop extend capability process when derating or stop charging
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.DeratingCtrlValue != 0 ||
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.StopChargingRequest)
- {
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.MorePowerConfirmed)
- {
- SetExtendPrechargeStop(master);
- }
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit = 0;
- return;
- }
- // start extend capability
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.MorePowerRequest && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.MorePowerConfirmed)
- {
- GetClockTime(&_ExtendCapability_time[master]);
- memset(&ShmPsuGrouping->GroupCollection[master].PossibleMember, 0x00, sizeof(PsuGroupPartner));
- FindPsuGroupPartner(master, (int)ShmPsuGrouping->GroupCollection[master].DiffPower_PhysicalLimit, &ShmPsuGrouping->GroupCollection[master].PossibleMember, _EXTEND_TYPE_POWER, ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit);
- if(ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity > 0)
- {
- PrepareToExtendCapability(master + 1, &ShmPsuGrouping->GroupCollection[master].PossibleMember);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.MorePowerConfirmed = true;
- }
- else
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit = 0;
- }
- }
- // set extend member precharge voltage
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.MorePowerConfirmed && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrechargeDone)
- {
- unsigned short voltage = ShmPsuData->PsuGroup[master].GroupPresentOutputVoltage >= PRECHARGE_OFFSET_VOLTAGE ?
- ShmPsuData->PsuGroup[master].GroupPresentOutputVoltage - PRECHARGE_OFFSET_VOLTAGE : 0;
- for(int i = 0; i < ShmPsuGrouping->GroupCollection[master].PossibleMember.Quantity; i++)
- {
- unsigned char slave = ShmPsuGrouping->GroupCollection[master].PossibleMember.Member[i];
- if(ShmPsuData->PsuGroup[slave].GroupPresentPsuQuantity > 0 && ShmPsuData->PsuGroup[slave].GroupAvailableCurrent > 0)
- {
- ShmPsuGrouping->GroupOutput[slave].GTargetVoltage = voltage;
- ShmPsuGrouping->GroupOutput[slave].GTargetCurrent = ZERO_CURRENT;
- }
- }
- if(!ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrecharge)
- {
- GetClockTime(&_ExtendCapability_time[master]);
- LOG_INFO("Gun %d Set ExtendPrecharge Voltage %d.%d V", master + 1, (voltage / 10), (voltage % 10));
- }
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrecharge = true;
- }
- // wait for extend member precharge ready
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrecharge && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrechargeDone)
- {
- bool ready = IsExtendPrechargeReady(master);
- time = GetTimeoutValue(_ExtendCapability_time[master]) / uSEC_VAL;
- if(ready || time >= WAIT_PRECHARGE_TIME)
- {
- LOG_INFO("Gun %d ExtendPrecharge %s", master + 1, ready ? "Ready" : "Timeout");
- if(ready)
- {
- GetClockTime(&_ExtendCapability_time[master]);
- SetExtendPrechargeCompleted(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrechargeDone = true;
- }
- else
- {
- SetExtendPrechargeStop(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit = 0;
- }
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendPrechargeDone && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendRelayOn)
- {
- // after a little delay, set extend parallel relay on
- time = GetTimeoutValue(_ExtendCapability_time[master]) / uSEC_VAL;
- if(time >= WAIT_PARALLEL_RELAY_DELAY)
- {
- unsigned short original = ShmPsuGrouping->ParallelRelayConfig.CtrlValue;
- GetClockTime(&_ExtendCapability_time[master]);
- SetParallelRelayOnOff(master, YES, _GROLE_PRECHARGE_READY);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendRelayOn = true;
- LOG_INFO("Gun %d Set Extend Parallel Relay On 0x%02X -> 0x%02X", master + 1, original, ShmPsuGrouping->ParallelRelayConfig.CtrlValue);
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendRelayOn && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendRelayConfirmed)
- {
- // wait until extend parallel relay on confirmed
- bool confirmed = IsParallelRelayConfirmed(master);
- time = GetTimeoutValue(_ExtendCapability_time[master]) / uSEC_VAL;
- //if(confirmed || time >= WAIT_RELAY_CONFIRMED_TIME)
- if(time >= WAIT_RELAY_CONFIRMED_TIME)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendRelayConfirmed = true;
- LOG_INFO("Gun %d Extend Parallel Relay Confirmed %s", master + 1, confirmed ? "OK" : "Timeout");
- }
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendRelayConfirmed && !ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendCompleted)
- {
- AddExtendMember(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendCompleted = true;
- }
- if(ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ExtendCompleted)
- {
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[master].ExtendQuantityLimit = 0;
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.OutputCurrentStable = false;
- GetClockTime(&_ReachCurrent_time[master]);
- UpdateGunAvailableCapability(master);
- ShmPsuGrouping->GroupCollection[master].GroupCtrl.bits.ReachMaxStageCurrent = false;
- GetClockTime(&_StageCurrent_time[master]);
- LOG_INFO("Gun %d Extend Capability Completed", master + 1);
- }
- }
- void ShowGunVoltageCurrent(unsigned char master)
- {
- unsigned short voltage = 0, current = 0, fireVoltage = 0;
- unsigned short diffVoltage = 0, diffCurrent = 0;
- if(ShmPsuGrouping->GroupCollection[master].Role == _GROLE_MASTER)
- {
- voltage = (int)(chargingInfo[master]->PresentChargingVoltage * 10);
- current = (int)(chargingInfo[master]->PresentChargingCurrent * 10);
- fireVoltage = chargingInfo[master]->FireChargingVoltage;
- diffVoltage = voltage >= evseOutVol[master] ? voltage - evseOutVol[master] : evseOutVol[master] - voltage;
- diffCurrent = current >= evseOutCur[master] ? current - evseOutCur[master] : evseOutCur[master] - current;
- if(diffVoltage >= 10 || diffCurrent >= 10)
- {
- evseOutputDelay[master] = SHOW_OUTPUT_DELAY;
- evseOutVol[master] = voltage;
- evseOutCur[master] = current;
- }
- if(evseOutputDelay[master] != 0)
- {
- LOG_INFO("Gun %d NeedV: %4d V, NeedC: %3d A, OutputV: %4d.%d V, OutputC: %3d.%d A, FireV: %4d V",
- master + 1, (int)chargingInfo[master]->EvBatterytargetVoltage, (int)chargingInfo[master]->EvBatterytargetCurrent,
- (voltage / 10), (voltage % 10), (current / 10), (current % 10), fireVoltage / 10);
- evseOutputDelay[master]--;
- }
- }
- }
- // group: self group index
- void TryCleanPsuAlarm(unsigned char group)
- {
- for(int i = 0; i < ShmPsuPosition->GroupLocationInfo[group].GroupPsuQuantity; i++)
- {
- int psu_index = ShmPsuPosition->GroupLocationInfo[group].PsuIndex[i];
- if(ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal == PSU_STATUS_FLAG_LOCK)
- {
- UnlockPsuAlarm(ShmPsuPosition->PsuAddressInfo[psu_index].Full_Address);
- PSU_LOG("Unlock PSU Group[%d] Index[%d] Alarm Status", group, ShmPsuPosition->PsuAddressInfo[psu_index].GIndex);
- }
- }
- }
- void CheckPsuAlarmStatus(void)
- {
- if(_isTriggerShutdown)
- {
- return;
- }
- for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
- {
- for(int j = 0; j < ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity; j++)
- {
- int psu_index = ShmPsuPosition->GroupLocationInfo[i].PsuIndex[j];
- int group = ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo;
- int gIndex = ShmPsuPosition->PsuAddressInfo[psu_index].GIndex;
- if(ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal != _LocalPsuStatus[psu_index].StatusVal)
- {
- if(((ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal & 0x02) != (_LocalPsuStatus[psu_index].StatusVal & 0x02)))
- {
- if((ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal & 0x02) != 0)
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Fault Occur", group, gIndex, psu_index);
- }
- else
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Fault Recovery", group, gIndex, psu_index);
- }
- }
- if(((ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal & 0x04) != (_LocalPsuStatus[psu_index].StatusVal & 0x04)))
- {
- if((ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal & 0x04) != 0)
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Alarm Occur", group, gIndex, psu_index);
- }
- else
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Alarm Recovery", group, gIndex, psu_index);
- }
- }
- if(((ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal & 0x08) != (_LocalPsuStatus[psu_index].StatusVal & 0x08)))
- {
- if((ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal & 0x08) != 0)
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Lock Occur", group, gIndex, psu_index);
- }
- else
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Lock Recovery", group, gIndex, psu_index);
- }
- }
- }
- _LocalPsuStatus[psu_index].StatusVal = ShmPsuPosition->SinglePsuStatus[psu_index].StatusVal;
- }
- }
- }
- void ShowInfyPsuErrState(int psu_index)
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] State2: [%02X], State1: [%02X], State0: [%02X]",
- ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo,
- ShmPsuPosition->PsuAddressInfo[psu_index].GIndex,
- psu_index,
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[2],
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[1],
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrState.StateVal[0]);
- }
- void InfyPwrStateSummary(void)
- {
- InfyPsuStateFlagInfo _InfyPwrState;
- memset(&_InfyPwrState, 0x00, sizeof(_InfyPwrState));
- for(int i = 0; i < MAX_PSU_MODULE_QUANTITY; i++)
- {
- _InfyPwrState.StateVal[0] |= ShmPsuPosition->SingleInfyPwrState[i].InfyPwrState.StateVal[0];
- _InfyPwrState.StateVal[1] |= ShmPsuPosition->SingleInfyPwrState[i].InfyPwrState.StateVal[1];
- _InfyPwrState.StateVal[1] |= ShmPsuPosition->SingleInfyPwrState[i].InfyPwrState.StateVal[2];
- }
- // 012264
- // DCDC short circuit
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = _InfyPwrState.bits.OutputShort ? YES : NO;
- // 012334
- // PSU Failure Alarm
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFault = _InfyPwrState.bits.PsuFault ? YES : NO;
- // 012268
- // PSU Protection Alarm
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = _InfyPwrState.bits.PsuProtect ? YES : NO;
- // 012269
- // Fan faults
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = _InfyPwrState.bits.FanFault ? YES : NO;
- // 012226
- // DCDC over temperature
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = _InfyPwrState.bits.OverTemperature ? YES : NO;
- // 012319
- // DCDC output over voltage
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = _InfyPwrState.bits.OutputOverVoltage ? YES : NO;
- // 012273
- // Module unders power limiting status
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = _InfyPwrState.bits.PowerLimit ? YES : NO;
- // 012263
- // ID number repetition
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = _InfyPwrState.bits.PsuIdRepetition ? YES : NO;
- // 012313
- // Phase loss
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = _InfyPwrState.bits.InputPhaseLost ? YES : NO;
- // 012271
- // Under voltage of any phase
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = _InfyPwrState.bits.InputUnderVoltage ? YES : NO;
- // 012270
- // Over voltage of any phase
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = _InfyPwrState.bits.InputOverVoltage ? YES : NO;
- }
- void ShowPhPsuErrRecord(int psu_index)
- {
- if(ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount == 0)
- {
- LOG_INFO("Group[%d][%d] Psu[%2d] Error Record Clear",
- ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo,
- ShmPsuPosition->PsuAddressInfo[psu_index].GIndex,
- psu_index);
- }
- else
- {
- char strErrRecord[128];
- char strError[16];
- sprintf(strErrRecord, "Group[%d][%d] Psu[%2d] Err:",
- ShmPsuPosition->PsuAddressInfo[psu_index].GroupNo,
- ShmPsuPosition->PsuAddressInfo[psu_index].GIndex,
- psu_index);
- for(int i = 0; i < ShmPsuPosition->SinglePhPsuError[psu_index].ErrorCount; i++)
- {
- sprintf(strError, " E-%2d", ShmPsuPosition->SinglePhPsuError[psu_index].PsuError[i]);
- strcat(strErrRecord, strError);
- }
- LOG_INFO("%s", strErrRecord);
- }
- }
- void CheckPsuErrRecord(void)
- {
- if(_isTriggerShutdown)
- {
- return;
- }
- for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
- {
- for(int j = 0; j < ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity; j++)
- {
- int psu_index = ShmPsuPosition->GroupLocationInfo[i].PsuIndex[j];
- if(ShmChargerInfo->Control.LibCtrl.bits.InfyPwrLib)
- {
- if(ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrStateFlag.bits.Changed)
- {
- ShowInfyPsuErrState(psu_index);
- InfyPwrStateSummary();
- ShmPsuPosition->SingleInfyPwrState[psu_index].InfyPwrStateFlag.bits.Changed = false;
- }
- }
- if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
- {
- if(ShmPsuPosition->SinglePhPsuError[psu_index].PhPwrStateFlag.bits.Changed)
- {
- ShowPhPsuErrRecord(psu_index);
- ShmPsuPosition->SinglePhPsuError[psu_index].PhPwrStateFlag.bits.Changed = false;
- }
- }
- }
- }
- }
- bool IsPsuGroupAnyAlarm(unsigned char group)
- {
- if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_ALARM) > 0)
- {
- return true;
- }
- return false;
- }
- bool IsPsuGroupAnyFault(unsigned char group)
- {
- if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_FAULT) > 0)
- {
- return true;
- }
- return false;
- }
- bool IsPsuGroupAllAlarm(unsigned char group)
- {
- if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal & PSU_STATUS_FLAG_ALARM) > 0)
- {
- return true;
- }
- return false;
- }
- bool IsPsuGroupAllFault(unsigned char group)
- {
- if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_AND[group].StatusVal & PSU_STATUS_FLAG_FAULT) > 0)
- {
- return true;
- }
- return false;
- }
- bool IsPsuGroupAnyLock(unsigned char group)
- {
- if((ShmChargerInfo->PsuGrouping.GroupPsuStatus_OR[group].StatusVal & PSU_STATUS_FLAG_LOCK))
- {
- return true;
- }
- return false;
- }
- void PsuGroupControlProcess(void)
- {
- int time = 0;
- unsigned char role = 0;
- //unsigned short TargetVoltage = 0, TargetCurrent = 0;
- for(byte group = 0; group < GENERAL_GUN_QUANTITY; group++)
- {
- role = ShmPsuGrouping->GroupCollection[group].Role;
- switch(role)
- {
- case _GROLE_IDLE:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.IdleCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.MasterCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.StopChargingCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.DeratingCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.SlaveCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].ExtendQuantityLimit = 0;
- PSU_LOG("===== PSU Group[%02X] ===== Idle", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- GetClockTime(&_CleanPsuAlarm_time[group]);
- ShmPsuGrouping->GroupOutput[group].GTargetVoltage = 0;
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent = 0;
- PreGroupOutput[group].GTargetVoltage = 0;
- PreGroupOutput[group].GTargetCurrent = 0;
- ShmPsuGrouping->TotalGroupOutput[group].GTargetVoltage = 0;
- ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent = 0;
- SetPsuGroupOutput(group);
- UpdatePsuGroupLoading(group);
- }
- if(isStartOutputSwitch[group])
- {
- SetPsuGroupPowerOnOff(group, _PSU_OFF);
- }
- if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
- {
- if(IsPsuGroupAnyAlarm(group))
- {
- time = GetTimeoutValue(_CleanPsuAlarm_time[group]) / uSEC_VAL;
- if(time >= PSU_CLEAN_ERR_INTERVAL)
- {
- PSU_LOG("PSU Group[%d] Alarm or Fault Occur, Need Do Something", group);
- GetClockTime(&_CleanPsuAlarm_time[group]);
- }
- // if module exist any alarm or fault, break here
- break;
- }
- else if(IsPsuGroupAnyLock(group))
- {
- time = GetTimeoutValue(_CleanPsuAlarm_time[group]) / uSEC_VAL;
- if(time >= PSU_CLEAN_ERR_INTERVAL)
- {
- TryCleanPsuAlarm(group);
- GetClockTime(&_CleanPsuAlarm_time[group]);
- }
- // if module exist any lock, break here
- break;
- }
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.IdleCtrlValue != 0)
- {
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- CheckChargingRequest(group);
- }
- else
- {
- }
- }
- break;
- case _GROLE_MASTER:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.MasterCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.StopChargingCtrlValue = 0;
- //ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.DeratingCtrlValue = 0;
- ShmPsuGrouping->GroupCollection[group].ExtendQuantityLimit = 0;
- PSU_LOG("===== PSU Group[%02X] ===== Master", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- OutputConfigStep[group] = _CURRENT_MODE_NONE;
- _preOutputConfigStep[group] = _CURRENT_MODE_NONE;
- MaxCurrentDemand[group] = 0;
- StageMaxCurrent[group] = 0;
- _GfdStep[group] = PREPARE_STEP_NONE;
- _VoltageResumeCnt[group] = 0;
- }
- if(!ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.AlreadyInChargingMode)
- {
- if(chargingInfo[group]->SystemStatus == S_CHARGING && Is_OutputK1K2_Ready(group))
- {
- LOG_INFO("Gun %d Enter Charging Mode", group + 1);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.AlreadyInChargingMode = true;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ReachMaxCurrentDemand = false;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ReachMaxStageCurrent = false;
- GetClockTime(&_MaxCurrent_time[group]);
- GetClockTime(&_StageCurrent_time[group]);
- GetClockTime(&_ChargingDelay_time[group]);
- }
- }
- if((chargingInfo[group]->SystemStatus <= S_IDLE) ||
- (chargingInfo[group]->SystemStatus >= S_TERMINATING && chargingInfo[group]->SystemStatus <= S_FAULT))
- {
- if(!ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest)
- {
- LOG_INFO("Gun %d SystemStatus(%d) Need Stop Charging", group + 1, chargingInfo[group]->SystemStatus);
- }
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest = true;
- }
- if((IsPsuGroupAllAlarm(group) || IsPsuGroupAllFault(group)) &&
- !_isTriggerShutdown &&
- !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest)
- {
- if(!ShmChargerInfo->GunError[group].ErrFlag.bits.PsuGroupNoResource)
- {
- LOG_INFO("Gun %d PsuGroup All Alarm/Fault >> No Resource, Need Stop Charging", group + 1);
- }
- if(strncmp(ShmChargerInfo->GunError[group].GunAlarmCode, "", 6) == EQUAL)
- {
- strcpy(ShmChargerInfo->GunError[group].GunAlarmCode, "042279");
- }
- ShmChargerInfo->GunError[group].ErrFlag.bits.PsuGroupNoResource = true;
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue == 0)
- {
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ExtendAvailable)
- {
- time = GetTimeoutValue(_ExtendCapability_time[group]) / uSEC_VAL;
- if(time >= EXTEND_CAPABILITY_DELAY)
- {
- #if 0
- int available = GetPsuGroupAvailable(group);
- if(available > 0)
- {
- ShmPsuGrouping->GroupCollection[group].ExtendQuantityLimit = MAX_GROUP_QUANTITY;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.MorePowerRequest = true;
- LOG_INFO("Gun %d Start Extend Capability", group + 1);
- }
- #endif
- ShmPsuGrouping->GroupCollection[group].ExtendQuantityLimit = 0;
- int reason = IsExtendConflict(group);
- char *str_conflict_reason[] = {STR_EXTEND_CONFLICT_NONE, STR_EXTEND_CONFLICT_AVAILABLE, STR_EXTEND_CONFLICT_AVERAGE, STR_EXTEND_CONFLICT_PRIORITY, STR_EXTEND_CONFLICT_UNKNOWN};
- if(reason == _CONFLICT_NONE)
- {
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.MorePowerRequest = true;
- LOG_INFO("Gun %d Start Extend Capability", group + 1);
- }
- else
- {
- LOG_INFO("Gun %d Extend Capability Conflict: %s", group + 1, str_conflict_reason[reason]);
- }
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ExtendAvailable = false;
- }
- }
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.ExtendCapabilityCtrlValue != 0)
- {
- CleanSmoothDerating(group);
- MasterExtendCapabilityProcess(group);
- }
- // need derating
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.DeratingCtrlValue != 0 &&
- !ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest)
- {
- CleanSmoothDerating(group);
- PsuGroupDeratingProcess(group);
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.StopChargingRequest)
- {
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.DeratingCtrlValue = 0;
- ShmPsuGrouping->GroupOutput[group].GTargetVoltage = 0;
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent = 0;
- ShmPsuGrouping->TotalGroupOutput[group].GTargetVoltage = 0;
- ShmPsuGrouping->TotalGroupOutput[group].GTargetCurrent = 0;
- CleanSmoothDerating(group);
- MasterStopChargingProcess(group);
- }
- else
- {
- UpdateGunLoading(group);
- UpdatePsuGroupOutputConfig(group);
- UpdateMasterPsuGroupLoading(group);
- PsuGroupOutputConfigCheck(group);
- }
- ShowGunVoltageCurrent(group);
- SetPsuGroupOutput(group);
- break;
- case _GROLE_SLAVE:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Slave", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.SlaveCtrlValue != 0)
- {
- SlaveStopChargingProcess(group);
- }
- else
- {
- if(IsPsuGroupAllAlarm(group) || IsPsuGroupAllFault(group))
- {
- if(!ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.SlavePowerOffRequest)
- {
- LOG_INFO("Gun %d PsuGroup (slave) All Alarm/Fault, Need Power Off", group + 1);
- }
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.SlavePowerOffRequest = true;
- }
- else
- {
- SetPsuGroupOutput(group);
- }
- }
- break;
- case _GROLE_PREPARE_SWITCH_OFF:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Prepare Off", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- time = GetTimeoutValue(_PsuGroupRole_time[group]) / uSEC_VAL;
- if(time >= MAX_PREPARE_SWITCH_OFF_TIME)
- {
- // timeout shall not happen
- SetPsuGroupRole(group, _GROLE_SLAVE_POWER_OFF);
- }
- else
- {
- SetPsuGroupOutput(group);
- }
- break;
- case _GROLE_SLAVE_POWER_OFF:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Slave Power Off", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- time = GetTimeoutValue(_PsuGroupRole_time[group]) / uSEC_VAL;
- if(time >= MIN_POWER_OFF_TIME &&
- (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent <= MAX_PSU_POWER_OFF_CURRENT || _isTriggerShutdown))
- {
- SetPsuGroupRole(group, _GROLE_SWITCH_OFF_OK);
- }
- else
- {
- ShmPsuGrouping->GroupOutput[group].GTargetVoltage = 0;
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent = 0;
- SetPsuGroupOutput(group);
- }
- break;
- case _GROLE_SWITCH_OFF_OK:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Switch Off OK, %d.%d V, %d.%d A", group,
- (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10), (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage % 10),
- (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent / 10), (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent % 10));
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- break;
- case _GROLE_WAIT_IDLE:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Wait Idle, %d.%d V, %d.%d A", group,
- (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10), (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage % 10),
- (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent / 10), (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent % 10));
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- break;
- case _GROLE_WAIT_SLAVE:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Wait Slave", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- time = GetTimeoutValue(_PsuGroupRole_time[group]) / uSEC_VAL;
- if(ShmPsuGrouping->GroupCollection[group].ReservedTarget != 0)
- {
- if(time >= WAIT_SLAVE_TO_CHARGING && (ShmPsuGrouping->GroupCollection[group].ReservedTarget - 1) == group)
- {
- SetPsuGroupRole(group, _GROLE_REQUEST_TO_CHARGING);
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.bits.ChargingRequest = true;
- ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.SlaveCtrlValue = 0;
- break;
- }
- }
- if(time >= WAIT_SLAVE_TIMEOUT)
- {
- PSU_LOG("Group[%02X] Wait Slave Timeout", group);
- SetPsuGroupToIdle(group);
- }
- break;
- case _GROLE_PREPARE_ATTACH_ON:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Prepare Attach On", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- SetPsuGroupOutput(group);
- break;
- case _GROLE_PRECHARGE_READY:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Precharge %d.%d V Ready",
- group, (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10), (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage % 10));
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- break;
- case _GROLE_EXTEND_STOP:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Extend Stop, %d.%d V",
- group, (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10), (ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage % 10));
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- time = GetTimeoutValue(_PsuGroupRole_time[group]) / uSEC_VAL;
- if(time >= MIN_POWER_OFF_TIME ||
- (ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent <= MAX_PSU_POWER_OFF_CURRENT &&
- ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage <= MAX_PSU_POWER_OFF_VOLTAGE))
- {
- SetPsuGroupToIdle(group);
- }
- else
- {
- ShmPsuGrouping->GroupOutput[group].GTargetVoltage = 0;
- ShmPsuGrouping->GroupOutput[group].GTargetCurrent = 0;
- SetPsuGroupOutput(group);
- }
- break;
- case _GROLE_REQUEST_TO_CHARGING:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Request To Charging", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- if(ShmPsuGrouping->GroupCollection[group].GroupCtrl.RoleCtrl.IdleCtrlValue != 0)
- {
- ChargingRequestProcess(group);
- }
- break;
- case _GROLE_TERMINATE:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Terminate", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- break;
- case _GROLE_WAIT_TERMINATED:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Wait Terminated", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- break;
- case _GROLE_NONE:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== None", group);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- break;
- default:
- if(ShmPsuGrouping->GroupCollection[group].PreRole != role)
- {
- ShmPsuGrouping->GroupCollection[group].PreRole = role;
- PSU_LOG("===== PSU Group[%02X] ===== Unknown Role = %d", group, role);
- GetClockTime(&_PsuGroupRole_time[group]);
- }
- SetPsuGroupRole(group, _GROLE_NONE);
- break;
- }
- }
- }
- // only for test & debug purpose
- void PsuSimulationSetting(void)
- {
- ShmPsuData->Work_Step = _WORK_CHARGING;
- ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity = 3;
- ShmPsuData->PsuGroup[1].GroupPresentPsuQuantity = 3;
- ShmPsuData->PsuGroup[2].GroupPresentPsuQuantity = 3;
- ShmPsuData->PsuGroup[3].GroupPresentPsuQuantity = 3;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[0].RemoteMaxPhysicalVoltage = 9500;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[0].RemoteMaxPhysicalCurrent = 5000;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[1].RemoteMaxPhysicalVoltage = 9500;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[1].RemoteMaxPhysicalCurrent = 2000;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[2].RemoteMaxPhysicalVoltage = 9500;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[2].RemoteMaxPhysicalCurrent = 5000;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[3].RemoteMaxPhysicalVoltage = 9500;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[3].RemoteMaxPhysicalCurrent = 2500;
- }
- // only for test & debug purpose
- void PsuGroupOutputSimulation(void)
- {
- byte master = 0;
- unsigned short pVoltage = 0, pCurrent = 0;
- unsigned short gVoltage = 0, gCurrent = 0;
- // psu output voltage & current simulation
- for(int i = 0; i < ShmPsuData->GroupCount; i++)
- {
- pVoltage = ShmPsuGrouping->GroupOutput[i].GTargetVoltage;
- pCurrent = ShmPsuGrouping->GroupOutput[i].GTargetCurrent;
- ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage = pVoltage;
- ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent = pCurrent;
- ShmPsuData->PsuGroup[i].GroupPresentOutputPower = (pVoltage * pCurrent) / 100 / 100;
- }
- // psu AvailableCurrent & GroupAvailablePower simulation
- for(int i = 0; i < ShmPsuData->GroupCount; i++)
- {
- if(ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage == 0)
- {
- ShmPsuData->PsuGroup[i].GroupAvailableCurrent = ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity * 1000;
- }
- else
- {
- if(ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage <= 3000)
- {
- ShmPsuData->PsuGroup[i].GroupAvailableCurrent = ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity * 1000;
- }
- else
- {
- ShmPsuData->PsuGroup[i].GroupAvailableCurrent = (30000 * 100 * ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity) / ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage;
- }
- }
- ShmPsuData->PsuGroup[i].GroupAvailablePower = ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity * 300;
- }
- for(int i = 0; i < ShmPsuData->GroupCount; i++)
- {
- master = ShmChargerInfo->PsuGrouping.GroupCollection[i].TargetGroup;
- if(master == 0)
- {
- // calculate PresentChargingVoltage and PresentChargingCurrent of self group
- chargingInfo[i]->PresentChargingVoltage = (float)ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage / 10;
- chargingInfo[i]->PresentChargingCurrent = (float)ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent / 10;
- }
- else
- {
- if(i == (master - 1))
- {
- gVoltage = ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage;
- gCurrent = ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent;
- for(byte j = 0; j < ShmPsuGrouping->GroupCollection[i].Partner.Quantity; j++)
- {
- byte slave = ShmPsuGrouping->GroupCollection[i].Partner.Member[j];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE ||
- ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PREPARE_SWITCH_OFF ||
- ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE_POWER_OFF)
- {
- gCurrent += ShmPsuData->PsuGroup[slave].GroupPresentOutputCurrent;
- }
- }
- chargingInfo[i]->PresentChargingVoltage = (float)gVoltage / 10;
- chargingInfo[i]->PresentChargingCurrent = (float)gCurrent / 10;
- }
- }
- }
- }
- // only for test & debug purpose
- void PsuGroupAvailableSimulation(void)
- {
- unsigned char master = 0;
- int _groupCurrent = 0, _groupPower = 0;
- for(int i = 0; i < ShmPsuData->GroupCount; i++)
- {
- master = ShmChargerInfo->PsuGrouping.GroupCollection[i].TargetGroup;
- // calculate output group capability
- if(master == 0)
- {
- chargingInfo[i]->AvailableChargingCurrent = ShmPsuData->PsuGroup[i].GroupAvailableCurrent;
- chargingInfo[i]->AvailableChargingPower = ShmPsuData->PsuGroup[i].GroupAvailablePower;
- }
- else
- {
- _groupCurrent = ShmPsuData->PsuGroup[master - 1].GroupAvailableCurrent;
- _groupPower = ShmPsuData->PsuGroup[master - 1].GroupAvailablePower;
- for(byte j = 0; j < ShmPsuGrouping->GroupCollection[master - 1].Partner.Quantity; j++)
- {
- byte slave = ShmPsuGrouping->GroupCollection[master - 1].Partner.Member[j];
- if(ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_SLAVE ||
- ShmPsuGrouping->GroupCollection[slave].Role == _GROLE_PREPARE_SWITCH_OFF)
- {
- _groupCurrent += ShmPsuData->PsuGroup[slave].GroupAvailableCurrent;
- _groupPower += ShmPsuData->PsuGroup[slave].GroupAvailablePower;
- }
- }
- if(ShmPsuGrouping->GroupCollection[master - 1].GroupCtrl.bits.DeratingConfirmed)
- {
- chargingInfo[master - 1]->AvailableChargingCurrent = ShmPsuGrouping->GroupCollection[master - 1].ReAssignAvailableCurrent;
- }
- else
- {
- chargingInfo[master - 1]->AvailableChargingCurrent = _groupCurrent;
- }
- chargingInfo[master - 1]->AvailableChargingPower = _groupPower;
- chargingInfo[master - 1]->MaximumChargingVoltage = 9500;
- if((master - 1) != i)
- {
- chargingInfo[i]->AvailableChargingCurrent = 0;
- chargingInfo[i]->AvailableChargingPower = 0;
- chargingInfo[i]->RealRatingPower = 0;
- chargingInfo[i]->MaximumChargingVoltage = 0;
- }
- }
- }
- }
- void CapabilitySimulation(void)
- {
- unsigned short voltage = 0, current = 0, power = 0;
- unsigned short limitPower = 0, limitCurrent = 0;
- unsigned char inUsingCnt = 0;
- for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
- {
- if(ShmChargerInfo->PsuGrouping.GroupCollection[i].Role == _GROLE_MASTER)
- {
- inUsingCnt += ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity;
- }
- }
- for(int i = 0; i < ShmPsuData->GroupCount; i++)
- {
- voltage = chargingInfo[i]->MaximumChargingVoltage;
- current = chargingInfo[i]->AvailableChargingCurrent;
- power = chargingInfo[i]->AvailableChargingPower;
- // ********** GetPhysicalLimitVoltageAndCurrent **********
- if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalVoltage != 0 &&
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalVoltage <= voltage)
- {
- voltage = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalVoltage;
- }
- if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalCurrent != 0 &&
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalCurrent <= current)
- {
- current = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].RemoteMaxPhysicalCurrent;
- }
- // ********** GetModelNameLimitPower **********
- if(ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity != 0 && inUsingCnt != 0 &&
- ShmChargerInfo->Control.ChargerRatingPower != 0)
- {
- limitPower = ShmChargerInfo->Control.ChargerRatingPower;
- if(ShmChargerInfo->Control.CabinetRole == _CROLE_MASTER)
- {
- limitPower += ShmChargerInfo->ParallelCabinet.TotalParallelPower;
- }
- limitPower = (limitPower * ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity) / inUsingCnt;
- }
- if(limitPower != 0 && limitPower <= power)
- {
- power = limitPower;
- }
- // ********** GetConfigLimitPowerAndCurrent **********
- if(ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity != 0 && inUsingCnt != 0 &&
- ShmSysConfigAndInfo->SysConfig.MaxChargingPower != 0)
- {
- limitPower = ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10;
- limitPower = (limitPower * ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity) / inUsingCnt;
- }
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].MaxTotalChargingPower = limitPower;
- if(ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity != 0 && inUsingCnt != 0 &&
- ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent != 0)
- {
- limitCurrent = ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10;
- limitCurrent = (limitCurrent * ShmChargerInfo->PsuGrouping.GroupCollection[i].GunPsuQuantity) / inUsingCnt;
- }
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].MaxTotalChargingCurrent = limitCurrent;
- if(limitPower != 0 && limitPower <= power)
- {
- power = limitPower;
- }
- if(limitCurrent != 0 && limitCurrent <= current)
- {
- current = limitCurrent;
- }
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityVoltage = voltage;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityCurrent = current;
- ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].CapabilityPower = power;
- }
- }
- void PsuGroupingInitial(void)
- {
- for(int i = 0; i < ShmPsuData->GroupCount; i++)
- {
- ShmPsuGrouping->GroupCollection[i].Role = 0;
- ShmPsuGrouping->GroupCollection[i].PreRole = 0xFF;
- memset(&ShmPsuGrouping->GroupCollection[i].Partner, 0x00, sizeof(PsuGroupPartner));
- memset(&ShmPsuGrouping->GroupCollection[i].PossibleMember, 0x00, sizeof(PsuGroupPartner));
- ShmPsuGrouping->GroupCollection[i].TargetGroup = 0;
- ShmPsuGrouping->GroupCollection[i].ReservedTarget = 0;
- memset(&ShmPsuGrouping->GroupCollection[i].GroupCtrl, 0x00, sizeof(PsuGroupControl));
- ShmPsuGrouping->GroupCollection[i].ReAssignAvailableCurrent = 0;
- ShmPsuGrouping->GroupCollection[i].ParallelCheck = 0;
- ShmPsuGrouping->GroupCollection[i].GunLoading = 0;
- memset(&ShmPsuGrouping->GroupOutput[i], 0x00, sizeof(GroupOutputConfigInfo));
- }
- }
- void PsuCommLostCheck(void)
- {
- if(ShmPsuData->Work_Step != INITIAL_START &&
- ShmPsuData->Work_Step != _NO_WORKING &&
- ShmPsuData->Work_Step != _INIT_PSU_STATUS)
- {
- if(!isCommStart)
- {
- isCommStart = true;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt = 0;
- lostCnt = 0;
- GetClockTime(&_PsuCommCheck_time);
- }
- if((GetTimeoutValue(_PsuCommCheck_time) / uSEC_VAL) >= PSU_COMM_CHECK_TIME)
- {
- ShmChargerInfo->Control.CommInfo.PsuComm.CommCnt = ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt;
- ShmChargerInfo->Control.CommInfo.PsuComm.RxCnt = 0;
- if(ShmChargerInfo->Control.CommInfo.PsuComm.CommCnt > COMM_LOST_CRITICAL)
- {
- if(ShmChargerInfo->Control.PsuCtrl.bits.CommunicationLost)
- {
- LOG_INFO("Psu Communication Recovery");
- }
- ShmChargerInfo->Control.PsuCtrl.bits.CommunicationLost = NO;
- lostCnt = 0;
- }
- else
- {
- lostCnt++;
- if(lostCnt >= LOST_CNT_CRITICAL)
- {
- if(!ShmChargerInfo->Control.PsuCtrl.bits.CommunicationLost)
- {
- LOG_INFO("Psu Communication Lost");
- }
- ShmChargerInfo->Control.PsuCtrl.bits.CommunicationLost = YES;
- }
- }
- GetClockTime(&_PsuCommCheck_time);
- }
- }
- else
- {
- isCommStart = false;
- ShmChargerInfo->Control.PsuCtrl.bits.CommunicationLost = NO;
- lostCnt = 0;
- /*
- if(ShmChargerInfo->Control.PsuCtrl.bits.Paused)
- {
- system("ifconfig can1 down");
- sleep(1);
- system("ifconfig can1 up");
- sleep(1);
- LOG_INFO("Psu Can Port Down & Up");
- }
- ShmChargerInfo->Control.PsuCtrl.bits.Paused = NO;
- */
- }
- }
- void InitialGunLimitSequence(void)
- {
- for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
- {
- _GunIndexOfPrioritySequence[i] = i;
- }
- }
- bool IsShutdownTrigger(void)
- {
- if(ShmChargerInfo->Control.RelayCtrl.bits.AcContactorOffByPsu == YES ||
- ShmChargerInfo->Control.RelayCtrl.bits.AcContactorOffByEmergency == YES)
- {
- if(!_isTriggerShutdown)
- {
- PSU_LOG("Psu Shutdown Flag Is Trigger!");
- }
- _isTriggerShutdown = true;
- return true;
- }
- if(_isTriggerShutdown)
- {
- PSU_LOG("Psu Shutdown Flag Recover");
- }
- _isTriggerShutdown = false;
- return false;
- }
- bool IsShutdownCompleted(void)
- {
- bool done = false;
- if(IsShutdownTrigger())
- {
- done = true;
- for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
- {
- if(ShmPsuGrouping->GroupCollection[i].Role != _GROLE_IDLE)
- {
- done = false;
- break;
- }
- }
- if(done)
- {
- if(!_isShutdownCompleted)
- {
- PSU_LOG("Psu Shutdown Completed!");
- }
- _isShutdownCompleted = true;
- }
- return done;
- }
- if(_isShutdownCompleted)
- {
- PSU_LOG("Psu Shutdown Clear!");
- }
- _isShutdownCompleted = false;
- return done;
- }
- void PsuIndication(void)
- {
- if(ShmChargerInfo->Control.LibCtrl.bits.InfyPwrLib)
- {
- for(int i = 0; i < MAX_PSU_MODULE_QUANTITY; i++)
- {
- if(ShmPsuPosition->SingleInfyPwrState[i].InfyPwrStateFlag.bits.Indicated)
- {
- LedSingleOnOff(i, _PSU_ON);
- LOG_INFO("Set Psu[%2d] Led Blinking", i);
- _Psu_Indication_Enable[i] = true;
- _Psu_Indication_Count[i] = PSU_INDICATION_TIME;
- ShmPsuPosition->SingleInfyPwrState[i].InfyPwrStateFlag.bits.Indicated = false;
- }
- else
- {
- if(_Psu_Indication_Enable[i])
- {
- _Psu_Indication_Count[i]--;
- if(_Psu_Indication_Count[i] == 0)
- {
- LedSingleOnOff(i, _PSU_OFF);
- LOG_INFO("Set Psu[%2d] Led Static", i);
- _Psu_Indication_Enable[i] = false;
- }
- }
- }
- }
- }
- if(ShmChargerInfo->Control.LibCtrl.bits.PhPwrLib)
- {
- }
- }
- int main(void)
- {
- byte _TotalModuleCount = 0;
- byte _PrePsuWorkStep = 0;
- byte isInitialComp = NO;
- if(InitShareMemory() == FAIL)
- {
- #ifdef SystemLogMessage
- LOG_ERROR("InitShareMemory NG");
- #endif
- if(ShmStatusCodeData != NULL)
- {
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
- }
- sleep(5);
- return 0;
- }
- LOG_INFO("Psu Task PID = %d", getpid());
- signal(SIGCHLD, SIG_IGN);
- // register callback function
- RefreshPsuIndex(&FindPsuIndex);
- RefreshGroup(&GetGroupCallback);
- RefreshAlarmStatus(&GetAlarmStatusCallback);
- RefreshInfyPwrAlarmFlag(&GetInfyPwrAlarmFlagCallback);
- RefreshPhPwrAlarmFlag(&GetPhPwrAlarmFlagCallback);
- RefreshAmbient(&GetAmbientCallback);
- RefreshModuleCount(&GetModuleCountCallback);
- RefreshSysModuleCount(&GetSysModuleCountCallback);
- RefreshAvailableCap(&GetAvailableCapCallback);
- RefreshFwDcVersion(&GetDcFwCallback);
- RefreshFwPfcVersion(&GetPfcFwCallback);
- RefreshInputVol(&GetInputVoltageCallback);
- RefreshGetOutput(&GetPresentOutputCallback);
- RefreshFanSpeedInfo(&GetFanSpeedCallback);
- RefreshInletTemp(&GetInletTempCallback);
- RefreshExletTemp(&GetExletTempCallback);
- RefreshOutletTemp(&GetOutletTempCallback);
- RefreshOtherTemp(&GetOtherTempCallback);
- RefreshIavailable(&GetIavailableCallback);
- RefreshGetOutputF(&GetPresentOutputFCallback);
- RefreshGetModuleOutput(&GetModuleOutputCallback);
- RefreshGetErrorRecord(&GetErrorRecordCallback);
- // GetPresentOutputCallback & GetStatusCallback
- AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback);
- // GetStatusCallback
- AutoMode_RefreshModuleStatus(&GetModuleStatusCallback);
- // GetInputVoltageCallback
- AutoMode_RefreshModuleInput(&GetModuleInputCallback);
- sleep(2);
- InitialGunLimitSequence();
- _gunCount = GENERAL_GUN_QUANTITY;
- _maxGroupCount = MAX_GROUP_QUANTITY;
- _PrePsuWorkStep = _INIT_PSU_STATUS;
- ShmPsuData->Work_Step = INITIAL_START;
- isInitialComp = NO;
- isCommStart = false;
- _isTriggerShutdown = false;
- _isShutdownCompleted = false;
- LOG_INFO("PSU Work Status = %d", ShmPsuData->Work_Step);
- // initial object
- Initialization();
- InitialPsuData();
- //libInitialize = InitialCommunication();
- Run_PsuRxCommProcess();
- //main loop
- while (1)
- {
- PsuCommLostCheck();
- IsShutdownCompleted();
- // 斷電狀態
- if (ShmChargerInfo->Control.RelayCtrl.bits.AcContactor == NO ||
- ShmChargerInfo->Control.PsuCtrl.bits.NeedSelfTest == YES ||
- ShmChargerInfo->Control.PsuCtrl.bits.Paused == YES ||
- _isShutdownCompleted)
- {
- //一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0
- if (!isInitialComp)
- {
- _PrePsuWorkStep = _INIT_PSU_STATUS;
- ShmPsuData->Work_Step = INITIAL_START;
- psuCmdSeq = _PSU_CMD_STATUS;
- _TotalModuleCount = 0;
- PsuGroupingInitial();
- sleep(2);
- InitialPsuData();
- isInitialComp = YES;
- }
- if(ShmChargerInfo->Control.PsuCtrl.bits.NeedSelfTest)
- {
- ShmChargerInfo->Control.PsuCtrl.bits.NeedSelfTest = NO;
- ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK = NO;
- memset(ShmChargerInfo->Control.PsuInitQuantity, 0x00, sizeof(ShmChargerInfo->Control.PsuInitQuantity));
- LOG_INFO("Psu Need Execute Self Test!");
- }
- sleep(1);
- continue;
- }
- else
- {
- if(isInitialComp)
- {
- system("ifconfig can1 down");
- sleep(1);
- system("ifconfig can1 up");
- LOG_INFO("Psu Can Port Down & Up");
- }
- isInitialComp = NO;
- }
- // only for test & debug purpose
- if(ShmChargerInfo->Control.TestCtrl.bits.ChargingSimulation)
- {
- PsuSimulationSetting();
- PsuGroupOutputSimulation();
- PsuGroupAvailableSimulation();
- CapabilitySimulation();
- }
- // 自檢失敗
- if (ShmPsuData->Work_Step == _NO_WORKING)
- {
- LOG_INFO("== PSU == self test fail.");
- sleep(5);
- }
- if((GetTimeoutValue(_PsuReceiveRecoveryCheck_time) / uSEC_VAL) >= PSU_TASK_CHECK_TIME)
- {
- //PsuReceiveRecoveryCheck();
- if(!Is_PsuRxComm_Alive())
- {
- Run_PsuRxCommProcess();
- }
- GetClockTime(&_PsuReceiveRecoveryCheck_time);
- }
- switch(ShmPsuData->Work_Step)
- {
- case INITIAL_START:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == INITIAL_START");
- }
- sleep(5);
- PsuGroupOnOff(SYSTEM_CMD, _PSU_OFF);
- SetWalkInConfig(SYSTEM_CMD, NO, 0);
- for (byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- isStartOutputSwitch[index] = false;
- }
- ShmPsuData->Work_Step = GET_PSU_COUNT;
- }
- break;
- case GET_PSU_COUNT:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == GET_PSU_COUNT");
- GetClockTime(&_PsuWorkStep_time);
- GetClockTime(&_cmdSubPriority_time);
- }
- int time = GetTimeoutValue(_PsuWorkStep_time) / uSEC_VAL;
- int interval = GetTimeoutValue(_cmdSubPriority_time) / uSEC_VAL;
- if(interval >= GET_PSU_COUNT_INTERVAL)
- {
- _TotalModuleCount = 0;
- for (byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- // 總和各群模組數量
- _TotalModuleCount += ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity;
- }
- LOG_INFO("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d",
- ShmPsuData->GroupCount, _TotalModuleCount, ShmPsuData->SystemInitialPsuQuantity);
- // 判斷系統數量與各群數量一致
- if(_TotalModuleCount == ShmPsuData->SystemInitialPsuQuantity && _TotalModuleCount > 0 &&
- time > GET_PSU_COUNT_TIME)
- {
- LOG_INFO("Psu Count = %d", _TotalModuleCount);
- for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
- {
- ShmChargerInfo->Control.PsuInitQuantity[i] = ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity;
- }
- ShmPsuData->Work_Step = Get_PSU_LOCATION;
- }
- else
- {
- // 發送取得目前全部模組數量
- GetSysModuleCount();
- for (byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- // 取各群模組數量
- GetModuleCount(index);
- }
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- }
- break;
- case Get_PSU_LOCATION:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == Get_PSU_LOCATION");
- // clean psu location info
- memset(ShmPsuPosition, 0x00, sizeof(PsuPositionInfoData));
- GetClockTime(&_cmdSubPriority_time);
- }
- int interval = GetTimeoutValue(_cmdSubPriority_time) / mSEC_VAL;
- if(interval >= GET_PSU_LOCATION_INTERVAL)
- {
- for(byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- if(ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity > 0)
- {
- // 取得狀態 : 支援模塊不須按照順序功能
- GetStatus(index);
- }
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- if(ShmPsuPosition->PsuLocationInit)
- {
- for(int i = 0; i < _maxGroupCount; i++)
- {
- UpdateGunTotalPsuQuantity(i);
- #if 1
- if(ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity > 0)
- {
- ShowGroupMember(i);
- }
- #endif
- }
- //ShmPsuData->Work_Step = Get_PSU_VERSION;
- ShmPsuData->Work_Step = PSU_COUNT_CONFIRM;
- }
- if(ShmPsuPosition->ReInitPsuLocation)
- {
- LOG_INFO("Retry Psu Location Initialization");
- ShmPsuData->Work_Step = GET_PSU_COUNT;
- }
- }
- break;
- case PSU_COUNT_CONFIRM:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == PSU_COUNT_CONFIRM");
- GetClockTime(&_PsuWorkStep_time);
- GetClockTime(&_cmdSubPriority_time);
- }
- int time = GetTimeoutValue(_PsuWorkStep_time) / uSEC_VAL;
- int interval = GetTimeoutValue(_cmdSubPriority_time) / mSEC_VAL;
- if(interval > PSU_COUNT_CONFIRM_INTERVAL)
- {
- _TotalModuleCount = 0;
- for (byte index = 0; index < _maxGroupCount; index++)
- {
- // 總和各群模組數量
- _TotalModuleCount += ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity;
- }
- if(time > PSU_COUNT_CONFIRM_TIME)
- {
- if(_TotalModuleCount == ShmPsuData->SystemInitialPsuQuantity && _TotalModuleCount > 0)
- {
- ShmPsuData->Work_Step = Get_PSU_VERSION;
- }
- else
- {
- LOG_INFO("Total PSU = %d, System PSU Quantity = %d", _TotalModuleCount, ShmPsuData->SystemInitialPsuQuantity);
- LOG_INFO("PSU Quantity Confirm Fail");
- ShmPsuData->Work_Step = GET_PSU_COUNT;
- }
- break;
- }
- // 發送取得目前全部模組數量
- GetSysModuleCount();
- for (byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- // 取各群模組數量
- GetModuleCount(index);
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- }
- break;
- case Get_PSU_VERSION:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == Get_PSU_VERSION");
- GetClockTime(&_cmdSubPriority_time);
- // clean version info
- memset(ShmPsuData->PsuVersion, 0x00, sizeof(ShmPsuData->PsuVersion));
- }
- int interval = GetTimeoutValue(_cmdSubPriority_time) / mSEC_VAL;
- if (interval >= GET_PSU_VERSION_INTERVAL)
- {
- bool isGetVersion = true;
- for(byte psu = 0; psu < ShmPsuData->SystemInitialPsuQuantity; psu++)
- {
- if (strcmp((char *)ShmPsuData->PsuVersion[psu].FwPrimaryVersion, "") == EQUAL)
- {
- isGetVersion = false;
- break;
- }
- }
- if(isGetVersion)
- {
- #if 1
- for(int i = 0; i < _maxGroupCount; i++)
- {
- if(ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity > 0)
- {
- ShowPsuVersion(i);
- }
- }
- #endif
- ShmPsuData->Work_Step = GET_SYS_CAP;
- }
- else
- {
- for(byte group = 0; group < _maxGroupCount; group++)
- {
- if(ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity > 0)
- {
- // 取版號
- GetAllModuleVer(group);
- }
- }
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- }
- break;
- case GET_SYS_CAP:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == GET_SYS_CAP");
- GetClockTime(&_PsuWorkStep_time);
- GetClockTime(&_cmdSubPriority_time);
- }
- int time = GetTimeoutValue(_PsuWorkStep_time) / uSEC_VAL;
- int interval = GetTimeoutValue(_cmdSubPriority_time) / mSEC_VAL;
- if (interval >= GET_PSU_CAP_INTERVAL)
- {
- if(time > GET_PSU_CAP_TIME && ShmPsuData->SystemAvailablePower > 0 &&
- ShmPsuData->SystemAvailableCurrent > 0)
- {
- #if 1
- for(int i = 0; i < _maxGroupCount; i++)
- {
- if(ShmPsuPosition->GroupLocationInfo[i].GroupPsuQuantity > 0)
- {
- ShowGroupAvailableCurrentPower(i);
- }
- }
- #endif
- // 判斷系統輸出額定功率與電流
- LOG_INFO("SystemAvailableCurrent = %d, SystemAvailablePower = %d",
- ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
- ShmPsuData->Work_Step = BOOTING_COMPLETE;
- }
- else
- {
- for(byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- if(ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity > 0)
- {
- // 取系統總輸出能力
- GetModuleCap(index);
- }
- }
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- }
- break;
- case BOOTING_COMPLETE:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == BOOTING_COMPLETE");
- }
- if(ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK)
- {
- ShmPsuData->Work_Step = _WORK_CHARGING;
- }
- else
- {
- LOG_INFO("== PSU == Self Test OK!");
- }
- ShmChargerInfo->Control.PsuCtrl.bits.SelfTestOK = true;
- }
- break;
- case _WORK_CHARGING:
- {
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == _WORK_CHARGING");
- GetClockTime(&_PsuWorkStep_time);
- GetClockTime(&_cmdSubPriority_time);
- PsuGroupingInitial();
- }
- int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
- // 低 Priority 的指令
- if (time >= 1000)
- {
- GetSysModuleCount();
- for(int i = 0; i < MAX_GROUP_QUANTITY; i++)
- {
- if(ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity > 0)
- {
- GetStatus(i);
- GetModuleCount(i);
- GetModuleInputVol(i);
- if(IsPsuGroupAnyAlarm(i) || IsPsuGroupAnyFault(i))
- {
- GetErrorRecord(i);
- }
- }
- }
- PsuIndication();
- for(int i = 0; i < MAX_GUN_QUANTITY; i++)
- {
- UpdateGunTotalPsuQuantity(i);
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- CheckPsuAlarmStatus();
- CheckPsuErrRecord();
- PsuGroupRoutineQuery();
- PsuGroupControlProcess();
- break;
- }
- case _TEST_MODE:
- {
- // 在測試模式中,保持與模塊的通訊
- int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
- if (time > 1500)
- {
- for (byte index = 0; index < ShmPsuData->GroupCount; index++)
- {
- // 取系統總輸出能力
- GetModuleCap(index);
- // 取各群輸出電壓電流 (float)
- GetModuleOutputF(index);
- }
- GetClockTime(&_cmdSubPriority_time);
- }
- byte _switch = 0x00;
- if ((chargingInfo[0]->EvBatterytargetVoltage * 10) > 0 && (chargingInfo[0]->EvBatterytargetCurrent * 10) > 0)
- _switch = 0x01;
- for (byte _groupCount_1 = 0; _groupCount_1 < conn_1_count; _groupCount_1++)
- {
- SetDirModulePresentOutput(connector_1[_groupCount_1],
- (chargingInfo[0]->EvBatterytargetVoltage * 10),
- (chargingInfo[0]->EvBatterytargetCurrent * 10),
- _switch, _switch);
- }
- for (byte _groupCount_2 = 0; _groupCount_2 < conn_2_count; _groupCount_2++)
- {
- SetDirModulePresentOutput(connector_2[_groupCount_2],
- (chargingInfo[0]->EvBatterytargetVoltage * 10),
- (chargingInfo[0]->EvBatterytargetCurrent * 10),
- _switch, _switch);
- }
- }
- break;
- case _INIT_PSU_STATUS:
- if(_PrePsuWorkStep != ShmPsuData->Work_Step)
- {
- _PrePsuWorkStep = ShmPsuData->Work_Step;
- LOG_INFO("== PSU == _INIT_PSU_STATUS");
- GetClockTime(&_cmdSubPriority_time);
- }
- break;
- default:
- break;
- }
- usleep(20000);
- }
- return FAIL;
- }
|