Tag Archives: xmega

Kakapo production boards

20140610_181047

The Kakapo production boards have arrived! These are a 2×2 panel (so a total of 4 boards within each panel) and the new silk has turned out fantastically well. Hackvana has supplied these boards and they have delivered very high quality PCBs again.

The new Kakapo logo was redone for this run, mostly to make it look better in white rather than the black I had originally planned. The drawing was redone in Inkscape, with cut-out lines for adding detail to the solid area. I think it’s turned out great, the picture doesn’t do justice to how fine the detail lines actually are.

I expect to start production on these at the weekend, starting with shipping the final configuration to Nicegear for feedback and then ramping up making the first run.

It’s also about time I worked out the pricing, I’m aiming for around the same as an Arduino Uno, at least as close as I can make it. It will depend on how much small runs (as it currently is being made) adds to the costs.

kakapo-beta-box

Kakapo beta testing

Well, I’ve finally shipped off the first beta test unit of the Kakapo dev board to nicegear. This is mostly to shake out what I haven’t resolved yet, get valuable feedback on the design and packaging, and a bit of time to prepare some tutorials and documentation.

Over the next few weeks, I hope to fill out that last part a lot more. My intention was always to make this a stepping stone away from the Arduino by focussing on boilerplate drivers and a heavy emphasis on the way the datasheets and avr-libc are written.

kakapo-pogopins

It’s also been a chance to develop some new ideas on production processes. The example to the left is a pogo-pins programming header that uses normal fixed pin headers to keep it in place. Frees up the hands, and allows me to program a board easily. But it’s also used to align the headers when soldering them down, and it’s a protoshield for end users!

More new PCBs

With a new job looming (actually, already started), it is the best time to start working on electronics projects again. No, I don’t know how that works either.

NTP Server 1.5 board has been made and now awaits testing. It’s pictured below:

The changes are documented on the history page. The two major changes are using a switch-mode power supply instead of a linear one, and removing some external flash that is no longer required now I have a working XBoot setup.

The other board to arrive is the first cut at an Arduino clone based on an XMEGA 64-pin chip. There are a few XMEGA based clones floating around, this one is mostly focussed on trying to support a wide range of 64-pin XMEGA chips and provide some extra hardware to get you started. This board is pictured below:

These are the first boards I’ve had made by the people at Hackvana. The build quality is good, with very clear silk and all drills have been correct. (I’ve had boards from other places with incorrect drills). In particular, despite the very small silk text for component labels (which, I should really have made a lower weight), they’re all clear enough to be read. Tented vias also came through just fine, and Hackvana will accept two drill files for plated and unplated holes, if you prefer to not plate mounting holes.

We’ll see how the boards perform when I get around to completing an assembly, but they look pretty good so far!

A busy few weeks

Rather unexpectedly, it’s been a busy few weeks on the electronics front. The result has been two new projects show up, and actual real honest progress on two other projects!

The two new designs are shields for an Arduino-based project that the great people at Nicegear are working on. One is a isolated driver and input shield, that allows switching higher voltages than the little Arduino can normally drive at much higher currents; the other is a compact switch-mode supply shield to allow you to run an Arduino off higher voltages without generating large amounts of heat.

The driver shield has been already built and tested by Nicegear, and works mostly as expected. There has been a revision to it already to include more voltage input options for the Arduino on the same shield as the drivers and input isolation. The original revision was limited to 12V for powering the Arduino.

The switch-mode supply shield hasn’t been built or tested just yet, but I’ve breadboarded the design so I am reasonably certain it’s going to work okay.

On the existing projects front, both the XMEGA-based Arduino clone and my long term NTP Server project have new boards ordered and on the way. The XMEGA board turned out pretty well I think, I’m hopeful with upcoming multiarch support in the Arduino IDE to see better support for such boards. On aspect about this board is rather than overloading the shield header with a bunch of useful but in-the-way peripherals, all additional hardware is conflict-free and allows full use of all the shield pins.

For example, the board includes pads for an 8-pin SOIC SPI flash or SRAM chip. While the SPI interface is wired to the usual Arduino pins for this (10-13), the CS line for the chip is on a discrete pin not shared with any of the shield pins. The same is true of extra LEDs, 32.768kHz watch crystal for the RTC, etc.

The NTP server had a minor polish up from the last post on it, but otherwise it’s down to just getting the board made and see if I’ve nailed down the last remaining issues. The software side of this is looking almost complete enough to start field testing!

Project Updates

A few small updates on the state of various projects..

