Posted 2 weeks ago

The top screenshot shows a perfect Q/E clock signal generated using a 4MHz clock source. No biggie; we’ve seen this before. Right?

The bottom photo shows what’s interesting about this particular clock signal. The XC9572XL is using my very first VHDL that I wrote all by myself, programmed using The JTAG Whisperer! I found a JK flip-flop out on the web, and wired up two of them using the recommended clock circuit in the 6809E datasheet. Synthesized it, generated an XSVF, and pow! It worked!

VHDL is turning out to be exactly as I’d hoped: it’s a text-based schematic entry language. Wire std_logic A to std_logic B, conjure up an imaginary signal here and there, proofread, and then call it all into existence. I’m still finding some parts of the language confusing, and the XSVF step is certainly tedious, but I’m already willing to declare the development process fun.

Code follows.

entity QE_CLOCK is
  Port ( OSC : in  STD_LOGIC;
         Q_CLK : out  STD_LOGIC;
         E_CLK : out  STD_LOGIC);
end QE_CLOCK;

architecture Behavioral of QE_CLOCK is
  component JK_FF_VHDL
    port( J,K: in  std_logic;
          Reset: in std_logic;
          Clock_enable: in std_logic;
          Clock: in std_logic;
          Q, NQ: out std_logic);
  end component;
  signal ff1_k : std_logic;
  signal ff1_nq : std_logic;
  signal q_clk_temp : std_logic;
  signal e_clk_temp : std_logic;
begin
  ff1: JK_FF_VHDL
    port map (e_clk_temp, ff1_k, '0', '1', OSC, q_clk_temp, ff1_nq);
  ff2: JK_FF_VHDL
    port map (q_clk_temp, ff1_nq, '0', '1', OSC, ff1_k, e_clk_temp);
  Q_CLK <= q_clk_temp;
  E_CLK <= e_clk_temp;
end Behavioral;

Posted 2 weeks ago
Posted 3 weeks ago

TTL Voltage and Current Cookbook Recipe

Now that I’m able to do something with this CPLD, I’ve been concerned about replacing $10 of discrete logic chips with a $2 chip that needs $8 of level shifters. Though the Xilinx XC9572XL is a fairly modern 3.3-volt device, I know its I/O pins are 5-volt tolerant, meaning that I can send in a 5-volt signal from my circa-1980s 5-volt 6809E. But the ‘72’s output voltage is selectable at either 3.3v or 1.8v, and not 5v. And as established earlier, 5 volts do not equal 3.3 volts. What to do? Some inspired laziness (“maybe it’ll just work”) led me to read the ‘09 datasheet, and then do a bit more general research.

And I have concluded that yes, maybe it’ll just work. TTL logic levels define a low as zero to 0.8 volts, and a high as 2 to 5 volts. Why not exactly zero and exactly five? Well, there needs to be some margin for error. We software engineers like to think of pure concepts like binary zeroes and ones. But on the oscilloscope, real-world logic values sometimes look like a nervous driver on a twisty road at night. (Sorry, that link is a PDF, but it nicely illustrates what the 45- and 90-degree angles in datasheets really look like.) So low is a range, and high is a range, and 3.3-volt digital logic values are entirely consistent with 5-volt ranges. It’s… as if… (concentrating very hard now)… when The Powers That Be wanted to move to lower-voltage — and thus lower-power — electronics, they didn’t come up with a new standard so much as pick tighter tolerances for the old one. 3.3 is almost exactly in the middle of the old 2- to 5-volt range, and there’s probably some other practical reason why it’s easier to generate 3.3 volts than 3.5 volts.

Anyway, speculative history lessons aside, I’m pretty sure the 6809E will recognize signals from the 3.3-volt I/O lines of the CPLD. I’ll wire something up before committing it to a PCB, of course, but everything I’ve read suggests this will work.

Here’s the current ingredient list for Prototype Board #1:

  1. Two power supplies: 5 and 3.3 volts.
  2. 6809E.
  3. 128KB SRAM.
  4. MicroSD card slot.
  5. ATmega32u4.
  6. 16MHz crystal.
  7. XC9572XL.
  8. DAC for audio, with an audio jack.
  9. DAC for video, with a video-out header.
  10. Game-control input header.
  11. [Placeholder for generating the digital side of the video signals.]

The ‘32u4 is the star of the show. I think it can do all these things:

  • As a JTAG Whisperer, program the CPLD during development.
  • Read the SD card and set up part of the SRAM as ROM from the perspective of the 6809E.
  • Assert the 6809E’s reset line when everything’s set up.
  • Handle all the 6821 game-control PIA duties.
  • Depending on what’s left, maybe even output sound using PWM.

Meanwhile, the CPLD should be able to do this:

  • Manage the address and data bus.
  • Turn the 16MHz crystal into the ‘32u4’s clock, and into the Q/E signals. I don’t yet know whether a CPLD can turn a crystal into an oscillating signal.
  • In a dream world where I’m much smarter than I am, fit the Williams Special Chip blitter into the 72 macrocells.
  • Feed the digital video signals into the resistor ladder.

