@ -19,11 +19,11 @@ The idea of making it easier to interact with low-level hardware from a \gls{PC}
\caption{\label{fig:rpi}Raspberry Pi minicomputers}
\end{figure}
The Raspberry Pi's \gls{GPIO} header, a row of pins which can be directly controlled by user applications running on the minicomputer, was one of the inspirations behind GEX. It can be controlled using C and Python (among others) and offers \gls{GPIO}, \gls{SPI}, \gls{I2C}, \gls{UART}, and \gls{PWM}, with other protocols and functions easy to emulate thanks to the high speed of the system processor.
The Raspberry Pi (\cref{fig:rpi}) is a low-cost minicomputer targeted at school environments and hobbyists. It is often used for home automation, as a simple web server, or built into projects that take advantage of its powerful processor, such as wildlife camera traps, or data acquisition devices with in-situ processing.
The Raspberry Pi is used in schools as a low-cost PC alternative that encourage students' interest in \gls{STEM}. The board is often built into more permanent projects that make use of its powerful processor, such as wildlife camera traps, fish feeders etc.
The board's \gls{GPIO} header, a row of pins supporting features such as \gls{SPI}, \gls{I2C}, \gls{UART}, or \gls{PWM}, directly accessible by user applications running on the minicomputer, was one of the inspirations behind GEX.
The Raspberry Pi could be used for the same quick evaluations or experiments we want to perform with GEX, however they would either have to be performed directly on the minicomputer, with an attached monitor and a keyboard, or use some form of remote access (e.g., \gls{SSH}, or screen sharing).
The Raspberry Pi's functionality clearly overlaps with features we wish to support in GEX. Its processor is powerful enough for a regular \gls{OS} with a graphical user interface, and after attaching a display and a keyboard, it can be used as a \gls{PC}. However, when we have a more powerful computer available and only want to extend it with the \gls{GPIO} header, having to use the Raspberry Pi seems inconvenient; this might be overcome with the use of screen sharing or \gls{SSH}, but a low-complexity solution like GEX certainly has its appeal.
\section{Bus Pirate}
@ -36,11 +36,13 @@ The Raspberry Pi could be used for the same quick evaluations or experiments we
%http://dangerousprototypes.com/blog/about/
% Dangerous Prototypes and manufactured by Seeed Studio\todo{link}
Bus Pirate, a project by Ian Lesnet, is a USB-attached device providing access to hardware interfaces like \gls{SPI}, \gls{I2C}, \gls{USART}, and 1-Wire, as well as frequency measurement and direct pin access. The board aims to make it easy for users to familiarize themselves with new chips and modules; it also provides a range of programming interfaces for flashing microcontroller firmwares and memories. It communicates with the \gls{PC} using a FTDI USB-serial bridge.
Bus Pirate~\cite{buspirate} is a USB-attached device providing access to hardware interfaces like \gls{SPI}, \gls{I2C}, \gls{USART}, and 1-Wire, as well as features like frequency measurement and direct pin access. The board aims to make it easy for users to familiarize themselves with unknown chips and modules; it also provides a range of programming interfaces to program microcontrollers and memory chips. The board communicates with the \gls{PC} using an FTDI USB-serial adapter.
Bus Pirate is open source and is, in its scope, similar to GEX. It can be scripted and controlled from the PC, connects to USB and provides a wide selection of hardware interfaces.
The board is based on a PIC16 microcontroller running at 32\,MHz. Its \gls{ADC} only has a resolution of 10 bits (1024 levels). There is no \gls{DAC} available on the chip, which makes applications that require a varied output voltage more difficult to implement. Another limitation of the board is its low number of \gls{GPIO} pins, which may be insufficient for certain applications. The Bus Pirate is available for purchase at around 30\,USD, a price comparable to some Raspberry Pi models.
The board is based on a PIC16 microcontroller running at 32\,MHz. Its \gls{ADC} only has a resolution of 10 bits (1024 levels). There is no \gls{DAC} available on the chip, which makes applications that require a varied output voltage more difficult to implement. Another limitation of the board is its low number of \gls{GPIO} pins, which may be insufficient for certain applications; this, however, is not a hindrance to its main purpose as a bus analyzer and tinkering tool.
The Bus Pirate is available for purchase at around 30\,USD (at the time of writing), a price comparable to some Raspberry Pi models.
The firmware is built around a \textit{core framework} which provides services to units, such as the settings storage, resource allocation, message delivery, and periodic updates. In this chapter, we will focus on the structure of this framework and the services provided by it.
\section{Internal Structure Block Diagram}
The data flows and other internal logic of the firmware are depicted in \cref{fig:gex_internal}, with more explanation following in this chapter. The interchangeable role of the three communication interfaces can be clearly seen in the diagram, as well as the central role of the message queue, which decouples interrupts from the processing thread.
\caption{\label{fig:gex_internal}Block diagram showing the internal logic in the GEX firmware}
\end{figure}
\section{Internal Structure Block Diagram}
The data flows and other internal logic of the firmware are depicted in \cref{fig:gex_internal}, with more explanation following in this chapter. The interchangeable role of the three communication interfaces can be clearly seen in the diagram, as well as the central role of the message queue, which decouples interrupts from the processing thread.
\noindent
The framework provides the following services to units:
if (LL_DMA_IsActiveFlag_GI6(DMA1)) { /* handle DMA1 channel 6 */ }
if (LL_DMA_IsActiveFlag_GI7(DMA1)) { /* handle DMA1 channel 7 */ }
}
\end{minted}
\end{ccode}
It is evident that multiple units might need to use the same handler, even at the same time, since each \gls{DMA} channel is configured, and works, independently. GEX implements a redirection scheme to accomplish such interrupt sharing: all interrupt handlers are defined in one place, accompanied by a table of function pointers. When a unit driver wants to register an interrupt handler, it stores a pointer to it in this redirection table. Then, once an interrupt is invoked, the common handler checks the corresponding entry in the table and calls the referenced routine, if any. Conversely, when a unit driver de-initializes a unit, it removes all interrupt handlers it used, freeing the redirection table slots for other use.
@ -40,7 +40,7 @@ All GEX hardware platforms have some common characteristics (\cref{fig:users_vie
\begin{itemize}
\item\textbf{Direct \gls{USB} connection}
This is the primary and most straightforward connection method. We use the \gls{CDCACM} and \gls{MSC}\gls{USB} classes to have the module appear as a virtual serial port and a mass storage device, as described in \cref{sec:usb_classes}. This method is the fastest of the three and works out-of-the-box on Linux and MacOS. On MS Windows it may require the right software driver to be installed and assigned manually\footnote{The STM32 Virtual COM port driver~\cite{stm-vcom} has been tested to work with GEX on MS Windows version 7 and 8, though it must be manually assigned to the device in the Device Manager. MS Windows 10 and later should support \gls{CDCACM} natively.}.
This is the primary and most straightforward connection method. We use the \gls{CDCACM} and \gls{MSC}\gls{USB} classes to have the module appear as a virtual COM port and a mass storage device, as described in \cref{sec:usb_classes}. This method is the fastest of the three and works out-of-the-box on Linux and MacOS. On MS Windows it may require the right software driver to be installed and assigned manually\footnote{The STM32 virtual COM port driver~\cite{stm-vcom} has been tested to work with GEX on MS Windows version 7 and 8, though it must be manually assigned to the device in the Device Manager. MS Windows 10 and later should support \gls{CDCACM} as a virtual COM port natively.}.
This chapter describes all functional blocks (units) implemented in GEX, version 1.0. The term ``unit'' will be used here to refer to both unit types (drivers) or their instances where the distinction is not important.
Each unit's description will be accompanied by a corresponding snippet from the configuration file, and a list of supported commands and events. The commands and events described here form the payload of TinyFrame messages 0x10 (Unit Request) and 0x11 (Unit Report), as described in \cref{sec:unit_requests_reports}.
Each unit's description will be accompanied by a corresponding snippet from the configuration file, and a list of supported commands and events. The commands and events described here form the payload of TinyFrame messages \CmdUnitRequest and \CmdUnitReport, as described in \cref{sec:unit_requests_reports}.
The number in the first column of the command (or event) tables, marked as ``Code'', is the command number (or report type) used in the payload to identify how the message data should be treated. When the request or response payload is empty, it is omitted from the table. The same applies to commands with no response, in which case adding 0x80 to the command number triggers a SUCCESS response after the command is finished.
The number in the first column of the command (or event) tables, marked as ``Code'', is the command number (or report type) used in the payload to identify how the message data should be treated. When the request or response payload is empty, it is omitted from the table. The same applies to commands with no response, in which case adding 0x80 to the command number triggers a type \CmdSuccess response after the command is finished.
It has been proposed earlier in the text that STM32 Nucleo and Discovery development boards might serve as the hardware platform for this project. Indeed, a Discovery board with the STM32F072 was used to development a major part of the GEX firmware. This inexpensive board may be used to try GEX without having access to the custom hardware.
It has been proposed earlier in the text that STM32 Nucleo and Discovery development boards might serve as the hardware platform for this project. Indeed, a Discovery board with the STM32F072 was used to develop a major part of the GEX firmware, and the firmware remains compatible with it. This inexpensive board may be used to try GEX without the custom hardware.
\subsection{Discovery STM32F072 Configuration and Pin Mapping}
This Discovery board is fitted with four \glspl{LED} on \gls{GPIO} pins PC6 through PC9, in a compass arrangement. The ``north'' \gls{LED}, PC6, is used as the GEX status indicator. The ``User'' button, connected to PA0, is mapped as the GEX Lock button, controlling the settings storage.
The Discovery board is fitted with four \glspl{LED} on \gls{GPIO} pins PC6 through PC9, in a compass arrangement. The ``north'' \gls{LED}, PC6, is used as the GEX status indicator. The ``User'' button, connected to PA0, is mapped as the GEX Lock button, controlling the settings storage.
We advise the reader, as a potential user of this discovery board, to review its schematic diagram (found in its documentation~\cite{disco-f072}) and ensure the solder-jumpers are configured correctly:
We advise the reader, as a potential user of the board, to review its schematic diagram (found in the documentation~\cite{disco-f072}) and ensure the solder-jumpers on the back side are configured correctly:
\begin{itemize}
\item Jumpers SB20 and SB23 must be closed to enable the User \gls{USB} connector.
@ -18,7 +18,7 @@ We advise the reader, as a potential user of this discovery board, to review its
\item Jumpers SB27 through SB32 should be closed to connect the \gls{GPIO} pins normally dedicated to the touch sensing strip to the board's header.
\end{itemize}
Capacitors C26, C27, and C28 are sampling capacitors for the \gls{TSC}. There are, unfortunately, no jumpers available to disconnect them, and they interfere in high-speed signals on the used pins (PA3, PA7, PB1). The only solution, when those pins are needed for another purpose, is to desolder the capacitors.
Capacitors C26, C27, and C28 are sampling capacitors for the \gls{TSC}. There are, unfortunately, no jumpers available to disconnect them, and they interfere in high-speed signals on the used pins (PA3, PA7, and PB1). The only solution, when those pins are needed for another purpose, is to desolder the capacitors.
An accelerometer \gls{IC} L3GD20 is fitted on the board, attached to SPI2 on pins PB13 (\gls{SCK}), PB14 (\gls{MISO}), and PB15 (\gls{MOSI}), with \gls{NSS} on pin PC0, and pins PC1 and PC2 used for interrupt flags. This chip cannot be disconnected or disabled and it is difficult to remove; care must be taken to avoid its interference on the used pins.
@ -26,15 +26,7 @@ An accelerometer \gls{IC} L3GD20 is fitted on the board, attached to SPI2 on pin
GEX Hub was the first custom \gls{PCB} designed for GEX. It uses the same microcontroller as the Discovery board, thus the firmware modifications needed to make it work with this new platform were minimal. The schematic diagram is attached in \hyperref[apx:gex_hub]{Appendix A}.
The Hub board provides access to all the \gls{GPIO} pins\footnote{With the exception of pins used by USB and the Lock button.} through three flat-cable connectors, one for each port; they also contain a ground and power supply connection to make the attachment of external boards or a breadboard easier, requiring just one cable. The use of flat cables, however, is not mandatory---the flat cable connectors are based on the standard 2.54\,mm-pitch pin headers, allowing the user to use widely available ``jumper wires''.
\subsection{GEX Hub Errata}
The first revision of the Hub board (\cref{fig:gexhub1}) proved functional and helped us validate the power supply design, but contained one layout error that had to be manually fixed (the boot jumper and the programming header footprints, on the left side of the board, had too fine pitch and could not be populated).
The second, updated revision of the board (\cref{fig:gexhub2}) removes the two problematic footprints altogether; a reorganization in the \gls{GPIO} connectors allowed them to be moved together with the other pins. The Boot jumper was meant to be closed during normal operation, to avoid it getting lost. Since revision 2 moved the boot pin into the top connector, this had to be changed; the jumper logic was inverted by changing its pull-up resistor to a pull-down. The bootloader is now activated by inserting a jumper into the connector, shorting the Boot pin (labeled ``B'') to the adjacent 3.3\,V pin.
A restart is required, in all cases, for the boot jumper changes to take effect. Revision 2 adds a flat reset button on the back side of the board for this purpose, so the \gls{USB} cable no longer needs to be re-connected to reset the \gls{MCU} in order to flash a new firmware version.
The Hub board provides access to all the \gls{GPIO} pins\footnote{With the exception of pins used by USB and the Lock button.} through three flat-cable connectors (IDC), one for each port; they also contain a ground and power supply connection to make the attachment of external boards or a breadboard easier, requiring just one cable. The use of flat cables, however, is not mandatory---the flat cable connectors are based on the standard 2.54\,mm-pitch pin headers, allowing the user to use widely available ``jumper wires''.
\begin{figure}[h]
\centering
@ -51,6 +43,18 @@ A restart is required, in all cases, for the boot jumper changes to take effect.
\caption[The GEX Hub module]{\label{fig:gexhub} Two revisions of the GEX Hub module, rev. 2 shown with the boot jumper and one flat cable.}
\end{figure}
\subsection{GEX Hub Errata}
The first revision of the Hub board (\cref{fig:gexhub1}) proved functional and helped us validate the power supply design and test the firmware, but contained one layout error that had to be manually fixed---the boot jumper and the programming header footprints, on the left side of the board, had too fine pitch and could not be populated.
An updated revision 2 of the board (\cref{fig:gexhub2}), manufactured together with the GEX Zero \glspl{PCB} (\cref{sec:gzero}), removes the two problematic footprints altogether; a reorganization in the \gls{GPIO} connectors allowed them to be moved together with the other pins.
The Boot jumper was meant to be closed during normal operation, to avoid it getting lost. Since revision 2 moved the boot pin into the top connector, this had to be changed; the jumper logic was inverted by changing its pull-up resistor to a pull-down. The bootloader is now activated by inserting a jumper into the connector, shorting the Boot pin (labeled ``B'') to the adjacent 3.3\,V pin.
A restart is required, in all cases, for the boot jumper changes to take effect. Revision 2 adds a flat reset button on the back side of the board for this purpose, making the firmware update process more straightforward.
@ -59,20 +63,18 @@ A restart is required, in all cases, for the boot jumper changes to take effect.
\caption[The GEX Zero module]{\label{fig:gexzcases}GEX Zero in the official Raspberry Pi Zero case and an aftermarket acrylic case}
\end{figure}
\section{GEX Zero}
Our desire to re-use the form factor of the Raspberry Pi (RPi) Zero to exploit the existing accessory market has been mentioned already in \cref{sec:formfactors}. It was brought to fruition with GEX Zero, the second realized GEX prototype. Its design involved several challenges given by constraints imposed by this form factor:
Our desire to re-use the form factor of the Raspberry Pi (RPi) Zero to exploit the existing accessory market has been mentioned already in \cref{sec:formfactors}. It was brought to fruition with GEX Zero, the second realized GEX prototype (\cref{fig:gexzcases}). Its design involved several challenges given by constraints imposed by this form factor:
\begin{itemize}
\item It must be a one-sided board, with no components on the bottom; this is needed for acrylic cases which sit flatly against the \gls{PCB}, with a cut-out for the pin header.
\item Buttons and the USB connector have to exactly align with connectors on the RPi Zero to fit the openings in its cases.
\item The board size is fixed, and rather small; we used only two layers to save production cost, but this proved a significant challenge when routing connections to the pin header.
\item To make use of the Raspberry Pi add-on boards, called HATs or pHATs, a particular organization of the pin header is required. We discuss this in more detail below.
\item It had to be a one-sided board, with no components on the bottom; this is needed for acrylic cases which sit flatly against the \gls{PCB}, with a cut-out for the pin header.
\item Buttons and the USB connector had to exactly align with connectors on the RPi Zero to fit the openings in its cases.
\item The board size was fixed, and rather small; we used only two layers to save production cost, but this proved a significant challenge when routing connections to the pin header.
\item To make use of the Raspberry Pi add-on boards, called HATs or pHATs, a particular organization of the pin header was required. We'll discuss this in more detail below.
\end{itemize}
\subsection{Pin Assignment}
Like our STM32 microcontroller, the Broadcom processor on the RPi multiplexes its \gls{GPIO} pins with alternate functions, and, likewise, each function is available only on a small selection of pins. The usual alternate function assignments of the RPi \gls{GPIO} header can be found in~\cite{piheader} and~\cite{piheaderxyz}, and are reproduced in \cref{tbl:pi_assignmenets}.
Like our STM32 microcontroller, the Broadcom processor on the RPi multiplexes its \gls{GPIO} pins with alternate functions, and, likewise, each function is available only on a small selection of pins. The usual alternate function assignments of the RPi \gls{GPIO} header can be found in~\cite{piheader} and~\cite{piheaderxyz}.
\begin{figure}[h]
\centering
@ -82,6 +84,7 @@ Like our STM32 microcontroller, the Broadcom processor on the RPi multiplexes it
\caption[GEX Zero back side]{\label{fig:gexz}Pin assignment diagram on the back side of GEX Zero}
\end{figure}
\iffalse
{
\def\ptcw{.07\textwidth}
\def\rpnl{\newline\footnotesize}
@ -240,77 +243,77 @@ Like our STM32 microcontroller, the Broadcom processor on the RPi multiplexes it
\caption[Raspberry Pi GPIO header]{\label{tbl:pi_assignmenets}Raspberry Pi GPIO header (split into two lines), top view of the board, oriented with the USB connectors facing away from the user. ``$\ast$''~marks pins without important alternate functions.}
\end{table}
}
The GEX Zero pin header's alternate functions should match those on the RPi Zero header, so that the existing add-on boards can be used without modifications. By inspecting the alternate function tables in the STM32F072 datasheet~\cite{f072-ds}, we found a layout that fulfills this requirement almost perfectly. The final assignment is shown in \cref{tbl:gz_rpi_compare}, and the full schematic diagram is attached in \hyperref[apx:gex_zero]{Appendix B}.
\gls{GPIO} ports A and B are fully exposed in the header, with the exception of pins PA11 and PA12 that are routed to the USB connector. The remaining positions were filled pith pins from port C. The omitted ``ID \IIC'' port on pins 27 and 28 is used by the RPi Zero to read configuration from an EEPROM chip on some add-on boards. As this is the only use of the \IIC port, its lack is not a big limitation.
The GEX Zero pin header's alternate functions had to match those on the RPi Zero header, so that the existing add-on boards can be used without modifications. By inspecting the alternate function tables in the STM32F072 datasheet~\cite{f072-ds}, we found a layout that fulfills this requirement almost perfectly. The final assignment is shown in \cref{tbl:gz_rpi_compare}, and the full schematic diagram is attached in \hyperref[apx:gex_zero]{Appendix B}.
\caption[Comparison of the RPI Zero and GEX Zero GPIO headers]{\label{tbl:gz_rpi_compare}
Comparison of the RPI Zero and GEX Zero GPIO header pin assignments. Names in parentheses represent STM32F072 alternate functions (e.g., MISO1 is the MISO pin of the SPI peripheral 1). ``$\ast$''~marks pins without important alternate functions that could be assigned arbitrarily in the GEX Zero header. All power pins are identical in both headers.
Comparison of the RPi Zero and GEX Zero GPIO header pin assignments. Names in parentheses represent STM32F072 alternate functions (e.g., MISO1 is MISO of the first SPI peripheral). ``$\ast$''~marks pins without important alternate functions that could be assigned arbitrarily in the GEX Zero header. All power pins are identical in both headers.
}
\end{table}
\gls{GPIO} ports A and B are fully exposed in the header, with the exception of pins PA11 and PA12 that are routed to the USB connector. The remaining positions were filled pith pins from port C. The omitted ``ID \IIC'' port on pins 27 and 28 is used by the RPi Zero to read configuration from an EEPROM chip on some add-on boards. As this is the only use of the \IIC port, its lack is not a big limitation.
\section{GEX Zero Errata}
Unfortunately, neither the GEX Zero \gls{PCB} was flawless in the first revision. The errors are minor and will not interfere much in the usage of the module. Nonetheless, they should be corrected in the next revision.
Unfortunately, neither the GEX Zero \gls{PCB} was flawless in the first revision. The errors are minor and will not interfere much in the usage of the module. Nonetheless, they should be corrected in the next revision:
\begin{itemize}[itemsep=0pt]
\item The \IIC pull-up resistor R8 is connected to PA8 instead of PB7. This can be fixed by cutting the trace near the \gls{GPIO} header and rewiring it, or using an external 1.8\,k$\Omega$ pull-up resistor on PB7, when the \IIC connection is required.
@ -319,7 +322,7 @@ Unfortunately, neither the GEX Zero \gls{PCB} was flawless in the first revision
\section{Wireless Gateway}\label{sec:rfgateway}
The wireless gateway was designed as a ``\gls{USB} dongle'', using the \gls{USB} type A connector (\cref{fig:gwxgw}). It is fitted with a STM32F103 microcontroller, selected for its low cost and availability in small packages (in this case LQFP48). The nRF24L01+ module is partly sticking outside the board outline, allowing the \gls{PCB} to be smaller (and thus cheaper to manufacture), while reducing interference between components and copper plating on the board and the antenna. The schematic diagram of the wireless gateway is attached in \hyperref[apx:gex_wgw]{Appendix C}.
The wireless gateway was designed as a ``\gls{USB} dongle'', using the \gls{USB} type A connector (\cref{fig:gwxgw}). It is fitted with an STM32F103 microcontroller, selected for its low cost and availability in small packages (in this case LQFP48). The nRF24L01+ module is partly sticking outside the board outline, allowing the \gls{PCB} to be smaller (and thus cheaper to manufacture), while reducing interference between components and copper plating on the board and the antenna. The schematic diagram of the wireless gateway is attached in \hyperref[apx:gex_wgw]{Appendix C}.
Beyond the use with GEX, the gateway is a versatile tool which could be programmed with a different firmware and serve other purposes, e.g., as a wireless connection between two computers, to scan the radio spectrum for interference in order to find a clear channel, or to communicate with other devices that use the nRF24L01+ transceiver. The chosen microcontroller, unfortunately, does not include a USB bootloader, so a SWD programmer is required to change the firmware; SWD is routed to the pin header next to the wireless module.
@ -95,7 +95,7 @@ The bus supports multi-master operation, which leads to the problem of collision
\section{1-Wire}\label{sec:theory_1wire}
The 1-Wire bus, developed by Dallas Semiconductor (acquired by Maxim Integrated), uses a single, bi-directional data line, which can also power the slave devices in a \textit{parasitic mode}, reducing the number of required wires to just two (compare with 3 in \gls{I2C} and 5 in \gls{SPI}, all including \gls{GND}). The parasitic operation is possible thanks to the data line resting at a high logic level most of the time, charging an internal capacitor.
The 1-Wire bus, developed by Dallas Semiconductor (acquired by Maxim Integrated), uses a single, bi-directional data line (\cref{fig:1w_topology}), which can also power the slave devices in a \textit{parasitic mode}, reducing the number of required wires to just two (compare with 3 in \gls{I2C} and 5 in \gls{SPI}, all including \gls{GND}). The parasitic operation is possible thanks to the data line resting at a high logic level most of the time, charging an internal capacitor.
1-Wire uses an open-drain connection for the data line, similar to \gls{I2C}, though the protocol demands it to be connected directly to V$_dd$ in some places when the parasitic mode is used; this is accomplished using an external transistor, or by reconfiguring the GPIO pin as output and setting it to 1, provided the microcontroller is able to supply a sufficient current.
@ -130,17 +130,25 @@ Since 1-Wire is a proprietary protocol, there is a much smaller choice of availa
\section{NeoPixel}\label{sec:theory_neo}
NeoPixel is a marketing name of the \textbf{WS2812} and compatible intelligent \gls{LED} drivers that are commonly used in ``addressable \gls{LED} strips''. Additional technical details about the chips and their protocol may be found in the WS2812B datasheet~\cite{neopixel-ds}. These chips include the control logic, PWM drivers and the \gls{LED} diodes all in one 5$\times$5\,mm SMD package.
NeoPixel is a marketing name of the \textbf{WS2812} and compatible intelligent \gls{LED} drivers that are commonly used in ``addressable \gls{LED} strips'' (\cref{fig:neopic}). These chips include the control logic, PWM drivers and the \gls{LED} diodes all in one 5$\times$5\,mm SMD package.
The NeoPixel protocol is unidirectional, using only one data pin. The \gls{LED} drivers are chained together. Ones and zeros are encoded by pulses of a defined length on the data pin; after the color data was loaded into the \gls{LED} string, a longer ``reset'' pulse (low level) is issued by the bus master and the set colors are displayed. The timing constraints are listed in \cref{fig:ws2812_dia}.
The NeoPixel timing is sensitive to pulse length accuracy; a deviation from the specified timing may cause the data to be misinterpreted by the drivers. Some ways to implement the timing use hardware timers or the \gls{I2S} peripheral. An easier method that does not require any additional hardware resources beyond the \gls{GPIO} pin is to implement the timing using delay loops in the firmware; care must be taken to disable interrupts in the sensitive parts of the timing; it may be advantageous to implement it in assembly for a tighter control.
@ -139,7 +139,7 @@ Capacitive sensing is a sequential process described in the following steps:
\begin{enumerate}
\item The sampling capacitor is discharged by connecting its free end to \gls{GND}.
\item The sensing pad is connected to V$_\mathrm{dd}$ (+3.3\,V) and, acting as a capacitor, charged to this voltage. It stores a small amount of charge, depending on its capacitance---this is the variable property we are trying to measure.
\item The sensing pad is connected to V$_\mathrm{DD}$ (+3.3\,V) and, acting as a capacitor, charged to this voltage. It stores a small amount of charge, depending on its capacitance---this is the variable property we are trying to measure.
\item The free terminals of the two capacitors (the sensing pad and the sampling capacitor) are connected together and their voltages reach an equilibrium as a portion of the stored charge leaves the sensing pad and flows into the bigger capacitor.
\item The steps (2) and (3) are repeated until the sampling capacitor's voltage exceeds a fixed threshold (set to a half of the supply voltage). The number of cycles needed to charge the sampling capacitor corresponds to the capacitance of the sensing pad.
Prototyping, design evaluation, and the measurement of physical properties in experiments make a daily occurrence in the engineering praxis. Those tasks often involve the generation and sampling of electrical signals coming to and from sensors, actuators, and other circuitry.
Recently, a wide range of intelligent sensors became available thanks to the drive to miniaturization in the consumer electronics industry. Those devices often provide sufficient accuracy and precision while keeping the circuit complexity and cost low. In contrast to analog sensors, here the signal conditioning and processing circuits are built into the sensor itself, and we access it using a digital connection.
Recently, a wide range of intelligent sensors became available thanks to the drive to miniaturization in the consumer electronics industry (\cref{fig:some_sensors}). Those devices often provide sufficient accuracy and precision while keeping the circuit complexity and cost low. In contrast to analog sensors, here the signal conditioning and processing circuits are built into the sensor itself, and we access it using a digital connection.
\caption[A collection of intelligent sensors and devices]{A collection of intelligent sensors and devices, most on breadboard adapters: (from the top left) a waveform generator, a gesture detector, a LoRa and two Bluetooth modules, an air quality and pressure sensor, a CO$_2$ sensor, a digital compass, an accelerometer, a GPS module, a camera, an ultrasonic range finder, a humidity sensor, a 1-Wire thermometer, a color detector, and an RGB LED strip}
\caption[A collection of intelligent sensors and devices]{\label{fig:some_sensors}A collection of intelligent sensors and devices, most on breadboard adapters: (from the top left) a waveform generator, a gesture detector, a LoRa and two Bluetooth modules, an air quality and pressure sensor, a CO$_2$ sensor, a digital compass, an accelerometer, a GPS module, a camera, an ultrasonic range finder, a humidity sensor, a 1-Wire thermometer, a color detector, and an RGB LED strip}
\end{figure}
If we wish to conduct experiments with those integrated modules, or just familiarize ourselves with a device before using it in a project, we need an easy way to interact with them. It would also be convenient to have direct access to low-level hardware, be it analog signal sampling, generation, or even just the access to logic inputs and outputs. However, advances in computer technology, namely the advent of the \gls{USB}, lead to the disappearance of low-level computer ports, such as the printer port (LPT), that would provide an easy way of doing so.
While the GEX firmware can be used with existing evaluation boards from ST Microelectronics (see \cref{fig:discovery} for an example of one such board), we wish to design and realize a few custom hardware prototypes that will be smaller and more convenient to use.
While the GEX firmware can be used with existing evaluation boards from ST Microelectronics (\cref{fig:discovery}), we wish to design and realize a few custom hardware prototypes that will be smaller and more convenient to use.
Three possible form factors are drawn in \cref{fig:ff_sketches}. The use of a common connector layout and pin assignments, here Arduino and Raspberry Pi, makes it possible to reuse add-on boards from those platforms. When we copy the physical form factor of another product, in this example the Raspberry Pi Zero, we can further take advantage of existing enclosures designed for it.
\caption{\label{fig:repo_structure}The general structure of the source code repository}
\caption{\label{fig:repo_structure}General structure of the source code repository}
\end{wrapfigure}
Understanding the GEX source code layout is important before attempting to implement any changes or to port it to a different microcontroller type. The directory layout is shown in \cref{fig:repo_structure}.
The analog/digital converter unit is one of the most complicated and powerful units implemented in the project. The unit can measure the voltage on an input pin, either as its immediate value, or averaged with exponential forgetting. Isochronous sampling is available as well: it is possible to capture a fixed-length block of data on demand, or as a response to a triggering condition on any of the enabled input pins. The \gls{ADC} must continuously sample the inputs to make the averaging and level based triggering possible; as a consequence, a pre-trigger buffer is available that can be read together with the block of samples following a trigger. The \gls{ADC} unit can also be switched to a continuous streaming mode, a block capture which continues indefinitely, until the host decides to stop the stream.
The analog/digital converter unit is one of the most complicated and powerful units implemented in the project.
It is possible to activate any number of the 16 analog inputs of the \gls{ADC} peripheral simultaneously, together with the internal input channels. The maximum continuous sampling frequency, which reaches 70\,ksps with one channel, lowers with an increasing number of enabled channels, as the amount of data to transfer host increases. Those high speeds are achievable in shorter block captures, taking advantage of the (configurable) data buffer. A streamed or too long block capture may be aborted after the buffer is exhausted.
The unit can measure the voltage on an input pin, either as its immediate value, or averaged with exponential forgetting. The smoothing formula is ($y$--averaged output, $t$--sample number, $k$--smoothing factor, $u$--raw measured value):
\todo[inline]{add a diagram}
\begin{equation}
y[t] = (1-k)\cdot y[t-1] + k\cdot u[t]
\end{equation}
Isochronous sampling is available as well: it is possible to capture a fixed-length block of data on demand, or as a response to a triggering condition on any of the enabled input pins. The \gls{ADC} must continuously sample the inputs to make the averaging and level based triggering possible, which is implemented using \gls{DMA}; as a consequence, a pre-trigger buffer is available that can be read together with the block of samples following a trigger (\cref{fig:adc_dma}). The \gls{ADC} unit can also be switched to a continuous streaming mode, a block capture which continues indefinitely, until the host decides to stop the stream.
It is possible to activate any number of the 16 analog inputs of the \gls{ADC} peripheral simultaneously, together with the internal input channels. The maximum continuous sampling frequency, which reaches 70\,ksps with one channel, lowers with an increasing number of enabled channels, as the amount of data to transfer host increases. Those high speeds are achievable in shorter block captures, taking advantage of the (configurable) data buffer. An ongoing capture may be terminated by the unit after the buffer is exhausted.
\begin{figure}[h]
\centering
\includegraphics[scale=1]{img/adc-dma-buf.pdf}
\caption{\label{fig:adc_dma}Principle of DMA-based ADC sampling. The buffer is continually filled with new samples; when the triggering condition is hit, the historical records from the buffer are sent as a pre-trigger buffer, and a block capture begins. The following samples are sent to the host when either half of the buffer is filled, or the required number of samples have been sent. The sampling never stops, ensuring a pre-trigger buffer is always ready.}
@ -4,9 +4,13 @@ The \gls{USART} unit provides access to one of the microcontroller's \gls{USART}
Most \gls{USART} parameters available in the hardware peripheral's configuration registers can be adjusted to match the application's needs. The peripheral is capable of driving RS-485 transceivers, using the \gls{DE} output for switching between reception and transmission.
The unit implements asynchronous reception and transmission with \gls{DMA} and a circular buffer. Received data is sent to the host in asynchronous events when a half of the buffer is filled, or after a fixed timeout from the last received byte. The write access is, likewise, implemented using \gls{DMA}.
The unit implements asynchronous reception and transmission with \gls{DMA} and a circular buffer (\cref{fig:uart_rx_dma}). Received data is sent to the host in asynchronous events when a half of the buffer is filled, or after a fixed timeout from the last received byte. The write access is, likewise, implemented using a \gls{DMA} buffer.
\todo[inline]{add a diagram of the dma-based reception}
\begin{figure}[h]
\centering
\includegraphics[scale=1]{img/uart-dma.pdf}
\caption{\label{fig:uart_rx_dma}Principle of DMA-based UART reception. Interrupt is generated in the half and at the end of the buffer, at which point the write pointer wraps back to the beginning.}
@ -10,11 +10,11 @@ This chapter presents an overview of the \acrfull{USB} Full Speed interface, wit
\caption[USB hierarchical structure]{\label{fig:usb_hierarchy}The hierarchical structure of the USB bus}
\end{figure}
\gls{USB} is a hierarchical bus with a single master (\textit{host}) and multiple slave devices. A \gls{USB} device that provides functionality to the host is called a \textit{function}~\cite{usb-function}.
\gls{USB} is a hierarchical bus (\cref{fig:usb_hierarchy}) with a single master (\textit{host}) and multiple slave devices. A \gls{USB} device that provides functionality to the host is called a \textit{function}~\cite{usb-function}.
\subsection{Pipes and Endpoints}
Communication between the host and a function is organized into virtual channels called \textit{pipes} connecting to the device's \textit{endpoints}, identified by endpoint numbers.
Communication between the host and a function is organized into virtual channels called \textit{pipes} connecting to the device's \textit{endpoints}, identified by endpoint numbers. Pipes and endpoints are a high level abstraction of the connection between the host and a device (\cref{fig:usb_logical}).
@ -85,7 +85,7 @@ A pair of these radio modules can form a bidirectional data connection, function
\vspace{-1em}
\centering
\includegraphics[scale=0.9]{img/rf-gw.pdf}
\caption{A block diagram of the wireless connection}
\caption{Wireless connection block diagram}
\end{wrapfigure}
The gateway presents itself to the host as a \gls{CDCACM} device, much like the GEX modules themselves (here called \textit{nodes}) when connected over \gls{USB}. However, the standard GEX communication protocol cannot be used directly, as the gateway itself needs to be managed through the interface, and it can connect to more than one GEX module at once, necessitating an addressing scheme. This problem could be solved by adding a side channel, additional \gls{USB} endpoints, to interact with the gateway itself; that option was not explored further, but it is clear that it would compromise our ability to use the simple virtual COM port \gls{USB} driver.
@ -97,7 +97,7 @@ The gateway has a 4-byte \textit{network ID}, a number derived from the \gls{MCU
The gateway protocol, when used to communicate with a node, encapsulates the raw binary data sent to or from connected nodes; the wrapped TinyFrame protocol remains unchanged.
All messages sent to or from the gateway are a multiple of 64 bytes long, padded with zeros if shorter. A message starts with a control byte determining its type, as summarized in the following table listing the structure of all supported messages.
All messages sent to or from the gateway are a multiple of 64 bytes long, padded with zeros if shorter. A message starts with a control byte determining its type, as summarized in the following table, listing the structure of all supported messages.