NTP Server: Version 1.5 board looks mostly final now. The 3.3V switchmode regulator design has been checked on a breadboard and seems to run 1.4 just fine, so we’ll be going with that on the 1.5 board. This will reduce the heat significantly, as the reverse-polarity diode (which itself loses about half a watt) is being replaced with a P-channel MOSFET and the switchmode supply loses far less heat compared to the linear regulators (almost 1.6W are sourced from them alone). Software side I’ve removed all the (hugely problematic) single precision floating point code and use the time reported in integer milliseconds instead. Much nicer!

AVR Programmer: First build has been completed, and it largely works with the LUFA code compiled and uploaded into it. Various issues have come up, such as the bootloader switch not working quite as expected (The bootloader will only enter DFU mode if the switch is closed and we’re coming out of external reset which isn’t just a power-on-reset. Ick.) External flashing of the MCU doesn’t work right (unsure why) and it seems to hold !RESET low on targets. There is a 1.1 which is in progress.

New Breadboard PSU: Following on from the tests on the new switchmode supply for the NTP server, I’ve sketched out a new breadboard PSU which uses the same design. This would be an alternative to the linear one I already make and sell. At the moment it’s a single output design, I’m thinking about ways to make it dual-output or at least easily switchable between 5V and 3.3V.

XMEGA Arduino: Most of this design is completed. I need to just do a build to see how it plays out. The new XMEGA C3 line looked interesting but imposes some annoying routing problems. While using the C3 would provide a USB XMEGA which isn’t encumbered by crypto modules (and, therefore, export regs) and the C3 has USB pins where they are on the AxU chips, it has the same selection of peripherals as the D3 and USB is camped on top of one of the SPI ports. Which makes routing hard. May stick to the D3+MEGA16U2 bridge approach for now.

 

XMega Clock System

The change between the AVR Mega and XMega architectures that I like the most is the clock system. It would be fair to say I have little love for the way that the Mega implements clock options, and given the changes in how it works in the XMega I don’t think I was alone.

On a Mega, the choice of system clock is set by fuses. It generally isn’t intended that you change fuses from your main code, instead they should be changed mostly by external programming or when asked by a bootloader. That is, you set fuses when doing a brand new build on an out of the box chip and never at any other time.

Mega fuses are a pain to work with. Apart from being inverted in sense (ie, 0 and 1 are called programmed and unprogrammed, and programmed means “active”) a single incorrect write to them can brick the chip and disable important programming interfaces. If you wanted to run a Mega at full clock speed, you had to carefully ensure an external crystal was present and then write the appropriate fuses. And hope.

(Pedant alert: technically there was one clocking option you could change from within your main code, that was system clock prescaler. It’s initalised from a fuse (CLKDIV8) to divide by 8 for a safe default from a variety of possible sources, but you could switch that to undivided in your main code quite easily and non-destructively. That still limited you do the internal 8MHz RC oscillator, however.)

The XMega does away with this disaster, and instead allows you to change the system clock source from within your main code at any time. It allows you to run the chips at their full speed without external components. You can use external components of a variety of speeds and multiply the clock in addition to dividing it. It’s a vastly better design.

By default, an XMega will always boot off the internal 2MHz RC oscillator, with the PLL multipler disabled and no prescaler divisions, giving us a nice simple reliable default clock to work with. Should any clock option you set later fail (and, yes, it has clock failure detection) the chip will always force itself back to the 2MHz RC oscillator. (It also generates a non-maskable interrupt for this situation, so you main code can do something about it.)

This means, in general, whatever you do to the chip is a simple flash of some new code to apply a different set of clocking options, even if you have pieces missing off the board you’ve built.

All XMegas are capable of running at 32MHz @ 3.3V and there’s a variety of ways to get this. The easiest to start with is using the internal 32MHz RC oscillator and run everything at the same clock rate. The only trick to enabling this is to ensure the oscillator is running before attempting to use it, and then changing the clock via a protection mechanism:

OSC.CTRL = OSC_RC32MEN_bm; /* start 32MHz RC oscillator */
while (!(OSC.STATUS & OSC_RC32MRDY_bm)); /* wait for ready */
CCP = CCP_IOREG_gc; /* allow changing CLK.CTRL */
CLK.CTRL = CLK_SCKLSEL_RC32M_gc; /* system clock is internal 32MHz RC */

This does mean all peripheral modules are running at  32MHz as well, which all modules will accept by default. Some modules (EBI, HiRes Timer Extensions) run off faster clocks, which can be twice (PER2) or four times (PER4) the maximum system clock speed. Setting up the clock system for those I might cover at a later date.

Otherwise, that’s all which is required to get an XMega with no external components running at full clock speed. A lot nicer than a Mega!

