diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..602d708 --- /dev/null +++ b/.gitignore @@ -0,0 +1,223 @@ +reated by https://www.gitignore.io/api/latex + +### LaTeX ### +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 + +## Intermediate documents: +*.dvi +*-converted-to.* +# these rules might exclude image files for figures etc. +# *.ps +# *.eps +# *.pdf + +## Generated if empty string is given at "Please type another file name for output:" +.pdf + +## Bibliography auxiliary files (bibtex/biblatex/biber): +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.run.xml + +## Build tool auxiliary files: +*.fdb_latexmk +*.synctex +*.synctex(busy) +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync + +## Auxiliary and intermediate files from other packages: +# algorithms +*.alg +*.loa + +# achemso +acs-*.bib + +# amsthm +*.thm + +# beamer +*.nav +*.pre +*.snm +*.vrb + +# changes +*.soc + +# cprotect +*.cpt + +# elsarticle (documentclass of Elsevier journals) +*.spl + +# endnotes +*.ent + +# fixme +*.lox + +# feynmf/feynmp +*.mf +*.mp +*.t[1-9] +*.t[1-9][0-9] +*.tfm + +#(r)(e)ledmac/(r)(e)ledpar +*.end +*.?end +*.[1-9] +*.[1-9][0-9] +*.[1-9][0-9][0-9] +*.[1-9]R +*.[1-9][0-9]R +*.[1-9][0-9][0-9]R +*.eledsec[1-9] +*.eledsec[1-9]R +*.eledsec[1-9][0-9] +*.eledsec[1-9][0-9]R +*.eledsec[1-9][0-9][0-9] +*.eledsec[1-9][0-9][0-9]R + +# glossaries +*.acn +*.acr +*.glg +*.glo +*.gls +*.glsdefs + +# gnuplottex +*-gnuplottex-* + +# gregoriotex +*.gaux +*.gtex + +# hyperref +*.brf + +# knitr +*-concordance.tex +# TODO Comment the next line if you want to keep your tikz graphics files +*.tikz +*-tikzDictionary + +# listings +*.lol + +# makeidx +*.idx +*.ilg +*.ind +*.ist + +# minitoc +*.maf +*.mlf +*.mlt +*.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* + +# minted +_minted* +*.pyg + +# morewrites +*.mw + +# nomencl +*.nlo + +# pax +*.pax + +# sagetex +*.sagetex.sage +*.sagetex.py +*.sagetex.scmd + +# scrwfile +*.wrt + +# sympy +*.sout +*.sympy +sympy-plots-for-*.tex/ + +# pdfcomment +*.upa +*.upb + +# pythontex +*.pytxcode +pythontex-files-*/ + +# thmtools +*.loe + +# TikZ & PGF +*.dpth +*.md5 +*.auxlock + +# todonotes +*.tdo + +# easy-todo +*.lod + +# xindy +*.xdy + +# xypic precompiled matrices +*.xyc + +# endfloat +*.ttt +*.fff + +# Latexian +TSWLatexianTemp* + +## Editors: +# WinEdt +*.bak +*.sav + +# Texpad +.texpadtmp + +# Kile +*.backup + +# KBibTeX +*~[0-9]* + +# auto folder when using emacs and auctex +/auto/* + +# expex forward references with \gathertags +*-tags.tex + +# End of https://www.gitignore.io/api/latex + diff --git a/docs/research plan/doc/code_structure.tex b/docs/research plan/doc/code_structure.tex new file mode 100644 index 0000000..c219f57 --- /dev/null +++ b/docs/research plan/doc/code_structure.tex @@ -0,0 +1,25 @@ +The code is structured in a layered approach. This has multiple advantages. It's now possible to change microcontroller platform by only having to port the platform layer. Or if a different screen driver is used, only the software driver will have to be ported. Or of the application is meant to be changed, the application layer has to be adjusted without any changes on the tightly integrated platform code.\\ +Other advantages are the reduction of having to test the whole system time after time, as it is possible to rely on the underlying layer if that is tested accordingly.\\ +\begin{figure}[H] + \centering + \label{fig:code_structure} + \includegraphics[width=0.6\textwidth]{../block/code_structure.png} + \caption{The layered approach.} +\end{figure} +In fig. \ref{fig:code_structure} the structure is visualized and it can be seen how every layer depends on a lower level layer. Every block can be swapped with different components while the system keeps running, if implemented well without breaches of layering.\newpar +To make this layered code structure a reality, a small operating system has been developed which allows event driven communication, and a modular approach for driver and sub-systems. This modular approach also makes power saving easier as a module will be uninitialized when it's not used anymore. Removing any possibility for the developer of the system to forget to disable the peripheral/module.\newpar +In fig.\ref{fig:block} the functions of the system can be observed, these functions can be translated into modules and a hierarchy can be created. Along with drivers for the hardware, some software drivers have been written as well. These software drivers provide support for internal development such as logging text in a proper fashion, and creating a way of executing commands on the device. All the platform drivers are interfaces to the system's peripheral. On top of this layer are the actual drivers. This houses the initialization code for the hardware drivers, and gives a way to access the functionality of the hardware without needing to know the registers/commands. The layer above this provides a more generic function set, where no knowledge of the hardware is needed anymore. This can then be used by the last layer, the Application layer. The application layer houses different applications, and a general state of the device can be found inside this layer. +\begin{figure}[H] + \centering + \label{fig:block_code} + \includegraphics[width=0.9\textwidth]{../block/block_code.png} + \caption{The system structure and hierarchy} +\end{figure} +above in fig. \ref{fig:block_code} this translation from system design to a more refined code structure is shown. A brief description of the required functionality for every block follows. +\subsection{App layer} The core in the App layer takes care of putting the system in the right state, and decides when to show which application on the screen. Furthermore it establishes the Wi-Fi connection and requests the data from the Internet which is required for all the other applications. Also it translates commands coming from the UART port into actions. The weather application takes data that is fed from the core, and shows the weather at a given position on the screen. The clock application listens to second pulses and shows the time on the screen, together with an alarm. The time is shown both analogue and digital. The time can be read from the Time module, or be set trough the Core, when it synchronizes with the Internet. The Screen Terminal application redirects all the log output and shows it on the screen. This can be used for debugging. Facebook and mail notifications are shown with the Social application. Finally the Lamp application houses information about different sunsets, and accounts for the right amount of red, green and blue in the light when the alarm goes off. +\subsection{Module layer} +The Wi-Fi module makes it possible to translate actions as getting the weather and the current time, to UDP and TCP requests. The Command module interprets data given from the Terminal and executes a given function paired with the command sent. Everything is written to the terminal via the Log module, which adds extra information to every message, such as the file name, line number and time. The screen module contains functions to draw shapes and images. Time reads the latest known time from the EEPROM after a total power failure, and keeps track of the current time via second pulses. To allow fades in the light, and stable output, a Controller module is available. This reads out the current voltage with which the lamp is being driven, and adjusts the PWM signal accordingly. +\subsection{Driver layer} +The ESP8266 Driver contains all the communication with the ESP8266 chip and keeps track of the network state. Its also possible to update the firmware of the ESP8266. Terminal is a software driver, with no external hardware dependencies by default. It can, however, use the SEP525F as output for text. The text can be formatted with the Terminal driver. In order to set up the screen and draw pixels, a screen driver is required. The OLED screen that is being used, has a SEP525F driver ic. For this a driver has been written. +\subsection{Platform layer} +Every required peripheral has a platform driver. The UART driver has an input and output buffer, and is being used with interrupts. Two UART channels are being used, one for the ESP8266 and one for the USB-Serial converter. The SEP525F has a SPI interface without a need or possibility to read, the SPI driver contains only blocking write. This should be changed to DMA and interrupt transfers. The EEPROM allows to save some settings and time and date on the clock. The timer sets up the real time counter for the second pulses, and has functions to set the PWM of every channel for the power board. And as last, the ADC peripheral. This scales the voltage read from the input pins and provides it to whoever needs the ADC values. \ No newline at end of file diff --git a/docs/research plan/doc/idea.tex b/docs/research plan/doc/idea.tex new file mode 100644 index 0000000..dec06e3 --- /dev/null +++ b/docs/research plan/doc/idea.tex @@ -0,0 +1 @@ +It is a well-known fact, that it is quite dark in Sweden in the winter. In a strong winter every source of light is a source of happiness. This wakeup light, which is based on a strong light source (10 W RGB LED), is able to give one the optimal start into a dark winter day. The \textit{Swakeup} (from engl. "Swedish Wakeup Light") is communicating to the user through the light. It does not simply wake one up, but also gives one information about Facebook, latest mails, calendar and weather. The user interface consits besides of a big LED of an OLED screen. \textit{Swakeup} is also part of the \textit{IoT} as it has the ability to communicate via \textit{IEEE 802.11}. This of course enables a lot of possibilities e.g. connecting your phone to the wakeup light. A lot of effort has been put into the designing maxim, that everything should be as small as possible. The whole electronics fit on an base area of 5 cm x 4 cm. So the \textit{Swakeup} fits smoothly on the bedside table. And honestly: What is the last thing you are doing before you go to sleep? Right! You look on your phone. That is why \textit{Swakeup} comes with a USB charger for your e.g. phone as well. diff --git a/docs/research plan/doc/logic.tex b/docs/research plan/doc/logic.tex new file mode 100644 index 0000000..176f8e4 --- /dev/null +++ b/docs/research plan/doc/logic.tex @@ -0,0 +1,10 @@ +The logic board has been realized with the commercial CAD program Altium. The whole circuit fits on one sheet, as the logic board is not a complex design consisting out of very few IC's and passives. +\subsection{Design choices} +To facilitate all the functionality, certain IC's had to be chosen. The design requirements were to also have a debug option and a way to flash firmware without the need of a specialized programmer. That is why a USB-Serial bridge IC had to be found. There are nowadays quite a few different bridges on the market which all have the same basic functionality that is needed, namely: writing and receiving over a serial port. In order to keep the workload low so that the goal could be reached, an a-synchronous chip was sufficient. Therefor the CP2102 had been chosen. Other competitors with the same functionality were more expensive because they also offered extras that are not needed.\newpar +For \textit{IEEE 802.11} connection the ESP8266 has been chosen. This because it's the cheapest solution on the market, while also providing enough flash and performance to execute the tasks on the module itself, rather than needing a strong microcontroller with it. The ESP8266 itself is preprogrammed with a subset of the Hayes commands. But the firmware can be altered and software can be written in many different languages such as LUA, C++, Python.\newpar +In order to give the user feedback about the time, some interface is needed. As the weather and social media status should be visible this interface has to be a graphic screen of some sorts. Standard LCD's have the disadvantage that they have backlight, which causes annoyances during night when its on. As it acts as a large light source. And if the backlight is turned off, the user won't be able to read out the time. That is why an OLED screen has been chosen, based on the SEPS525F driver. OLED has the advantage that every pixel is lit individually, thus not creating a large light source when only time is displayed. Another advantage is the power consumption, which depends on the state of the screen. Fewer pixels being lit means a lower power consumption. \newpar +Only two microcontroller models were available to choose, as the course required to make use of an 8-bit AVR chip. Either the Atmega, or the more recent XMega. The Xmega has an updated design, and provides more efficient power management due to lower power supply while maintaining performance. Other advantages are a multi level interrupts and more advanced GPIO access. In order to facilitate possibilities to flash the ESP8266 module from the xmega, a large flash size is needed. The xmega with the smallest footprint and largest flash was chosen, which is the xmega128a4u. +\subsection{Implementation} +The XMega will be programmed trough a PDI port. Furthermore four ADC and PWM pins are exposed for use with the power board. The screen is connected via a flat flex connector, rather than soldered directly on the board. This allows for reuse of the screen on further revisions without having to purchase new screens.\newpar +An external crystal is used for the real time clock. This gives the possibility to use the 32 bit real time counter on the XMega which is more precise than using a build in oscillator. Two low side n-channel MOSFETS are connected for reverse voltage protection. \newpar +The full schematics can be found in Appendix \ref{append:logic}. \ No newline at end of file diff --git a/docs/research plan/doc/os.tex b/docs/research plan/doc/os.tex new file mode 100644 index 0000000..7a63299 --- /dev/null +++ b/docs/research plan/doc/os.tex @@ -0,0 +1,35 @@ +To make the previously discussed layering possible with communication, a small operating system has been developed with a minimum subset of functions. This subset is divided in two parts, Events and Modules. +\subsection{Module} +The modular system is realized by a struct. Every module contains a name, a usage counter, initialize and deinitialize functions, and dependencies. A module can be initialized by the "module\_init" function. This function will check for all the dependencies, whether they are already initialized. If this is not the case, it will be initialized including all the dependencies of the dependency. The "module\_init" function will also call the initialize function, which can be used for a module to set up registers for example. Once a module is not needed anymore, it can be deinitialized with the "module\_deinit" function. This function will decrease the usage counter for every dependency, and once a dependency is not used anymore it will also be deinitialized. This function also calls the deinitialize function of the given module. + +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +#define MODULE_DEFINE(VAR, DESC, INIT, DEINIT, ...) \ + Module VAR = { \ + .init = INIT, \ + .deinit = DEINIT, \ + .cnt = 0, \ + .name = DESC, \ + .deps = { __VA_ARGS__ } \ + } +MODULE_DEFINE(CORE, "Central core", init, deinit, &TIME, &COMMAND, &ESP8266); +\end{minted} +In the code above a simplified usage example can be seen of this modular system + +\subsection{Event} +For communication between modules an event based system has been realized. The developed system does not have any kind of priority for events, and events can be ignored if the event buffer is full because of a too heavy event. Every event contains a counter for debugging purposes, a pointer to data that can be given along with the event, and a description. An event can be created by use of the following code: +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +#define EVENT_REGISTER(eventName, desc)\ + Event eventName = \ + {.eventId = __COUNTER__, .data = 0, .description = desc, .descLen = sizeof(desc) } +EVENT_REGISTER(EVENT_UART_DELIMITER, "Got UART delimiter"); +\end{minted} +Events alone do not serve any purpose without listeners. Thus it's possible to register listeners in the event system. With the "event\_addListener" function a module can listen to a certain event and provide a function to be called upon the reception of such an event. This can be seen in the code below: +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +event_addListener(&EVENT_UART_DELIMITER, callback); +\end{minted} +The listeners can be removed with the "event\_removeListener" function. The adding listeners is usually done in the initialization function, as the modules require these events during the period that they are active. In order to fire an event to all the listeners the following example can be used: +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +event_fire(&EVENT_UART_DELIMITER, SYSTEM_ADDRESS_CAST (&delimiters[USART_ID][i])); +\end{minted} +This line of code will fire a EVENT\_UART\_DELIMITER event, and adds some information to go with it.\newpar +In order for these events to be processed the "event\_process" has to be called. This should be the only function called in the infinite while loop of the system. A way to save energy is to pass functions to the event system if the system is capable of a sleeping functionality. Now the system will sleep whenever there are no more events to process, or wake up when an interrupt occurs. diff --git a/docs/research plan/doc/outlook.tex b/docs/research plan/doc/outlook.tex new file mode 100644 index 0000000..fa9143b --- /dev/null +++ b/docs/research plan/doc/outlook.tex @@ -0,0 +1,3 @@ +Hopefully the LED driver will work with the next revision. The new boards have not arrived until the deadline. As soon as the hardware is working, the controllers will be implemented in software. +\newpar +Aditional funtionality will be implemented e.g. connecting you calendar to the device and seing your daily agenda when you wake up. Also there is no housing yet. diff --git a/docs/research plan/doc/overview.tex b/docs/research plan/doc/overview.tex new file mode 100644 index 0000000..f32a888 --- /dev/null +++ b/docs/research plan/doc/overview.tex @@ -0,0 +1,13 @@ +\begin{figure}[H] + \centering + \label{fig:block} + \includegraphics[width=0.6\textwidth]{../block/block.png} + \caption{Blockdiagram of the Swakeup wakeup light.} +\end{figure} +In fig. \ref{fig:block} the actual system architecture from an abstract point of view is displayed. One can clearly see, that the system is divided into two physical boards. The logic board consists of the µC, a serial connection infrastructure, an OLED screen, an \textit{IEEE 802.11} module, a ISP programming infrastructure and some LEDs/a button (UI). +\newpar +The power board takes the 20 V input of a low-cost power supply and breaks it down to 2.8 V (Vcc), 5 V for phone charging and the power which is needed for the RGB LED. +\newpar +The partitioning of the system functionalities on two boards has a bunch of advatages: Two people worked on this project, so each could develop a PCB; It is quite common to seperate signals from power lines out of EMI reasons; There was simply not eanough space on one two-layer board for the whole system keeping a base area of 5 cm x 4 cm. +\newpar +The two boards are connected together through four headers. By these headers an electrical and mechanical connection is maintained. The headers allow a feedback from the LED driver on the power board to the logic board (ADC). Also the control variable (PWM) comes via the headers from the µC to the LED driver. The 2.8 V Vcc is produced and regulated on the power board and is also availabe at one header. Another voltage available from one header is the OLED driver voltage. diff --git a/docs/research plan/doc/power.tex b/docs/research plan/doc/power.tex new file mode 100644 index 0000000..8d0d992 --- /dev/null +++ b/docs/research plan/doc/power.tex @@ -0,0 +1,17 @@ +The board design has been made in \textit{KiCAD}. \textit{Git} was used for version control. In the schematics (Appendix \ref{append:power}) one can see that the whole board consists of three main building blocks: Connectors, a LED driver with feedback and two step-down converters. A part of the LED driver is also "abused" to drive the OLED. +\subsection{Microcontroller Power Supply} +It is the LM2840 which in combination with a simple voltage divider ensures the 2.8 V for Vcc. All step-down converters use the same inductor with a value of 33 uH. It is a low-cost, quite small, shielded inductor which is ment to be used for switching power supplies. Moreover all step-down converters are enhanced with a SMD schottky diode and a of course at least one SMD capacitor for smoothing the output signal. As it is good practice to do so all ICs are making use of decoupling capacitors. +\subsection{Designated USB Charging Port} +For charging ones phone the TS30012, another step-down converter IC, is used. The feedback voltage divider of this IC is already integrated and does not need to be provided externally as the IC provides fixed 5 V output. The output is connected to a USB connector type A. This IC can deliver up to 2 A. An interesting feature of the phone charging circuitry on the power board is the "Dedicated Charging Port" (DCP) functionality. The TPS2514 is a small, easy-to-use, 6-pin component, which complies to the USB standard and a majority of the minefield of propriatary standards to signal a DCP. Now you might ask: What does this mean? Well this means, that if you connect your IPhone, it will know, that it can draw more than 100 mA, which is the minimum current provided by a normal USB 2.0 port. Otherwise the current drawn by the phone will be limited. The charging functionality can be turned on and off via a GPIO pin. The TS30012 comes in a QFN16 package (pad pitch of 0.5 mm) to save space. +\subsection{HW Debugging} +For testing purposes a lot of test points have been included into the design. Futhermore there are LEDs for different voltages (e.g. Vcc). +\subsection{RGB LED Driver} +The LED driver consists of an actual power electronics part and a feedback part. The main idea is, that the current driven through the three color channels of the RGB LED (see fig. \ref{fig:led}) can be controlled by software (PID controller). In the power electronics part there are three analog circuits. Each circuit mainly consists of a p-channel MOSFET, which is switched by a NPN bipolar transistor. This bipolar transistor gets its intput signal from the µProcessor (PWM). By pulling the 20 V to GND the PMOS "sees" a negative gate-to-source voltage and opens. The additional bipolar transistor ensures, that the gate-source capacity is charged fastly as soon as the PWM NPN blocks. In this case the base is pulled up via \SI{10}{\kilo\ohm} to 20 V and as long as the collector (which has the same potential as the gate of the PMOS) does not also have 20 V the NPN keeps pumping charges into the gate-source capacity. The simple silicon diode ensures that the gate-charging NPN has no effect as soon as the PWM NPN opens. The rest of the circuit is again a standard step-down converter. At the output of every single color channel power circuit one can see a shunt resistor of \SI{0.1}{\ohm}. This shunt resistor is combined with a simple low-pass filter. The feedback signal is amplified by a differential amplifier which comes after the filter. The signal is supposed to be between 0 V and 1 V (if the internal reference voltage is used). By doing so one can use all bits of the ADC and therefore supress quantization noise. +\newpar +So as there are three color channels (red, green and blue) one needs three operational amplifiers. Hence the LM324QT, which provides four operational amplifiers, has been chosen. Of course the decision has been made to take QFN16 packaging once more to save even more space. An additional operational amplifier was now ready to be used as a digital-analog converter to drive the OLED screen (this was referred to earlier as "abuse"). For this reason a low-pass filter is attached to the input of the fourth opamp. Apart from that the opamp is configured just like a standard non-inverting amplifier. By software the OLED screen brightness is steerable. The feedback from the OLED is generated by a voltage divider. +\begin{figure} + \centering + \includegraphics[width=0.3\textwidth]{./fig/led.jpg} + \caption{10 W RGB LED} + \label{fig:led} +\end{figure} diff --git a/docs/research plan/doc/realization.tex b/docs/research plan/doc/realization.tex new file mode 100644 index 0000000..6793a20 --- /dev/null +++ b/docs/research plan/doc/realization.tex @@ -0,0 +1,137 @@ +The function of this chapter is to get a deeper understanding of the modules and code that has been written. Due to time constraints and hardware failure, the following modules were not realized: "Lamp, Social, Wi-Fi, Controller, ADC, EEPROM". Thus these modules will not be discussed in this chapter. +\subsection{Platform} +Starting with the most tightly with the microcontroller integrated layer. +\subsubsection{UART} +The UART module delivers all the communication to the USB-Serial converter and ESP8266. The code has been kept as generic as possible so that adjustments to the external hardware has no influence to the driver code. It would even be possible to move to a different xmega model with more USART ports since a macro is used for generating the interrupt code. Every USART port has a status, an array with delimiters, an in and output buffer, a sending status and an id. The status contains variables for the buffers, and allows for a ring-buffer usage. A ringbuffer is chosen as it has little overhead compared to lists or queues, the order of the data matters, and we don't expect to go outside of our given buffer capacity. The delimiters are used for the USART to listen to certain characters on the receiving data. Once there is a match an event will be fired. The example below shows the usage of this delimiter. +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +uint8_t uart_add_delimiter(char delimiter, USART_t * port); +static void callback(Event * event, uint8_t * data) { + if(event == EVENT_UART_DELIMITER){ + struct UartDelimiter * delimiter = (struct UartDelimiter*)data; + if (delimiter->port == &ESP_UART_PORT) { + //Read buffers etc + } + } +} +static uint8_t init(void) { + uart_add_delimiter('\n', &ESP_UART_PORT); + event_addListener(&EVENT_UART_DELIMITER, callback); + return 1; +} +\end{minted} +In this example, a certain module will tell the UART module to listen for a new line character, and the module will subscribe to the event. The UART module passes the delimiter information with it, so that there is knowledge about how much data can be read since the last delimiter event.\\ +The interrupts are generated with the macros that can be found at appendix \ref{append:usartinterruptgen}. +The following code can be used to generate the interrupt code for every USART channel:\newpage +\begin{minted}[baselinestretch=1, breaklines=true, fontsize=\small, linenos=true,frame=single,framesep=5pt]{C} +USARTRXCISR(USARTE0, DEBUG_UART, USARTE_ID, received); +USARTDREISR(USARTE0, DEBUG_UART, USARTE_ID); +USARTRXCISR(USARTD1, ESP_UART_PORT, USARTD_ID, ); +USARTDREISR(USARTD1, ESP_UART_PORT, USARTD_ID); +\end{minted} +Since the system could be writing to the buffer that is being handled in the interrupt, a lock has been implemented to prevent unexpected outcome. One lock waits while the lock signal is freed, while the other lock function returns a 0 upon failure to acquire the lock. +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +#define lock(id) while (outBufferLock[id]); outBufferLock[id] = 1 +#define unlock(id) outBufferLock[id] = 0 + +static inline uint8_t softlock(uint8_t id) { + if (outBufferLock[id]) return 0; + outBufferLock[id] = 1; + return 1; +} +\end{minted} +The USART on both channels have the same settings: 8 bit words, medium level interrupts and a baudrate of 115200. This baudrate can go higher once the whole system is tested with good results. +\subsubsection{SPI} +The SPI driver is incomplete as is, a lot of performance optimizations can and should be done. One of the biggest disadvantages at the moment is that it is blocked writing. When a lot of data is being sent consecutively by the SPI driver, the event buffer fills up and might even get full. Interrupt based design should be looked at and investigated, as this would still allow the events to be handled. The caveat with this, however, is that a large buffer has to be allocated for the SPI. And memory is costly. DMA is another technique to solve the problem, this would eliminate the need for a CPU at all and give the system all the time to process the other tasks. One needs to be cautious, as DMA has overhead on low data amounts. +\subsubsection{Timer} +The Timer design is incomplete, and only houses a RTC. Due to a hardware failure, the internal crystal is being used. Which implies a worse accuracy than an external one. However since the most recent time can be retrieved from the internet this is not a major issue. Future additions to the Timer module include: Alarm function for timeouts on waiting, PWM functionality and using the 32 RTC with the external crystal. The Timer module is set up to use it's overflow interrupt. The period is set to 1023. As soon as the counter reaches 1024, a second pulse event will get fired and the run time will get incremented. +\subsection{Driver} +One step up gives the communication with external hardware. +\subsubsection{SEPS525F} +As mentioned before, the screen uses a SEPS525F IC. This driver drives allows for driving screens with a resolution of up to 160x128 pixels with 18 bit combined color. This means that there are 6 bits for blue, 6 bits for green and 6 bits for red. However this would require to send 3 bytes for 2 bits of color precision. There is also a 16 bits combined color option available, which has been used in this driver. 5 bits for blue, 6 bits for green and 5 bits for red. A 24 bit color (8 bits per color, 0-255) can be converted with the following define: +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +#define SEPS525F_TO656(r,g,b)((r>>3)<<11)|((g>>2)<<5)|(b>>3) +\end{minted} +The SEPS525F has three data interfaces that could be used: SPI, RGB, Parallel. In retrospect a parallel interface would have given major performance advantages. However due to time constraints a SPI interface has been chosen. The clock frequency of the SPI is set at the CPU speed divided by two. Which is a clock of 8 MHz when not in any power saving mode.\newpar +The SEPS525F has two modes, a data mode and a command mode. With the command mode a register can be set. In order to achieve this the register will be written first, while clearing the RS and the CS pin. Once the register is written, the RS pin will be set while keeping the CS pin low. After the data is written the CS pin will be set. +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +static void SEPS525F_reg(int idx, int value) { + SEPS525F_PORT.OUTCLR = SEPS525F_CSB | SEPS525F_RS; + spi_write_blocked(idx); + SEPS525F_PORT.OUTSET = SEPS525F_RS; + SEPS525F_PORT.OUTCLR = SEPS525F_CSB; + spi_write_blocked(value); + SEPS525F_PORT.OUTSET = SEPS525F_CSB; +} +\end{minted} +This can be seen in the code above. The driver gives the possibility to draw a single pixel, but it's significantly faster to write multiple pixels at once. For this a region that will be drawn on has to be set. Then the driver ic will expect a certain amount of pixels, which have to be written as data. According to the datasheet special scrolling features should be available, however this is not explained later on in the datasheet. There are a lot of parameters that can be set for the screen, such as duty cycle, frame rate, driving currents. The explanation of all these can be found in the datasheet, just like the recommended values. The given initialization sequence of the datasheet did not work, so an Arduino library has been ported successfully\cite{github:oled}. +\subsubsection{Terminal} +The Terminal driver gives the possibility to format strings, and outputs the formatted strings to a sink. The default sink writes to the USB-Serial IC via the UART driver. Formatting is done via the tinyprintf library\cite{sparetimelabs:tinyprintf} and implements the 'd' 'u' 'c' 's' 'x' 'X' formats. +\subsubsection{ESP8266} +The ESP8266 is a low cost Wi-Fi module which can be flashed with own firmware. In a next version this own firmware will be developed, however for now the standard firmware is used. UART is used to communicate with the module, via an Hayes command set based protocol\cite{lonestar:at}. The commands implemented allow for basic HTTP get requests. Due to time constraints it was not possible to finalize the usage of the module. Networks can be scanned, and a connection with a wireless action point can be established. But there is no functionality beyond that. +\subsection{Modules} +Although all the drivers talked about before make use of the Module system, they are not located on the Module layer. This is a naming convention mistake. +\subsubsection{Command} +The Command module has the purpose of setting up an accessible possibility to execute commands received by the USB-Serial connection. It is possible to register up to 26 commands. One for every letter in the alphabet. A command can be registered by use of the following code: +\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C} +command_hook_description( + 'T', &terminalCommand, "Log sink T