And of course the several-dozen other jobs I’ve forgotten. Phew!

Posted 3 weeks ago

More than you ever wanted to know about electrical characteristics of JTAG

A few days ago I posted a very confused question about JTAG signals. Here is my less confused answer.

Cup or Face?

You’ve surely seen the cup-or-face picture before, where some see two people looking at each other, and others see a single white chalice in the middle. Both groups are correct, and fortunately everyone can easily tell their brains to see the other image, too. That’s what happened with me and JTAG signals. I saw this:

  1. Write TDI/TMS.
  2. Set TCK.
  3. Wait.
  4. Clear TCK.
  5. Wait.
  6. Read TDO.

And the code I originally wrote probably would have worked just fine like this. But it didn’t, so I scoured the web looking for working examples (none of which was both working and targeted toward the Arduino, unfortunately). Most were some variation of this:

  1. Read TDO, write TDI/TMS.
  2. Clear TCK.
  3. Set TCK.

Which seemed to be out of whack with the spec (if not the spec then XAPP058). I conformed my code; it still didn’t work. I permuted the bit-banging code madly. It still didn’t work. I found subtle logic bugs that didn’t matter, because it still didn’t work after I fixed them. I was ready to see five fingers when O’Brien held up his hand.

As you already know from prior entries, the voltage fiasco was the answer. My code would never have worked with the hardware running at 5 volts instead of the required 3.3. But in my experience, the nice thing about debugging code in an impossible situation is that by the time you figure out and solve the thing that was making it impossible, the rest of the code is absolutely perfect because you’ve debugged the living daylights out of it.

Now that I have working hardware and have been able to run some experiments, I’ve started seeing the cup instead of the faces. It’s not that TCK’s signals are inverted (active-low); it’s that the master divides the work into two categories:

  1. Stuff I care about.
  2. Everything else.

Its job is to write out TDI/TMS before TCK goes high, and to read TDO after TCK goes low. But it’s OK for the work relative to TCK’s edges to overlap. For example, I can write TDI, then clear TCK, then set TCK, because TDI was still set before TCK’s rising edge. It just looks weird because it seems like the code is saying “set TDI before TCK’s falling edge.” Nope, TDI and TCK’s falling edge have absolutely nothing to do with each other. Taking the transitive closure of dependencies, yes, TDI and TCK’s falling edge are related in the sense that TCK’s rising edge comes before its falling edge, but other than that, the code is free to rearrange itself in a sensible fashion as long as it respects those constraints. (There is one timing characteristic, TDOXZ, that I am still convinced is a typo in XAPP058.) Taking out the “wait” steps from the original sequence, looking at it as a circle rather than a line of steps, and reordering slightly in that “sensible fashion,” it ends up like this:

  1. Read TDO and write TDI/TMS, in any order.
  2. Set TCK.
  3. Clear TCK.

… which is exactly what most implementations on the web do. QED.

Posted 3 weeks ago

It works! Yay! The main problem all along was that I was running the board at 5 volts, not the 3.3 volts it needs. It was able to respond to JTAG commands at the higher voltage, but it correctly reported that it couldn’t write its flash memory under those conditions.

I still need to update the README for the JTAG Whisperer, but the code in the repository should work right now. Hooray!

Posted 3 weeks ago

5.0 != 3.3

I just realized that the XC9572XL’s “5-volt tolerant I/O pins” do not mean that the device itself can be powered with 5 volts. It’s a 3.3-volt device. I’ve been running it from the Arduino’s 5-volt supply.

Sigh.

With this newly understood information, I hope to discover that the JTAG Whisperer is working correctly, and that the incorrect voltage was preventing the CPLD from programming itself. Other possibilities are (1) my code is still buggy but the CPLD is happy to be finally running at the right voltage, and (2) I’ve fried my poor little ‘9572.

Posted 3 weeks ago

JTAG TCK: active-low?

Why does it seem like the JTAG clock signal is active low? Consider this snippet from Xilinx’s XAPP058 source code.

/* toggle tck LH.  No need to modify this code.  It is output via setPort. */
void pulseClock()
{
    setPort(TCK,0);  /* set the TCK port to low  */
    setPort(TCK,1);  /* set the TCK port to high */
}

This means that when the clock isn’t being pulsed, it’s high. Right? If so, why don’t any descriptions of JTAG’s electrical characteristics say it’s active low?

Posted 3 weeks ago

The JTAG Whisperer

Available here on GitHub. The JTAG Whisperer turns your Arduino into a JTAG cable. Wow, sounds great! Here are the caveats:

  • It’s actually just an XSVF player. This is a tiny subset of what JTAG does. The current architecture has the desktop load the XSVF file, then send it over serial to the Arduino. Since serial is going to be limited to the kilobits-per-second range of speed, it’s unlikely it’ll be suitable for more ambitious interactive JTAG operations. But it’d be interesting to see what could be accomplished with the newer Arduinos that have replaced the FTDI chip with the more flexible ATmega U-series chips.
  • It has been tested only on a Xilinx XC9572XL breakout board from Dangerous Prototypes, and the only function it has performed so far is asking the chip its device ID (spoiler: it’s 0xf9604093). I would have happily used the Bus Pirate’s XSVF Player firmware, but it hasn’t yet been ported to my BPv4 hardware, and I wasn’t willing to invest in learning PIC development.
  • It doesn’t work very well yet. The serial communication between the desktop and the PC frequently gets logjammed, and the Arduino sometimes has to ask repeatedly for the ID.

