Big Mess o’ Wires


A home-built CPU, and other messy electronics adventures

Archive for the 'Bit Bucket' Category

Cramming Everything In

I’ve made a little bit of progress on the CPU in a CPLD project. As mentioned previously, this will be an 8-bit CPU with a 10-bit address space, targeting a 128 macrocell CPLD. The instruction set will be a simplified version of BMOW’s, which itself was a close cousin of the 6502 instruction set. Exactly how “simplified” it needs to be in order to fit remains to be seen, but I’m planning to omit the Y register, zero page, and indirect addressing modes. It will still have A and X registers, a hardware stack pointer, and all the “standard” opcodes in immediate, absolute, and indexed addressing modes. I’ve mostly just been planning and not writing much Verilog yet, but after fleshing out the datapath and a tiny bit of control logic, I’ve used 73 macrocells so far.

Working with the Altera software has been pretty good so far, and I’ve been much less frustrated than when I was working with the Xilinx software to create 3DGT from an FPGA. I’m not sure if that’s the software itself, or simply that I’m working on a simpler project and a simpler device, but it’s a welcome change.

I found a couple of similar CPU projects that might provide some inspiration:

MCPUhttp://www.opencores.com/project,mcpu - A very tiny CPU that fits in a 32 macrocell CPLD. It has a single 8-bit register, and just a 6-bit (64 word) address space. It also has only four instructions: NOR, ADD, store, and conditional jump. Yet with combinations of those instructions, you can do some pretty complicated stuff. Very clever! Check it out.

MPROZhttp://www.unibwm.de/ikomi/pub/mproz/mproz_e.pdf - MCPU borrows its instruction set from here. MPROZ has a 15-bit address space, but NO data registers. All computation is done directly on locations in memory. It also does MCPU one better by having only three instructions: NOR, ADD, and branch. It fits in an FPGA with 484 macrocells.

1 comment

A CPU in a CPLD

OK, the CPU design spark is back, sooner than I’d expected. I have an urge to implement a minimal CPU using a CPLD. If you’re not familiar with the term, a CPLD is a simple programmable logic chip, existing somewhere on the complexity scale between PALs (like the 22V10’s I used in BMOW) and FPGAs. Typically a CPLD has a similar internal structure to PALs, with macrocells containing a single flip-flop and some combinatorial logic for sum-of-products expressions. They are also non-volatile like PALs. Yet typical CPLDs contain 10x as many macrocells as a PAL, with some macrocells used for internal purposes and not connected to any pin. FPGAs are generally much larger and more complex, with thousands of macrocells and specialized hardware blocks for tasks like multiplication and clock synthesis. FPGAs also normally contain some built-in RAM, and are themselves RAM-based, requiring configuration by some other device whenever power is applied.

I’m attracted to CPLD’s because I’m hoping they’ll provide a good step up from PAL’s, without drowning me in FPGA complexity, as happened when I worked on 3D Graphics Thingy.  I’m pretty confident I can figure out how to work with CPLD’s without driving myself crazy, increasing the chances that I might actually finish this project. Given the limited hardware resources of CPLD’s, fitting a CPU will also be an interesting challenge.

I’ve also been wanting to design my own custom PCB’s for quite some time, and this will give me an opportunity. The end goal of this project will be a single-board computer on a custom PCB, with my CPLD-CPU, RAM, ROM, some input buttons/switches, and some output LEDs/LCD. I need to limit myself to CPLD’s that come in a PLCC package, so I can use a through hole socket and solder it myself. Unfortunately that will limit my choices pretty severely. I think it’s theoretically possible to hand-solder the more common TQFP surface-mount package, but I’m not excited to try it. And for other package types, forget it.

Here’s some back-of-the envelope figuring to get the ball rolling. This is assuming an 8-bit CPU with a 10-bit address space (1K).

I/O pins needed:

  • 8 data bus
  • 10 address bus
  • 1 clock
  • 1 /reset
  • 1 /irq
  • 1 read-write
  • ~4 chip selects for RAM, ROM, peripherals

That’s 26 I/Os. So a PLCC-44 package should be fine, as CPLDs in that package typically have about 34 I/Os.