An external crystal is not much harder, again you need to start the appropriate oscillator, wait for it to be ready, and change the clock via a protection mechanism. But in this case, we’re going to start with an 8MHz crystal and multiply it up to 32MHz using the PLL:

OSC.XOSCCTRL = OSC_FREQRANGE_2TO9_gc | OSC_XOSCSEL_XTAL_256CLK_gc; /* configure the XTAL input */
OSC.CTRL |= OSC_XOSCEN_bm; /* start XTAL */
while (!(OSC.STATUS & OSC_XOSCRDY_bm)); /* wait until ready */
OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 0x4; /* XTAL->PLL, 4x multiplier */
OSC.CTRL |= OSC_PLLEN_bm; /* start PLL */
while (!(OSC.STATUS & OSC_PLLRDY_bm)); /* wait until ready */
CCP = CCP_IOREG_gc; /* allow changing CLK.CTRL */
CLK.CTRL = CLK_SCLKSEL_PLL_gc; /* use PLL output as system clock */

While this is quite a lot more code than using a crystal clock on a Mega, it is still better since we get flexibility about what kind of crystal we’re using and the desired real clock rate we want from it. We could have done this with just a 32MHz crystal, and avoided the PLL. But only needing a cheaper 8MHz one and being able to multiply it up to the desired clock rate is a nice feature.

It would help if I knew what done looked like

Clearly posting about the NTP Server v1.4 board being done was a mistake, as I ended up launching myself into a major overhaul of it anyway. Yep, 1.4c was forked into 1.4d and has many many changes.

Part of the problem is I’m not settled on what “done” looks like. I was originally planning on not migrating from a simple watch crystal RTC to the DS3234 RTC until after 1.4 was completed. But working with the XMega RTC has given me a lot of niggly issues around getting it to behave well with aligning the clock.

The problems with the XMega RTC are a mix of just the result of using a 20ppm crystal (ie, you get 20ppm accuracy, and that’s not so cool) and some interesting choices about how it’s built.

Some AVR Megas have an async clock timer, usually it’s the single 8-bit timer. It’s pretty basic, but 8-bit is actually a good choice since you can cover off the rest of the needed bits for a 32.768kHz crystal off interrupts, once every 256 ticks is not a heavy interrupt workload. The Xmega doesn’t have an async clock timer, instead there’s an explicit 16-bit RTC with a crystal input.

At first (mostly when reading the datasheet) this looks pretty good. But, there’s a few annoyances. A number of Megas (and, more specifically, the ones I’ve been using like the 1284P) allow not only a 32.768kHz crystal but an external clock input. This allows you to use a variety of other clock options. The Xmega RTC has no such option, not in the A and D series anyway, and that’s almost all of the ones actually shipping. (You can brute force an external clock into a crystal input but I’d prefer to stay within what the datasheet says the chip is expecting.)

The other issue with the RTC is the way you access it. Because it’s running in it’s own clock domain – specifically off whatever 32-ish-kHz source you chose – you have to jump through a lot of busywaiting to get configuration pushed into it. Busywait. Set something. Busywait. Set something else. And so on. The same problem plagues accessing the current count, if you want to change it yet more busywaiting.

You also don’t get any capture options with the RTC, it has just compare and period registers, that’s it.

This makes it quite difficult to align the RTC to a fine degree. Sure, it’s great if you just need a simple timer to fire, say, a 1Hz interrupt to do something else in your code. It’s actually very good at that. But if you actually care what “now” really is, then it doesn’t cut it.

Falling out of that has been a large redesign, and involving the DS3234 RTC to replace the simple crystal. Thankfully while they did take away async clocking for a timer, they replaced it with a much more awesome system and the result is any of the normal 16-bit timers can provide a better replacement with finer control and more reliable capture. I’ll probably post about that some other time.

I’ll still be using the Xmega RTC, but it’ll just be there as a system clock for trivial event timing that we don’t really care about alignment for. Hell, 1% RC oscillators used as an RTC will be fine for many other timing needs in the code.

NTP Update; XMEGA thoughts

Just a minor update about the NTP server project, the board has been reworked a fair bit and this has resulted in a much cleaner design. There’s some parts coming so I can better prove the changes, before I get the PCB made. In the meantime, I’ve been playing more with the XMEGA chip I intend to use on the next revision.

One of the features I like about the AVR XMEGA series of MCUs is having a ton of peripherals is the design freedom you get – most digital blocks of pins have a couple of USARTs, SPI, and four to six channels of PWM output.

Compared to the older MEGA series chips, where you were lucky to get two USARTs and had no choice about where they were, it’s much easier to allocate pins to where you need them close to other components.

