Getting started with STM32
Dec 7, 2016

ARM Cortex microcontrollers are incredibly powerful 32-bit computers - many not larger than the size of a fingernail, and able to sleep with just a few µA of current draw. There’s a whole bunch of cheap little boards on eBay so you don’t even have to get your soldering iron to have a lot of fun with ‘em:

But there’s a catch: you also need a way to connect to them, and you need the proper toolchain to write code for them and upload it into the chips. This week’s article series is about overcoming all these pesky hurdles:

Next week, I’ll re-use these boards and do something different with ‘em - stay tuned!

For comments, visit the forum.

Blu-Ray safety copies
Nov 30, 2016

Having been bitten by data loss occasionally during the past decades (several of them dumb “operator error”, I must admit), I’ve adjusted my backup strategy a few times.

Since I live in an “all-Mac” world (plus a bunch of RasPi/Odroid Linux boxes), I’ve been adopting other solutions than some people out there, I suppose.

Data storage requirements are fairly low here at JeeLabs. I don’t keep a video collection (I don’t see the point, we rarely watch a movie more than once). We only have a growing personal photo collection (over 45,000 by now), lots of music CDs, ripped from the physical version, and my personal stash of articles, PDFs, source code, and tons of web pages (saved as full-search “web archives”, not URLs).

A central Odroid file server has backup copies of much of this, but Liesbeth and I use well under 1 GB (yes: “G”) of shared storage right now. Everything else resides on our two machines, i.e. a Mac Mini and a MacBook Pro. It’s less than 2 TB of data.

As I said: we have fairly low storage needs.

But what we store is important to us. So I keep 3 external 2.5” hard disks (each of a different brand), and use them to rotate backups, automatically maintained several times a day by Time Machine, which is built into Mac OSX (soon to be called “macOS”).

Once a week, I swap disks. Roughly once a month, I swap one of ‘em with my parents.

So far so good, but if a virus were to roam around undetected for a month, I’d be in trouble. Which is why I keep extra copies on old IDE/SATA hard drives… just in case.

Except that hard drives fail, even when off-line. Magnetism is not a permanent state, rotating media sometimes won’t, and disk connectors change (remember PATA?).

So I’ve decided to use these for cold storage:

That’s a single-layer Blu-Ray disk (disc?), with an estimated 250,000,000,000 little burn marks in it (assuming 25% overhead for error-correction) - €0.60 each, amazing!

Blu-Ray is not mainstream, but for archival storage it’s great: low cost burners for disks of 25..100 GB and write-once. When stored, they’re said to last over 50 years (with the M-DISC variant claiming 1,000 years…).

I bought a USB-connected “LG BP55EB40” burner, a 50-pack of single-layer disks, and a few dual-layer ones - just for kicks. It also reads and writes CD-ROMs and DVDs:

On Mac OSX, this drive works out of the box, and without extra software: push a blank disk in, a “burn folder” opens, drag stuff to it (it creates symlinks, without copying anything, and reports remaining free space), then click the “Burn” button, choose a name + speed setting, and wait. When done, the drive ejects the new disk.

Burning 25 GB takes about 40 minutes and verifying almost doubles that. I had a few verification failures, but they all happened before the drive started reading any data - I suspect that it’s a driver timing issue and that it’s harmless. The disks I’ve checked afterwards all had exactly the right set of files with the correct MD5 checksums.

I’ve labeled a pouch to holds all my archive disks. When the pouch fills up, I’ll start replacing disks with dual- or even triple-layer ones, and move the old copies off-site. The pouch sits in our home safe. Only one disk has data which is sensitive enough to require encryption. The rest can be viewed in any Blu-Ray data reader.

Looks like others have had the same idea.

If Blu-Ray disks become obsolete, I’ll have to copy stuff over. But I don’t really expect that to happen - not in my lifetime anyway.

As a gimmick – and to raise awareness – I’ve started telling our family and friends coming over for dinner that “if they bring a laptop, we can make a safety copy of their most precious files and folders” and they’ll get a freshly-baked disk when they leave.

Because an ounce of prevention…

PS. The extended break is over: starting next week, I’ll be posting several articles per week again. Stay tuned for lots of new Physical Computing fun!

For comments, visit the forum.

A fast µC to FPGA bus
Nov 23, 2016

For reasons which will become clear later, I’d like to exchange data quickly between an STM32 µC and an FPGA. SPI is a serial bus, which can be pushed to several dozen Mbit/sec - but what if we want more?

