frequency capture

master
Ondřej Hruška 6 years ago
parent 3f295ae0ad
commit 44d3394f0b
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 101
      ch.hw_buses.tex
  2. 54
      ch.hw_functions.tex
  3. 6
      ch.usb.tex
  4. 3
      document_config.tex
  5. BIN
      img/2-foot-wide-various-heights-and-widths-vinyl-banners-vertical-standard-vertical-banner-size.jpg
  6. BIN
      img/e2b9824cda1033cd.jpg
  7. BIN
      img/fcap-direct.pdf
  8. BIN
      img/fcap-reciprocal.pdf
  9. 6224
      img/freqmethods.eps
  10. BIN
      img/neo-diagram.png
  11. BIN
      img/neo-lengths.png
  12. BIN
      img/ws2812b-detail.jpg
  13. BIN
      thesis.pdf
  14. 1
      thesis.tex

@ -1,22 +1,31 @@
\chapter{Supported Hardware Buses}
\chapter{Supported Hardware Buses} \label{ch:hw_buses}
Hardware buses implemented in GEX are presented in this chapter. The description of each bus is accompanied by several examples of devices that can be interfaced with it. The reader is advised to consult the official specifications and particular devices' datasheets for additional technical details.
\section{UART and USART}
The \textit{Universal Synchronous / Asynchronous Receiver Transmitter} has a long history and is still in widespread use today. It is the protocol used in RS-232, which was once a common way of connecting modems, printers, mice and other devices to personal computers. UART framing is also used in the industrial bus RS-485.
UART and USART are two variants of the same interface. USART includes a separate clock signal, while the UART timing relies on a well-known clock speed and the bit clock is synchronized by start bits. USART was historically used in modems to achieve higher bandwidth, but is now mostly obsolete.
USART, as implemented by microcontrollers such as the STM32 family, is a two-wire full duplex interface that uses 3.3\,V or 5\,V logic levels. The data lines are in the high logical level when idle. A frame, pictured in figure \ref{fig:uart-frame} starts by a start-bit (low level for the period of one bit) followed by \textit{n} data bits (typically eight), an optional parity bit and a period of high level called a stop bit or stop bits, usually between one and two bits long.
\begin{figure}
\centering
\includegraphics[width=.8\textwidth] {img/usart.png}
\caption{\label{fig:uart-frame}UART frame, as shown by the STM32F072 Reference Manual. Break frames are used by some UART based protocols, like LIN (Local Interconnect Network).}
\caption[UART frame structure]{\label{fig:uart-frame}UART frame, as shown by the STM32F072 Reference Manual. Break frames are used by some UART based protocols, like LIN (Local Interconnect Network).}
\end{figure}
UART and USART are two variants of the same interface. USART includes a separate clock signal, while the UART timing relies on a well-known clock speed and the bit clock is synchronized by start bits. USART was historically used in modems to achieve higher bandwidth, but is now mostly obsolete.
USART, as implemented by microcontrollers such as the STM32 family, is a two-wire full duplex interface that uses 3.3\,V or 5\,V logic levels. The data lines are in the high logical level when idle. A frame, pictured in figure \ref{fig:uart-frame} starts by a start-bit (low level for the period of one bit) followed by \textit{n} data bits (typically eight), an optional parity bit and a period of high level called a stop bit or stop bits, usually between one and two bits long.
RS-232 uses the UART framing, but its logic levels are different: logical 1 is represented by negative voltages $-3$ to $-25$\,V and logical 0 uses the same range, but positive. To convert between RS232 levels and TTL (5\,V) levels, a level-shifting circuit such as the MAX232 can be used. In RS232, the two data lines (Rx and Tx) are accompanied by RTS (Ready To Send), CTS (Clear To Send) and DTR (Data Terminal Ready) which facilitate handshaking and hardware flow control. In practice, those additional signals are often unused or their function differs; for instance, Arduino boards (using a USB-serial converter) use the DTR line as a reset signal to automatically enter their bootloader for firmware flashing.
\todo[inline]{examples}
\subsection{Examples of Devices Using UART}
\begin{itemize}
\item \textbf{MH-Z19B} - NDIR CO2 concentration sensor
\item \textbf{NEO-M8} - uBlox GPS module
\item \textbf{ESP8266} with AT firmware - a WiFi module
\item \textbf{MFRC522} - NFC MIFARE reader/writer IC (also supports other interfaces)
\end{itemize}
\section{SPI}
@ -28,26 +37,50 @@ SPI devices often provide a number of control, configuration and status register
\begin{figure}
\centering
\includegraphics[width=.9\textwidth] {img/spi-multislave.png}
\caption{\label{fig:spi-multislave}A SPI bus with 1 master and 3 slaves, each enabled by its own Slave Select signal (\textit{STM32F072 Reference Manual})}
\includegraphics[width=.7\textwidth] {img/spi-multislave.png}
\caption[SPI master with multiple slaves]{\label{fig:spi-multislave}A SPI bus with 1 master and 3 slaves, each enabled by its own Slave Select signal (\textit{STM32F072 Reference Manual})}
\end{figure}
\todo[inline]{examples}
\subsection{Examples of Devices Using SPI}
\begin{itemize}
\item \textbf{SX1276} - LoRa transceiver
\item \textbf{nRF24L01+} - 2.4\,GHz ISM band radio module
\item \textbf{L3GD20} - 3-axis gyroscope
\item \textbf{BMP280} - pressure sensor
\item \textbf{BME680} - air quality sensor
\item \textbf{ENC28J60} - Ethernet controller
\item \textbf{L6470} - intelligent stepper motor driver
\item \textbf{AD9833} - DDS-based DAC / waveform generator (MOSI only)
\item \textbf{ADE7912} - triple $\Sigma$-$\Delta$ ADC for power metering applications
\item \textbf{SD cards}
\item SPI-interfaced EEPROMs and Flash memories
\end{itemize}
\section{I2C}
I2C is a two-wire (SDA--\textit{Serial Data}, SCL--\textit{Serial Clock}), open-drain bus that supports multi-master operation. The protocol was developed by Philips Semiconductor (now NXP Semiconductors) and until 2006 implementors were required to pay licensing fees, leading to the development of compatible implementations with different names, such as Atmel's Two Wire Interface (TWI). I2C is the basis of the SMBus and PMBus protocols which add additional constraints and rules for a more robust operation.
I2C is a two-wire (SDA--\textit{Serial Data}, SCL--\textit{Serial Clock}), open-drain bus that supports multi-master operation. The protocol was developed by Philips Semiconductor (now NXP Semiconductors) and until 2006 implementors were required to pay licensing fees, leading to the development of compatible implementations with different names, such as Atmel's Two Wire Interface (TWI) or Dallas Semiconductor's "Serial 2-wire Interface" (e.g. used in the DS1307 RTC chip). I2C is the basis of the SMBus and PMBus protocols which add additional constraints and rules for a more robust operation.
I2C uses two addressing modes: 7-bit and 10-bit. Due to the small address space, exacerbated by many devices implementing only the 7-bit addressing, collisions between chips from different manufacturers are common; many devices thus offer several pins to let the board designer choose a few bits of the address by connecting them to different logic levels. I2C allows slow slave devices to stop the master from sending more data by holding the SCL line low at the end of a byte. As the bus is open-drain, the line can't go high until all participants release it. This function is called \textit{Clock Stretching}.
\begin{figure}
\centering
\includegraphics[width=.9\textwidth] {img/i2c-frame.png}
\caption{\label{fig:i2c-frame}An I2C message. The frame starts with a start condition and stops with a stop condition, defined by an SDA edge while SCL is high. The address and data bytes are acknowledged by the slave by sending a 0 on the open-drain SDA line in the following clock cycle. A slave can terminate the transaction by sending 1 in place of the acknowledge bit. (\textit{Diagram taken from the I2C specification UM10204 by NXP Semiconductors})}
\caption[I2C message diagram]{\label{fig:i2c-frame}An I2C message diagram. The frame starts with a start condition and stops with a stop condition, defined by an SDA edge while SCL is high. The address and data bytes are acknowledged by the slave by sending a 0 on the open-drain SDA line in the following clock cycle. A slave can terminate the transaction by sending 1 in place of the acknowledge bit. (\textit{Diagram taken from the I2C specification UM10204 by NXP Semiconductors})}
\end{figure}
The bus supports multi-master operation, which leads to the problem of collisions. Multi-master capable devices must implement a bus arbitration scheme as specified by the I2C standard. This feature is not often used in intelligent sensors and modules; the most common topology is multi-drop single-master, similar to SPI, with the advantage of using only two pins on the microcontroller.
\subsection{Examples of Devices Using I2C}
\begin{itemize}
\item \textbf{APDS-9960} - ambient light, proximity and gesture sensor
\item \textbf{L3GD20}, \textbf{BMP280}, \textbf{BME680} - listed as SPI devices, those also support I2C
\item \textbf{DS1307} - RTC; I2C is not mentioned in the entire datasheet, presumably to avoid paying license fees, but it is fully compatible
\item \textbf{IS31FL3730} - LED matrix driver
\item Cameras with an SCCB port can be accessed through I2C
\end{itemize}
\section{1-Wire}
The 1-Wire bus, developed by Dallas Semiconductor, uses a single bi-directional data line which can also power the slave devices, reducing the number of required wires to just two (compare with 3 in I2C and 5 in SPI, all including GND).
@ -60,31 +93,41 @@ The 1-Wire bus, developed by Dallas Semiconductor, uses a single bi-directional
\caption{\label{fig:1w-topology}1-Wire topology (by \textit{Dallas Semiconductor})}
\end{figure}
\begin{figure}
\centering
\includegraphics[width=\textwidth] {img/1w-rw.png}
\includegraphics[width=\textwidth] {img/1w-reset.png}
\caption{\label{fig:1w-pulses}1-Wire DIO pulse timing (by \textit{Dallas Semiconductor})}
\end{figure}
1-Wire is a master-slave multi-drop bus. Devices are addressed by their unique 64-bit ID numbers (called ROMs); those IDs are found by the bus master with the cooperation from slaves using a ROM search protocol. If only one device is connected, a special command set can be used to skip addressing.
\section{NeoPixel}
NeoPixel is a marketing name of the WS2811, WS2812 and compatible intelligent LED drivers that is commonly used in "addressable LED strips". Those chips include the control logic, PWM drivers and usually the LED diodes all in one miniature package.
The NeoPixel protocol is unidirectional, using only one data pin. The LED drivers are chained together. Ones and zeros are encoded by a pulse length on the data pin; after loading the color data to the LED string, a longer "reset" pulse is issued by the bus master and the set colors are displayed.
The NeoPixel timing is very sensitive to pulse length accuracy. Reliable ways to implement it use DMA with a hardware timer, or a I2S peripheral. An easier method that does not use any additional hardware resources is implementing the protocol as delay loops in the firmware; care must be taken to disable interrupts in the sensitive parts of the timing.
\subsection{Examples of Devices Using 1-Wire}
\begin{itemize}
\item \textbf{DS1820}, \textbf{DS18S20}, \textbf{DS18B20} - digital thermometers
\item \textbf{iButton} - contact-read access tokens, temperature loggers etc.
\end{itemize}
Since 1-Wire is a proprietary protocol, there is a much smaller choice of available devices and they also tend to be more expensive. The DS18x20 thermometers are, however, popular enough to warrant the bus's inclusion in GEX.
\begin{figure}
\centering
\includegraphics[width=.85\textwidth] {img/1w-rw.png}
\includegraphics[width=.85\textwidth] {img/1w-reset.png}
\caption{\label{fig:1w-pulses}The 1-Wire DIO pulse timing (by \textit{Dallas Semiconductor})}
\end{figure}
\section{NeoPixel}
NeoPixel is a marketing name of the \textbf{WS2811}, \textbf{WS2812} and compatible intelligent LED drivers that is commonly used in "addressable LED strips". Those chips include the control logic, PWM drivers and usually the LED diodes all in one miniature package.
The NeoPixel protocol is unidirectional, using only one data pin. The LED drivers are chained together. Ones and zeros are encoded by a pulse length on the data pin; after loading the color data to the LED string, a longer "reset" pulse is issued by the bus master and the set colors are displayed. The timing diagram and constraints are shown in figure \ref{fig:ws2812-dia}.
The NeoPixel timing is very sensitive to pulse length accuracy. Reliable ways to implement it use DMA with a hardware timer, or a I2S peripheral. An easier method that does not use any additional hardware resources is implementing the protocol as delay loops in the firmware; care must be taken to disable interrupts in the sensitive parts of the timing.
\begin{figure}
\centering
\includegraphics[width=.6\textwidth] {img/ws2812b-detail.jpg}
\caption{\label{fig:ws2812-detail}A close-up photo of the WS2812B package, showing the LED driver IC}
\end{figure}
\begin{figure}
\centering
\includegraphics[width=.4\textwidth] {img/neo-diagram.png}
\includegraphics[width=\textwidth] {img/neo-lengths.png}
\caption{\label{fig:ws2812-dia}NeoPixel pulse timing diagram and time constraints table \textit{(WS2812 datasheet)}}
\end{figure}