There’s other details they’ve really thought through from the code side as well. For many uses you’ll want to just turn particular pins on and off, the way I tended to do this on the MEGA series was something like:

PORTA |= (1 << PORTA3);

which works, and it’s okay for readability. (Aside: I could replace (1 << PORTA3) with _BV(PORTA3) or a bunch of other methods, I’m not saying that’s the only way to do it.). The compiler can optimize this where it’s in IO space down to a single instruction. What happens when you want to raise a couple of lines at once tho?

PORTA |= (1 << PORTA3) | (1 << PORTA4);

The compiler can’t reduce that to a single instruction (CBI and SBI only accept a single bit to clear/set), instead it has to do a read-modify-write cycle. On the XMEGAs however you have bitmask ranges on ports. Setting two bits on PORTA can be done by:

PORTA.OUTSET = PIN3_bm | PIN4_bm;

This is just a write to IO space, not a read-modify-write, and the chip takes care of applying the appropriate changes. (PINn_bm macros are new and replace the old PORTxn macros. They more correctly refer to the pin within any port, which technically was just as true of the PORTxn macros, just not so obvious.) The XMEGA line also includes some other nifty features, which the line above hints at: ports and peripherals are structs from a base, instead of random named addresses.

This means considerably less rewrite for different chips (you can either macro away the PORTA chunk, or pass it into functions as a pointer) and better code reuse. For example, on the old MEGAs if we were setting up a pin as an output and then toggling it once a second (ie, blinky LEDs!), we’d do something like:

#include <avr/io.h>
#include <util/delay.h>

#define LED_DDR DDRA
#define LED_PORT PORTA
#define LED_PIN (1 << PORTA2)

LED_DDR |= LED_PIN; /* pin is output */
LED_PORT &= ~(LED_PIN); /* off by default */
while (1) {
  LED_PORT |= LED_PIN; /* LED on, assuming pin to anode */
  _delay_ms(1000);
  LED_PORT &= ~(LED_PIN); /* LED off */
  _delay_ms(1000);
}

It does the job. It blinks the LEDs. On the XMEGA you can do this a bit differently:

#include <avr/io.h>
#include <util/delay.h>

#define LED_PORT PORTA
#define LED_PIN PIN2_bm

LED_PORT.DIRSET = LED_PIN; /* pin is output */
LED_PORT.OUTCLR = LED_PIN; /* make it off by default */

while (1) {
 LED_PORT.OUTTGL = LED_PIN; /* toggle it! */
 _delay_ms(1000);
}

This has exactly the same result, 1 second on then 1 second off looped. But since the XMEGA has an explicit pin toggling IO register, we can shorten it to using that. Note that we’re also more clearly setting and using features on the port (setting current levels, direction, toggling), rather than ungrouped assignments. Our LED_PORT define is how we access all the features of the port, not just setting state.

Trying out an XMEGA uC

Above is the shiny new XMEGA development board which arrived a few days ago. I have had a plan for a while to switch the NTP Server project from the smaller MEGA microcontrollers to something a bit larger.

It’s been something of an ordeal to get just basic features of the board functioning. I appear to have tripped over some sort of bug in the Linux USB CDC code since it utterly refuses to treat the USB Serial bridge on the board as anything useful at all. Thankfully I wasn’t planning on relying on any bootloader in the main XMEGA chip, so lacking the bridge is an annoyance rather than a complete killer – the board still breaks out two further TTL-level USARTs (as well as SPI and I2C!) so I can actually work around it fairly easily.

Otherwise the board is quite neat. It has the requisite blinky LEDs (8 of them!), a bunch of buttons arranged the way I tend to do so (they pull the input to ground, and rely on an internal pull-up in the uC), RTC crystal, along with stuff slightly less useful to me now (a speaker wired up to the DAC, a temp sensor, a light sensor, and 1MB of SDRAM). What’s great is none of this takes away from having a decent number of IO pins left over. They’ve also made sure that while the firmware on the bridge chip needs some improvements, the hardware has been built to support a number of interesting future uses for the bridge chip.

So far I’ve managed to also validate I can reflash the USB bridge chip with arbitrary code, since it has a DFU bootloader on it. I think the only things they’ve got wrong is they could have staggered the USB bridge chip off the accessible JTAG port as well as the main XMEGA chip, but instead it’s JTAG interface is test points on the underside. And it has unpopulated footprints for flash, which considering it’s maybe a couple of bucks for 1MB of flash is a bit cheap to leave off.

We’ll see how this goes. It’s looking at least promising enough I’m willing to consider switching to the XMEGA line for the next major board revision of the endless NTP Server project!