{"id":10755,"date":"2017-03-23T16:24:18","date_gmt":"2017-03-23T15:24:18","guid":{"rendered":"https:\/\/sysprogs.com\/w\/?p=10755"},"modified":"2017-03-23T16:24:18","modified_gmt":"2017-03-23T15:24:18","slug":"how-we-turned-8-popular-stm32-boards-into-powerful-logic-analyzers","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/w\/how-we-turned-8-popular-stm32-boards-into-powerful-logic-analyzers\/","title":{"rendered":"How We Turned 8 Popular STM32 Boards into Powerful Logic Analyzers"},"content":{"rendered":"<p>The idea of\u00a0making a &#8220;soft logic analyzer&#8221; that will run on top of\u00a0popular prototyping boards\u00a0has been crossing my mind since\u00a0we first got acquainted with the STM32 Discovery and Nucleo\u00a0boards. The STM32 GPIO is blazingly fast and the built-in DMA controller\u00a0looks powerful enough to handle high bandwidths. So having that in mind, we spent several months\u00a0perfecting both software and firmware side and here is what we got in the end.<\/p>\n<h2>Capturing the signals<\/h2>\n<p>The main challenge when using a\u00a0microcontroller like STM32 as a core of a logic\u00a0analyzer is dealing with sampling irregularities. Unlike FPGA-based analyzers, the\u00a0microcontroller has to\u00a0share\u00a0the same resources to load instructions from memory, read\/write the program state and capture\u00a0the\u00a0external inputs from the GPIO.\u00a0Given that, it could be tricky\u00a0for the microcontroller to keep up the sampling\u00a0frequency perfectly straight and could make the capture\u00a0very innaccurate. To quantify that, I designed a simple test. The on-board timer was configured to generates series of signals with different characteristics and the DMA was used to record their parameters and compare them with the\u00a0expected ones:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10757\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing-1-1024x300.png\" alt=\"timing\" width=\"474\" height=\"139\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing-1-1024x300.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing-1-300x88.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing-1-768x225.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing-1.png 1121w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/timing.png\">T<\/a>he\u00a0general idea is that\u00a0if a test signal is sampled with regular intervals (A), it will always appear as the same repeating sequence of zeroes and ones, while if the\u00a0sampling\u00a0becomes sporadic (B), it will quickly introduce observable distortions. Having this methodology mind, we conducted several tests and\u00a0discovered a few interesting results:<\/p>\n<ul>\n<li>The STM32 DMA\u00a0was unexpectedly fast. It can reliably read GPIO inputs\u00a0every 3th or 4th clock cycle on many devices.\u00a0For fast boards like STM32F746-Nucleo this means sampling frequencies up to 72 MHz.<\/li>\n<li>If the CPU is properly\u00a0stalled for the duration of the sampling,\u00a0it is\u00a0extremely precise given that it is configured properly.<\/li>\n<\/ul>\n<h2>Compressing the signals<\/h2>\n<p>Sampling the inputs at the maximum speed\u00a0imposes an important limitation. Once the on-board RAM is filled with the\u00a0data, the sampling needs to be stopped to transfer the data to the computer. While capturing ~1ms at 72MHz could be sufficient for fast and\u00a0periodic signals, it could be hard to catch\u00a0the interesting part if the signal is sparse. To support that, we experimented with doing double-buffered compression: while the DMA was filling\u00a0half of the buffer with raw samples, the CPU was reading through the other half\u00a0and doing a very basic compression.<\/p>\n<p>This\u00a0brought back the challenge of uniform sampling:\u00a0if the CPU was not just waiting, but actively accessing the memory, the DMA controller had\u00a0to compete with the CPU for the RAM access and could not keep up the sampling\u00a0uniform. The\u00a0key to resolving this was to optimize the\u00a0memory access patterns of the compression algorithm. Having them spaced far enough apart and lowering the sampling frequency\u00a0to allow the CPU to keep up brought back very precise sampling at a rate of 6.2-8.4MHz for most boards.<\/p>\n<h2>Something in-between<\/h2>\n<p>Using the CPU to compress the signal in real time took a heavy toll on the sampling frequency, so we decided to add a mode\u00a0that will combine the fast sampling frequency and the ability to\u00a0capture the interesting\u00a0part of the signal. The classical triggered mode (capturing the data around a chosen event) solved the problem but\u00a0presented new challenges:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/trigger.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10758\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/trigger.png\" alt=\"trigger\" width=\"706\" height=\"629\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/trigger.png 706w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/trigger-300x267.png 300w\" sizes=\"(max-width: 706px) 100vw, 706px\" \/><\/a><\/p>\n<p>Checking for the trigger would mean not stalling the CPU while the capture was active, and that\u00a0undoubtedly\u00a0disrupted the\u00a0uniform capture pattern. The solution here was to use the external interrupt controller and carefully timing\u00a0the memory access patterns of the interrupt-related code to avoid interference with the sampling. The\u00a0result was worth the effort:\u00a0for most of the boards the triggered mode was significantly faster than the compressed mode. We also added trigger support for the compressed mode\u00a0that\u00a0works with slightly lower sampling frequencies.<\/p>\n<h2>Continuous mode<\/h2>\n<p>Being inspired by the sampling quality in the compressed mode,\u00a0we\u00a0decided to try another idea: how far can we go if we\u00a0setup 3 processes in parallel: sampling the data, compressing it and transferring the\u00a0compressed part to the\u00a0computer non-stop? The result was surprisingly good: lowering the sampling frequency to ~6MHz for the fastest boards\u00a0and playing around with memory access patterns got precise non-stop sampling, so we could record hours of non-stop activity on slower buses like I2C\u00a0not being limited by the\u00a0on-chip RAM anymore.<\/p>\n<h2>Usability<\/h2>\n<p>Having the\u00a0capture modes figured out and the firmware optimized, we faced the final\u00a0challenge: how to make a logic analyzer software that will be intuitive, easy to use and scalable at the same time. So we created an tool\u00a0for viewing the captured signals and started analyzing some real-world hardware interactions and\u00a0figuring out how to make\u00a0the process as user-friendly as possible. So here&#8217;s what we have found:<\/p>\n<h3>Setup and Live Streaming<\/h3>\n<p>We wanted to make\u00a0the process of starting the analyzer and beginning to view signals as easy as possible. If you are concerned why your SPI is not working properly, you probably don&#8217;t\u00a0want to be distracted by downloading the\u00a0board schematics to figure out how to connect it, or\u00a0seeing why the ST-Link driver is not\u00a0being recognized. So we designed the\u00a0viewer application to be as straight-forward as possible.\u00a0So after the board is connected and selected in the list, it shows the picture of the board\u00a0and\u00a0highlights the signals that can be used as inputs:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10760\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig-1024x732.png\" alt=\"sig\" width=\"474\" height=\"339\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig-1024x732.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig-300x215.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig-768x549.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig.png 1151w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<p>Clicking at\u00a0the signals immediately adds them to the live view, beginning to show the\u00a0current signal. The frequency is chosen automatically\u00a0(unless set manually) by first trying to sample the signal as fast as possible, and\u00a0if it looks slow enough, retrying in the compressed mode.<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/sig-1.png\"><br \/>\n<\/a><\/p>\n<h3>Viewing Data<\/h3>\n<p>One of the first\u00a0important things we figured out was\u00a0the\u00a0importance of easy signal labeling.\u00a0Having to keeping mind that PB0 is the red cable connected to the SCK signal does not make things easy. So we have added an intuitive way of specifying\u00a0the signal colors and labels:<br \/>\n<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/colors.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10762\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/colors.png\" alt=\"colors\" width=\"718\" height=\"253\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/colors.png 718w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/colors-300x106.png 300w\" sizes=\"(max-width: 718px) 100vw, 718px\" \/><\/a><\/p>\n<p>We also\u00a0added a &#8220;trigger&#8221; column that allows enabling and disabling triggers by just clicking on the corresponding signal as a quick alternative to going deep into capture settings.<\/p>\n<p>While trying to\u00a0explore several real-world bus interactions, we quickly\u00a0found that\u00a0while the clocked\u00a0buses are easy to observe, counting the pulses and\u00a0translating the signal view to ones and zeroes is\u00a0annoying, so we added a special\u00a0clocked view mode that is activated by selecting a signal that looks like a clock and clicking on the &#8220;set as primary clock&#8221; button:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/clk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10763\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/clk-1024x437.png\" alt=\"clk\" width=\"474\" height=\"202\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/clk-1024x437.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/clk-300x128.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/clk-768x328.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/clk.png 1169w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<p>This will\u00a0split the selection into intervals\u00a0aligned at the clock edges and will automatically\u00a0annotate all other signals with &#8216;0&#8217;, &#8216;1&#8217; or &#8216;X&#8217; depending on their value during that clock cycle:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cycles.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10764\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cycles-1024x437.png\" alt=\"cycles\" width=\"474\" height=\"202\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cycles-1024x437.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cycles-300x128.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cycles-768x328.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cycles.png 1169w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<p>We also added a similar mode for the asynchronous signals where the selection is split based on time instead of clock edges.<\/p>\n<h3>Notes<\/h3>\n<p>Another time-consuming process while trying to understand some complex bus interactions was to keep track when one of the transaction ends and another part begins. If the captured frame contained several similar packets,\u00a0navigating between them\u00a0and keeping in mind where each part starts could be tricky. So we added a mechanism for annotating arbitrary points in time with\u00a0color-coded labels and arbitrary descriptions:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/notes-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10765\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/notes-1-1024x437.png\" alt=\"notes\" width=\"474\" height=\"202\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/notes-1-1024x437.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/notes-1-300x128.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/notes-1-768x328.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/notes-1.png 1169w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<p>Notes can also be used to\u00a0quickly navigate between events in a large capture file:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/nav.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10766\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/nav.png\" alt=\"nav\" width=\"472\" height=\"245\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/nav.png 472w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/nav-300x156.png 300w\" sizes=\"(max-width: 472px) 100vw, 472px\" \/><\/a><\/p>\n<h3>Protocol Analyzers<\/h3>\n<p>We have also added automatic\u00a0analyzers for commonly used protocols like UART, SPI, I2S and I2C. Dragging them to the\u00a0protocol analyzer panel and\u00a0connecting the inputs\u00a0automatically replaces the raw\u00a0view with a higher-level\u00a0view\u00a0showing the decoded data:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10768\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1-1024x230.png\" alt=\"proto1\" width=\"474\" height=\"106\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1-1024x230.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1-300x67.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1-768x172.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1-1038x235.png 1038w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto1.png 1048w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a>Playing around with the protocol analyzers, we quickly discovered another challenge:\u00a0displaying the decoded bytes in place of the original signals can only show a small amount of text before it gets zoomed out too much and\u00a0decoding everything as text\u00a0makes it hard to see the timings and values of other signals.<\/p>\n<p>So we have combined the best of both approaches by adding the &#8220;text view&#8221; pane:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10767\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto-1024x721.png\" alt=\"proto\" width=\"474\" height=\"334\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto-1024x721.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto-300x211.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto-768x541.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/proto.png 1169w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/p>\n<p>The pane shows all the decoded output from the entire frame (or file), allows browsing through it and doing full-text searches and it&#8217;s automatically synchronized with the\u00a0timing view: selecting some characters in the text view will automatically\u00a0select the corresponding time range and selecting a\u00a0time range will highlight the characters belonging to it.<\/p>\n<h3>Continuous Capture Files<\/h3>\n<p>Being able to capture data continuously at ~600KB\/s was great, but it\u00a0presented\u00a0another challenge. Several minutes of capturing can produce hundreds of megabytes of data and\u00a0instantly\u00a0navigating\u00a0through it, zooming in and out, \u00a0especially while the\u00a0recording is still\u00a0in progress, is tricky. So we designed a special capture file format using a technique\u00a0roughly resembling image\u00a0thumbnails that allows\u00a0looking (and searching) through a huge file while it&#8217;s being captured,\u00a0instantly opening and analyzing large files and\u00a0remembering notes and protocol analyzer settings when you reopen the file later:\u00a0<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cont.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10769\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cont-1024x721.png\" alt=\"cont\" width=\"474\" height=\"334\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cont-1024x721.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cont-300x211.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cont-768x541.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2017\/03\/cont.png 1169w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<h3>Try it out<\/h3>\n<p>After months of\u00a0resolving hardware and software challenges and tweaking the usability, <a href=\"http:\/\/analyzer2go.com\/\">Analyzer2Go<\/a> was born.\u00a0 It currently supports <a href=\"http:\/\/analyzer2go.com\/boards\">8\u00a0popular boards<\/a> from ST and runs on Windows.\u00a0Support for more boards and other operating systems is coming soon.<\/p>\n<h3>The next step<\/h3>\n<p>The hardware is capable. The software is mighty. So go ahead and <a href=\"mailto:sysprogs@sysprogs.com\">send us<\/a> your feedback and suggestions for new boards to support and we will turn your board into a\u00a0reliable and\u00a0easy-to-use logic analyzer next!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The idea of\u00a0making a &#8220;soft logic analyzer&#8221; that will run on top of\u00a0popular prototyping boards\u00a0has been crossing my mind since\u00a0we first got acquainted with the STM32 Discovery and Nucleo\u00a0boards. The STM32 GPIO is blazingly fast and the built-in DMA controller\u00a0looks powerful enough to handle high bandwidths. So having that in mind, we spent several months\u00a0perfecting &hellip; <a href=\"https:\/\/sysprogs.com\/w\/how-we-turned-8-popular-stm32-boards-into-powerful-logic-analyzers\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">How We Turned 8 Popular STM32 Boards into Powerful Logic Analyzers<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/10755"}],"collection":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/comments?post=10755"}],"version-history":[{"count":3,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/10755\/revisions"}],"predecessor-version":[{"id":10771,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/10755\/revisions\/10771"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/media?parent=10755"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/categories?post=10755"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/tags?post=10755"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}