Macrocells needed for holding CPU state:

  • 10 program counter
  • 10 stack pointer
  • 10 scratch/address register
  • 8 opcode register
  • 3 opcode phase
  • 8 accumulator
  • 8 index register
  • 3 ALU condition codes

That’s 60.

Then I’ll need some macrocells for combinatorial logic. This is a lot harder to predict, and in many cases I should be able to use the combinatorial logic resources and the flip-flop from a single macrocell. I’ll just pull some numbers out of thin air.

Macrocells needed for combinatorial logic:

  • 16? arithmetic/logic unit (8-bit add, AND, OR, shift, etc)
  • 16? control/sequencing logic
  • ??? other stuff I forgot

So that’s a grand-total of 92 macrocells for everything.

If I shrunk the address space down, and maybe changed to a 4-bit word size, I might be able to fit it in a 64 macrocell CPLD. But more than likely, it seems I’ll be looking for a CPLD in the 100 to 128 macrocell range. Considering my requirement for PLCC packaging, that will limit the choices to two or three possibilities, but more on that later.

I think the most challenging part of this project will be the control/sequencing logic, and the assignment of opcodes. BMOW was microcoded, and used a separate microcode ROM to execute a 16-instruction microprogram to implement each CPU instruction. In this case, I’ll need to create dedicated combinatorial logic to drive all the enables, selects, and other inputs in the right sequence to ferry data around the CPU to execute the instructions. Doing this with minimal logic will be a real challenge, and undoubtedly I’ll be using the bits of the opcode itself to derive many of those control signals.

5 comments

RC Servo Signal Decoder for Camera Shutter Switch

Hey, I’m back. I think my oscilloscope made me do it. For the past six months I’ve been working with RC airplanes, not doing any electronics work. The oscilloscope has been taking up space on my desk while it sits untouched, gathering dust. Last week I finally decided I was never going to use it again, and packed it away in a closet. But that got me to thinking about electronics again, and about what kind of projects I could do related to RC. So after just a few days, the oscilloscope has returned from its closet banishment and is in use once more for a new project.

I recently bought an Aiptek SD 1.3 megapixel camera, with the idea to mount it on the fuselage of one of my planes, and do some aerial photography. The Aiptek weighs just 52 grams (about 2 ounces), and so it won’t weigh down the plane excessively. But the tricky part is finding a way to activate the shutter while the plane is in the air. It turns out that this is mostly a solved problem, and it’s possible to build a circuit to decode the servo signal from an unused receiver channel, creating a 0 or 1 pulse depending on the position of a transmitter switch or stick. Then by hacking into the camera guts and a bit of soldering, that pulse can be used to trigger the shutter.

Spektrum 6110 receiver with servo hacking harness connected

Here’s one of my planes (a GWS Slow Stick), with three spare wires hooked into the receiver’s “gear” channel (which I don’t normally use), connected to the oscilloscope and a growing circuit on the protoboard. It turns out that these servo signals for the channels are ideal for hacking with digital logic. Of the three wires connected to the receiver, one is ground, one is a regulated +5 volts, and one is a modulated position signal that indicates the desired position for that channel (rudder, elevator, aileron, flaps, gear, whatever). The connectors are even standard 0.1 inch male headers. What could be easier?

Slow Stick sevo decoder

I examined the servo signal with the oscilloscope. It’s a regular pulse train with a 22ms period. The width of the pulse varies depending on the desired position for the channel. The width is about 1.2ms at the minimum position, and 2ms at the maximum position. Taking 1.6ms as the midpoint, what’s needed is a circuit that outputs 0 if the pulse width is less than 1.6ms, and 1 if it’s greater than 1.6ms. This could be done many different ways: the first two that come to mind are a small microcontroller, or a low-pass filter that turns the servo signal into a DC voltage, and compares it to a reference voltage.

I’ve decided to follow another example I found, which I thought was especially clever. It uses just two flip-flops and a couple of passive components. You can check out the circuit schematic for the details. The servo signal pulse train is used to clock the first flip-flop. It’s D input is tied high. When it’s clocked, its Q output goes high, which begins to charge an RC circuit. When the capacitor voltage gets high enough, it activates the asynchronous reset, clearing the Q output. The complementary /Q output is used to clock the second flip-flop, whose D input is the servo signal. If the RC time constant is chosen correctly, then the second flip-flop will be clocked 1.6ms after the first one, sampling the servo signal at that time. If the pulse width is less than 1.6ms it will sample a 0, otherwise it will sample a 1. Pretty neat!