Suppose we could “map” the FPGA into the STM32’s memory space and then simply read and write bytes? No handshaking, no interrupts, no polling. One advantage of such an approach, is that it could transfer data really quickly through DMA - without tying up the µC’s CPU at all.

As it so happens, most STM32 chips with 100 pins or more include a “Flexible Static Memory Controller” which can do just that. And in an earlier weblog post I already used DMA to pump data into the (built-in) D/A converter at 2.7 million samples per second.

If we can make the FPGA act as a memory chip of some sort, and make it compatible with the FSMC, then that built-in hardware could take care of all the pesky little details.

It turns out that the simplest interface for bulk data transfers is the one implemented in NAND flash chips. These are not truly random-access: you send it a block number, and then you can read or write a bunch of consecutive bytes and it’ll auto-increment its internal address on each cycle.

A benefit of this bus protocol is that it needs relatively few I/O pins: 21 pins are enough to transfer data 16-bit words at a time.

This Storm IV FPGA board has just enough free pins to set up a test jig, using a compact STM32F103ZE board from eBay on top:

Time for some pin-planning and soldering!

Now we need to get the two talking, to verify that it all works. Let me just say that it took quite a bit of debugging to get there! - It all kinda-sorta worked fairly quickly, but I kept seeing off-by-one errors, and not reading the same data back as what was being sent out to the FPGA.

This is the time when a Logic Analyser from Saleae turns out to be invaluable. I didn’t want to solder wires to attach the probes to the above setup, so instead I simply hooked up another STM32F103ZE board:

It turns out that I was running the FSMC controller slightly too fast, and using the wrong edges of the read and write pulses. Once fixed, everything fell into place:

For testing, I just can’t get enough of Forth: easy to set up, fast, and great for interactive development. You simply cannot beat the “edit-compile-run” cycle when there is no compilation. There is a 1-sec upload delay, due to the way I re-send entire modified source files, but that’s of a different order.

The full test code (all 45 lines) is on GitHub. Here is the test data and basic test:

create wdata
hex
  1234 h, 4321 h, 5678 h, 8765 h, 2345 h, 5432 h, 6789 h, 9876 h,
  8080 h, 4040 h, 2020 h, 1010 h, 0808 h, 0404 h, 0202 h, 0101 h,
  1111 h, 2222 h, 3333 h, 4444 h, 5555 h, 6666 h, 7777 h, 8888 h,
decimal

: test
  fpga-init
  $00 wdata      fpga-write  $00 rdata fpga-read  show
  $40 wdata 16 + fpga-write  $40 rdata fpga-read  show
                             $00 rdata fpga-read  show
                             $40 rdata fpga-read  show
                             $80 rdata fpga-read  show
; test

And this is what gets reported via serial:

 1234 4321 5678 8765 2345 5432 6789 9876
 8080 4040 2020 1010 0808 0404 0202 0101 0000
 8080 4040 2020 1010 0808 0404 0202 0101
 1111 2222 3333 4444 5555 6666 7777 8888 0000
 1234 4321 5678 8765 2345 5432 6789 9876
 8080 4040 2020 1010 0808 0404 0202 0101 0000
 8080 4040 2020 1010 0808 0404 0202 0101
 1111 2222 3333 4444 5555 6666 7777 8888 0000
 0000 0000 0000 0000 0000 0000 0000 0000
 0000 0000 0000 0000 0000 0000 0000 0000 0000 ok.

Each test writes eight 32-bit values, which the FSMC then sends across as 16-bit words (since this interface is 16-bit only). Then we read back 8 values and print them out. Each test sends different values, and the results are indeed correct.

As quick timing test, let’s read 2048 bytes:

: timing ( n -- )  \ perform a timing test, reading 1024 words via the FSMC
  micros swap 0 do NAND @ drop loop micros swap - . ;
512 timing 236  ok.

As you can see, this takes 236 µs. A bare loop takes 43 µs, so the actual transfers take under 200 µs. That’s 2 KB in 200 µs: this setup is transferring data at > 10 MB/sec!

Best of all, is that the transfer mechanism has become invisible: we can just write a position to “NAND-ADR” and then read or write consecutive words from/to “NAND”. From a µC code perspective, they’re both simply memory addresses - it’s magic!

For comments, visit the forum.

Weblog © Jean-Claude Wippler. Generated by Hugo.