XESS Corp.http://www.xess.com/blog/feeds/atom/2016-09-09T14:04:46+00:00Are You In An Abusive Relationship With Your Schematic Editor?2016-09-09T14:04:46+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/are-you-in-an-abusive-relationship-with-your-schematic-editor/<img src="/static/media/uploads/blog/devbisme/2016-09-08/abusive_schematic.jpg" alt="Abusive Schematic based on Scream by Paulius Lizdenis" class="thumbnail-it float-it-left"/>
Having hung out on [forum.kicad.info](https://forum.kicad.info/) for over a year, I'm quite aware of the problems engineers have with their CAD tools.
In particular, I hear a lot of moaning and groaning about *schematic editors*.
(For the record, I know my graphic to the left shows a PCB, not a schematic. What can I say? *Art trumps accuracy.*)
For all the complaints, we don't seem to change: resignedly shuffling off to use the same tools that mistreated us the day before.
And I thought: "Well, that's pretty dysfunctional!"
So I googled "are you in an abusive relationship" and my computer came back with 3,830,000 hits.
(Luckily, they were all the same basic article, just with different pictures.)
I glanced through a few lists of characteristics for these relationships and I thought they seemed kind of familiar.
Then I picked a prototypical example and repurposed it for schematic designers.
Take a look and see how many of these excuses you've made in the past month...
##Take the Test!
###___ *It's Normal, Really.*
Everyone who uses schematic editors has problems with them.
Using a DOS program that was ported to linux and then back to Windows 10, that's just part of the job.
*No biggie!*
###___ *It's My Fault: I Made It Do That.*
It wouldn't have core dumped and destroyed three hours of work
if I hadn't tried to merge two named nets.
*My bad!*
###___ *It's Just the Way It Works. It's Not Malicious.*
Sure, the pins have to be *exactly* on the grid (an *imperial* grid, mind you, not metric)
or else the wires won't connect (even though they *look* connected).
That's just the way it works.
It's a pain, but it's not *intentional*. I mean, I guess...
###___ *It's Just Its Weird Way of Showing It Loves Me.*
Yes, it makes me open two instances of the editor outside the normal
design flow in order to copy-and-paste stuff from one schematic to another.
But knowing how to do that makes me less replaceable.
*My schematic editor is helping me keep my job!*
###___ *I'm Not Perfect, Either.*
I'll admit that - from time to time - I call my schematic editor "old poopy doo-doo head".
Perhaps if I were more understanding it wouldn't freeze while loading libraries from Github.
###___ *I Can Take It.*
I'm an engineer: I've been shit on by the worst of the worst!
(And, to be honest, pretty much everybody else.)
So there's no way this schematic editor can break me.
What? You say I have to route a 128-wire bus from twenty levels deep in the hierarchy?
*Bring it on!*
###___ *I Like Being Treated This Way.*
Is that a global bus? A hierarchical connection? A local net? Hell, I don't know!
But figuring out puzzles like that is the best part of my day.
###___ *It Could Be Worse*
Even the simplest operation takes several point-and-click operations with the mouse combined with pressing obscure
hotkeys, but at least the editor doesn't snap off my fingers with some crazy
keyboard guillotine thingy last seen in a "Saw" movie.
Oh, wait, that's planned for the *next release?*
###___ *If I Just Stick It Out, Things Will Change.*
They're really trying to change and the next release will fix a lot of these issues.
I know they've said that before, but this time they mean it.
If I can just hold out, things will be better.
Except for the keyboard guillotine thingy: *that's gonna suck*.
## So, How'd You Do?
How many of those excuses did *you* check, and what does that mean?
Read on to find out...
### *Five or More...*
You're definitely ready to get out.
If there was a safe house, you'd be checking into it.
### *Two to Four...*
You recognize you have a problem, you're looking for something better, but
there doesn't seem to be a reasonable alternative.
### *Just One...*
You're throwing me a bone, right?
You really wanted to say "zero" but were afraid you'd be labeled as a GUI fanboy.
### *None. Not a Single One...*
Your are *so* deep in denial.
You're obviously involved with some Svengaliesk Rasputin of a schematic editor that has trapped you in a Stockholm Syndrome nightmare.
## What Now?
Have I taken you all this way, shown you that you have a problem, and then left you with no solution?
Would I do that?
Well, yeah, I probably would do something like that. *But not this time!*
I've suffered from the same problems with schematics as everyone else, but I decided to do something about it.
Taking my cue from things like [PHDL](https://sourceforge.net/p/phdl/wiki/Home/) and
[MyHDL](http://myhdl.org/),
I created the
[SKiDL module](https://xesscorp.github.io/skidl/docs/_build/singlehtml/index.html)
that turns Python into a language for building schematics.
It changes circuit design from a fiddly drawing exercise into a programming task.
Why is that important?
Because for decades, coders have been successfully building programs a lot larger and more complicated
than any schematic.
SKiDL acts as a bridge that allows the methods and tools of programmers to be applied to the problem of electronic design because it:
* Has a powerful, flexible syntax (because it *is* Python).
* Permits compact descriptions of electronic circuits (think about not having to trace signals through a multi-page schematic).
* Allows textual descriptions of electronic circuits (think about using diff and git for circuits).
* Enables global refactoring of a design (and eliminates the need to point-and-click on every ... single ... component).
* Performs electrical rules checking (ERC) for common mistakes (e.g., unconnected device I/O pins).
* Supports linear / hierarchical / mixed descriptions of electronic systems.
* Fosters design reuse (think about using PyPi and Github to distribute electronic designs).
* Makes possible the creation of *smart circuit modules* whose behavior / structure are changed parametrically (think about filters whose component values are automatically adjusted based on your desired cutoff frequency).
* Can work with any ECAD tool (only two methods are needed: one for reading the part libraries and another for outputing the correct netlist format).
* Takes advantage of all the features and benefits of the Python ecosystem (because it *is* Python).
Getting started with SKiDL is easy.
If you already have Python on your system (either 2 or 3), then just use:
pip install skidl
and you're ready to go!
(Well, *almost* ready to go. Right now, SKiDL only supports [KiCad](http://kicad-pcb.org/), but I'm working on others.)
\[Credits: I used "Scream" by Paulius Lizdenis for my opening image and merged it with a picture of a PCB. Sorry I mangled your artwork, Paulius, but what can I say? *Marketing trumps art.*\]
Walk In, Walk Out2016-06-26T14:55:47+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/walk-in-walk-out/<p><img class="thumbnail-it float-it-left" src="http://www.30sleeps.com/images/tracks-in-the-desert.jpg">I wrote a blog post several years ago about <a href="/blog/my-first-kicad-board/">my first KiCad design</a>: an eight-channel analog-to-digital StickIt! board. While <a href="http://www.xess.com/blog/test-results-for-my-first-kicad-board/">testing it</a>, I discovered the signals in the analog channels could leak into one another if the signal drivers had too high an impedance. The design kind of languished after that.</p>
<p>But a few months ago as I was building an array of StickIt! boards for fabrication, I decided to resurrect the ADC board (now called the OctoADC). I modified the design so the ADC inputs would be driven by dual quad opamps (<a href="http://www.ti.com/lit/ds/symlink/tl971.pdf">TL974</a>) with low-impedance outputs to stop the signal leakage. Here's the modified schematic:</p>
<p><img alt="OctoAdc Board Schematic" src="/static/media/uploads/blog/devbisme/2016-06-22/octoadc_schematic.png"></p>
<p>Eleven copies of the PCB array containing the OctoADC (and six other designs) were fabricated by <a href="http://dirtypcbs.com">dirtypcbs.com</a> for $25.</p>
<p><img alt="StickIt Board Array" src="/static/media/uploads/blog/devbisme/2016-06-22/stickit-array.png"></p>
<p>Upon receiving the PCBs, I assembled an OctoADC board and ran a test where it samples three, low-resolution sine waves (4-5 bits).
These are the results I got:</p>
<p><img alt="Three Sampled Waveforms from OctoADC Board" src="/static/media/uploads/blog/devbisme/2016-06-22/vga_voltage_x3.png"></p>
<p><img alt="Single Sampled Waveform from OctoADC Board" src="/static/media/uploads/blog/devbisme/2016-06-22/vga_voltage_x1.png"></p>
<p>Yowsa! Definitely a turn for the worse!</p>
<p>By looking at the waveform for a single channel, it became apparent that the sampled waveform goes nuts when the input drops near ground. It turns out I had mistakenly assumed the TL974 could handle an input voltage near ground (which I used as the negative rail) because they were described as "rail-to-rail" opamps. However, that only applies to the <em>opamp output</em>; the input has to stay at least 1.15 V away from either rail. (Doh! I really should start reading these datasheets.)</p>
<p><img alt="Common-Mode Limits of the TL974 Opamp Inputs" src="/static/media/uploads/blog/devbisme/2016-06-22/input_limits.png"></p>
<p>So my opamps needed at least a -1.15 V supply, but there's not a negative supply on the board. I had walked myself into a real mess and now I was going to have to to walk myself out of it.</p>
<p>My first thought was to use an <a href="http://www.ti.com/lit/ds/symlink/lm2660.pdf">LM2660</a> to generate a negative supply. But that chip is relatively expensive and the datasheet recommends placing <em>another</em> regulator on the output of the LM2660 to clean-up the noise. That seemed like a lot of added circuitry and expense for what I needed, so I decided to look for more "creative" options.</p>
<p>Taking a look at my existing design, one resource I did have was four unused I/Os on the PMOD connector that can be driven by the FPGA. From my beginning circuits classes I knew I could generate a negative voltage by applying positive pulses to a combination of diodes and capacitors like the circuit shown below. To test the idea, I modeled the FPGA pin in LTspice as a pulsed 3.3V supply with a 70-ohm series resistance, and I represented the current draw of the opamp with a 1mA current source.</p>
<p><img alt="Negative Voltage Generator" src="/static/media/uploads/blog/devbisme/2016-06-22/voltage_inverter_single.png"></p>
<p>Simulation showed that, after an initial charging transient, pulsing the circuit with a 1 MHz square wave resulted in a stable negative voltage:</p>
<p><img alt="Negative Voltage Generator" src="/static/media/uploads/blog/devbisme/2016-06-22/voltage_inverter_output.png"></p>
<p>Due to their series resistance, the FPGA pins can't output an infinite amount of current. In combination with the current draw of the opamp, this limits the size of the negative voltage that can be generated. By varying the current source, I could plot the negative voltage that would result for various amounts of opamp supply current:</p>
<p><img alt="Negative Voltage Generator Output Current Versus Output Voltage" src="/static/media/uploads/blog/devbisme/2016-06-22/voltage_inverter_V_vs_I.png"></p>
<p>From the graph, it looks like I can draw no more than 6 mA from the negative supply before it fails to provide the -1.15 V the opamps need. The datasheet shows each opamp consumes 3.2 mA (worst case), so eight of them will require 25.6 mA. By combining four FPGA pins in parallel to decrease the equivalent series resistance, I thought I might be able to achieve that.</p>
<p>At this point, more accuracy was needed so I downloaded the <a href="http://www.ti.com/lit/zip/slom243">Spice model for a single TL972 opamp</a>. I placed the <code>TL972.lib</code> file in a local directory and used a <code>.lib</code> Spice directive to access it. I instantiated a single TL972 in a unity gain configuration with the non-inverting input driven by a 5 V, 10 KHz sine wave centered at 2.5 V. The positive rail of the opamp was fed by a 6.15 V source while the negative voltage generator feeds the negative rail.</p>
<p><img alt="Negative Voltage Generator" src="/static/media/uploads/blog/devbisme/2016-06-22/voltage_inverter_with_tl972.png"></p>
<p>A simulation showed the opamp was working correctly as its output (the blue trace) exactly matched the input sine wave (the green trace). The output was also able to get to ground without any distortion.</p>
<p><img alt="Input and Output Sine Waves" src="/static/media/uploads/blog/devbisme/2016-06-22/tl972-vin_and_vout.png"></p>
<p>In addition, the negative rail current (the red trace) was only 2 mA (albeit with some substantial spikes) while the voltage (the green trace) was -2.27 V and free of noise.</p>
<p><img alt="TL972 Negative Rail Supply Current and Voltage" src="/static/media/uploads/blog/devbisme/2016-06-22/tl972_icc-_and_vcc-.png"></p>
<p>Simulations are nice, but eventually you have wire together some parts and make it work in the real world. So I drew up a component layout for the negative voltage generator (otherwise I'd end up wiring it wrong):</p>
<p><img alt="Component Arrangement for the Negative Voltage Generator" src="/static/media/uploads/blog/devbisme/2016-06-22/voltage_inv_layout.png"></p>
<p>And then I soldered it onto the OctoADC board (which is even uglier than the drawing):</p>
<p><img alt="Component Arrangement for the Negative Voltage Generator" src="/static/media/uploads/blog/devbisme/2016-06-22/octoadc_front.JPG"></p>
<p>Once the hardware modifications were complete, I modified the FPGA design to include a <a href="https://github.com/xesscorp/VHDL_Lib/blob/master/pwm.vhd">pulse-width modulator</a> (PWM) that outputs a 1.5 MHz square wave. The PWM signal exits the FPGA on up to four pins to drive the negative voltage generator, but I found in my experiments that using three outputs was enough to generate a stable -2.7 V supply rail. (Obviously, my modeling of the FPGA outputs as a voltage source with a 70-ohm resistor was too conservative.)</p>
<p>When I re-ran the test with the modified OctoADC board, the results were much better. Now you can clearly see the three, separate quantized sine waves.</p>
<p><img alt="Three Sampled Waveforms from OctoADC Board With the Negative Supply Rail" src="/static/media/uploads/blog/devbisme/2016-06-22/invclk_x_3.png"></p>
<p>So I managed to walk (crawl?) my way out of my current problem. Now it's just a matter of modifying the OctoADC PCB and including it in my next array. And then on to the next problem...</p>Colossus-al!2016-06-08T15:31:19+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/colossus-al/Every now and then, one of my customers comes back with something they've been working on.
In this case, it's [Ben North](http://www.redfrontdoor.org/blog/) showing some work he did modeling the [Colossus code-breaking machine]() built at Bletchley Park.
![Colossus in use](http://redfrontdoor.org/blog/wp-content/uploads/2016/04/Colossus-w240.jpg)
First, Ben had to understand how Colossus actually broke codes.
He did this by creating a [Jupyter notebook](http://redfrontdoor.org/Dickens-Teleprinter/index.html) that replicated the process of encrypting some plain-text (in his case, Dicken's *Pickwick Papers*) with a Lorenz cipher and then analyzing it as Colossus did.
Doing this, he was able to debug his understanding of each step in the algorithm.
He shows how a small feature of the Lorenz cipher (that the encryption wheels do not always advance after each letter) leads to an observable distortion of the letter frequency in the encrypted text which can be used to guess likely settings for the wheels.
Once the operational details were understood, Ben went about [implementing (most of) Colossus in the Spartan-6 LX25 FPGA](http://bennorth.github.io/fpga-colossus/doc/Content/notes.html) of a XuLA2 board.
He created [VHDL code describing each portion of Colossus](https://github.com/bennorth/fpga-colossus/tree/published/src).
These pieces communicated with a *dataflow* protocol (i.e, a unit would start processing if it had data available in its input buffer and space available to hold the result in its output buffer).
Because of this loose coupling, it was relatively easy for Ben to add multiple analysis pipelines to his design.
![Colossus pipelines](http://bennorth.github.io/fpga-colossus/doc/Content/whole-pipeline.png)
To test his design, Ben wrote unit tests in Python that drove a simulation of his VHDL code.
When it came time to test the real thing running in the FPGA, he just changed his unit tests so they interfaced with the Raspberry Pi GPIO pins connected to the XuLA2 board.
![XuLA2 + StickIt! motherboard + RPi](http://bennorth.github.io/fpga-colossus/doc/Content/labelled-photo.png)
The results from the actual hardware test matched with the simulation on the first attempt.
According to Ben, he found this a "satisfying outcome".
I guess he picked up a penchant for English understatement while working on this project.
For those looking for a project, it would be great to recode Ben's VHDL into [MyHDL](http://myhdl.org/).
Then it could be included in the same Jupyter notebook with the Lorenz encryption/decryption theory,
and the tests could be run using only Python with no need for the VHDL simulator.
You could probably also get dynamic animations of the Colossus pipelines that Ben had to
hard-code in his documentation.
Some colossal work here, Ben! Thanks for sharing it.
*(Figures: Ben North, used under CC BY-SA 4.0)*Extinction Level Event2016-05-25T16:17:21+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/extinction-level-event/<img src="http://allnewspipeline.com/images/asteroidELE.jpg" class="thumbnail-it float-it-left"/>
Well, there are [rumblings that Xilinx is going to be bought](http://seekingalpha.com/news/3185340-xilinx-jumps-5_9-percent-amid-15b-takeover-rumor).
As everyone already knows, [Intel bought Altera last year](https://newsroom.intel.com/news-releases/intel-completes-acquisition-of-altera/), looking at integrating FPGAs with CPUs for the datacenter market. That removed a company that serviced roughly 40% of the FPGA market.
If Xilinx is also bought by someone looking to compete in the datacenter, then the suppliers of more than 80% of the FPGA market will have vanished.
That's the equivalent of an [extinction level event](https://en.wikipedia.org/wiki/Extinction_event).
So what happens next?
##High-end FPGA development stalls.##
First, high-end FPGA development will stall. This was bound to happen once Intel bought Altera because that removed Xilinx's main competitor. Much of the increase in FPGA capabilities was due to that rivalry. If Xilinx also becomes a captive supplier to some other company with eyes on the data center, then that removes the apex innovator of the FPGA market. So you can forget about getting denser, cheaper discrete FPGAs every year for the immediate future.
##The traditional FPGA market is abandoned.##
Won't the purchasers of Altera and Xilinx keep servicing traditional FPGA markets? Why would they walk away from all that money?
*Because it's not that much money.* Currently, Xilinx and Altera were both around $4B in yearly revenue and each made around $500M in profit. [And the projected (and historic) growth rate has only been 7%](http://blogs-images.forbes.com/kurtmarko/files/2015/06/FPGA-market.png). Meanwhile, Intel's revenue from the datacenter alone was [$16B last year and it's growing at 11%](http://www.fool.com/investing/general/2016/02/04/intel-corps-data-center-business-is-truly-wonderfu.aspx).
<img src="http://blogs-images.forbes.com/kurtmarko/files/2015/06/FPGA-market.png" alt="FPGA market trends" class="center-it" style="width: 80%;"/>
Why would Intel spend $16B to buy Altera and then use any of the acquired resources (i.e., Altera FPGA engineers) to service a slower-growing market where the potential profit is a tiny fraction of what they can make in a faster-growing market? It doesn't make sense.
Plus, the FPGA market is highly fragmented. It takes a lot of expertise to service each one of those segments. It's just plain easier to handle a single, large segment like the data center.
That said, Intel will probably keep selling to the telecomm guys because they have similar characteristics to the datacenter: a few major customers building base stations or networking hubs where performance is king and chip costs are secondary. And networking is an integral part of any data center as well.
Anybody that purchases Xilinx will have these same market forces affecting their decisions. They'll abandon the traditional FPGA markets (consumer, industrial, automotive, aerospace) and concentrate on the datacenter and telecomm. (Although telecomm will have to get used to not being in the driver's seat as far as setting the direction of FPGA development.)
##More innovation and consolidation occurs.##
Lattice is the only pure FPGA company that will be left. They have less than $500M in annual revenue. The Actel portion of Microsemi is roughly that size as well.
And with 80% of the FPGA market up for grabs (if Xilinx is purchased), then that makes Lattice an attractive purchase for a larger semiconductor company that finds an $8B market attractive (because not everybody is Intel).
It also opens the market for a lot of innovation. Previously, companies found it hard to penetrate with customers against Xilinx and Altera. Once they were starved of revenue, Xilinx and Altera purchased the remnants. Now there may be a more open playing field.
##So what happens to me, the individual FPGA developer?##
You'll live in interesting times.
You'll still be able to buy existing Xilinx and Altera FPGAs. All the development is done, it's just a matter of having them cranked out by the fabs. That's easy money. But the yearly improvement of these discrete chips that we've come to expect may cease as the engineers devote themselves to the wishes of their new masters.
And you'll still have the Quartus and Vivado FPGA programming environments, but further development and dissemination of those is questionable. Of course, nobody really loved them (because nobody loves *any* EDA software), but they are necessary for programming the current chips. So they'll still be around.
But there may also be new FPGAs that are made widely available. As Intel injects the FPGA into the data center, some of the developments will make their way to the desktop. That will make FPGA programming a possibility for a much larger audience. And just as compilers massively improved when PCs became widespread, maybe FPGA tools will also. And there would be a market incentive for that if multiple companies are struggling for control of the data center: ease of programming will be a big incentive for customers.
Meanwhile, there will be new FPGA architectures and programming environments springing up in the decimated ecosystem as a diaspora of FPGA engineers leave Intel and other megacorps to try it on their own. But that's a tough business given the level of technical expertise needed and the number of places where it's easier to make money (e.g., social networking, VR). Which of these will grow into the new apex innovator is anybody's guess.
In the end, it's not all good and it's not all bad. It's just going to be different. Kind of like 1985 when FPGAs first started to appear.
So if you like change, you're going to get it. Lots of it.
ESP8266: Re-Reflash Dance!2016-03-28T18:44:51+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/esp8266-re-reflash-dance/<img src="/static/media/uploads/blog/devbisme/2016-03-22/jbeals_again.png" class="thumbnail-it float-it-left"/>
Over a year ago, I posted about [how I reflashed an ESP-01 module with new firmware](http://www.xess.com/blog/esp8266-reflash/).
That post has been very popular and I got the idea in my head that I was some sort of expert on doing this.
But when I recently tried to do the same for an ESP-201 module, *I found out I wasn't!*
[Note: If you would rather watch than read, there is a video at the end of this post that goes
through the ESP-201 flash reprogramming process.](#reflash_video)
Backing up a bit, about a year ago I bought ten of the -201 modules on Aliexpress for $33.
(Now you can [get the same thing for $26](http://www.aliexpress.com/item/10pcs-lot-ESP8266-Serial-Port-WIFI-Wireless-Transceiver-Send-Receive-Module-IO-Lead-Out-ESP-201/32401815422.html?ws_ab_test=searchweb201556_6,searchweb201602_1_505_506_503_504_10034_10032_10020_502_10001_10014_10002_10017_10005_10010_10006_10011_10003_10021_10004_10022_10009_10008_10018_10019,searchweb201603_2&btsid=8bc51a7e-4656-48c1-9087-f3864c8f4cb8).)
I was going to do something with them; I've quite forgotten what that was.
But I've become interested in integrating the ESP8266 chip in another project so I thought I'd
pull these out and get reacquainted.
The ESP8266 has been integrated into the Arduino environment since I last looked, and that
would be an easy way for me to reprogram the chip.
The first thing I did was connect some resistors, buttons, jumpers and my
[C232HM cable](http://www.ftdichip.com/Support/Documents/AppNotes/AN_190_C232HM_MPSSE_Cable_in_USB_to_I2C_Interface.pdf)
to the pins of the ESP-201 module in a manner similar to what I did
[previously for the ESP-01 module](http://www.xess.com/static/media/uploads/blog/devbisme/2014-12-09/esp8266_flash_prog_board_sch.png):
<img src="/static/media/uploads/blog/devbisme/2016-03-22/esp-201_no_work.png" alt="Non-working ESP-201 module connections" class="center-it" style="width: 400px;"/>
(Note that in the photo above, the `RX` and `TX` labels apply to the serial
receiver and transmitter pins *of the -201 module*.
The attached C232HM cable leads have the opposite functions.)
I put the ESP8266-201 module into flash reprogramming mode using the
same procedure as for the ESP-01 module:
1. press and hold the `PROG` button,
2. press and release the `RESET` button,
3. release the `PROG` button.
Next, I downloaded and installed the [latest Ardunio IDE](http://www.arduino.cc/en/Main/Software).
It doesn't support the ESP8266 out of the box, so I opened the `File => Preferences`
dialog box and entered `http://arduino.esp8266.com/stable/package_esp8266com_index.json`
into the `Additional Boards Manager URLs` field.
<img src="/static/media/uploads/blog/devbisme/2016-03-22/rereflash_url.png" alt="" class="center-it" style="width: 600px;"/>
Then I clicked on `Tools => Board: => Boards Manager...`.
At the bottom of the `Boards Manager` window that appeared, I found the `esp8266` entry and clicked on it.
Then I clicked on the `Install` button which downloaded and installed the
appropriate compiler & linker (plus code samples).
<img src="/static/media/uploads/blog/devbisme/2016-03-22/brd_manager.png" alt="" class="center-it" style="width: 600px;"/>
In order to work with the ESP-201 module, I selected the `Generic ESP8266 Module` entry from the list of boards:
<img src="/static/media/uploads/blog/devbisme/2016-03-22/brd_select.png" alt="" class="center-it" style="width: 600px;"/>
Selecting this entry reconfigures the `Tools` menu with new options having default values.
The only thing I changed was the port for my C232HM cable:
<img src="/static/media/uploads/blog/devbisme/2016-03-22/port_select.png" alt="" class="center-it" style="width: 600px;"/>
Now that I had my environment set up, I needed something to compile and run to test my board.
I selected the `WiFiWebServer`: an application that turns an LED on and off
when a particular web page served by the ESP8266 is accessed.
<img src="/static/media/uploads/blog/devbisme/2016-03-22/wifiwebsrv_open.png" alt="" class="center-it" style="width: 600px;"/>
Once the project loaded, I just selected `Sketch => Upload` to see if it would
compile and get programmed into my -201 module.
Naturally, it failed:
<img src="/static/media/uploads/blog/devbisme/2016-03-22/wifi_load_fail.png" alt="" class="center-it" style="width: 600px;"/>
OK, that's not surprising: the -201 module may need a different set up than the -01 module.
After searching for a while, I found this
[handy ESP-201 cheat sheet](http://adlerweb.deviantart.com/art/ESP8266-ESP-201-Module-Pinout-Diagram-Cheat-Sheet-575951137).
It indicated that for the ESP-201 to enter the flash mode, the GPIO2 and GPIO15
pins had to be attached to +3.3V and ground, respectively.
I added a few jumpers to do that, repeated the steps for putting the ESP-201 into programming mode, and tried another upload...
Failure.
From there, I tried various combinations of options under the `Tools` menu:
different upload speeds, different COM ports, different board frequencies,
different flash settings...
Failure.
Failure.
Failure.
Failure.
My next thought was that maybe the AT firmware in my modules was too old to work with
the Arduino uploader.
I installed the [ESP Flash Download Tool by Espressif](http://bbs.espressif.com/viewtopic.php?f=57&t=433) and then
downloaded a [fresher version of the AT firmware that would fit into the 4 Mb flash](http://bbs.espressif.com/viewtopic.php?f=46&t=1123)
on my -201 modules.
But when I tried the tool, it wouldn't link to my module, either.
So I went looking for another program to update the firmware.
I decided to try
[esptool.py](https://github.com/themadinventor/esptool/) since it is mentioned frequently.
There, halfway down its README page, I found this:
The following ESP8266 pins must be pulled high/low for either normal or serial
bootloader operation. Most development boards or modules make these connections
already, internally:
| GPIO | Must Be Pulled |
--------------------------
| 15 | Low/GND (directly, or with a resistor) |
| 2 | High/VCC (always use a resistor) |
If these pins are set differently to shown, nothing on the ESP8266 will work as expected.
There was my problem: I had tied GPIO2 to +3.3 directly rather than through a resistor.
So I replaced the jumpers on the GPIO2 and GPIO15 pins with 1K resistors as shown below:
<img src="/static/media/uploads/blog/devbisme/2016-03-22/esp-201_work.png" alt="Working ESP-201 module connections" class="center-it" style="width: 400px;"/>
Then I tried the Arduino uploader again:
<img src="/static/media/uploads/blog/devbisme/2016-03-22/wifi_load_success.png" alt="" class="center-it" style="width: 600px;"/>
Success!
OK, now I could upload to my ESP-201 module.
I edited the web server code to enter the SSID and password for my local WiFi network
and then recompiled and uploaded it to my board.
Then I clicked on `Tools => Serial Monitor` to bring up a window that would show
status messages output by the web server.
Pressing the `RESET` button (*without pressing* the `PROG` button) initiated
the web server and it put out the following information:
<img src="/static/media/uploads/blog/devbisme/2016-03-22/wifiwebsrv_msgs.png" alt="" class="center-it" style="width: 600px;"/>
These indicated that the web server had started and connected to the local WiFi
with the displayed IP address.
The web server outputs a high or low level on the `GPIO2` pin depending upon the
web page that's accessed.
To observe the output level, I connected an LED plus a current-limiting resistor
from the `GPIO2` pin to ground.
Then I just opened a web browser and went to the pages shown below to turn the LED on and off.
<div class="container">
<div class="row">
<div class="span4">
<img alt="Web server page for GPIO2 set high." src="/static/media/uploads/blog/devbisme/2016-03-22/gpio_1.png">
</div>
<div class="span1"></div>
<div class="span4">
<img alt="GPIO LED on." src="/static/media/uploads/blog/devbisme/2016-03-22/led_on.jpg">
</div>
</div>
<div class="row">
<div class="span9">
</div>
</div>
<div class="row">
<div class="span9 text-center">
<strong>Web page result and LED state from accessing web address 192.168.0.104/gpio/1.</strong>
</div>
</div>
<div class="row">
<div class="span9">
</div>
</div>
<div class="row">
<div class="span9">
</div>
</div>
<div class="row">
<div class="span4">
<img alt="Web server page for GPIO2 set low." src="/static/media/uploads/blog/devbisme/2016-03-22/gpio_0.png">
</div>
<div class="span1"></div>
<div class="span4">
<img alt="GPIO LED off." src="/static/media/uploads/blog/devbisme/2016-03-22/led_off.jpg">
</div>
</div>
<div class="row">
<div class="span9">
</div>
</div>
<div class="row">
<div class="span9 text-center">
<strong>Web page result and LED state from accessing web address 192.168.0.104/gpio/0.</strong>
</div>
</div>
<div class="row">
<div class="span9">
</div>
</div>
</div>
So after a lot of effort and a few dead ends, I had my ESP-201 boards working with the Arduino IDE.
In order to make it easier in the future to program the modules, I used the schematic shown below
and added the necessary sockets and components to
[a programming board I previously built for the ESP-01](http://www.xess.com/static/media/uploads/blog/devbisme/2014-12-09/esp8266_flash_prog_board.jpg):
<div class="container">
<div class="row">
<div class="span4">
<img alt="ESP-201 flash programming board schematic." src="/static/media/uploads/blog/devbisme/2016-03-22/esp8266_flash_prog_board_sch.png">
</div>
<div class="span1"></div>
<div class="span4">
<img alt="ESP-201 flash programming board." src="/static/media/uploads/blog/devbisme/2016-03-22/esp8266_flash_prog_board1.jpg">
<p> </p>
<img alt="ESP-201 flash programming board." src="/static/media/uploads/blog/devbisme/2016-03-22/esp8266_flash_prog_board2.jpg">
</div>
</div>
</div>
I hope this post will help you get started with using your own ESP-201 modules.
Even if you use a different programming environment than the Arduino IDE,
the steps for building the programming hardware may still save you from the
mistakes I made.
<a name="reflash_video"></a>Finally, if you're someone who would rather watch than read,
then here's a video showing the entire process of building the hardware for the
ESP-201 and reprogramming it with the Arduino IDE:
<iframe class="center-it" width="560" height="315" src="https://www.youtube.com/embed/fsPZPv76gvw" frameborder="0" allowfullscreen></iframe>
Random Number Generators and Hardware Sorters2016-02-25T15:31:16+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/random-number-generators-and-hardware-sorters/Just a short post to alert you to some things I've done that are FPGA-related but don't appear on this site.
First, I released a [Jupyter notebook about building random number generators (RNGs)](https://github.com/xesscorp/CAT-Board/blob/master/tests/RNG_with_MyHDL.ipynb).
For those that aren't familiar with it, [Jupyter](http://jupyter.org/) gives us a way to build *executable documents* that are displayed in a browser.
My notebook uses Python and [MyHDL](http://myhdl.org/) to explore several methods for building RNGs.
The neat thing is you can change the RNG parameters, simulate the effects, and visualize the results
right in the browser.
Then you can dump out Verilog or VHDL code to run in an FPGA.
Second, I released [another Jupyter + MyHDL notebook](https://github.com/xesscorp/Hardware-Sorters/blob/master/hardware_sorters.ipynb) showing how I built two FPGA-based circuits to
sort lists of numbers.
One of the sorters was [recently discussed on the Hackaday site](http://hackaday.com/2016/01/20/a-linear-time-sorting-algorithm-for-fpgas/), and the other is an [IBM design](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.83.5786&rep=rep1&type=pdf) that I first built back in 1983 for a VLSI design class.
The notebook generates a random list of numbers and you can see the progress as each
sorter works through it.
And just like the previous notebook, you can dump out the HDL code to make your own sorter.
The links I gave above go to static documents, but if you want to interact with the documents,
you'll need the following:
* A Python interpreter. ([Anaconda](https://www.continuum.io/downloads) is a popular choice for this,
and it already has Jupyter bundled in.)
* The Jupyter notebook (if you aren't using Anaconda).
* The MyHDL Python package (easily installed by `pip install myhdl` ).
Once you have those installed, you can download notebook files with the `.ipynb` extension to your computer
and open them with Jupyter.
The combination of Jupyter and MyHDL provides some unique advantages for exploring, documenting, and disseminating designs of digital systems.
It's definitely worth checking out!
Giving Back to KiCad2015-08-25T13:00:00+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/giving-back-to-the-community/<img src="/static/media/uploads/blog/devbisme/2015-08-24/helping-hand-cropped.jpg" class="thumbnail-it float-it-left"/>
[I switched over to KiCad a while ago](http://www.xess.com/blog/my-first-kicad-board/),
mainly because paying fees for Eagle upgrades that didn't have much "up" in them seemed pretty stupid.
In exchange for providing a free tool, the KiCad open-source developers get a lot of grief,
mostly about the GUI and library management.
That's to be expected: all EDA software, like unhappy families, sucks in its own unique way.
A lot of these are [bike-shed issues](https://en.wiktionary.org/wiki/bikeshedding) that are easy to
understand so people form opinions they're not shy about expressing.
But it's not a big problem to me as long as the right wires end up in the right places.
It's fine to voice your concerns so the developers get some feedback;
then put on your big-boy pants and make do with what you've got.
And I've gotten *a lot* out of KiCad: well-documented ASCII design files, Python scripting,
push-and-shove length-matched differential routing, etc. *And I paid nothing to get it!*
It's possible to [donate money to KiCad](https://giving.web.cern.ch/civicrm/contribute/transact?reset=1&id=6),
mostly to support the [CERN team that's working on it](http://www.ohwr.org/projects/cern-kicad/wiki/WorkPackages).
A lot of great work is being done for a pittance.
But, to be frank, I have too many people in my life who really need money to be sending it
away to strangers in foreign lands.
What I do have is time and energy.
(Well, as much energy as I have left at 59.)
So I've started building open-source point-tools to surround KiCad with features I want.
The first two of these are [KiCost](https://pypi.python.org/pypi/kicost) and
[KiPart](https://pypi.python.org/pypi/kipart).
[KiCost](https://pypi.python.org/pypi/kicost) is a back-end tool to automate the most-hated portion
of electronic design: finding the cost of the components and placing an order.
It takes the bill-of-materials from KiCad and gets the current, quantity-adjusted price and
availability for each component from a set of online distributors (Digi-Key, Mouser and
Newark/Farnell are currently supported).
It places all of this information into a pretty spreadsheet:
<img src="/static/media/uploads/blog/devbisme/2015-08-24/kicost-spreadsheet.png"
class="center-it" style="width:80%;" alt="KiCost Spreadsheet."/>
With the spreadsheet, you can see who has parts and what they'll cost for the quantities you need.
Then (and this is the big time-saver for me), it makes lists of the parts you select in a format
that can be cut-and-pasted into the online order forms of each distributor.
Just press "Submit" and your parts are on the way.
Here's a video that demonstrates what KiCost does:
<iframe class="center-it" width="560" height="315" src="https://www.youtube.com/embed/AeccxROpDfY" frameborder="0" allowfullscreen></iframe>
While KiCost helps on the back-end of a design, [KiPart](https://pypi.python.org/pypi/kipart) is oriented
toward another hated task at the front-end: building schematic symbols.
When you're confronted with a high pin-count microcontroller or FPGA, KiCad (like Eagle) makes you use
a cumbersome, GUI-based schematic symbol editor to enter the pins one ... by ... one.
It's slow, tedious and error-prone but, other than that, it's just great.
(See, even I get in on the act of bashing the KiCad GUI.)
That's avoided with KiPart because it lets me enter the device pin descriptions into a spreadsheet that's
automatically processed into a schematic symbol library.
The spreadsheet really speeds-up data entry and makes it easy to spot errors (like setting a
pin to be an input instead of bidirectional).
Plus, all my parts look consistent because I'm not manually drawing them.
KiPart speeds up symbol creation 3x-4x, even for simple parts.
And it's a *thousand times faster* if the device manufacturer already provides the pin information
as CSV files ([as many FPGA companies do](http://www.xilinx.com/support/packagefiles/)).
Here's a symbol KiPart created almost instantly for one of the *smaller* 256-pin FPGAs
(if you think you want to do this manually, wait until you get one of those 2000-pin behemoths...):
<img src="/static/media/uploads/blog/devbisme/2015-08-24/schematic-symbol.png"
class="center-it" style="width:80%;" alt="256-pin FPGA Symbol Generated by KiPart."/>
And here's another video that shows how to use KiPart:
<iframe class="center-it" width="560" height="315" src="https://www.youtube.com/embed/hX4l8i4TSWY" frameborder="0" allowfullscreen></iframe>
In addition to being offered as open source tools to the KiCad community, KiCost and KiPart let me contribute in other ways.
For example, [I've been releasing schematic symbols generated by KiPart on GitHub](https://github.com/xesscorp/KiCad-Schematic-Symbol-Libraries).
So far there are libraries for the Xilinx Virtex-6, Spartan-6 and 7-Series FPGAs (a total of 166 different devices)
and for the Cypress PSoC5LP microcontrollers (awww, only 8 devices).
More libraries are planned: I'm currently working my way through the Lattice iCE FPGAs.
It's easy to get started with KiPart and KiCost:
pip install kipart
pip install kicost
Then go to [readthedocs.org](http://readthedocs.org) to read the documentation.
Let me know if you have any suggestions for improvements.
Of course - since it's open source - I have the right to say "Hell no! I won't be doing that!" and you can reply
"OK, I'll just fork it and do it myself."
That's the *free* part of FOSS that I *really* like.
Easier Connections2015-05-25T17:38:21+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/easier-connections/One of the real pains when using the StickIt! boards is trying to figure out how they connect to the FPGA pins.
For example, you have to trace each I/O pin of an [LEDDigits board](http://www.xess.com/shop/product/stickit-leddigits/) through a particular socket of a [StickIt! motherboard](http://www.xess.com/shop/product/stickit-mb/) and over to the socket that holds the [XuLA2 FPGA board](http://www.xess.com/shop/product/xula2-lx25/).
Then you have to follow the route from the XuLA2 I/O pin to the pin on the FPGA.
Finally, you have to record that information in a user-constraints file and pass it to the FPGA compilation tools.
In order to make life easier, I've released the `xsconnect` Python package which automates the entire process.
The package includes both command-line and GUI tools for generating the pin assignments given the
connection of a peripheral board, motherboard and daughterboard.
For example, just highlight your choices in the `gxsconn` window and it spits out the FPGA pin assignments as
shown below.
<img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-25/gxsconn.png"
class="center-it" style="width:75%" alt="GUI version of xsconnect tool."/>
You can find out more about the `xsconnect` package at its [Github page](https://github.com/xesscorp/xsconnect) and [online manual](https://xsconnect.readthedocs.org/en/latest/index.html).83 Boards. 25 Bucks.2015-05-11T15:51:18+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/83-boards-25-bucks/A lot of product ideas don't work out.
Sometimes they're infeasible.
If not, you build it and find out it sucks.
If not, you build more and your customers say they suck.
(Or so few say that it *doesn't* suck that there's no reason to make any more.)
If not, then you've got a winner. Congratulations.
Still, most times you fail.
But you have to keep trying because that's the only way to tell for sure.
So you have to minimize the expense of each attempt.
One avenue I've taken for making low-cost products is the
[StickIt! board](http://www.xess.com/shop/product/stickit-mb/)
with it's [add-on modules](http://www.xess.com/store/add-on-boards/).
The modules are small (less than two square inches) and
perform some limited function (think LEDs, buttons, VGA, ADC, etc.)
in service to an FPGA that does all the heavy lifting.
The limited functionality and small size makes the modules easy to design and
cheap to produce.
I chose the 0.8" width of the StickIt! modules to mimic
the width of many of the Digilent PMOD modules.
And the length was chosen so they would fit into the low-cost, small 5 cm × 5 cm
panel size offered by places like
[Itead](http://store.iteadstudio.com/index.php?main_page=index&cPath=19_20) and
[Seeed](http://www.seeedstudio.com/service/index.php?r=pcb).
Using a snap-off tab, I can lay out a simple 2 × 1 board array that fits into a single panel
like this:
<img src="http://www.xess.com/static/media/uploads/blog/devbisme/2014-11-17/itead_reject_1.png"
class="center-it" style="width:50%" alt="Dual-board PCB array."/>
The total cost was $10 for 10-12 panels and $4 for shipping with a total turn-around
time of 19-26 days from Gerber submission to receipt of the panels.
So for $14, I could get 20-24 StickIt! module PCBs in less than a month.
That was great until last year when
[Itead started rejecting my Gerber files](http://www.xess.com/blog/necessity-is-a-mother/).
Essentially, they didn't like manufacturing arrays of boards connected by snap-off tabs.
They would do a single board per panel, but that halved the number of boards I got for my $14.
That's not a deal-killer, but once you get used to sub-$1 PCBs, you don't want to go back.
So I moved over to Seeed who had no problem with accepting and manufacturing my little PCB arrays.
At least, *they didn't for the very first one I sent!*
After that, my next array was rejected.
They would do it, but only if I used a V-score instead of snap-off tabs.
And the cost for V-scoring more than doubled the price, so I would have been better off
just doing a single board per panel.
So I went in search of another manufacturer.
I eventually hit upon [Dirt Cheap Dirty Boards](http://dirtypcbs.com/) who go by the tag line
"No bull, just crappy PCBs".
Now, that may give you pause as to the quality of the panels you'll get from them,
but the customer testimonials were ecstatic and *they said they could do 5 mil trace/space etching!*
(Seeed and Itead only claim to do 6 mil and recommend 8.)
They offered a 5 cm × 5 cm panel for $14 and a 10 cm × 10 cm panel for $25.
(All their prices include shipping, so they're equivalent to the prices charged by
Seeed and Itead.)
The 10 cm × 10 cm panel is less than twice the cost of the 5 cm × 5 cm panel but
offers 4× the area, so I figured why not go for broke and make a bigger panel with
eight module PCBs on it?
That would bring the per-PCB price down even further and it's no more likely to get rejected than
the smaller panel.
So I submitted Gerber files for this:
<img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/dirtypcb_grove.png"
class="center-it" style="width:70%" alt="Eight PCB array."/>
*That* is a really funky board outline and there are *nine* internal slots,
some of them very oddly shaped.
I wouldn't have blamed Dirty PCBs for rejecting it,
but 24 days later I got this in the mail:
<img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/dirtypcb_pckg.jpg"
class="center-it" style="width:70%" alt="Receipt of Dirty PCBs order."/>
The panels looked pretty good.
| Front | Back |
|:-----:|:----:|
| <img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/array_front.jpg" class="center-it" style="width:80%" alt="Front of PCB array."/> | <img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/array_back.jpg" class="center-it" style="width:80%" alt="Back of PCB array."/> |
After buffing-out the mouse bites left by removing the snap-off tabs, the individual boards looked OK.
| Front | Back |
|:-----:|:----:|
| <img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/grove_front.jpg" class="center-it" style="width:80%" alt="Front of individual PCB."/> | <img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/grove_back.jpg" class="center-it" style="width:80%" alt="Back of individual PCB."/> |
Lest you think everything was all sweetness-and-light, Dirty PCBs did nick a few of the panels
when they were being routed. I lost five individual boards from this.
<img src="http://www.xess.com/static/media/uploads/blog/devbisme/2015-05-10/panel_nick.jpg"
class="center-it" style="width:70%" alt="Nicked panel."/>
I ordered ten panels, but I received eleven which gave me 88 individual PCBs.
Subtracting the five damaged PCBs left me with 83 usable boards for a per-board
cost of 30¢.
At least, they *would* have been usable if *I* hadn't screwed up!
I didn't have a datasheet or any physical copies of the four-pin Grove socket to measure,
so I used a footprint from someone else's design.
When the actual sockets arrived, the holes were a little too small and the plating a little
too thick so the socket leads didn't fit.
I'll have to correct the socket footprint and make another batch.
Luckily, that's only going to cost me $25.
This dream is not my dream.2015-04-07T19:28:37+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/this-dream-is-not-my-dream/I've been alerted by a few people today of a [Kickstarter campaign](https://www.kickstarter.com/projects/414249697/32-bit-microcontroller-chip-next-generation-eco-in?ref=category_location) by DreamMICRO that uses some images of our [XuLA2 FPGA board](http://www.xess.com/shop/product/xula2-lx9/):
<div class="container">
<div class="row">
<div class="span4">
<img alt="The DREAM-1." src="https://ksr-ugc.imgix.net/assets/003/381/364/76bbcbba4e2aa0caa407f67a21bf5db3_original.png?v=1425479089&w=700&h=&fit=max&auto=format&lossless=true&s=4fbf6bdeb37fde810c18fa960ccfeb6c"/>
<p><em>Their DREAM-1</em></p>
</div>
<div class="span1"></div>
<div class="span4">
<img alt="The XuLA2." src="http://www.xess.com/static/media/product/XuLA2_1.png"/>
<p><em>Our XuLA2</em>.</p>
</div>
</div>
</div>
They've also proposed an additional prototyping platform that uses their DREAM-1 as a daughterboard and supplements it with auxiliary functions implemented as Digilent PMODs™.
This is quite similar to our existing [StickIt! board](http://www.xess.com/shop/product/stickit-mb/) and [StickIt! modules](http://www.xess.com/store/add-on-boards/):
<div class="container">
<div class="row">
<div class="span4">
<img alt="The DREAM-1 Prototyping Platform." src="https://ksr-ugc.imgix.net/assets/003/467/451/06d09d4ce3874a2a8b62fe1a14ea123b_original.png?v=1426783472&w=700&h=&fit=max&auto=format&lossless=true&s=6470138b01914c7f431e0f5b1877bea5"/>
<p><em>Their DREAM-1 Prototyping Platform</em></p>
</div>
<div class="span1"></div>
<div class="span4">
<img alt="The StickIt! Board." src="http://www.xess.com/static/media/product/.thumbnails/StickIt_board-0x300.png"/>
<p><em>Our StickIt! Board</em></p>
</div>
</div>
</div>
**Now, there's no problem with this**: the XuLA2 and StickIt! boards are [OSHW](http://en.wikipedia.org/wiki/Open-source_hardware) and Creative-Commons licensed. Anyone is free to download the schematics and layout files to make and sell their own versions. The DreamMICRO team even references that they've used the "open-source Xula pcb design" for their stuff. (No mention of *us*, but hey, the world's not a perfect place.)
So I'm not calling foul on the DreamMICRO team or saying they're bad people. They've made use of OSHW to build their project. That's kind of what OSHW is for. I just want to make it public that XESS isn't involved in this campaign. If you contribute to their campaign, anything good or bad that comes out of that is between you and them. XESS is not involved in any way. (Well, we did design the original XuLA2 and StickIt! boards, but any design modifications, manufacturing details, distribution, delivery and customer support are the responsibility of the DreamMICRO team.)
Meanwhile, XESS is still selling our XuLA2 and StickIt! boards. And, of course, you can buy one. Today. Like, right now.Led Panels2015-03-12T01:00:00+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/led-panels/<img src="/static/media/uploads/blog/devbisme/2015-03-10/supreme_leds.jpg" class="thumbnail-it float-it-left"/>
My Twitter friend, [Jeremiah Johnson](https://twitter.com/naikrovek), sent me a couple of LED panels
in January.
These things retail for about $40 each, so I thought I should at least develop a driver for him.
From the picture, you can see the panels are 32 × 32 arrays of RGB LEDs.
Ribbon cables are used to concatenate panels to form larger displays.
There's a total of 2 × 32 × 32 × 3 = 6,144 red, green and blue LEDs on both boards
which can supposedly take up to 4 amps of current, but I got away with using a single
[1A power adapter](http://www.xess.com/shop/product/ps0004/).
<img alt="LED panel hardware." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-03-10/led_panel_hdw.jpg"
style="width: 60%;"/>
The panels don't contain a frame buffer to store an image: the LEDs have to be continuously refreshed.
This is done by shifting-in a sequence of bits to activate selected RGB LEDs in a given row
and then latching those bits to drive the LEDs while another set of bits is shifted in for the next row.
An entire image is created by moving rapidly from one row to the next.
And if you adjust the proportion of how often a particular LED bit is on or off, you can also
display colors of varying intensity.
Naturally this takes a fair amount of bit-twiddling over a short period of time, but
that's a perfect job for an FPGA.
The block diagram for the FPGA-based LED panel driver that I built is shown below.
<img alt="FPGA-Based LED Panel Driver." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-03-10/blk_diag.png"
style="width: 100%;"/>
The image is stored in a dual-port RAM that is written (or read) by some other
logic circuit in the FPGA (usually something like a processor).
The LED panel driver reads the image pixels from the other port of the RAM.
There is no need to double-buffer the RAM: the high-bandwidth interface to the rest of
the FPGA means that any re-write of the image occurs much too quickly to be noticed.
(Of course, you *can* make a buffer in some other part of the FPGA where you slowly build
an image and then quickly dump it into the dual-port RAM, but that can be done as needed on a case-by-case
basis so as not to reduce the overall area-efficiency of the display circuitry.)
Each word of RAM is divided into three bit-fields which each hold the intensity
value for the red, green and blue LEDs of a pixel.
The bit field values are compared to a threshold and the associated LED is turned on
if the bit field value is greater than the threshold.
The intensity of the pixel colors is varied by scanning a line of pixels multiple times
while ramping-up the threshold.
For example, a red LED will be on twice as much (and shine twice as brightly)
if its bit field has the value 42 as compared to when it stores 21.
The LED panel is divided into top and bottom halves, so the RAM stores
pixels for one half in the locations with even addresses and pixels for the other
half at odd addresses.
The sequencer outputs odd and even addresses on alternate clock phases.
The RGB bits for the pixel in one half of the panel are stored temporarily
while the bits for the pixel in the other half are generated.
Then both sets of bits are sent simultaneously to the panel on the falling-edge
of the clock so they'll be stabilized before the rising edge of the clock
shifts them into the panel.
The sequencer also generates the latching signal and selects the active row of the display.
Because several clock cycles are needed to fetch pixels from the RAM and do the threshold comparisons,
the latch and active-row signals have to be delayed a few cycles to get them back in sync
with the RGB signals.
The sequencer also solves a timing problem that arises when it comes time to change the active row of the panel.
If the row is changed before the latch is activated, then the pixels for the previous row
will appear faintly in the new row before the new pixel values are established.
Likewise, if the row changes after the latch signal, then the new pixels will appear
briefly in the previous row before they show up in the desired location.
Finally, if a pixel is on but then has its driver turned off, the charge residing in the wiring capacitance
can partially illuminate other pixels in the same column.
These are examples of *[ghosting](http://www.rayslogic.com/propeller/Programming/AdafruitRGB/AdafruitRGB.htm)*.
Since a row of pixels is scanned multiple times while ramping the
threshold to create varying colors, ghosting can be eliminated by doing one final scan
where all the pixels are off (or "blanked") before the row address is changed.
While this leads to a slight diminution in the overall pixel brightness,
it's much less noticeable than the partially-on pixels
that occur with ghosting.
You can examine the VHDL code for the LED panel driver [here](https://github.com/xesscorp/VHDL_Lib/blob/master/LedPanel.vhd).
Some things to note are:
+ The circuitry can resize itself at compile time by setting a few generic parameters
that describe the width and height of the LED panel and how many are strung together.
+ The dual-port RAM is done using *VHDL inference* instead of instantiating a vendor-specific
block RAM. That makes it easier to port this module to other FPGA families.
The VHDL file also contains a version of the LED panel driver with a Wishbone interface.
This makes it easy to attach as a peripheral to the
[ZPUino softcore processor](https://github.com/xesscorp/ZPUino-HDL/tree/LED_Panel/zpu/hdl/zpuino/boards/xula2/xula2).
The combined ZPUino plus LED panel driver can be loaded into a XuLA2 board that is then inserted into
a [Logic Pod](http://www.xess.com/shop/product/logicpod/).
The Logic Pod provides a convenient connector for mating with the cable to the LED panel;
the voltage translation capabilities of the Logic Pod are not needed since the LED panels accept 3.3V logic levels.
<img alt="Connection of the XuLA2 to the LED panel." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-03-10/xula2_led_panel_connection.jpg"
style="width: 60%;"/>
With the ZPUino + LED panel driver, it becomes possible to generate graphics just by
writing Arduino sketches.
Because the panel driver offloads all the real-time processing needed to refresh the display,
the ZPUino processor just has to concern itself with loading an image into the RAM.
I took some code from [here](https://github.com/bikerglen/beagle/tree/master/projects/led-panel-v01/software) and
[adapted it](https://github.com/xesscorp/ZPUino-HDL/blob/LED_Panel/zpu/hdl/zpuino/boards/xula2/xula2/LedPanelPerlin.ino)
to generate Perlin noise on a 64 × 32 display:
<img alt="Perline noise generated by the ZPUino and displayed using the LED panel driver." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-03-10/perlin_noise_generator.jpg"
style="width: 60%;"/>
That's about it, but in closing I'll tell you a few things I tried that didn't work so you won't repeat them:
+ I built the driver starting from the pinout and my best guess as to how the circuitry expected
the signals to toggle.
Big mistake. I ended up rediscovering all the ghosting problems that others had already found
and solved.
Next time: read the blogs!
+ I originally used a random number generator (RNG) for the threshold.
I figured that creating a uniform distribution between 0 and 255 would give the same
effect as a linear ramp and would require less sequencing and circuitry.
Unfortunately, I noticed a lot of sparkling and correlation effects in the pixels
even when using an eight-bit slice of a 32-bit RNG.
+ The output-enable control input for the LED panels is practically useless.
I tried to use it to eliminate ghosting by disabling the outputs when the row was switched,
but it had no effect.
I ended up just enabling the panel all the time by pulling this input to ground.
Timing Diagrams Made Easy2015-02-12T18:00:00+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/timing-diagrams-made-easy/<img src="/static/media/uploads/blog/devbisme/2015-02-12/timing_diag_small.JPG" class="thumbnail-it float-it-left"/>
If you do electronics design, especially digital circuits, you'll eventually find yourself
drawing timing diagrams showing the clock, control and data waveforms.
They help you clarify the sequencing of data and control signals as they pass through your
circuit.
They also serve as valuable documentation to others who might use your design later.
Unfortunately, timing diagrams are painful and time consuming to draw.
They're also a pain to keep up to date as you modify your design.
So they fall out of sync with your current prototype,
at which point they no longer help the design process (and can, in fact, hinder it by
propagating a false view of how the circuit operates).
Then you have to try and update them at the end of the project, probably misremembering a few details
along the way.
It would help if there was a simple way to describe timing waveforms instead of trying to
draw all the fiddly bits using a generic drawing program.
This is where [WaveDrom](http://wavedrom.com) comes in.
It uses a simple [JSON syntax](http://www.w3schools.com/json/json_syntax.asp) like this:
{ signal: [
{ name: "clk_i", wave: 'P...' },
{ name: 'add_i', wave: '010.' },
{ name: 'data_i', wave: 'x=x.', data:["data"] },
{ name: 'upEmpty_o', wave: 'x.0.' },
{ name: 'upFull_o', wave: '0.x.' },
{ name: 'upLevel_o', wave: '=.=.', data:["N","N+1"] },
],
config: {hscale: 2},
head: {text: 'Up FIFO Push Example', tick:0,}
}
to create timing diagrams like this:
<script type="WaveDrom">
{ signal: [
{ name: "clk_i", wave: 'P...' },
{ name: 'add_i', wave: '010.' },
{ name: 'data_i', wave: 'x=x.', data:["data"] },
{ name: 'upEmpty_o', wave: 'x.0.' },
{ name: 'upFull_o', wave: '0.x.' },
{ name: 'upLevel_o', wave: '=.=.', data:["N","N+1"] },
],
config: {hscale: 2},
head: {text: 'Up FIFO Push Example', tick:0,}
}
</script>
The waveform objects that make up the timing diagram are contained in the `signal:[...]` JSON array.
In the simplest case, each waveform object has a `name` field and a `wave` field.
The value in the wave field is just a string of characters where each character represents the
logic level of the wave during a single time slot.
The meanings of the characters are as follows:
Character | Meaning
-----------|:--------------------------------------
p | Clock pulse with positive polarity (i.e., starts off at a logic high and transitions to a logic low.
P | Positive polarity clock pulse with an arrow drawn on the rising edge.
n | Clock pulse with negative polarity (i.e., starts off at a logic low and transitions to a logic high.
N | Negative polarity clock pulse with an arrow drawn on the falling edge.
l, 0 | Low logic level.
L | Low logic level with an arrow drawn on the falling edge.
d | Low logic level maintained by a pulldown resistor.
h, 1 | High logic level.
H | High logic level with an arrow drawn on the rising edge.
u | High logic level maintained by a pullup resistor.
x | Unknown logic level or bus value.
z | Tri-state (undriven) logic level.
=, 2 | Digital bus value with white fill color.
3, 4, 5 | Digital bus value with various fill colors.
. | Repeat the previous value of the waveform.
Probably the most used character is the period, which just repeats the last value of the waveform.
For example, `wave: 'p....'` would draw five, consecutive, positive-polarity pulses like so:
<script type="WaveDrom">
{signal: [{wave:'p....'}]}
</script>
Or `wave: '1..0...=.'` would draw a waveform that is high for three periods, low for four periods,
and then displays a bus value for two periods like this:
<script type="WaveDrom">
{signal: [{wave:'1..0...=.'}]}
</script>
Note that using the period is **not** the same as just repeating the character.
Here's what the previous example looks like if you use `wave: '1110000=='` instead:
<script type="WaveDrom">
{signal: [{wave:'1110000=='}]}
</script>
It's nice to be able to label waveforms for digital buses with the values they carry.
That can be done using a `data` field whose consecutive values are inserted into the
bus waveform as each `=` sign is encountered.
For example, this `wave: '=..=...=.', data:['N','N+1','N+2']` results in this:
<script type="WaveDrom">
{signal: [{wave:'=..=...=.', data:['N','N+1','N+2']}]}
</script>
It also works if you replace the `=` with a character for one of the colored buses like this
`wave: '3..4...5.', data:['N','N+1','N+2']`
<script type="WaveDrom">
{signal: [{wave:'3..4...5.', data:['N','N+1','N+2']}]}
</script>
I've only shown a fraction of what WaveDrom can do.
I haven't even touched on these features:
+ Offsetting individual waveforms by arbitrary intervals.
+ Adding gaps to represent omitted parts of waveforms.
+ Hierarchical labeling of groups of waveforms.
+ Placing splines and lines to show relations between transitions in two waveforms.
+ Scaling the size of the timing diagram.
+ Adding descriptive headers and footers to an entire timing diagram.
+ Changing the overall style of the timing diagram using *skins*.
You can learn more by reading the [WaveDrom tutorial](http://wavedrom.com/tutorial.html).
There's even a [live WaveDrom editor page](http://wavedrom.com/editor.html) where you can type in
JSON code to try out the various features.
If you decide you like WaveDrom (and, really, *who wouldn't!?*), there are two ways to use it.
The first is in an off-line mode for generating timing diagrams to include in your documents.
First, [download an archive](https://github.com/wavedrom/wavedrom.github.io/releases) of
the WaveDrom editor for your particular OS.
Unpack it into a directory and run the executable.
Then you can type in JSON code and see the resulting waveforms just like you did on the
live editor web page.
You can export your timing diagram as either a PNG image or as an SVG file.
The interesting thing is that you can open the SVG file with a graphic editor like
[Inkscape](https://inkscape.org/en/) and modify the drawing.
This is useful if there is some formatting you absolutely need that WaveDrom can't provide.
The second option is to use the WaveDrom Javascript library to show timing diagrams in your web pages.
Get the `WaveDrom.js` file and the `skins` directory from the
[WaveDrom Github page](https://github.com/drom/wavedrom).
Place these files somewhere that your web server can find them.
Then load the Javascript libraries by placing the following into the
`<head>...</head>` section of your web page:
<script src="your_website_path/skins/default.js"></script>
<script src="your_website_path/WaveDrom.js"></script>
Next, place the following call to the timing waveform rendering function at the bottom of
your web page:
(function(){ window.addEventListener("load", WaveDrom.ProcessAll, false); })();
Then you can draw a timing diagram anywhere in your page by inserting JSON code
inside a `<script type="WaveDrom">...</script>` bracket like this:
<script type="WaveDrom">
{ signal: [
{ name: "clk_i", wave: 'P...' },
{ name: 'add_i', wave: '010.' },
{ name: 'data_i', wave: 'x=x.', data:["data"] },
{ name: 'upEmpty_o', wave: 'x.0.' },
{ name: 'upFull_o', wave: '0.x.' },
{ name: 'upLevel_o', wave: '=.=.', data:["N","N+1"] },
],
config: {hscale: 2},
head: {text: 'Up FIFO Push Example', tick:0,}
}
</script>
After you reload the web page, you should see the same figure shown at the beginning of this article.
Cut the Cord: Using the ZPUino Without an FTDI Cable2015-02-06T14:00:00+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/cut-the-cord/<img alt="Cutting the cord." class="thumbnail-it float-it-left" style="width:25%" src="https://nelato.files.wordpress.com/2013/04/gordian-knot.jpg"/>
In my previous two posts, I've talked about
[extending the ZPUino with custom peripherals](http://www.xess.com/blog/extending-the-zpuino/)
and
[creating a terminal-like communication link over USB to an application running in an FPGA](http://www.xess.com/blog/terminal-velocity/).
Now it's time to combine those two concepts to create a terminal link to the ZPUino over the
USB link of a XuLA board.
Why would I do this? For one reason only: to get rid of the
[FTDI cable I've been using to communicate with the ZPUino](http://www.xess.com/blog/ive-never-bought-an-arduino-but-now-i-have-1000-of-them/).
It's just a pain in the ass to have two cables connected to the XuLA: one for downloading bitstreams to the FPGA and the
other for loading programs into the ZPUino softcore.
Plus, it costs over $25 to get an FTDI cable and that dissuades some who might want to
try out the ZPUino just to see what it's like.
The block diagram of the communication link is similar to last time except for the endpoints.
One end is now the Arduino-like IDE which compiles C source code and downloads it to the ZPUino.
At the other end, naturally, is a ZPUino softcore processor running in the FPGA of a XuLA board.
<img alt="Complete communication link." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-02-04/ZPUino_Comm_Blk_Diag.jpg"
style="width: 100%"/>
A valid question at this point is "Why run the USB-to-serial server and null modem? Why not just write a
direct interface for the IDE since it's open source?"
The answer is that it avoids the effort of creating, maintaining and distributing
a new version of the IDE.
For the same reason, nobody wants to change the ZPUino firmware that's used to communicate with the IDE.
Therefore, the HostIoComm module has to mimic the UART the ZPUino usually talks to.
Since the ZPUino talks to the UART (and other peripherals) through a Wishbone interface,
the same interface has to be attached to the HostIoComm module (see the
[VHDL for the WbHostUart module](https://github.com/xesscorp/VHDL_Lib/blob/master/HostIoComm.vhd)).
The resulting WbHostUart module has to be inserted into slot 1 in the
[top-level module of the ZPUino VHDL](https://github.com/xesscorp/ZPUino-HDL/blob/RGB_LED_Example/zpu/hdl/zpuino/boards/xula2/xula2/xula2_top.vhd).
<img alt="HostIoComm Wishbone interface." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-02-04/ZPUino_Interface.jpg"
style="width: 80%; box-shadow: none"/>
In order to pass as the standard UART, the WbHostUart operates as follows:
+ The `id` that the module reports to the ZPUino core is set as follows:
id <= VENDOR_ID_G & PRODUCT_ID_G
where `VENDOR_ID_G` and `PRODUCT_ID_G` are set by default to the same values as the
normal ZPUino UART.
This ensures the ZPUino will accept this UART when it scans the identifiers
of all the peripherals located in the slots.
+ Data transmission and reception is done through the data register located at address 0.
Any time the ZPUino reads this register, it gets the next byte from the download FIFO that receives
data from the IDE running on the host PC.
Any write to this register queues a byte of data into the upload FIFO for transmission back to the IDE.
+ Flow control is managed by querying the status register at address 1.
If bit 0 is set, then the download FIFO is holding one or more bytes of data from the host PC that
can be read by the ZPUino.
If bit 1 is set, then the upload FIFO is full and the ZPUino shouldn't try to push any more data into it.
OK, this is all great, but how do you actually *use* this?
Here's a complete list of steps to follow:
1. Get the [ZPUino HDL code](https://github.com/xesscorp/ZPUino-HDL.git) using
`git clone -b RGB_LED_Example --recursive https://github.com/xesscorp/ZPUino-HDL.git`.
Then go to the `ZPUino-HDL\zpu\hdl\zpuino\boards\xula2\xula2` folder and build it with `make xula2-lx9` or `make xula2-lx25`.
Or you can just download the bitstreams I already compiled for the
[XuLA2-LX9](/static/media/uploads/blog/devbisme/2015-02-04/xula2-lx9_routed.bit)
and [XuLA2-LX25](/static/media/uploads/blog/devbisme/2015-02-04/xula2-lx25_routed.bit).
(These bitstreams also include the RGB LED driver peripheral I talked about [here](http://www.xess.com/blog/extending-the-zpuino/).)
2. Download the [ZPUino IDE](http://alvie.com/zpuino/downloads/2.0/beta2/) for your operating system and install it.
3. Install the [Python version of the XSTOOLs](https://pypi.python.org/pypi/XsTools) using
`pip install xstools --allow-all-external --allow-unverified intelhex`.
4. Download the [com0com null-modem emulator](https://code.google.com/p/powersdr-iq/downloads/detail?name=setup_com0com_W7_x64_signed.exe&can=2&q=)
and use it to create a null modem connection between two COM ports (I usually choose COM7 and COM8).
5. Plug a XuLA2-LX9 board into a USB port and flash it with the ZPUino bitstream via the command `xsload -flash xula2-lx9_routed.bit`.
(I'm using a XuLA2-LX9 here. If you're using a XuLA2-LX25, then just change the commands accordingly.)
Then unplug and re-plug the USB connection; toggling the power will make the FPGA load itself with the ZPUino bitstream from the flash.
6. Start the USB-to-serial server in debugging mode to create a connection between the USB port and one of the COM ports (I used COM8 here): `usb2serial -d -c 8 -m 253`.
7. Start the ZPUino IDE and select the `ZPUino 2.0 on XuLA2 (LX9)` as your board and the other end of the null-modem connection for the port (`COM7` in this case).
8. Create, compile, and download some ZPUino C source code. I used the RGB LED demo code found
[here](https://github.com/xesscorp/ZPUino-HDL/blob/RGB_LED_Example/zpu/hdl/zpuino/boards/xula2/xula2/RGB_color_ramp/RGB_color_ramp.ino).
Once the object code is downloaded and starts executing, the ZPUino will run an RGB LED through a sequence of colors.
That may sound pretty complicated, but most of these steps only have to be done once. After the first run, developing ZPUino software is just a matter of plugging in the XuLA (the ZPUino bitstream is stored in flash), initiating the usb2serial server (the null-modem emulator is persistent and runs whenever the PC is booted), and starting the ZPUino IDE (all the settings are retained from the last time it was run).
Here's a video of me doing most of it (except for all the software installs):
<iframe class="center-it" width="420" height="315" src="https://www.youtube.com/embed/28_DXxy4mgY" frameborder="0" allowfullscreen></iframe>
<br>
Multi-Year Z80 Build2015-02-03T17:00:00+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/multi-year-z80-build/Let's face it: a lot of us buy dev boards but never get around to doing anything with them. We have the attention span of gnats. But not Roger Milne! He's been on a [three-year mission to build a Z80 computer](http://24.87.49.120/z80computer/z80computer.html) in his spare time. And he did it! Take a look at the block diagram for his home build:
<img src="http://24.87.49.120/z80computer/images/Z80BlockDiagram.gif" class="center-it" style="width:70%"/>
There's a load of stuff in there:
+ A Z80 CPU chip as the main processor.
+ An XC9572 CPLD for the address decoder.
+ An FPGA on a [XuLA2-LX25 board](http://www.xess.com/shop/product/xula2-lx25/) for generating the audio.
+ An FPGA on another XuLA2-LX25 for generating the video.
+ Another CPLD on a daughter card that functions as a 4096-color video DAC.
+ A dsPIC30 for the BIOS MPU.
+ A PIC18F for the input coprocessor.
+ Two Bluetooth serial-port modules that provide wireless control interfaces to the BIOS and Z80 MPUs.
+ A 128-KByte SRAM chip for the main memory.
+ A handful of 74-series chips for miscellaneous logic.
Most of these components are mounted on a couple of 6" × 6" PCBs (a size he selected to allow etching
in a typical Pyrex baking dish):
<div class="contained">
<div class="row">
<div class="span4">
<img src="http://24.87.49.120/z80computer/images/CpuBoardBottom.jpg">
</div>
<div class="span4">
<img src="http://24.87.49.120/z80computer/images/CustomChipBoardBottom.jpg" style="height:275px" class="center-it">
</div>
</div>
<div class="row"><div class="span8"> </div></div>
<div class="row">
<div class="span4">
<img src="http://24.87.49.120/z80computer/images/VideoDac.JPG">
</div>
<div class="span4">
<img src="http://24.87.49.120/z80computer/images/Fpgas.JPG">
</div>
</div>
</div>
In addition to constructing the hardware, there's the equally daunting task of developing the firmware for the microcontrollers, HDL for the FPGAs and CPLDs, and software for the Z80.
To assist with this, he built a bunch of support tools:
+ Convertors for turning images into sprites, tiles, color maps and palettes.
+ Convertors for sound samples and music files.
+ A compiler for the Copper coprocessor inside the video chip.
+ Testbeds for exercising the hardware.
+ Downloading tools for getting everything from the development system into the various processors, FPGAs and CPLDs of the target system.
Finally, knowing that modifications to the CPLD and FPGA HDL would cause changes to register addresses that would have to be propagated into the firmware of the processors, he created a tool to take a hardware definition in a text database and spit it out as headers for various compilers.
That made it much easier to keep all the pieces of his design in sync.
His tool even outputs a [nice table of register addresses](http://24.87.49.120/z80computer/docs/RegisterMap.html) that can be used for documentation.
Now, some will look askance at building a Z80-based computer in an age where a four-core Raspberry Pi running at 900 MHz goes for $35. But there's no denying that Roger mastered a tremendous range of technical subjects during his three-year odyssey that will have a large payback as he continues building stuff. This really is a case where it's the journey and not the destination.Terminal Velocity!2015-01-27T16:00:50+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/terminal-velocity/<img alt="Terminal communication with an application." class="float-it-left"
src="/static/media/uploads/blog/devbisme/2015-01-24/goal.jpg"
style="width: 40%; box-shadow: none"/>
With processor-based systems, many of us like the simplicity and flexibility
of communicating with our software applications through a terminal
(like [PuTTY](http://en.wikipedia.org/wiki/PuTTY)).
Taken to an extreme, some of us even want to communicate with our
*FPGA applications* through a terminal.
But that can be difficult with something like the [XuLA FPGA board](http://www.xess.com/store/fpga-boards/),
which doesn't even have a serial port.
So what do you do?
For the XuLA, I've beaten problems like this before by building a data pipeline
that goes through the USB link to talk with application logic in the FPGA as shown
[here](/blog/test-results-for-my-first-kicad-board/)
and [here](/blog/playing-around-with-sound/).
But those examples use a Python API on the host computer side and any data
buffering in the FPGA is implemented using the SDRAM, which is "complicated".
Sometimes I'd like a simpler system with a couple of FIFOs: one that the
application logic can dump data into so that it will eventually appear
back at the PC, and another that receives data from the PC which
the application logic can read.
<img alt="FIFO communication with an application." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/fifos.jpg"
style="width: 55%; box-shadow: none"/>
Of course, the PC needs a way to access the FIFOs, so I can just add
a HostIoToRam interface on that side.
While technically not RAMs, the FIFOs can be read and written using
a RAM-like interface.
A write from the PC over the USB link will push data into the download FIFO, while a read will
pop data from the upload FIFO.
<img alt="PC communication with the FIFOs." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/hostiotoram.jpg"
style="width: 70%; box-shadow: none"/>
That still leaves the problem of providing a terminal-like interface on the PC side.
For that, I'll build a server in Python that mirrors any data coming or going
through the USB link onto a serial link.
<img alt="USB to serial mirroring." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/usb2serial.jpg"
style="width: 40%; box-shadow: none"/>
But how does that help?
Sending data to a serial interface on a PC typically means sending it to
an external serial port.
(Do PCs even have those anymore?)
But my server is running as software inside the PC.
How do I get access to the serial stream of data using PuTTY?
The answer is to use a *null modem emulator*
(also called a [virtual null modem](http://en.wikipedia.org/wiki/Null_modem))
which is a software process that mimics two connected, physical serial I/O ports.
So my server transfers data from the USB link to one serial port while
the PuTTY talks to the other serial port.
The end result is that PuTTY thinks it it talking directly to the
application on the FPGA through a serial interface.
<img alt="Null modem." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/null_modem.jpg"
style="width: 70%; box-shadow: none"/>
Putting it all together, this is what the complete link looks like.
<img alt="Complete communication link." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/complete_link.jpg"
style="width: 100%; box-shadow: none"/>
This is all great in theory, but how do you actually do it?
There are a few issues that need more explanation:
+ What does the FIFO interface look like to the application logic?
+ How is data transferred between the PC and the FIFOs?
+ How does flow control work?
+ What null modem emulator will work with this?
The application logic hooks to the
[FIFOs](https://github.com/xesscorp/VHDL_Lib/blob/master/fifo.vhd)
as follows:
<img alt="FIFO interface to FPGA application logic." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/FPGA_App_Interface.jpg"
style="width: 70%; box-shadow: none"/>
The current piece of data received from the PC (call it `data[T]`) is always available on
the `data_o` bus of the download FIFO.
To pop `data[T]` from the FIFO and get the next data word, the `rmv_i` input is raised.
On the next rising edge of `clk_i` (edge #2 in the example below),
the new data (`data[T+1]`) appears on the `data_o` bus and the
`dnEmpty_o`, `dnFull_o`, and `dnLevel_o` outputs are updated to
reflect the empty, full and occupancy level status of the FIFO, respectively.
<script type="WaveDrom">
{ signal: [
{ name: "clk_i", wave: 'P...' },
{ name: 'rmv_i', wave: '010.', phase: -0.5 },
{ name: 'data_o', wave: '=.=.', data:["data[T]", "data[T+1]"] },
{ name: 'dnEmpty_o', wave: '0.x.' },
{ name: 'dnFull_o', wave: 'x.0.' },
{ name: 'dnLevel_o', wave: '=.=.', data:["N","N-1"] },
],
config: {hscale: 2},
head: {text: 'Down FIFO Pop Example', tick:0}
}
</script>
<br>
For sending data to the PC, a new data word is placed on the `data_i` bus
of the upload FIFO and the `add_i` input is raised.
The new data is accepted on the next rising edge (edge #2 in the example below)
and the status outputs are updated.
<script type="WaveDrom">
{ signal: [
{ name: "clk_i", wave: 'P...' },
{ name: 'add_i', wave: '010.', phase: -0.5 },
{ name: 'data_i', wave: 'x=x.', data:["data"], phase: -0.5 },
{ name: 'upEmpty_o', wave: 'x.0.' },
{ name: 'upFull_o', wave: '0.x.' },
{ name: 'upLevel_o', wave: '=.=.', data:["N","N+1"] },
],
config: {hscale: 2},
head: {text: 'Up FIFO Push Example', tick:0}
}
</script>
<br>
Moving over to the PC-facing side, the FIFOs connect to a
[HostIoToRam module](https://github.com/xesscorp/VHDL_Lib/blob/master/HostIo.vhd)
through a piece of *shim logic*.
<img alt="Host interface to FPGA application logic." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-24/Host_Interface.jpg"
style="width: 80%; box-shadow: none"/>
The shim logic maps the FIFO interfaces into a set of
read/write registers with the following functions:
<div class="center-it">
<table class="table-bordered table-striped" style="width:60%">
<thead>
<tr>
<th style="width:10%">Address</th>
<th style="width:5%">R/W</th>
<th style="width:45%">Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>R</td>
<td>Pop and return data from the upload FIFO</td>
</tr>
<tr>
<td>0</td>
<td>W</td>
<td>Push data onto the download FIFO</td>
</tr>
<tr>
<td>1</td>
<td>R</td>
<td>
Read the empty/full status of both FIFOs:<br>
<ul>
<li>Bit 0: Download FIFO is empty when set</li>
<li>Bit 1: Download FIFO is full when set</li>
<li>Bit 2: Upload FIFO is empty when set</li>
<li>Bit 3: Upload FIFO is full when set</li>
</ul>
</td>
</tr>
<tr>
<td>1</td>
<td>W</td>
<td>Reset both FIFOs to the empty state</td>
</tr>
<tr>
<td>2</td>
<td>R</td>
<td>Get the # of words in the download FIFO</td>
</tr>
<tr>
<td>3</td>
<td>R</td>
<td>Get the # of words in the upload FIFO</td>
</tr>
<tr>
<td>4</td>
<td>W</td>
<td>Outputs an active-high signal to indicate a BREAK condition to the FPGA application logic.</td>
</tr>
</tbody>
</table>
</div>
<br>
To make it easier to use, the VHDL for the HostIoToRam module, shim logic and FIFOs are
packaged together as the
[HostIoComm module](https://github.com/xesscorp/VHDL_Lib/blob/master/HostIoComm.vhd).
Included in the VHDL file is an example FPGA design that accepts characters from a host PC and
echoes them back.
The section of the EchoTest design that interacts with the HostIoComm module
is reproduced below:
-- Instantiate the HostIoComm communication interface.
u2 : HostIoComm
generic map(
SIMPLE_G => true
)
port map(
reset_i => reset_s,
clk_i => clk_s,
rmv_i => rmv_r, -- Pull high to remove data received from the host.
data_o => dataFromHost_s, -- Data from the host.
dnEmpty_o => empty_s, -- False if the download FIFO has data from the host.
add_i => add_r, -- Pull high to add data to FIFO going back to host.
data_i => std_logic_vector(dataToHost_r), -- Data to host.
upFull_o => full_s -- False if the upload FIFO has room for more data.
);
-- This process scans the incoming FIFO for characters received from the host.
-- When found, it removes the character from the incoming FIFO and places it in the FIFO that
-- transmits back to the host. This process works on the falling clock edge
-- while the HostIoComm works on the rising clock edge. So the control signals
-- for the echo transfer are set up on the falling edge and the actual transfer
-- between FIFOs occurs on the next rising edge. The FIFO statuses are also updated
-- on the rising edge so they can have an effect on this process on the next falling edge.
echoProcess : process(clk_s)
begin
if falling_edge(clk_s) then
-- By default, don't add or remove characters (no echo).
rmv_r <= LO;
add_r <= LO;
if (reset_s = LO) and (empty_s = NO) and (full_s = NO) then
-- If there is no reset and the incoming FIFO has data while
-- the outgoing FIFO has room for it, then transfer the
-- character from the incoming to the outgoing FIFO.
rmv_r <= HI; -- Removes char received from host.
dataToHost_r <= unsigned(dataFromHost_s); -- Echo the char.
add_r <= HI; -- Places char on FIFO back to host.
end if;
end if;
end process;
<br>
Since USB data transfers are always initiated by the host device (the PC, in this case),
most of the responsibility for the control of data flowing over the link resides with the
USB-to-serial server
Using the [XSTOOLs Python package](https://pypi.python.org/pypi/XsTools),
the server performs simple register reads/writes to transfer data to/from the FIFOs in the FPGA.
The server implements flow control by querying the FIFO status and level registers and
acting accordingly, i.e. don't send more data if the download FIFO is full or it will be lost,
and don't read data from the upload FIFO if it is empty or else it will be garbage.
The FPGA application logic must also abide by these rules when it sends and receives data.
For the null-modem emulator on linux, [socat](http://unix.stackexchange.com/questions/63116/create-null-modem-pair-linux)
seems to be the most mentioned tool.
For Windows, I had to try several before eventually settling on
[com0com](https://code.google.com/p/powersdr-iq/downloads/detail?name=setup_com0com_W7_x64_signed.exe&can=2&q=)
because it is:
+ Free
+ Compatible with modern versions of Windows
+ Creates persistent null-modem connections that do not disappear after a system reboot.
This video shows how to download the EchoTest bitstream into a XuLa board, create a null-modem interface,
get the USB-to-serial server running, and then connect PuTTY to it for sending/receiving characters.
<iframe class="center-it" width="420" height="315" src="http://www.youtube.com/embed/IIAG8lZMgRQ" frameborder="0" allowfullscreen></iframe>
<br>
Now that terminal-like communications with an FPGA are possible, it should be relatively
easy to add this feature to the [ZPUino and ditch the FTDI-to-UART cable](http://www.xess.com/blog/ive-never-bought-an-arduino-but-now-i-have-1000-of-them/).
<br>
Extending the ZPUino2015-01-06T14:00:00+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/extending-the-zpuino/<img src="/static/media/uploads/blog/devbisme/2015-01-05/ZPUino_Extend.png" class="thumbnail-it float-it-left"/>
In previous posts, I've
[introduced the ZPUino softcore processor](/blog/ive-never-bought-an-arduino-but-now-i-have-1000-of-them/)
and shown how to [build the base instance for an FPGA](/blog/building-the-zpuino/).
But the real advantage of the ZPUino is being able to extend it by attaching new peripherals
to the core processor in the VHDL description.
The best way to learn something is by doing it, so in this post I'll show how to integrate a
simple RGB LED driver peripheral into the ZPUino.
The ZPUino architecture incorporates 16 *slots* that can be populated with peripherals.
A particular slot is activated when the ZPUino core processor accesses an I/O address within the
range of addresses assigned to that slot.
Then the peripheral in that slot can pass data back-and-forth with the processor through a
[Wishbone interface](http://en.wikipedia.org/wiki/Wishbone_%28computer_bus%29)
that consists of parallel address and data buses along with control signals and
a handshake synchronization protocol.
The Wishbone interfaces to peripherals are instantiated in the
[top-level module of the ZPUino VHDL code](https://github.com/xesscorp/ZPUino-HDL/blob/RGB_LED_Example/zpu/hdl/zpuino/boards/xula2/xula2/xula2_top.vhd).
Within the module are empty slots like this:
--
-- IO SLOT 9
--
slot9: zpuino_empty_device
port map (
wb_clk_i => wb_clk_i, -- Clock to peripheral.
wb_rst_i => wb_rst_i, -- Reset to peripheral.
wb_dat_o => slot_read(9), -- Data from peripheral.
wb_dat_i => slot_write(9), -- Data to peripheral.
wb_adr_i => slot_address(9), -- Address to peripheral.
wb_we_i => slot_we(9), -- Write-enable to peripheral.
wb_cyc_i => slot_cyc(9), -- Cycle handshake to peripheral.
wb_stb_i => slot_stb(9), -- Chip-select to peripheral.
wb_ack_o => slot_ack(9), -- handshake acknowledge from peripheral.
wb_inta_o => slot_interrupt(9), -- Interrupt from peripheral.
id => slot_ids(9) -- Peripheral ID (not part of Wishbone).
);
All the signals are part of the Wishbone interface except for `id` which outputs a peripheral-specific code
that the ZPUino processor can use to associate a peripheral performing a specific function
(e.g., a UART) with software drivers for that function.
I constructed the RGB peripheral according to the following block diagram:
<img alt="Block diagram for a Wishbone-compliant RGB LED driver peripheral." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-05/RGB_Peripheral_Blk_Diag.jpg"
style="width: 70%; box-shadow: none"/>
The Wishbone interface allows the processor to read or write a single 32-bit register at address 0.
Each of the lower three bytes of this register controls the duty-cycle of a
pulse-width modulator (PWM).
Varying the duty cycles of the PWMs will change the intensities of the red, green and blue components
which changes the overall color of the RGB LED.
For the excruciating operational details, check out the VHDL for the [PWM](https://github.com/xesscorp/VHDL_Lib/blob/master/pwm.vhd)
and the [RGB peripheral](https://github.com/xesscorp/VHDL_Lib/blob/master/RgbLed.vhd).
Next, I instantiated the RGB peripheral in the top-level ZPUino module as follows:
--
-- IO SLOT 9
--
slot9: WbRgbLed
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_dat_o => slot_read(9),
wb_dat_i => slot_write(9),
wb_adr_i => slot_address(9),
wb_we_i => slot_we(9),
wb_cyc_i => slot_cyc(9),
wb_stb_i => slot_stb(9),
wb_ack_o => slot_ack(9),
wb_inta_o => slot_interrupt(9),
id => slot_ids(9),
redLed_o => led_r, -- Output for driving red led.
grnLed_o => led_g, -- Output for driving green led.
bluLed_o => led_b -- Output for driving blue led.
);
The `led_r`, `led_g`, and `led_b` output signals have to be attached to pins of the ZPUino
in order to connect to the physical RGB LED. I could have made these pin assignments
statically, but the ZPUino provides a much more flexible solution with its
*Peripheral Pin Select* (PPS) mechanism. The PPS is basically a collection of
multiplexers that allow any one of *N* outputs to be attached to any one of *M*
pins under software control. (There is an equivalent PPS block for redirecting the inputs.)
So with the PPS, I can assign the ZPUino pins that output the RGB PWM signals at run-time.
<img alt="PPS output block diagram." class="center-it"
src="/static/media/uploads/blog/devbisme/2015-01-05/PPS_Blk_Diag.jpg"
style="width: 70%; box-shadow: none"/>
Within the top-level ZPUino VHDL module, I attached the RGB peripheral outputs to
the output PPS as follows:
process(gpio_spp_read, spi_pf_mosi, spi_pf_sck,
sigmadelta_spp_data,timers_pwm,
spi2_mosi, spi2_sck, led_r, led_g, led_b )
begin
gpio_spp_data <= (others => DontCareValue);
-- PPS Outputs
gpio_spp_data(0) <= sigmadelta_spp_data(0); -- PPS0 : SIGMADELTA DATA
ppsout_info_slot(0) <= 5; -- Slot 5
ppsout_info_pin(0) <= 0; -- PPS OUT pin 0 (Channel 0)
.
.
.
gpio_spp_data(6) <= uart2_tx; -- PPS6 : UART2 TX
ppsout_info_slot(6) <= 8; -- Slot 8
ppsout_info_pin(6) <= 0; -- PPS OUT pin 0 (Channel 1)
-- Attach the RGB LED driver outputs to the PPS outputs.
gpio_spp_data(7) <= led_r; -- PPS7 : Red LED driver
gpio_spp_data(8) <= led_g; -- PPS8 : Green LED driver
gpio_spp_data(9) <= led_b; -- PPS9 : Blue LED driver
-- PPS inputs
spi2_miso <= gpio_spp_read(0); -- PPS0 : USPI MISO
ppsin_info_slot(0) <= 6; -- USPI is in slot 6
ppsin_info_pin(0) <= 0; -- PPS pin of USPI is 0
uart2_rx <= gpio_spp_read(1); -- PPS1 : UART2 RX
ppsin_info_slot(1) <= 8; -- USPI is in slot 6
ppsin_info_pin(1) <= 0; -- PPS pin of USPI is 0
end process;
In order to make room in the PPS for the new outputs, I bumped-up the `PPSCOUNT_OUT` constant in the
[`zpuino_config.vhd`](https://github.com/xesscorp/ZPUino-HDL/blob/RGB_LED_Example/zpu/hdl/zpuino/boards/xula2/xula2/zpuino_config.vhd)
file:
-- Set this to the max. number of output pps on the system
constant PPSCOUNT_OUT: integer := 10; -- Increased to handle RGB LED drivers.
After making these changes, I rebuilt the ZPUino FPGA bitstream with the newly-added RGB peripheral.
Now it's just a matter of writing the software for accessing the new peripheral.
I'll demonstrate this by writing an
[example program](https://github.com/xesscorp/ZPUino-HDL/blob/RGB_LED_Example/zpu/hdl/zpuino/boards/xula2/xula2/RGB_color_ramp/RGB_color_ramp.ino)
that ramps-up and then fades an RGB LED over a sequence of colors.
The program starts (as most do) with a set of definitions.
This is where I tell the program about the decisions I made in the VHDL code:
the location of the RGB peripheral (slot 9), the address offset of the color register (0),
and the position of the red, green and blue outputs going into the PPS block (7, 8, and 9).
I also specify the ZPUino pins that the RGB LED will be connected to (5, 4 and 3).
// Slot the RGB peripheral is assigned to.
#define RGB_SLOT 9
// Address of the color register in the RGB peripheral.
#define COLOR_REG 0
// Position of the red, green and blue PWM outputs
// within the PPS output block.
#define RED_PPS_POS 7
#define GRN_PPS_POS 8
#define BLU_PPS_POS 9
// ZPUino pins for driving an RGB LED.
#define RED_PIN 5
#define GRN_PIN 4
#define BLU_PIN 3
Next, I use these definitions in the `setup()` routine.
The ZPUino pins driving the RGB LED are enabled as outputs,
and these outputs are driven by the multiplexers from the PPS.
Then each multiplexer is programmed to output one of the PWM signals
from the RGB peripheral.
void setup() {
// Enable the outputs to the RGB LED.
pinMode(RED_PIN, OUTPUT);
pinMode(GRN_PIN, OUTPUT);
pinMode(BLU_PIN, OUTPUT);
// Enable the peripheral pin multiplexer for the outputs.
pinModePPS(RED_PIN, HIGH);
pinModePPS(GRN_PIN, HIGH);
pinModePPS(BLU_PIN, HIGH);
// Map the PWM outputs to the RGB output pins.
outputPinForFunction(RED_PIN, RED_PPS_POS);
outputPinForFunction(GRN_PIN, GRN_PPS_POS);
outputPinForFunction(BLU_PIN, BLU_PPS_POS);
}
Then there's the little `set_rgb_color()` subroutine that accepts a 24-bit color value
and writes it to the color register within the RGB peripheral.
The `IO_SLOT(RGB_SLOT)` macro-call generates the base address for the RGB peripheral.
Then the `REGISTER(...)` macro-call adds the offset of the color register
to the base address to generate the final address where the new color value is written.
void set_rgb_color(unsigned int color)
{
REGISTER(IO_SLOT(RGB_SLOT), COLOR_REG) = color;
}
The meat of the example program is contained in the `brighten_then_fade()` subroutine that ramps the RGB LED
up to its maximum color intensity and then down to zero.
It accepts a `color_increment` argument that contains either a 0 or a 1
in each of its eight-bit fields.
For example, the value `0x000101` would change both the red and green
fields while leaving the blue component alone.
Starting from zero, this argument is added to the RGB color until it reaches
its maximum intensity (`0x00FFFF` for the example value of the `color_increment`).
Then the argument is subtracted from the color until it again reaches zero.
void brighten_then_fade(unsigned int color_increment)
{
// Start at black and ramp up color intensity.
unsigned int color = 0;
for(int i=0; i<256; i++)
{
set_rgb_color(color);
color += color_increment;
delay(3);
}
// Stay at maximum intensity for a while.
delay(200);
// Ramp back down to black.
for(int i=0; i<255; i++)
{
color -= color_increment;
set_rgb_color(color);
delay(3);
}
}
Finally, there's the never-ending `loop()` routine that applies the previous subroutine
to a sequence of colors:
void loop() {
// Color sequence: red, green, blue, yellow, magenta, cyan and white.
unsigned int color_increment[] = {0x000001, 0x000100, 0x010000, 0x000101, 0x010001, 0x010100, 0x010101};
// Brighten and then fade each color in the sequence.
for(int i=0; i<sizeof(color_increment)/sizeof(unsigned int); i++)
brighten_then_fade(color_increment[i]);
}
When I run the program on the extended ZPUino, I get the expected output on the LED as shown here:
<iframe class="center-it" width="420" height="315" src="//www.youtube.com/embed/VixKPF7m-RI" frameborder="0" allowfullscreen></iframe>
So to recap, I added a new peripheral to the ZPUino by:
+ Describing the peripheral using VHDL.
+ Putting a Wishbone interface on it.
+ Instantiating the peripheral in one of the empty slots in the top-level ZPUino module.
+ Adding input and output signals of the peripheral to the PPS blocks.
+ Writing ZPUino code using the `IO_SLOT` and `REGISTER` macros to access the peripheral.
That's it!
ESP8266: Reflash Dance!2014-12-19T19:13:13+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/esp8266-reflash/<img src="http://i.dailymail.co.uk/i/pix/2011/03/15/article-1366374-01E4A6C5000004B0-566_233x338.jpg" class="thumbnail-it float-it-left"/>
It's been a while since I [connected my ESP8266 board to a ZPUino soft processor running in a XuLA2 board](http://www.xess.com/blog/esp8266-it-dont-come-easy/). I thought I would update the firmware on the ESP8266 to the latest version and see if it still worked.
Since everyone is compiling [new applications for the Espressif chip](http://bbs.espressif.com/viewtopic.php?f=7&t=67) now, merely reprogramming the serial flash on the board should be easy, right? Just download a binary file and you're done! It turned out to be a bit more confusing.
[Note #1: If you would rather watch than read, there is a video at the end of this post that goes through the flash reprogramming process.](#reflash_video)
[Note #2: Here's a newer post about building the hardware and reprogramming an ESP-201 module using the Arduino IDE.](/blog/esp8266-re-reflash-dance/)
Part of the confusion is that there are a lot of different programming tools being used: binary executables, Python scripts, whatever. Some tools require [specifying four different binary files](http://scargill.wordpress.com/2014/11/29/espressif-update-for-esp8266/), one for each particular address range of the flash chip. But the downloadable archives don't usually have four files in them, and if they do, they don't have filenames matching the ones shown in the examples. I didn't want to brick my modules, even if [they only cost $2.71/each](http://www.aliexpress.com/item/2PCS-ESP8266-Serial-Esp-01-WIFI-Wireless-Transceiver-Module-Send-Receive-LWIP-AP-STA/32232009463.html).
Finally, I settled on using the Espressif's official [`esp8266_flasher.exe` program](https://drive.google.com/file/d/0B3dUKfqzZnlwVGc1YnFyUjgxelE/view?usp=sharing). I also downloaded the [`v0.9.2.2 AT Firmware.bin` file](https://drive.google.com/file/d/0B3dUKfqzZnlwdUJUc2hkZDUyVjA/view?usp=sharing).
After dumping the contents of both archives into a local directory, I had this:
<img alt="Files found in the downloaded ESP8266 flash programming archives." class="center-it" src="/static/media/uploads/blog/devbisme/2014-12-09/directory_contents.jpg" style="width: 60%;"/>
Double-clicking the `esp8266_flasher.exe` icon brought up the flashing tool:
<img src="/static/media/uploads/blog/devbisme/2014-12-09/esp8266_flash_tool.jpg" class="center-it" style="width:60%;" alt="ESP8266 flashing tool." />
Clicking the `Bin` button opened a window where I selected the binary file to download into the serial flash of the board:
<img src="/static/media/uploads/blog/devbisme/2014-12-09/select_bin.jpg" class="center-it" style="width:60%;" alt="Flashable binary files." />
Selecting the `v0.9.2.2 AT Firmware.bin` file and clicking `Open` took me back to the main window with the firmware file displayed in the `Bin` field.
<img src="/static/media/uploads/blog/devbisme/2014-12-09/ready_to_flash_1.jpg" class="center-it" style="width:60%;" alt="Binary file ready for downloading to the serial flash on the ESP8266 board." />
Next I needed to put the ESP8266 into its flash programming mode. This is done by resetting the ESP8266 board while holding its GPIO0 pin low. I could do this with a few wires and a breadboard but, since I might be doing this more than once, I decided to build a little programming board. It has a 4 × 2 socket for the ESP8266 board that is wired to a header where my C232HM USB-to-serial cable is attached. A couple of 2.2 KOhm pullup resistors for the chip-select and reset pins keep the ESP8266 enabled. `PROG` and `RESET` pushbuttons are provided to momentarily pull the GPIO0 and reset pins input to ground, respectively.
<div class="container">
<div class="row">
<div class="span4">
<img alt="ESP8266 flash programming board schematic." src="/static/media/uploads/blog/devbisme/2014-12-09/esp8266_flash_prog_board_sch.png">
</div>
<div class="span1"></div>
<div class="span4">
<img alt="ESP8266 flash programming board." src="/static/media/uploads/blog/devbisme/2014-12-09/esp8266_flash_prog_board.jpg">
</div>
</div>
</div>
After inserting my ESP8266 board into the programming board and attaching the C232HM cable, I entered the flash programming mode by holding down the `PROG` button and then pressing and releasing the `RESET` button. In the flashing tool, I changed the serial port from `COM1` to `COM6` because that's where the CH232HM cable resides on my system. Clicking on the `Download` button started the reprogramming of the flash chip. The progress was displayed in the lower pane of the window and, after about a minute, the reprogramming was done.
<img src="/static/media/uploads/blog/devbisme/2014-12-09/flashing_done.jpg" class="center-it" style="width:60%;" alt="Progress pane after the flash programming is done." />
Note that the progress pane indicated "Failed to leave flash mode". That's probably because the flashing program doesn't have any way to bring the ESP8266 board out of programming mode. But it's not really a problem provided the contents of the flash chip were rewritten.
To verify the flash programming was successful, I needed to talk to the chip and query the firmware version. I closed the flash programming window and pressed the `RESET` button (without pressing the `PROG` button) to place the ESP8266 board in user mode. Then I brought up a PuTTY window and configured it as shown below.
Note that I set the speed to 9600 bps. The new firmware defaults to this communication rate rather than the 115 Kbps rate used in the factory-installed firmware.
<img src="/static/media/uploads/blog/devbisme/2014-12-09/putty_config.jpg" class="center-it" style="width:60%;" alt="PuTTY configuration." />
After opening the PuTTY terminal window, I sent the ESP8266 the reset command (`AT+RST`) and then had it print the firmware version (`AT+GMR`). The version was shown to be 0018000902 rather than the 00160901 version that originally came loaded in the board. So the firmware update appeared to have worked.
<img src="/static/media/uploads/blog/devbisme/2014-12-09/show_fmw_version.jpg" class="center-it" style="width:60%;" alt="PuTTY configuration." />
In order to push the transfer speed of the board back up to 115 Kbps (since the ZPUino can handle that speed, there's no need to cripple the interface), I used the `AT+CIOBAUD=115200` command. Then I checked that the change took using the `AT+CIOBAUD?` command. (Observe that it required two attempts to change the baud rate, so don't be put off if that happens to you.) The baud rate is stored in nonvolatile memory so it will remain in effect from then on, even if the power is interrupted or a reset occurs.
<img src="/static/media/uploads/blog/devbisme/2014-12-09/change_speed.jpg" class="center-it" style="width:60%;" alt="PuTTY configuration." />
With the new firmware in place and the baud rate back at 115Kbps, I took the ESP8266 module from the programming jig and put it back into [my ZPUino development board](/blog/esp8266-lets-get-physical/). Now it was just a matter of running [my existing program](https://gist.github.com/xesscorp/3f791cdec611db3eb400#file-esp8266-ino) that downloads the contents of a web page over the wireless link, right?
<img alt="Attachment of prototyping board with ESP8266 Wifi module to StickIt! board with XuLA2 FPGA board" class="center-it" src="/static/media/uploads/blog/devbisme/2014-10-11/ready_to_program.jpg" style="width: 40%;">
Wrong! It turned out the update of the ESP8266 firmware is sufficiently different that the following minor changes were needed:
+ AT commands to the ESP8266 had to be terminated with "\015\012" (ctrl-M, ctrl-J or carriage-return, linefeed) instead of "\n".
+ After initiating a reset using the AT+RST command, the string the ESP8266 uses to terminate its response changed from "ready" to "ai-thinker.com]".
While making those changes, I also had to fix my code for timing-out if no characters were received from the ESP8266. The updated program can be found [here](https://gist.github.com/xesscorp/0f3546c674fb7e1d34ac).
So after all that, I finally had an updated Wifi module and a working example. I hope this procedure helps if you decide to update your own ESP8266.
<a name="reflash_video"></a>Finally, if you're someone who would rather watch than read, then here's a video showing the entire process of updating the ESP8266 firmware:
<iframe class="center-it" width="420" height="315" src="//www.youtube.com/embed/cOnPWltYtQs" frameborder="0" allowfullscreen></iframe>
Necessity is a Mother...2014-11-18T04:58:53+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/necessity-is-a-mother/<img src="http://3.bp.blogspot.com/-L5p5ODnxW40/T8exr0DoEkI/AAAAAAAALaE/_-ZoirzcfMQ/s1600/water-bottle-sandal.jpg" class="thumbnail-it float-it-left"/>
Sometimes things go well. And then they don't. And then you have to improvise.
I had a 5cm × 5cm panel containing two boards connected by a break-away tab.
[Itead](http://imall.iteadstudio.com/open-pcb/pcb-prototyping.html) had previously fabricated this for me.
When I submitted the Gerber files this time, Itead rejected it because the tab connecting the two boards was too thin.
They recommended using a 10mm tab.
<img src="/static/media/uploads/blog/devbisme/2014-11-17/itead_reject_1.png" class="center-it" style="width:40%" alt="Itead rejection #1: connecting tab to narrow."/>
So I widened the tab and resubmitted the panel. They rejected it again, saying that I could not have so many drill holes so close together.
<img src="/static/media/uploads/blog/devbisme/2014-11-17/itead_reject_2.png" class="center-it" style="width:40%" alt="Itead rejection #2: Holes too closely packed."/>
So I replaced the single tab with two, thinner tabs spaced further apart. Itead rejected it again:
Here are sub-board in your panel, but the slot between them is not pernitted.
Also please increase the coonection between them to at least 1 cm.
Obviously, there's no getting anything past them!
At this point, it looked like I would have reduce the panel to a single instance of the board in order to have Itead fabricate it.
But Itead charges $9.90 to make ten 5cm × 5cm panels regardless of how much of the panel I use.
So now I was only going to get ten individual boards whereas I was getting twenty boards in previous orders.
Since I use Itead to get small runs of boards for low-volume products, this would essentially double my PCB costs.
So I decided to give [Seeed Fusion PCB service](http://www.seeedstudio.com/service/index.php?r=pcb) a try.
They have the same deal as Itead: ten 5cm × 5cm panels for $9.90.
Seeed uses an automated system that scans your Gerber files upon order submission and then assigns the panel size depending
upon your dimensions.
In my case, Seeed's system came up with a panel size of 10cm × 5cm, even though my panel fits into a 5cm × 5cm area.
So I contacted Seeed's customer support and said "what's the dealio, yo?" (No, I didn't really say *that.*)
They replied:
We make the board size according to the outline, the part out off the outline may be cut off. So please make sure all the layer are in the outline.
Well, the panel outline as defined in my `.GKO` Gerber file *did* fit in the 5cm × 5cm area.
However, my top-level silkscreen didn't; some of the part outlines overlapped the edges of the panel.
Maybe Seeed was actually looking at more than just the `.GKO` file?
To test this, I did a trial submission of my Gerber files with the silkscreen layers omitted.
Sure enough, the Seeed system assigned it to a 5cm × 5cm panel.
Now the question was how to eliminate the silkscreen overlap?
Some of the overlap was caused by part outlines with features that should have only appeared in
the documentation layers (which aren't fabricated) instead of the silkscreen.
I could fix those in the libraries and re-import the parts into the original PCB layout, but then I would have to rebuild the array
and put in the connecting tabs, etc. That seemed like a lot of work.
Plus, it wouldn't fix the overlaps caused by part outlines that actually were supposed to be on the silkscreen
(such as connectors at the edges of the board).
The next option was to edit the Gerber files directly and clip-off the overlaps in the silkscreen layer.
I check my Gerber files using a free program from Pentalogix called [ViewMate](http://www.pentalogix.com/viewmate.php) and it also
allows editing. However, it doesn't allow you to *save* the edited files.
Pentalogix will sell you a program called ViewMate Deluxe which does that. For $95.
Well, I didn't want to pay $95 for a program that I only needed to clip-off some silkscreen.
Plus, I would need to use it manually on any board that had an overlap.
I don't want to do things manually.
*I live in the future, where everything is automatic!*
So I went looking for something that was free and/or open-source to do this for me.
I mean, this isn't some esoteric procedure that only I would want to do, right?
However, the programs that were out there either didn't do editing, had a funky user interface, or wouldn't run on Windows.
But then I found [pcb-tools](https://github.com/curtacircuitos/pcb-tools).
This is a Python module for handling Gerber files.
It seems to be mainly geared for displaying Gerber files.
But right off the bat, it handled getting the bounding box of a layer.
How hard could it be to modify the code to clip-off elements that went outside a given bounding box?
Well, it was a *little* harder than I thought. I had to recall how to clip a line segment
against a bounding box from the computer graphics course I taught 25 years ago.
Then there were those little edge cases (literally) where the endpoints of segments ended up right on the edge of the bounding box.
But, eventually, [I got it working](https://github.com/xesscorp/pcb-tools).
Here's the result for my board as seen with ViewMate:
<div class="container">
<div class="row">
<div class="span3">
<img src="/static/media/uploads/blog/devbisme/2014-11-17/overlap.png"/ alt="Original board outline and silkscreen showing overlap.">
</div>
<div class="span3">
<img src="/static/media/uploads/blog/devbisme/2014-11-17/clip.png"/ alt="Board outline with clipped silkscreen.">
</div>
<div class="span3">
<img src="/static/media/uploads/blog/devbisme/2014-11-17/overlap_clip.png"/ alt="Superimposed clipped and unclipped silkscreens.">
</div>
</div>
<div class="row">
<div class="span3">
<p>The original silkscreen with the board outline. Notice the overlap.</p>
</div>
<div class="span3">
<p>The clipped silkscreen with the board outline. No more overlaps.</p>
</div>
<div class="span3">
<p>The original silkscreen superimposed with the clipped version.
The magenta shows where they coincide.
Notice that only the part of the silkscreen outside the bounding box has been removed.
</div>
</div>
</div>
Using my new program, I was able to clip my silkscreen layer and resubmit my panel to Seeed.
They accepted it with a panel size of 5cm × 5cm. Success!
ESP8266: "It don't come easy!"2014-10-18T16:20:22+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/esp8266-it-dont-come-easy/<img src="http://news.upperplayground.com/wp-content/uploads/2010/07/e03365af2905x598.jpg.jpg" class="thumbnail-it float-it-left"/> Nobody ever accused Ringo of being the smartest Beatle, but he sure nailed that particular bit of philosophy: It don't come easy! Not only when singing the blues, but for pretty much everything else as well. I found that out first-hand.
After [building my ESP8266 protoboard](http://www.xess.com/blog/esp8266-lets-get-physical/), my next task was to recompile the VHDL of the ZPUino to add another serial port for communicating with the Wifi module. The microcontroller core in the ZPUino can be augmented with [Wishbone](http://en.wikipedia.org/wiki/Wishbone_(computer_bus))-compatible peripherals that communicate with the core through a set of sixteen *slots*. One slot is already occupied by a UART that's used to talk to the ZPUino IDE running on the PC, so it was just a matter of instantiating another UART in an empty slot. Easy enough.
Once the ZPUino VHDL was recompiled and downloaded to the XuLA board, it was all down to the programming. Getting access to the second serial port requires a single declaration:
HardwareSerial esp8266(2); // Find the second UART attached to the ESP8266 module.
This causes the ZPUino to scan through the sixteen slots and query the identifier of every device it finds. Once it finds the second UART, it maps the register address space of the device to the `esp8266` object.
The ZPUino also supports a feature called *Peripheral Pin Select* (PPS). This allows the assignment in software of a peripheral's I/O signals to any of the physical I/O pins of the ZPUino. Connecting the transmit and receive pins of the UART to the receive and transmit pins of the ESP8266 module is done like this:
esp8266.begin(115200, TX(3), RX(17)); // Set bit-rate and assign transmit and receive pins.
(I had previously mapped-out that I/O pins 3 and 17 of the ZPUino exited the XuLA board, traversed the StickIt! board, exited through the PM2 connector, entered my protoboard, and terminated on the serial receive and transmit pins of the ESP8266 module.)
I made these small changes to an [existing program](http://dunarbin.com/esp8266/retroBrowser.ino) that uses the ESP8266 module to [load a version of the hackaday website](http://hackaday.io/project/3072/instructions). I compiled and downloaded the program to my ZPUino and ...
Nothing.
OK, it was unreasonable to expect that was going to work. So I started tracing out the problems. First, I needed to make sure the PPS mapping was OK. I attached an LED to the FPGA pin that outputs the serial datastream to the ESP8266 module. It came on, which is good because that shows the output is active. (If I had messed up the PPS assignment, the pin would have been in a high-impedance mode and the LED would have been off.)
Next, I slowed the tranmission rate from 115200 down to 300 bits per second. That would allow me to see the LED flickering as the serial data was transmitted. Unfortunately, the LED stayed on solidly when I executed the program. So the program wasn't accessing the second serial port.
With the help of some ZPUino library routines that check the status of devices, I found the second serial port wasn't getting assigned and its register space wasn't mapped. Poking through the library code, I found an error that skipped any duplicate device after the first had been mapped. Since the ESP8266 serial port was the second UART, it was just ignored.
After correcting my copy of the library (and filing a bug report with the ZPUino's author), I recompiled the program and ...
Success! The LED flickered, showing that serial data was getting to the ESP8266 module.
Restoring the transmission rate back to 115200 bps and executing the program again brought some results that resembled my [initial tests of the ESP8266 module using the C232HM cable](http://www.xess.com/blog/esp8266-is-alive/). The module reset and firmware version commands were eliciting the correct responses, but the connection to the website was still failing.
By echoing the commands back to the terminal on the PC, I could see the connection wasn't being made because the IP address and other pieces of information weren't getting inserted into the command strings. After running a few simple tests, I found the `String` class wasn't operating as it should: creation and concatenation operations were just returning empty strings. Looking through the library code again, I found the `realloc` subroutine was just a stub that always returned a NULL pointer. (This was probably a placeholder and the originator never got around to replacing it with something that functioned.) I wrote a naive implementation and sent another bug report.
Now when I recompiled and ran my code, the correct command strings were generated but it still wasn't connecting and was sometimes responding `Busy...` when commands were sent. At this point, I went to the [ESP8266 forum](http://www.esp8266.com) to see if more experienced users had some wisdom. There I found mention of the `Busy...` prompt coming from the ESP8266, indicating it was still working on a previous operation and could not accept a new command string. I also saw that tying the reset, chip-select, and general-purpose I/O pins to 3.3V was thought to make the chip act more reliably.
So I went back and modified my protoboard to tie those pins high and then re-ran the program ...
No change. The same errors occurred.
At this point I couldn't figure out why some commands worked when I typed them in manually through the C232HM cable, but wouldn't work when the ZPUino sent the same commands (e.g., the `AT+CWLAP` for listing any in-range access points). The only difference was that I entered the commands much more *slowly*. So I modified my program to put a five-second delay between each command transmission and ran it ...
Success! It connected to the website and retrieved the HTML for the page. You can see a trace of the commands and responses [here](https://gist.github.com/xesscorp/edc69d2aa3aed30c46f2#file-esp8266_connection_trace).
Now it was just a matter of reducing the delays to their minimum values and removing any unneeded delays between commands. In the end, only three delays remained: a two-second delay before the access points were listed, a four-second delay after the Wifi connection was made, and a final two-second delay after establishing the TCP link to the website. The finished program can be seen [here](https://gist.github.com/xesscorp/3f791cdec611db3eb400#file-esp8266-ino).
I hope this helps some others get their ESP8266 modules working. Most of my problems were caused by the ZPUino libraries, but the ESP8266 is still finicky about how you talk to it. However, I was still able to get it to work with the stock firmware that came loaded on it. My next job is to update the firmware and see what effect that has.
Until then, take us out, Ringo!
<iframe class="center-it" width="560" height="315" src="//www.youtube.com/embed/bvEexTomE1I" frameborder="0" allowfullscreen></iframe>
ESP8266: Let's Get Physical!2014-10-11T15:28:47+00:00Dave Vandenbout/blog/author/devbisme/http://www.xess.com/blog/esp8266-lets-get-physical/<p><img class="thumbnail-it float-it-left" src="http://cdp.crida.net/2014/wp-content/uploads/2014/02/physical2450sp4.jpg">I've gone through <a href="http://www.xess.com/blog/esp8266-resources/">a bunch of resources about the ESP8266 Wifi module</a> and <a href="http://www.xess.com/blog/esp8266-is-alive/">verified that I have a couple of working units</a>, so now it's time to start using them with a <a href="http://www.xess.com/blog/ive-never-bought-an-arduino-but-now-i-have-1000-of-them/">ZPUino softcore processor running on a XuLA2 board</a>.</p>
<p>But before I could actually start writing programs, I needed to physically attach the ESP8266 module to a XuLA2 board. The module has an unfriendly 4x2 header that doesn't conveniently fit into a breadboard. And the arrangement of power, ground and I/O pins on the header doesn't match up with any of the connectors on the <a href="http://www.xess.com/shop/product/stickit-mb/">StickIt! board</a>.</p>
<p>Then I remembered I designed some small StickIt! prototyping boards for last year's <a href="http://www.xess.com/blog/learn-fpga-programming-with-myhdl/">PyOhio class on programming FPGAs</a>. I figured I could mount an ESP8622 module on one of those, insert it in a PMOD connector of a StickIt! board, and then insert a XuLA2 in the StickIt! board socket.</p>
<p>I didn't want to solder one of my ESP8266 modules to the prototyping board, so I decided to build a socket for it. I had some six-pin, right-angle PMOD sockets laying around, so I ripped out some pins, cut-and-sanded the socket housing, and bent the leads into a pattern to fit on the board as shown below.</p>
<div class="container">
<div class="row">
<div class="span2">
<img alt="A six-pin, right-angle PMOD socket" src="/static/media/uploads/blog/devbisme/2014-10-11/PMOD_socket.jpg">
</div>
<div class="span2">
<img alt="Removing pins from the PMOD socket" src="/static/media/uploads/blog/devbisme/2014-10-11/rip_out_pins.jpg">
</div>
<div class="span2">
<img alt="Cut and sand the PMOD socket housing" src="/static/media/uploads/blog/devbisme/2014-10-11/cut_and_sand.jpg">
</div>
<div class="span2">
<img alt="Bend the PMOD socket leads to fit the prototyping board" src="/static/media/uploads/blog/devbisme/2014-10-11/bend_leads.jpg">
</div>
</div>
</div>
<p>Then I mounted the modified socket and made connections from the serial TX and RX, reset, and select pins of the ESP8266 module to the PMOD interface of the prototyping board.</p>
<p><img alt="Completed prototyping board with socket for ESP8266 Wifi module" class="center-it" src="/static/media/uploads/blog/devbisme/2014-10-11/finished_protoboard.jpg" style="width: 40%;"></p>
<p>Finally, I inserted the ESP8266 module into the socket and attached the prototyping board to a StickIt! board with a XuLA2 FPGA board. VoilĂ , a nice, neat little package ready for programming!</p>
<p><img alt="Attachment of prototyping board with ESP8266 Wifi module to StickIt! board with XuLA2 FPGA board" class="center-it" src="/static/media/uploads/blog/devbisme/2014-10-11/ready_to_program.jpg" style="width: 40%;"></p>