Archive for January, 2011


OctoPDI5 challenges ;-(


So I ran into a number of problems while getting the octopdi5 board up and running…

  • First round of soldering I wasn’t paying attention in the slightest and managed to mount all the ADuM chips backwards.
  • Once I got them the right way around, I discovered that somewhere way early in the process I managed to spec the wrong part number.  The ADuM5403 is what I had in my PCB art, which has 1 channel “out” and 3 “in”, whereas I really needed the ADuM5401 that’s the other way around.  Queue DigiKey….
  • After shuffling the micro-B pinout, I found that I had tied Tx to Tx and Rx to Rx, which doesn’t really work.  I’ve managed to rework one of the ports by cutting traces and cramming replacement wires into a stupidly tiny space.
  • Ports ended up with random shorts between the shield and various pins.  Turns out the micro-B connector is pretty much solid metal all the way across the bottom, and I placed vias underneath.  Programming worked with my micro-B pigtail but not with a stock cable.  After carefully removing the connector I managed to resolder it with Kapton tape (stolen from a mini-B connector ) covering the holes.

At this point I actually have a target connected to the board via a stock micro-B to micro-B cable, and I can program it ;-)

Next step is to perform the same surgery on the other 7 ports as needed, and submit new PCB artwork for the next group order (which goes out in over a week…)


OctoPDI5 board underway


The product I’m working on consists of a number of devices strung out on a bus, all of which need to be reprogrammed and debugged at the same time.  The problem is, they’re potentially meters apart, and more critically their ground potentials are all different (they derive power from said bus, which will sag inward from 0-V+ over distance).  I’ve made several attempts to solve this problem (isolated USB, wireless debugger) and so far they’ve all fallen short for various reasons (none of which can’t be overcome, given enough time, which I don’t have).  This latest attempt is far more likely to work, because it’s based on existing tech and more straightfoward (and breadboarded!).

This board consist of an Xmega 128A1 coupled with an FT245R, along with 8 isolated PDI5 ports.  The ports consist of an Analog “isoPower” ADuM5403 and a 74AHC1G125 tristate buffer plus USB micro-B connector.

The FT245R is hooked up to the memory interface of the Xmega, which means in theory I can read and write the USB serial port just by reading and writing a memory location.  I haven’t had much success getting that to actually work in the past, but I’m giving it one more shot.  I know the bitbang interfacing works, so I can always fall back on that.

Each PDI5 interface is half of an “interface” port on the Xmega, and is set up for the USART.  The TXD, XCK, and TXEN lines go through the ADuM5403 one direction, and the RXD goes the other way.  TXEN drives the 1G125 buffer to engage TXD, because the target side of the PDI5 interface ties the RXD and TXD lines together via resistors to provide the PDI_DATA line.  The Xmega can easily tristate the TXD line when it’s time for the target microcontroller to talk back, but the ADuM5403 doesn’t know any better.  The buffer enables this to work on the isolated side of the circuit.

The software I’m porting over to this beast is existing code that multiplexes communication to all the configured logical modules over the USB uplink.  Each PDI5 port consists of two logical modules: the STK600-compatible programming stack, and a straight serial port.  Using the STK600 port disables the serial port for the duration, but otherwise the serial port provides debug communication with the target.

The micro-B connector has a different pinout than I originally planned.  Rather, this one is actually planned…  I’ve found that even though mini- and micro-B connectors have 5 pins and a shield, nobody makes pre-made cables that have the 5th wire.  As a result I’ve shuffled things so that the +3v3 pin is the one that ends up not being connected between the programmer and target.  This is fine for two reasons: we have a ground and known voltage level, and the ADuM5403 also provides power on the isolated side to run the buffer.

Once this board is up and running, I can use the collection of micro-B to micro-B cables I purchased from Digikey in order to spider out to all the units I’m developing.


High-accuracy clock sync


So… I was describing part of the product I’m working on to somebody at dorkbotpdx last week.  He was more impressed with the idea than I expected, so I figure it might be interesting to post here.

A requirement of the product is that I have a series of ADC’s running in very close synchronization, yet they’re separated by 10’s or 100’s of meters by a bus.  They’re slow ADC’s running 4Ksps and the target is in the 0.1 – 1.0% sample accuracy, meaning a 0.25 – 2.5ppm relative accuracy.  The fact that these might be running continuously for minutes or hours (and eventually days to months) and still need to be in sync means that I have to have a zero-drift system.  These are not exactly easy things to achieve on the same PCB, let alone separated by lots of wire.

The key component here is the FD77T from Pletronics (see my previous post about the part’s capabilities), which combines a tunable crystal with a highly-capable PLL.  The PLL is set up to simultaneously drive both the microcontroller (an Xmega, of course) and the ADC at the required speeds (4.096MHz for the ADC, 6.400MHz for the MCU’s PLL, would be 32MHz except I misrouted the PLL outputs).  This means the MCU and ADC are always synchronized on the PCB, and any change to one will be reflected in the other.  The MCU then has a DAC output wired to the PLL VCXO’s control voltage, which allows me to push & pull the frequency of the crystal by around 150ppm.

To sync up the multiple units, I use carefully-timed edge capture of the bus itself.  The master unit sends out the packet preamble and turns on the Xmega edge trigger (via event) for a very specific window as the serial data trickles out various levels of in-chip buffering (TEMP register, clock-domain bridge, etc.).  The 16+16(+32)-bit cycle counter is the recipient of this edge capture event, and locks the cycle number for subsequent retrieval.  A second packet is sent out on the bus that contains this cycle number as the reference point.  The slaves do this same trick except during a receive interrupt function (lots of fun to get timed right, let me tell you…) and eventually feed the local and remote cycle numbers to the clock engine.

The first time we get these two sync numbers, the difference between them is stored and used for the rest of the unit run-time to convert the local cycle counter to the master’s.  All subsequent sync packets give us a chance to determine how much drift has been going on since the last packet.  The relative difference is fed into a PID controller, which has been manually (and very roughly) tuned to output a control value that is fed out the DAC and into the VCXO of the FD77T.

The current development code runs this sync operation at 10Hz, and at this point will coalesce to bouncing between -1 and +1 within a few seconds.  This +- 1 difference is measured in units of 31.25nS per 100mS sync period.  The PID keeps this narrow window indefinitely, which means that years later I could come back to these two units and be able to tell you exactly what the master’s clock is solely by looking at the slave.

To sync the ADC, I will simply have the master pick a particular cycle number and push that value to all the slaves.  They’ll flip their cycle counters around into PWM mode (without stopping their counting!), and set up to fire off the required SYNC pulse to their local ADCs.  Because the ADC is driven by the PLL which also drives the MCU that’s running a feedback loop against the PLL, all the distributed ADC’s will stay locked forever.

(I’ll see if I can make a diagram at some point to make the arrangement clearer)