\chapter{Realizace - MCU Firmware}
	Programy jsou koncipovány tak, že hlavní smyčka (jádro programu) volá jednotlivé API a pak podprogramy, které zpracovávají události generované API. Podstatou API je přizpůsobit události, data a stavy standardnímu formátu nadřazené vrstvy (aplikaci). API pracují s danou periférii pomocí jejího ovladače. Takto je program modulární, a lze tak jednoduše kód pro práci s periférií použít v jiném programu. Tohoto bylo využito například pro komunikaci UART. API a ovladač periférie zkopírován z programu \texttt{modul ovládání} do \texttt{modul výkonového zdroje}. Dále bylo možno využít i samotného jádra programu z \texttt{modulu ovládání}. Práce s některými API byly odebrány, byla vytvořena API regulátoru a nakonec bylo jádro programu zjednodušeno, protože v komunikaci vystupuje jenom jako podřízené zařízení.
	
	Programy pro oba mikrokontroléry jsou napsané v AtmelStudio\cite{AtmelAtmelStudio} od společnosti Atmel. 
	
	\section{Komunikační schéma}
		\FloatBarrier	
		Na obrázku \ref{fig:FwCommSchema} je znázorněno schéma komunikace. Modul ovládání je v této komunikaci stěžejním článkem. Veškerá komunikace je řízena právě tímto modulem. Ovládací modul může přijímat příkazy přes rozhraní USB(PC) i SPI (lokální ovládací jednotka). Podle schématu je patrné, že komunikace může být směřována pouze k ovládacímu modulu, což mohou být například základní příkazy(\texttt{*IDN?, *RST}) nebo k zařízení na jednom z konců komunikačního schématu. 
		
		Ovládací modul vystupuje na rozhraní USB jako podřazené zařízení. SCPI příkazy jsou jen příjmány nikoliv vysílány. Vysílány jsou však případné odpovědi. Veškerá komunikace přes toto rozhraní je kódována v \texttt{ASCII}.  
		
		Na rozhraní SPI modul vystupuje jako nadřazené zařízení, nicméně jen z pohledu iniciace komunikace. Tato komunikace není v tuto chvíli navržena, ale předpokládá se nepřetržitá komunikace v rámci API. Pokud ani jedno ze zařízení nebude mít žádná data k odeslání, budou posílány packety prázdné zprávy. Pokud však bude přijmuta zpráva obsahující informace, budou tyto informace postoupeny vyšší vrstvě aplikace. Tato koncepce umožní i podřazenému zařízení, tedy místní ovládací jednotce, odesílat příkazy ovládacímu modulu či modulu výkonového zdroje. Předpokládaný komunikační protokol bude stejný jako pro komunikaci ovládacího modulu s moduly výkonového zdroje.
		
		Na rozhraní UART působí modul ovládání opět jako nadřazené zařízení. Modul výkonového zdroje tak může zasílat jen případné odpovědi na dotazy. Jelikož je toto rozhraní jako jediné polo-duplexní (RS-485), modul ovládání v rámci řízení komunikace dohlíží, aby na rozhraní nebylo vysíláno, když je očekávána odpověď od podřízeného zařízení (modul výkonového zdroje). 
		
		Jelikož jsou všechna zařízení připojená k rozhraním ovládacího modulu vnímána jako součást jedné sítě, má každé zařízení svou adresu. Adresy zařízení jsou uvedeny v tabulce \ref{tab:FwDevAdd}. Zařízení mají pevně přidělenou adresu a ovládací modul tak může rozhodnout, kterému zařízení je zpráva určena. Zjistí se tak i na jaké rozhraní má tato zpráva být přesměrována.		
		
		\begin{table}[!h]
			\caption{Přehled adres jednotlivých zařízení}
			\begin{center}
				\small
				\begin{tabular}{|c|l|}
					\hline
					Zařízení    						& Adresa 	\\
					\hline\hline
					USB zařízení	& $0x01$ 	 	\\
					\hline              
					Modul ovládání	& $0x02$ 	 \\		 
					\hline             
					Jednotka místního ovládání	& $0x03$ 	\\ 			  
					\hline              
					Hromadné volání zdrojů	& $0x04$ 	 \\          
					\hline            				  
					Zdroj č. 1	& $0x05$ 	 \\		    
					\hline
					Zdroj č. 2	& $0x06$ 	 \\  
					\hline            
					Zdroj č. 3	& $0x07$ 	 \\      
					\hline           
					Zdroj č. 4	& $0x08$ 	 \\      
					\hline            
					Zdroj č. 5	& $0x09$ 	 \\      
					\hline            
					Zdroj č. 6	& $0x0A$ 	 \\      
					\hline           
					Zdroj č. 7	& $0x0B$ 	 \\      
					\hline           
					Zdroj č. 8	& $0x0C$ 	 \\      
					\hline           
					Zdroj č. 9	& $0x0D$ 	 \\      
					\hline           
					Zdroj č. 10	& $0x0E$ 	 \\
					\hline
					Zdroj č. 11 & $0x0F$ 	 \\
					\hline
					Zdroj č. 12	& $0x10$ 	 \\
					\hline
					Zdroj č. 13	& $0x11$ 	 \\
					\hline
					Zdroj č. 14	& $0x12$ 	 \\
					\hline
					Zdroj č. 15	& $0x13$ 	 \\
					\hline
					Zdroj č. 16	& $0x14$ 	 \\
					\hline
				\end{tabular}
			\end{center}
			\label{tab:FwDevAdd}
		\end{table}
		
				
		\begin{figure}[!ht]
			\begin{center}
				\includegraphics[scale=0.21,angle=0]{obrazky/Firmware/CommSchema}
			\end{center}
			\caption{Komunikační schéma navrhovaného zařízení}
			\label{fig:FwCommSchema}
		\end{figure}
		\FloatBarrier

	\section{Komunikační protokol pro sériová rozhraní}
		Komunikační protokol je navržen tak, aby byl univerzální. Umožnil synchronizaci příjmu dat a zahrnoval v sobě i jednoduchou formu kontroly správnosti dat. Struktura protokolu je popsána na diagramu \ref{fig:CommSerProt}. Aby bylo možné dodržet pravidla struktury protokolu a ponechat unikátní \texttt{Start Symbol} a \texttt{Stop Symbol}, byla zavedena substituční tabulka\ref{tab:FwProtSymConv} pro konverzi hodnot stejné hodnoty jako zmiňované symboly. 
		
		Protokol je zpracováván v několika vrstvách. V první \texttt{Linkové vrstvě} se pracuje se samotným rozhraním a provadí se zde linkové kódování viz tabulka \ref{tab:FwProtSymConv}. Dále je na této vrstvě prováděn kontrolní součet zprávy. V tomto případě se jedná o \uv{jednotkový doplněk}. \texttt{Linková vrstva} take zajišťuje sudý počet bytů nutných k výpočtu kontrolního součtu. Pokud tedy délka datového rámce z vyšší vrstvy je lichá, bude její délka upravena na sudou přidáním \uv{nulového} byte.
		
		Další vrstva na které je protokol řešen je \texttt{síťová vrstva}. V této vrstvě dochází k rozhodování zda ono zařízení je adresátem či ne. Zda ID zprávy (\texttt{Paket ID}) je správné. V každém zařízení je při inicializaci uložena adresa zařízení buď z definičního souboru nebo z vyčtené hodnoty stavu přepínače (viz \ref{sec:PwrModFw}). Pokud je zařízení nadřazené generuje ID zprávy. Na zprávu s tímto ID musí podřazené zařízení odpovědět se stejným ID zprávy. Toto řešení zabraňuje zpracování odpovědí na jinou zprávu. V rámci síťové vrstvy je dále zpracován tzv. \texttt{broadcast} nebo \texttt{sub-broadcast}. Tyto funkce umožňují hromadné adresování zařízení. První z jmenovaných adresuje všechna zařízení (adresa 0x00), druhý umožňuje adresovat pouze skupinu zařízení. Pro hromadné ovládání modulů výkonového zdroje je použita adresa třídy (\texttt{Hromadné volání zdrojů} tj. 0x04).
		
		Komunikace je navržena takovým způsobem, aby po každém příkazu, který není adresován hromadně se muselo odpovědět. Na tento příkaz je odpovězeno buď zprávou obsahující \zk{zkACK} (\zkratkatext{zkACK}) nebo \zk{zkNACK} (\zkratkatext{zkNACK}). Odpověď není nikdy generována v rámci nižších vrstev a tedy zcela pod kontrolou \uv{aplikační vrstvy}. Odpovědí je signalizováno zpracování příkazu. Maximální velikost paketu je 254B včetně START a STOP symbolu. Užtečných dat tak\\
		($ACK/NACK/CMD + delka dat + (D0-D_{n})$) lze přeneést až 121B.
		
		\FloatBarrier	
		\begin{table}[!h]
			\caption{Tabulka převodu symbolů pro navržený protokol}
			\begin{center}
				\small
				\begin{tabular}{|c|c|c|}
					\hline
					Symbol    					& Popis	& Substituce \\
					\hline\hline
					$0xAB$ & START SYMBOL & $0x80;0x81$ \\
					\hline
					$0xBA$ & STOP SYMBOL  & $0x80;0x82$\\
					\hline
					$0x80$ & KONVERZNÍ SYMBOL & $0x80;0x81$\\
					\hline
				\end{tabular}
			\end{center}
			\label{tab:FwProtSymConv}
		\end{table}
		
		\begin{table}[!h]
			\caption{CMD/ACK/NACK komunikace}
			\begin{center}
				\small
				\begin{tabular}{|c|c|c|}
					\hline
					Typ zprávy    						& Symbol 				& Popis 	\\
					\hline\hline
					Command \texttt{CMD} 			& $0x01-0xFD$ 	& libovolný příkaz \\
					\hline
					Acknowledgement \texttt{ACK} & $0xFE$		& kladné potvrzení \\
					\hline
					Negativge-Acknowledgement \texttt{NACK} & $0xFF$	& záporné potvrzení \\
					\hline
				\end{tabular}
			\end{center}
			\label{tab:FwProtCmdAckNack}
		\end{table}	
		
		\begin{figure}[!ht]
			%\begin{center}
			\raggedright
				\begin{bytefield}[bitheight=2.2\baselineskip,bitwidth=1.8em]{8} %endianness=big,
					%\wordbox[lrt]{1}{0xAB (START SYMBOL)} \\
					\bitbox{8}{0xAB (START SYMBOL)} \\
				\end{bytefield}
			%\end{center}
			\centering
			%\begin{center}
				\begin{bytefield}[bitheight=2.2\baselineskip,bitwidth=1.8em]{16} %endianness=big,
					\bitheader{0,7,8,10,15} \\
					%\bitbox{8}{0xAB (START SYMBOL)} & \bitbox{8}{ADRESA příjemce} \\
					\begin{rightwordgroup}{$16bit$\\$CHKSUM$}
						\bitbox{8}{ADRESA příjemce} & \bitbox{8}{ADRESA odesílatele} \\
						\bitbox{3}{rezervováno} & \bitbox{5}{ID packetu} & \bitbox{8}{CMD/ACK/NACK} \\
						\bitbox{8}{délka datové zprávy ($D0-D_{n}$)} & \bitbox[lrt]{8}{} \\
						\wordbox[lr]{1}{$D0-D_{n}$} \\
						\skippedwords \\
						%\wordbox[lrb]{1}{} \\
						\bitbox[lrb]{8}{} & \bitbox{8}{0x00 (pro lichou dálku dat)}
					\end{rightwordgroup} \\
					\bitbox{8}{CHKSUM16$-$H (jednotkový doplněk)} & \bitbox{8}{CHKSUM16$-$L (jednotkový doplněk)}\\
					%\bitbox{8}{0xBA (END SYMBOL)} \\
				\end{bytefield}
			%\end{center}
			\raggedright
				\begin{bytefield}[bitheight=2.2\baselineskip,bitwidth=1.8em]{8} %endianness=big,
					\bitbox{8}{0xBA (END SYMBOL)} \\
				\end{bytefield} 
			\caption{Komunikační protokol RS-485 rozhraní}
			\label{fig:CommSerProt}
		\end{figure}
		\FloatBarrier


	\section{Modul ovládání}
		Funkce ovládacího modulu je vykonávat příkazy a přeposílat data na cílová rozhraní. Program začíná inicializací mikrokontroléru, kde se vykoná inicilaizace periférií, které nejsou kontrolovány pomocí API. Dále se inicializují API, které nakonfigurují periferii a inicializují své proměnné. Nakonec se inicializují proměnné programu. Další operace programu jsou vykonávány v nekonečné smyčce. Nicméně lze tuto smyčku přerušit resetováním mikrokontroléru. Resetovat mikrokontrolér lze příkazem \uv{\texttt{*RST}}. Tento příkaz zahrnuje reset celého zařízení, proto je nejdříve po přijetí tohoto příkazu odeslán příkaz \texttt{RESET} všem ostatním zařízením, tj. moduly výkonového zdroje prostřednictvím adresy pro \texttt{Hromadné volání zdrojů - sub-broadcast} a jednotka lokálního ovládání pokud je připojena. Až poté se ovládací modul sám resetuje. Na obrázku \ref{fig:FwCtrlModFlow} je znázorněn vývojový diagram programu.
		
		Jako první jsou ve smyčce vykonávané úkoly všech API. Na všech rozhraních se zpracují příchozí a odchozí zprávy. Jsou aktualizovány stavy událostí na rozhraních. Tyto stavy informují dalšími podprogramy. Například o nově příchozí zprávě čekající na zpracování.
		
		Dále jsou zpracovávány zprávy přijaté perifériemi. Na základě adresáta zprávy je buď zpráva přeposlána nebo zpracována. Jelikož se prostřednictvím SCPI příkazů žadná adresa neposílá, je adresa přidělena na základě druhu deódované zprávy. Pokud je tedy zpráva \texttt{DISP: \dots}, je adresátem \texttt{jednotka místního ovládání}. V případě adresování modulu výkonového zdroje je situace vyřešena tak, že nativně se používá adresa zdroje č. 1. Pokud je požadavek na adresování jiného zdroje, lze to provést příkazem \texttt{INSTrument[:NSELect]} a zvolit požadované číslo zdroje. Ovládací jednotka detekuje připojená zařízení ihned po zapnutí. Aby bylo možné adresovat zařízení, které bylo připojeno později, je nutné použít SCPI příkaz\\ \texttt{INSTrument:RINStrument}. Tím jednotka provede \uv{\texttt{PING}} všech adres. Adresy od kterých obdrží odpověď jsou uloženy do seznamu dostupných zařízení. V případě adresování, které není v seznamu je zpráva zahozena.
		
		Dále jsou zpracovávány neočekávané zprávy (odpovědi) od zařízení. Tato situace by neměla nastat a je zpracována zpravidla jako chyba.
		
		Chyby jsou zpracovávány v posledním kroku hlavní smyčky. Pokud se jedná o nezávažnou chybu, je chybě přiděleno číslo a vloženo do chybového zásobníku. Tento zásobník lze vyčítat pomocí SCPI příkazu \texttt{SYSTem:ERRor?}. V zásobníku může být nashromážděno až 8 chyb. Po vyčtení se chyba ze zásobníku smaže.
		
		\FloatBarrier	
		\begin{figure}[!ht]
			\begin{center}
				\includegraphics[scale=0.21,angle=0]{obrazky/Firmware/CtrlModFlow}
			\end{center}
			\caption{Exekuce programu Ovládacího modulu}
			\label{fig:FwCtrlModFlow}
		\end{figure}
		\FloatBarrier
	
		\subsection{SCPI parser}
			Tato funkce zpracovává řetězec znaků dle specifikace SCPI\cite{IviFoundationScpi}. SCPI zpráva je složena z příkazu a jeho prarametru. Podle SCPI je možné vynechat nepovinnou část příkazu (ohraničena \texttt{$[$nepovinný příkaz$]$}) a použít zkrácené (\texttt{INST:}) nebo celé části přikazu (\texttt{INSTrument:}). Příkazová čast může být zakončena \texttt{'?'}, pak se nejedná o \texttt{příkaz}, ale o \texttt{dotaz} (query). Na dotaz je nutné odpovědět. Odpověď je v podobě hodnoty či textu převedeného do ASCII řetězce zakončeného termínovacím znakem. 
			
			\FloatBarrier
			
			Na diagramu \ref{fig:FwCtrlModScpiCmd} je znázorněno zpracování příkazové části. Nejdříve je načten první kompletní příkaz ze seznamu podporovaných příkazů. Následuje srovnání první části načteného příkazu s první částí přijatého příkazu. Když se tyto části rovnají, pokračuje se srovnáním druhých částí. Pokud se části nerovnají a první část načteného příkazu nebyla povinná, pokračuje se srovnáním druhé části načteného příkazu a první částí přijatého příkazu. Takto se v porovnání pokračuje až na konec přijatého příkazu, pokud jsou části příkazů shodné nebo chybí nepovinná část příkazu. V opačném případě se operace přeruší a začne se porovnávat další načtený příkaz s přijatým příkazem od začátku. Pokračuje se dokud nejsou otestovány všechny podporované příkazy nebo dokud není nalezena shoda. Na konci shodných příkazů se také testuje shoda zda jsou oba příkazy \texttt{dotaz} či ne.
			
			\begin{figure}[!ht]
				\begin{center}
					\includegraphics[scale=0.21,angle=0]{obrazky/Firmware/CtrlModScpi}
				\end{center}
				\caption{Dekodér SCPI zprávy - příkazové části}
				\label{fig:FwCtrlModScpiCmd}
			\end{figure}
			
			Parametr SCPI zprávy může nabývat spousty podob. Pro účely zařízení však byly vybrány jen některé možné podoby parametrů viz tab.\ref{tab:FwScpiParserPar}. Na základě zpracovaného příkazu je očekáván text nebo hodnota. Text se nezpracovává, jen je zjištěna jeho délka a je funkcí vrácen. Pokud je očekávána hodnota, funkce nejdříve testuje zda se nejedná o stavový parametr. Když tomu tak není, je příchozí parametr testován zda splňuje interpretaci hodnoty v rozsahu definovaném tabulkou \ref{tab:FwScpiParserPar}. Nejdříve se testuje možný začátek číselné hodnoty \texttt{($.;+;-;0-9$)}, dále následuje složení celého čísla dokud funkce nenarazí na jiný znak než číslo. Funkce pokračuje testováním desetiné části, pokud desetiná část existuje, je složena desetinná část čísla. Nakonec se testuje zda hodnota je opatřena jednotkou a veličinou. V závěru funkce složí číslo, přidělí znaménko a vynásobí případným násobitelem jednotky pokud číslo bylo jednotkou opatřeno.			
			
			\begin{table}[!h]
				\caption{Podoby podporovaných parametrů}
				\begin{center}
					\small
					\begin{tabular}{|c|c|c|}
						\hline
						Prvek    						& rozsah 				& Popis 	\\
						\hline\hline
						\texttt{jednotky} & $[-;m;k]$	& jednotky - volitelné \\
						\hline
						\texttt{veličiny} & $[-;V;A]$	& veličina - volitelné \\
						\hline
						\texttt{stavy} & $[TRUE;FALSE;ON;OFF]$	& vyjádření stavu \\
						\hline
						\texttt{hodnoty} & $\pm iiii.tttt$	& výjádření číselné hodnoty \\
						\hline
					\end{tabular}
				\end{center}
				\label{tab:FwScpiParserPar}
			\end{table}	
			
			\begin{figure}[!ht]
				\begin{center}
					\includegraphics[scale=0.11,angle=90]{obrazky/Firmware/CtrlModScpiPar}
				\end{center}
				\caption{Dekodér SCPI zprávy - parametrické části}
				\label{fig:FwCtrlModScpiPar}
			\end{figure}
			\FloatBarrier

	\section{Modul výkonového zdroje} \label{sec:PwrModFw}
		Struktura programu je obdobná jako u modulu ovládání. Nejdříve se provede inicializace. Na začátku smyčky se provede obsluha API. V tomto případě to je komunikace UART a Regulace výstupní veličiny. Pak se provede zpracování příchozích příkazů a nakonec se provede zpracování chyb. Stejně jako u ovládacího modulu, když nastane vážná chyba nebo bude přijmut příkaz \texttt{*RST}, se zařízení resetuje.
		
		Tento modul vystupuje jako podřízené zařízení. Navržený protokol určuje, že toto zařízení nikdy neiniciuje komunikaci, ale vždy čeká na příkaz. Až po přijetí příkazu může zařízení odpovědět.
		
		V rámci iniciace UART API je přečtena hodnota \texttt{hexadecimálního} přepínače na DPS. K této adrese je přičtena adresa \texttt{prvního zdroje}. Takto vzniklá adresa je považována za adresu modulu výkonového zdroje. Aby celý systém fungoval správně, nesmí se vyskytnout zařízení se stejnou adresou. Zařízení by odpovídala na stejný příkaz a na sběrnici RS-485 by poté vysílala obě zařízení. Došlo by ke konfliktu na lince. Tuto skutečnost musí mít uživatel na paměti.
		
		\FloatBarrier
		\begin{figure}[!ht]
			\begin{center}
				\includegraphics[scale=0.21,angle=0]{obrazky/Firmware/PwrModFlow}
			\end{center}
			\caption{Exekuce programu modulu výkonového zdroje}
			\label{fig:FwPwrModFlow}
		\end{figure}
			
		\subsection{Regulace}
			Regulace elektrických veličin je rozdělena do 4 funkčních bloků. Každý z těchto bloků pokrývá jeden z možných stavů regulace. Po zapnutí se zařízení nachází ve stavu vypnuté regulace, všechny požadované veličiny mají nulovou hodnotu. Tento stav nastává také, když ovládací jednotka nastaví obě požadované veličiny (napětí a proud) na nulovou hodnotu. 
			
			Dalším stavem regulace je inicializace (reinicializace) dvou referenčních PWM výstupů. Tento stav slouží pouze k prvotnímu nastavení PWM dle vypočtených hodnot. Referenční výstupy jsou inicializovány vždy, když ovládací jednotka změní alespoň jednu z požadovaných veličin. Podle těchto hodnot pak rychlá regulace tvořená dvěma komparátory nastaví výstupní veličiny.
			
			Po inicializaci referenčních výstupů regulaci přebírá zpětnovazební regulace, která slouží pro průběžné korekce výstupních veličin na základě měřených veličin. Takto lze však regulovat jen jednu z možných veličin. To, která z veličin je regulována se rozhoduje na základě předchozího porovnání naměřených a požadovaných hodnot. Regulace je nativně nastavena na regulaci napětí, avšak za splnění podmínek uvedených níže je prováděna regulace veličiny proudu. Funkční diagram regulace je na obrázku \ref{fig:FwPwrModReg}.
			
			\FloatBarrier
			\begin{equation*}
				\text{Regulace } I: \: \:  I_{mer} > I_{poz} - I_{tol} \\
			\end{equation*}
			\begin{description}
				\item[$I_{mer}$] - naměřená veličina proudu
				\item[$I_{poz}$] - požadovaná veličina proudu
				\item[$I_{tol}$] - povolený rozdíl měřené a požadované veličiny
			\end{description}
			\FloatBarrier
			\hfill
			
			Mimo regulační funkční bloky je postaven konfigurátor zapojení vinutí transformátoru. Tento konfigurátor je spouštěn na začátku regulační smyčky. Funkce vyhodnotí zda se napětí za regulátorem blíží nastavenému meznímu napětí. Případně provede rekonfiguraci vinutí transformátoru pomocí dvou TrueSwitch spínačů. Tento konfigurátor má hysterézní vlastnosti.
			
			Pro stabilizaci provedených změn regulací referenčních hodnot je zavedena stabilizační doba. Tato doba je proměnná na základě provedené regulační akce. V průběhu této stabilizační doby se neprovádí pruběžné korekce výstupní veličiny.
		
			\begin{figure}[!ht]
				\begin{center}
					\includegraphics[scale=0.13,angle=0]{obrazky/Firmware/PwrModReg}
				\end{center}
				\caption{Regulace požadovaných veličin}
				\label{fig:FwPwrModReg}
			\end{figure}
			\FloatBarrier