@ -0,0 +1,54 @@
\chapter{Additional Hardware Functions}
In addition to communication buses, described in chapter \ref{ch:hw_buses}, GEX implements several measurement and output functions that take advantage of the microcontroller's peripheral blocks, such as timers/counters and DAC. The more complicated ones are described here; simpler functions, such as the raw GPIO access, will be described later together with their control API.
\section{Frequency Measurement}
Applications like motor speed measurement and the reading of a VCO (voltage-controlled-oscillator) or VCO-based sensor's output demand a tool capable of measuring frequency. This can be done using a laboratory instrument such as the Agilent 53131A. A low cost solution is to use a timer/counter peripheral of a microcontroller, such as the STM32F072 used in GEX.
\begin{figure}
\centering
\includegraphics[scale=1] {img/fcap-direct.pdf}
\caption{\label{fig:fcap-direct-dia}Direct frequency measurement method}
\end{figure}
\begin{figure}
\centering
\includegraphics[scale=1] {img/fcap-reciprocal.pdf}
\caption{\label{fig:fcap-reci-dia}Reciprocal frequency measurement method}
\end{figure}
\begin{figure}
\centering
\includegraphics[width=.9\textwidth] {img/freqmethods.eps}
\caption[Frequency measurement methods comparison]{\label{fig:freqmethods-graph}Worst-case error using the two frequency measurement methods with an ideal 48\,MHz timer clock. The crossing lies at 7\,kHz with an error of 0.015\,\%, or 1.05\,Hz.}
\end{figure}
Two basic methods to measure frequency exist, each with it's advantages and drawbacks:
\begin{itemize}
\item The \textit{direct method} (fig. \ref{fig:fcap-direct-dia}) is based on the definition of frequency as a number of cycles $n$ in a fixed-length time window $\tau$ (usually 1\,s); the frequency is then calculated as $f=n/\tau$.
One timer generates the time window and its output gates the input of another, configured as a pulse counter. At the end of the measurement window an interrupt is generated and we can read the pulse count from the counter's register.
The direct method has a resolution of 1\,Hz with a sampling window of 1\,s (only a whole number of pulses can me counted). The resolution can be increased by using a longer time window, provided the measured signal is stable enough to make averaging possible without distorting the result.
\item The \textit{indirect} or \textit{reciprocal method} (fig. \ref{fig:fcap-reci-dia}) measures one period $T$ as the time interval between two pulses and this is then converted to frequency as $f=1/T$.
This method needs only one timer/counter. Cycles of the system clock are counted for the duration of one period on the input pin (between two rising edges). If we additionally detect the falling edge in between, the counter's value gives us the duty cycle when related to the overall period length.
Te reciprocal method's resolution depends on the counter's clock speed; if driven at 48\,MHz, the tick period is 20.83\,ns, which defines the granularity of our time measurement. It is common to measure several pulses and average the obtained values to further increase the precision.
We can easily achieve a sub-hertz resolution with this method, but its performance degrades at high frequencies where the time measurement precision becomes insufficient. The input frequency range can be extended using a hardware prescaller\footnote{\textit{Prescaller} is a divider implemented as part of the timer/counter peripheral block that can be optionally enabled and configured to a desired division factor.}, which is also applicable to the direct method, should the measurement of frequencies outside the counter's supported range be required. A duty cycle measurement available in this method can be used to read the output of sensors that use a pulse-width modulation.
\end{itemize}
Which method to use depends on the frequency we want to measure; the worst-case measurement errors of both methods, assuming an ideal 48\,MHz system clock, are plotted in figure \ref{fig:freqmethods-graph}. It can be seen that the reciprocal method leads in performance up to 7\,kHz where the direct method overtakes it. If a higher error is acceptable, the reciprocal method could be used also for higher frequencies to avoid a reconfiguration and to take advantage of its higher speed.
A good approach to a universal measurement, when we don't know the expected frequency beforehand, could be to first obtain an estimate using the direct method, and if the frequency is below the worst-case error crossing point (here 7\,kHz), to take a more precise measurement using the reciprocal method.
The system clock's frequency, which we use to measure pulse lengths and to gate the pulse counter, will be affected by tolerances of the used components, the layout of the PCB, temperature effects etc., causing measurement errors. A higher accuracy could be achieved using a temperature-compensated oscillator (TCO), or, in the direct method, by using the synchronization pulse provided by a GPS receiver to time the measurement interval.
\section{Waveform Generation with Direct Digital Synthesis}
\todo[inline]{todo}