My only headache is that I don’t have the 4013 CMOS flip-flop called for in the circuit. I do have lots of 74LS74 flip-flops, which are similar, but are TTL designs with an active low asynchronous reset instead of active high. I’d thought it would be simple to modify the circuit to work with an active low reset, but after a couple of hours of futzing around with it, I concluded that it’s either not possible, or I’m just not smart enough. I started by swapping the positions of the resistor and capacitor, but the circuit initializes in the reset state and never exits it. And even if I found a solution to that, the input current on this LS series chip is so high, that with a 10K resistor to ground, the voltage at the input pin is actually pulled up to 2 volts! Ack! I decided I’ll just buy a 4013 for a few cents, and stop banging my head.

3 comments

Uzebox, Take 2

It’s done. Yes, it cost twice as much money and 100X as much time as just buying one from Adafruit or Sparkfun, but I’ve finished my home-made Uzebox.

Notable features vs. the “stock” Uzebox:

  • vertical mount
  • mini-stereo jack for audio
  • internal speaker
  • transparent acrylic case
  • lots of glue

And it plays Arkanoid! Now I can return to my regularly scheduled life. :-)

   

I wrote about the Uzebox earlier: it’s an open-source hardware project utilizing a microcontroller to synthesize an NTSC video signal on the fly, in software. Many classic games have been ported to it, and there’s an active developer community.

11 comments

Care Package

After reading about BMOW on Slashdot last week, Jim George offered up some Augat wire-wrap boards and old-school ICs that were sitting around gathering dust. His care package arrived today, just in time for a weekend of tinkering.

There are four Augat boards, each one about 7 x 2.5 inches, or about 25% of the area of the BMOW system board. Each board has space for five columns of skinny DIP 0.3 inch chips. The undersides (not shown) are pre-populated with about 600 wire-wrap pins.


Jim also threw in a few dozen wire-wrap tags, which are just little plastic cards with holes in them that can be placed on the pin side of the board, showing where the chips are placed and marking the pin numbers. I can’t believe I built all of BMOW without these. They seem like such an obvious thing. Staring at a featureless green board with a thousand pins on it, it’s easy to get disoriented without markers like these.

To round out the package, Jim also included a handful of 7400 series logic chips, and other related parts:

  • 74AS181 x 5, 4-bit ALU
  • 74ALS374 x 11, 8-bit register
  • 74F323 x 7,  8-bit shift register
  • 74F299 x 6, 8-bit shift register
  • 6116 x 3, 2K x 8 SRAM
  • Intel 8255 peripheral interface adapter

Thank you Jim!

5 comments

More Uzebox

Finally, I got the Uzebox to work! I’m not quite sure what made the difference, though.

First, I tore apart my earlier breadboard setup, and rebuilt the circuit from scratch, as neatly as I possibly could. Then I scrapped my grayscale DAC, and dropped the AD725 RGB to NTSC chip into the circuit (which had arrived in the mail since my previous attempts). Soldering the AD725 was my first experience at SMD soldering, and it was a little challenging, but not too bad. I managed to get 15 of the 16 pins soldered successfully on the first attempt, but the last pin just wouldn’t bond to the pad. I must have made 20 attempts to solder it, and was about to give up and solder a jumper wire to the pin, when I finally got it.

I connected the circuit to my finicky Dell monitor, turned it on, and voila! It worked!

The image quality is OK, but seems a bit blurry, and there’s noticeable color blooming. The interior of a red letter R is dark red instead of black, for instance. The photos here actually make it look cleaner than it really is. It’s certainly very playable, though, and maybe I’ve just forgotten what composite video quality looks like.

The rewired circuit on the breadboard:

Pac-Man title screen on the Dell monitor:

Pac-Man maze on the Dell monitor:

2 comments

Uzebox