I have high hopes for this project. Its immediate use will be to program the ‘9572 so that I can start experimenting with replacing discrete logic 74xx chips. Eventually I hope it’ll become a robust, reliable XSVF player for the Arduino.

Please give it a try. I look forward to your pull requests!

Posted 3 weeks ago

Linux on Nexys2?

All the search results for [linux nexys2] discuss how the heck you run that djtgtgtgjdsasdfghjkcfg Digilent tool on Linux. In other words, how do you program the Nexys2 on Linux?

But what would it take to run Linux on the Nexys2, or a similar medium-sized FPGA? Can you just download an http://opencores.org/ processor that has a gcc toolchain for it, throw in some I/O controllers, and get the kernel booted up? I am so new to FPGA that I can’t even do a back-of-the-envelope calculation whether a Linux-capable core, plus glue, would fit. But it would be a fun project to find out!

Posted 3 weeks ago

Rescue guide for your Adafruit ATmega32u4 breakout board

The ATmega32u4 breakout board is a beta product. The hardware is essentially perfect, but the firmware is wonky. At least once, I’ve convinced myself that mine was broken, but I eventually figured it out. Here’s how to get yours back in shape.

Things required to get all the way through these steps:

  • The board
  • A USB cable to connect the board to your computer
  • A working copy of avrdude. If you have the Arduino IDE on your system, then it’s buried deep inside the IDE.
  • Possibly an in-system programmer. These instructions will work with any USBTiny-compatible programmer.

Before we get going, a warning: the fuses and the bootloader must match, because the fuses tell the chip where the bootloader is. If you have the Leonardo bootloader on your board, beware! That one uses a different fuse combination (I think FCD5C3) from the Adafruit one (FCD0C3). Moreover, you need the ISP to change the fuses; an ATmega32u4 unfortunately can’t change its own fuses. It’s completely possible for you to flash the wrong bootloader to the board, leaving it in a zombie state, needing the ISP to fix it. This means that these steps might take you from a sort-of working board (e.g., an early Leonardo bootloader) to one that’s completely broken (the Adafruit bootloader with the wrong fuses), and if you don’t have an ISP to set the fuses, you’ll be stuck. TL;DR: if you have a board that mostly works, and don’t have an ISP, then stop now.

If your board is showing up as a serial device, we can learn a little from it directly, without the ISP. Run avrdude -c avr109 -p m32u4 -v -U lfuse:r:-:i -U hfuse:r:-:i -U efuse:r:-:i -P /dev/tty.usb_path_to_the_device_serial_port. A bunch of information should get spit out, ending with something like this:

avrdude: safemode: lfuse reads as FC
avrdude: safemode: hfuse reads as D0
avrdude: safemode: efuse reads as C3
avrdude: safemode: Fuses OK

If you get an error, it’s possible your board is running the Leonardo bootloader, so you’ll need to ask differently. Instead of avr109 in the previous command, try arduino.

Now you want to figure out what those fuses mean. Visit the AVR Fuse Calculator (in fact, you might want to set that as your home page) and type the three into the “Current settings” fields at the bottom of the page. Apply values, then go back up to the top of the page and see what the “Boot flash size” dropdown is set to.

If the size is 2048, this is GOOD because it’s what matches the known-good 2K Adafruit CDC bootloader. If this size is anything else (probably 512), then stop unless you have an ISP because you need an ISP to change the fuses. If the size is not 2048 but you do have an ISP, proceed to change the fuses.

To change the fuses, plug your board into your ISP and run avrdude -v -c usbtiny -p m32u4 -U lfuse:w:0xFC:m -U hfuse:w:0xD0:m -U efuse:w:0xC3:m. Again, skip this step if your boot flash size is already 2048.

Next, flash the one true bootloader that today is known to work: BootloaderCDC.hex. Run either of these commands, depending on whether your board is connected to the ISP or directly to your machine:

Directly connected: avrdude -c avr109 -p m32u4 -P /dev/tty.usb_path_to_the_board_serial_port -U flash:w:BootloaderCDC.hex

Connected to your ISP: avrdude -c usbtiny -p m32u4 -U flash:w:BootloaderCDC.hex

Note that, unlike in the previous step, I am not telling you to substitute arduino for avr109 in this step. That’s because doing so would kill your board and require the ISP to rescue it. If you wanted to follow that step, it means you misunderstood the earlier steps about current bootloader size.

By this point, you should have BootloaderCDC on your board, and fuses for a 2048-byte bootloader. Plug the board via USB into your computer. You should see the pulsing green light as well as a new serial port on your computer. All should be well.