@ -5,7 +5,7 @@ This chapter presents an overview of the \textit{Universal Serial Bus} (USB) \te
\begin{figure}[H]
\centering
\includegraphics[width=0.8\textwidth] {img/usb-hierarchy.png}
\caption{\label{fig:usb-hierarchy}A diagram from the USB specification rev. 1.1 showing the hierarchical structure of the USB bus; The PC (Host) controls the bus and initiates all transactions.}
\caption[USB hierarchical structure]{\label{fig:usb-hierarchy}A diagram from the USB specification rev. 1.1 showing the hierarchical structure of the USB bus; The PC (Host) controls the bus and initiates all transactions.}
\end{figure}
\section{Basic Principles and Terminology}
@ -63,12 +63,12 @@ The USB cable contains 4 conductors:
The data lines, D+ and D--, are also commonly labeled DP and DM. This differential pair should be routed in parallel and kept at approximately the same length.
USB revisions are, where possible, backwards compatible, often even keeping the same connector shape. The bus speed is negotiated by the device using a 1.5\,k$\Omega$ pull-up resistor to 3.3\,V on one of the data lines: for Full Speed, D+ is pulled high (fig. \label{fig:usb-pullup-fs}), for Low Speed it's on D--. The polarity of the differential signals is inverted depending on the used speed. Some microcontrollers integrate the correct pull-up resistor inside the USB block (including out STM32F072), removing the need for an external resistor.
USB revisions are, where possible, backwards compatible, often even keeping the same connector shape. The bus speed is negotiated by the device using a 1.5\,k$\Omega$ pull-up resistor to 3.3\,V on one of the data lines: for Full Speed, D+ is pulled high (fig. \ref{fig:usb-pullup-fs}), for Low Speed it's on D--. The polarity of the differential signals is inverted depending on the used speed. Some microcontrollers integrate the correct pull-up resistor inside the USB block (including out STM32F072), removing the need for an external resistor.
\begin{figure}
\centering
\includegraphics[width=.8\textwidth]{img/usb-pullup-fs.png}
\caption{\label{fig:usb-pullup-fs}Pull-up and pull-down resistors of a Full Speed function, as prescribed by the USB specification rev. 2.0}
\caption[USB pull-ups]{\label{fig:usb-pullup-fs}Pull-up and pull-down resistors of a Full Speed function, as prescribed by the USB specification rev. 2.0}
\end{figure}
When a function wants to be re-enumerated by the host, which is needed to reload the descriptors and re-attach the correct drivers, it can momentarily remove the pull-up resistor, which the host will interpret as if the device was plugged out. With an internal pull-up this can be done by flipping a bit in a control register. An external resistor can be connected through a transistor controlled by a GPIO pin.

@ -15,6 +15,9 @@
\usepackage{framed}
\usepackage{subcaption}
\usepackage{flafter} % ensures embeds won't go before their references
\usepackage{enumitem} % better list spacing
\usepackage{bigfoot} % verbatin in footnote
\newcommand{\uF}{\micro\farad}

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

@ -31,6 +31,7 @@
\input{ch.freertos}
\input{ch.fat16} % TODO
\input{ch.hw_buses} % TODO
\input{ch.hw_functions} % TODO
\part{Firmware Implementation}

Loading…
Cancel
Save