I’ve decided to build a minimal Uzebox. The Uzebox is a software-generated video game system based on an open source hardware design. It uses an ATMega644 microcontroller with 4K RAM to synthesize a composite video signal and sound on the fly, line by line. The official Uzebox design uses an Analog Devices AD725 RGB-to-composite chip, along with an SD card interface, and MIDI and joystick ports. I really wanted something super-minimal, though, so I dropped everything from the system except the ‘644 itself, the power supply, a piezo speaker, and some resistors and capacitors. I think it’s about as bare bones as you can get. Here’s what I came up with:

To replace the AD725 color chip, I constructed a grayscale binary weighted DAC from nine resistors. The eight color bits and the sync signal from the ‘644 are combined. I did some math to solve for the correct resistor values to produce 1 volt when all the colors bits are 1’s, and 0.3 volts when all the color bits are 0’s, assuming the sync signal is 1 in both cases. I must be getting dumber in my old age, because it took me a long time to churn through the math, and I eventually had to ask my wife to help. This was the result:

This seems right mathematically, but when I tried it connected to the TV, the resulting voltage was too low. When I removed the 75 Ohm resistor, everything looked nearly perfect. I don’t really understand that… should the video cable and TV itself be treated as a 75 Ohm resistor to ground in this calculation? Something about impedance matching that I don’t really grasp.

With the 75 Ohm resistor removed, I burned a Pac-Man game into the ‘644, connected the breadboard to the living room TV, and was rewarded with this:

The image quality is middling, but it’s not too bad for a quick breadboard job. The grayscale is definitely working, although it’s hard to see in this picture. The ghosts show the grayscale levels best.

Unfortunately I couldn’t get the Uzebox to work with the composite video input on my Dell monitor. It didn’t show anything at all, behaving the same as if nothing was even plugged in. I’m assuming this is because my video signal is too noisy, or out of spec somehow, and the monitor is more picky about signal quality than the TV. I looked at the video signal on the oscilloscope, though, and it looks pretty decent to me. Not too much noise, baseline is right at 0.3 volts, HSYNC pulses look fine. The brightest parts of the image do overshoot to about 1.25 volts, but I wouldn’t guess that would be a huge problem. I need to find a solution, though, because hauling the whole thing into the living room for every test isn’t too practical.

Although my interest here is primarily in the hardware, it’s damn impressive that this single ATMega644 with just 4K RAM is able to generate all the video and audio for a very faithful Pac-Man recreation. Remember, there’s no frame buffer. The video signal is generated on the fly, line by line, pixel by pixel, in the midst of all the other necessary game-related computation.

10 comments

Software-Generated Video

I’ve become interested in software generated video, after reading the book The Black Art of Video Game Console Design by André LaMothe. It’s a unique book, covering everything from atomic theory all the way up to building your own embedded computer system. Unfortunately it’s plagued by a million errors, but I was still fascinated by the idea of direct synthesis of video in software, which is part of the design of the game system discussed in the book.

Most computer systems (including BMOW) have dedicated video display hardware. The CPU writes data to video memory, and at the same time, the display hardware reads data from video memory and synthesizes the actual analog voltages that constitute the video signal for the monitor or TV. In BMOW the display hardware consists of fourteen separate chips, including the video memory itself, character generator, counters for the current row and column, shifter, oscillator, various registers and buffers, and a RAMDAC. It took a long time to design, but it’s pretty powerful.

In contrast, software-generated video creates the final video signal voltages directly from the CPU or microcontroller pins, with no intervening hardware at all except a handful of resistors to form a simple R2R DAC. You’ve got a MCU, some resistors, and that’s all. It generates the video signal in real time, on the fly, and there’s no need for any video memory or frame buffer. Fascinating stuff. The downside is that you need a fast MCU, and your code must be deterministic and per-clock-cycle exactly identical from scanline to scanline. Almost all the processing power is consumed by generating the video, so there’s little left for other logic, and logic code must be interleaved with the video code. I was vaguely aware of this technique before, but never really looked at it deeply because of all these problems with it. At least, that was the case until I saw some of the things the XGameStation from LaMothe’s book can do.

Check out the XGameStation Micro Edition web page. That’s some fairly impressive stuff from a little microcontroller and software-generated video. I decided I wanted to build one of these myself, as a short but interesting detour from work on 3D Graphics Thingy. Most of the XGameStation systems are prebuilt systems, which don’t interest me much, but there’s also the XGameStation Pico Edition that you can put together yourself. Perfect! Except it’s pretty expensive for what you get. I just can’t stomach paying $60 for a kit that contains a $3 microcontroller and a bunch of passive components that I mostly already own anyway. To make matters worse, a $50 SX-Key is also required to program the SX28 microcontroller, bringing the total cost to $110 for a simple little breadboard project.

I did some research, and found that I can get all the parts I need from the $60 Pico Edition kit for under $10 total, except one: the 78.75 MHz clock oscillator. In order to generate color video, you need a high-speed clock that’s an integer multiple of the base NTSC frequency of 3.579545 MHz. Sadly, these just don’t seem to exist anywhere that I’ve found. The only solution appears to be to buy a programmable oscillator, which is what the kit contains, I think. But programmable oscillators with the speed and precision needed are pretty expensive, and only sold in large quantities. Without that oscillator, it’s possible to generate black and white NTSC video only. Of course this still doesn’t change the need for the $50 SX-Key, for which I’ve found no alternative and no used ones for sale. Sigh.

As an alternative, I also looked into making a simple software-generated video system from a PIC24, which is at the heart of another XGameStation design. That’s a little more questionable, since there’s no specific “Pico” design using the PIC24 whose software I could use, but there is a wider selection of tools and software for the PIC series than the SX28. But the same oscillator requirements exist,  and while the PicKit2 programmer is a little cheaper than the SX-Key, it’s still not cheap.

At the moment then I’m stuck, and not sure if I should pursue this idea any further. The microcontroller and other parts can be had for just a couple of bucks, so it’s a bit frustrating that the oscillator and programmer requirements are turning this into a $100+ project.

21 comments

Death of a Dremel

My last planned bit of BMOW case construction was a front-mounted LCD. This required cutting a hole for the LCD in the faceplate, as well as a gap for the wires to pass through the steel case front. Once again my trusty Dremel tool was put to use. This time I enlisted the help of my daughter to get some action photos, while I cut through the steel. Look at those sparks fly! Yee-ha!!!

I am a manly man, cutting steel! Unfortunately, moments after this photo was taken, the Dremel unexpectedly shut down. At first I thought maybe I’d blown a fuse, but the house outlet still works fine, and there’s no fuse I can find anywhere on the tool. I tried cleaning out the motor brushes, but that’s about all I could think to try. The Dremel manual doesn’t mention anything about what to do when the tool fails to turn on. I guess I killed it. At least I had the cut about 95% finished, and I may be able to finish it off by hand.

Dremel Tool: 2009-2009 R.I.P

7 comments

Fun With Dremel

A while ago I purchased an old X-terminal and ripped out the guts, with the intention of using the case for BMOW. Upon opening it up, I discovered that the interior was partitioned into two parts by a steel divider welded to the base. The logic board was on one half and the power supply on another. Unfortunately BMOW needs the entire space in order to fit its oversized board.

Enter the Dremel tool. I got a Dremel and assortment of attachments for Christmas, but didn’t have a chance to try it until today. My plan was to simply cut the divider off, requiring about a 12 inch cut. The divider is made of 1/32 inch steel. Would the Dremel cut it? What kind of cutting attachment should I use? Would I slice off a thumb? I really had no idea how to use a Dremel, but a couple of the included attachments looked like cutting wheels, so I gave them a try. It took me about an hour and a half to make the 12 inch cut, and it looks pretty darn ragged, but the operation was a success. Sparks were flying everywhere… it was quite a sight! I ate up two entire cutting wheels, though, so I’m guessing a wheel made specifically for cutting steel would be better next time.

Here’s my handiwork. You can see the stump of the divider running from the case’s front to its back, about two-thirds of the way from left to right.

BMOW Case

I had hoped to cut a large hole in the case lid, and cover it with a piece of plexiglass, to make a window where people could peer in and see BMOW’s guts. Given how this cut turned out, though, I think I’m going to abandon that idea. It would probably take me several hours to make a hole that large, and it would end up looked pretty ragged and ugly. Instead, I’ll just pop the lid when I do demos!

7 comments

Next Page »