ATmega Arduino USART in SPI Master Mode MSPIM

The AVR ATmega MCU used by the Arduino Uno and its clones and peers (Leonardo, Pro, Fio, LilyPad, etc) and the Arduino Mega have the capability to use their USART (Universal Serial Asynchronous Receiver Transmitter), also known as the Serial Port, as an additional SPI bus interface in SPI Master mode. This fact is noted in the datasheets of the ATmega328p, ATmega32u4, and the ATmega2560 devices at the core of the Arduino platforms, but until recently it hasn’t meant much to me.

Over the past 18 months I’ve been working on an advanced derivative of the Arduino platform, using an ATmega1284p MCU at its core. I consider the ATmega1284p device the “Goldilocks” of the ATmega family, and as such the devices I’ve built have carried that name. Recently I have been working on a platform which has some advanced analogue output capabilities incorporating the MCP4822 dual channel DAC, together with a quality headphone amplifier, and linear OpAmp for producing buffered AC and DC analogue signals. This is all great, but when it comes down to outputting continuous analogue samples to produce audio it is imperative that the sample train is not interrupted or the music simply stops!

The issue is that the standard configuration of the Arduino platform (over)loads the SPI interface with all of the SPI duties. In the case of the Goldilocks and other Arduino style devices I have ended up having the MicroSD card, some SPI EEPROM and SRAM, and the MCP4822 DAC all sharing same SPI bus. This means that the input stream of samples from the MicroSD card are interfering and time-sharing with the output sample stream to the DAC. The MicroSD card has a lot of latency, often taking hundreds of milliseconds to respond to a command, whereas the DAC needs a constant stream of samples with no jitter and no more than 22us between each sample. That is a conflict that is difficult to resolve. Even using large buffers is not a solution, as when streaming audio it is easy to consume MBytes of information; which is orders of magnitude more than can be buffered anywhere on the ATmega platform.

Other solutions using a DAC to generate music have used a “soft SPI” and bit-banging techniques to work around the issue. But this creates a performance limitation as the maximum sample output rate is strongly limited by the rate at which the soft SPI port can be bit-banged. There has to be a better way.

USART in SPI mode

The better way to attach SPI Slave devices to the ATmega platform is referenced in this overlooked datasheet heading: “USART in SPI mode”. Using the USART in “Master SPI Mode” (MSPIM) is may be limiting if you need to use the sole serial port to interact with the Arduino (ATmega328p), but once the program is loaded (in the case of using a bootloader) there is often no further need to use the serial port. But for debugging if there is only one USART then obviously it becomes uncomfortable to build a system based on the sole USART in SPI mode.

However in the case of the Goldilocks ATmega1284p MCU with two USARTs, the Arduino Leonardo with both USB serial and USART, and the Arduino Mega ATmega2560 MCU with four USARTs, there should be nothing to stop us converting their use to MSPIM buses according to need.

Excuse me for being effusive about this MSPIM capability in the AVR ATmega. It is not exactly a secret as it is well documented and ages old, but it is a great feature that I’ve simply not previously explored. But now I have explored it, I think it is worthwhile to write about my experience. Also, I think that many others have also overlooked this USART MSPIM capability, because of the dearth of objective review to be found on the ‘net.

Any ATmega datasheet goes into the detailed features and operation of the USART in SPI mode. I’ll go into some of the features in detail and what it means for use in real life.

  • Full Duplex, Three-wire Synchronous Data Transfer – The MSPIM does not rely on having a Slave Select line on a particular pin, and further it doesn’t rely on having both MOSI and MISO lines active at the same time. This means that it is possible to attach a SPI Slave device that doesn’t use the _SS to begin or end transactions with just two pins, being the XCK pin and the Tx pin. If a _SS is required (as in the MCP4822) then only three wires are required. The fact that the MISO (Rx) pin is optional saves precious pins too.
  • Master Operation – The MSPIM only works in SPI Master mode, which means that it is only really useful for connecting accessories. But in the Arduino world, that is what we are doing 99% of the time.
  • Supports all four SPI Modes of Operation (Mode 0, 1, 2, and 3) – yes, it does.
  • LSB First or MSB First Data Transfer (Configurable Data Order) – yes, it does.
  • Queued Operation (Double Buffered) – The MSPIM inherits the USART Tx double buffering capability. This is a function not available on the standard SPI interface and is a great thing. For example, to output a 16bit command two writes to the I/O register can follow each other immediately, and the resulting XCK has no delay between each Byte output. To output a stream of bytes the buffer empty flag can be used as a signal to load the next available byte, ensuring that if the next byte can be loaded with 16 instructions then we can generate a constant stream of bytes. In contrast with the standard SPI interface transmission is not buffered and therefore in Master Mode we’re invariably wait-looping before sending the next byte. This wastes cycles in between each byte in recognising completion, and then loading the next byte for transmission.
  • High Resolution Baud Rate Generator – yes, it is. The MSPIM baud rate can be set to any rate up to half the FCPU clock rate. Whilst there may be little need to run the MSPIM interface at less than the maximum for pure SPI transactions, it is possible to to use this feature, together with double buffered transmission, to generate continuous arbitrary binary bit-streams at almost any rate.
  • High Speed Operation (fXCKmax = FCPU/2) – The MSPIM runs at exactly the same maximum clock speed as the standard SPI interface, but through the double buffering capability mentioned above the actual byte transmission rate can be significantly greater.
  • Flexible Interrupt Generation – The MSPIM has all the same interrupts as the USART from which it inherits its capabilities. In particular the differentiation between buffer space available flag / interrupt and transmission complete flag / interrupt capabilities make it possible to develop useful arbitrary byte streaming solutions.

Implementation Notes

As the USART in normal mode and the USART in MSPIM mode are quite similar in operation there is little that needs to be written. The data sheet has a very simple initialisation code example, which in practice is sufficient for getting communications going. I would note that as there is no automatic Slave Select management, the _SS line needs to be manually configured as an output, and then set (high) appropriately until such time as the attached SPI device is to be addressed. Also note that the XCKn (USART synchronous clock output) needs to be set as an output before configuring the USART for MSPIM. And also to note that the transmission complete flag (TXCn) is not automatically cleared by reading (it is only automatically cleared if an Interrupt is processed), and needs to be manually cleared before commencing a transmission (by writing a 1 to the TXCn bit) it you are planning to use it to signal transaction completion in your code. The Transmit and Receive Data Register (UDRn) is also not automatically cleared, and needs to be flushed before use if a receive transaction is to synchronised to the transmitted bytes.

So the implementation of a simple initialisation code fragment looks like this:

SPI_PORT_DIR_SS |= SPI_BIT_SS;   // Set SS as output pin.
SPI_PORT_SS |= SPI_BIT_SS;       // Pull SS high to deselect the SPI device.
UBRR1 = 0x0000;
DDRD |= _BV(PD4);                // Setting the XCK1 port pin as output, enables USART SPI master mode (this pin for ATmega1284p)
UCSR1C = _BV(UMSEL11) | _BV(UMSEL10) | _BV(UCSZ10) | _BV(UCPOL1);
                                 // Set USART SPI mode of operation and SPI data mode 1,1. UCPHA1 = UCSZ10
UCSR1B = _BV(TXEN1);             // Enable transmitter. Enable the Tx (also disable the Rx, and the rest of the interrupt enable bits set to 0 too).
                                 // Set baud rate. IMPORTANT: The Baud Rate must be set after the Transmitter is enabled.
UBRR1 = 0x0000;                  // Where maximum speed of FCPU/2 = 0x0000

And a fragment of the code to transmit a 16 bit value looks like this. Note with this example there is no need to wait for the UDREn flag to be set between bytes, as we are only writing two bytes into the double transmit buffer. This means that the 16 clocks are generated on XCKn with no gap in delivery.

UCSR1A = _BV(TXC1);              // Clear the Transmit complete flag, all other bits should be written 0.
SPI_PORT_SS &= ~_BV(SPI_BIT_SS); // Pull SS low to select the SPI device.
UDR1 = write.value.u8[1];        // Begin transmission of first byte.
UDR1 = write.value.u8[0];        // Continue transmission with second byte.
while ( !(UCSR1A & _BV(TXC1)) ); // Check we've finished, by waiting for Transmit complete flag.
SPI_PORT_SS |= _BV(SPI_BIT_SS);  // Pull SS high to deselect the SPI device.

Results

Looking at the output generated by the two different SPI interfaces on the AVR ATmega, it is easy to see the features in action. In the first image we can see that the two bytes of the 16 bit information for the DAC are separated, as loading the next byte to be transmitted requires clock cycles AFTER the transmission completed SPIF flag has been raised.

DAC control using SPI bus.

DAC control using SPI bus.

In the case of the MSPIM output, we can’t recognise where the two bytes are separated, and the end of the transaction is triggered by the Transaction complete flag. This example shows that the MSPIM can be actually faster than the standard SPI interface, even though the maximum clock speed in both cases is FCPU/2.

DAC control using USART MSPIM bus.

DAC control using USART MSPIM bus.

The final image shows the Goldilocks DAC generating a 44.1kHz output signal, with dual 12 bit outputs. Whilst this is not fully CD quality, comparisons with other DAC solutions available on the Arduino platform have been favourable.

44.1kHz samples using USART MSPI output.

44.1kHz samples using USART MSPI output.

Conclusion

I am now convinced to use the USART MSPIM capability for the Goldilocks Analogue, and I think that it is time to write some generalised MSPIM interface routines to go into my AVRfreeRTOS Sourceforge repository to make it easy to use this extremely powerful capability.

DS3231 RTC hwclock for Raspberry Pi and Arduino

I’ve been spending some time with the Maxim Integrated DS3231 “Extremely Accurate I2C Integrated RTC”. Many have recommended it to provide a RTC for an advanced Arduino style board called the Goldilocks, so I looked into putting one of these SOIC16 devices on the board. The bottom line is that the best device price to me is greater than the finished price for a Raspberry Pi compatible module, complete with either a battery or a super capacitor to maintain the time should the main power be lost.

DS3231 RTC Module

The DS3231 also contains an accurate thermometer, used to trim the timing to maintain the +-2ppm accuracy characteristic from 0 to 40 degrees Celcius. The registers for the temperature can be read, and make a useful secondary function for this device.

I purchased some DS3231 modules for my Raspberry Pi devices, and also to test their use as an option for the Goldilocks. This is to remind myself how the Raspberry Pi needs to be configured to use the DS3231 RTC module.

Configuring for Raspberry Pi

To contain cost the Raspberry Pi doesn’t have a hardware or real time clock capability. A fake RTC is provided which simply stores the time the Raspberry Pi was shut down, and reads this time out when the Raspberry Pi is booting. Obviously this time can be wrong by anything from 10 seconds to a year, depending on how long the Raspberry Pi is left unused.

The DS3231 module is an I2C device that is attached to IO pins 1 through 5 on the Raspberry Pi. The DS3231 can run from either 3V3 or 5V so it can work with both Arduino and Raspberry Pi I2C bus levels.

Sunfounder DS3231 module installed on a Raspberry Pi B+

SunFounder DS3231 module installed on a Raspberry Pi B+

There are several Internet references on how to get the DS3231 working on the Raspberry Pi. But the most concise version is by Drew Keller. Initially I used these to get started, but the method described activates the RTC at the end of the boot sequence, long after the time is really needed to set logging and disk access times correctly. Fortunately, there is another instruction that describes some minor changes to the hwclock.sh script which enables the DS3231 early in the boot sequence, ensuring that we have the correct time when we need it. Unfortunately it describes insertion of the wrong module, and refers to the DS1307 (although this is essentially the same).

So that I don’t forget what to do, here are the instructions again.

Update: Kernel 3.18 breaks some things. This is the fix.

First lets fix something only relevant to those who are running the 3.18+ kernel.

Help, my I2C interface has disappeared. What do I do? Add

dtparam=i2c=on

to your /boot/config.txt and reboot. If you are feeling terse you can omit the “=on”, since that is the default option.

Now we have to edit the hwclock.sh file in /etc/init.d/ to add this function to initialise the RTC. Note that the i2c-bcm2708 module is used.

HCTOSYS_DEVICE=rtc0

init_rtc_device()
{
  [ -e /dev/$HCTOSYS_DEVICE ] && return 0;

  # load i2c and RTC kernel modules
  modprobe i2c-bcm2708
  modprobe rtc-ds1307

  # iterate over every i2c bus as we're supporting Raspberry Pi rev. 1 and 2
  # (different I2C busses on GPIO header!)
  for bus in $(ls -d /sys/bus/i2c/devices/i2c-*);
  do
    echo ds3231 0x68 >> $bus/new_device;
    if [ -e /dev/$HCTOSYS_DEVICE ];
    then
      log_action_msg "RTC found on bus `cat $bus/name`";
      break; # RTC found, bail out of the loop
    else
      echo 0x68 >> $bus/delete_device
    fi
  done
}

Then a bit further down in the start) section add in a call to the initialisation function we’ve just prepared, and also comment out the udev search as it won’t find the DS3231.

case "$1" in
  start)
    # initialise the hardware RTC DS3231
    # this is for the module attached
    init_rtc_device
...
    # As UDEV won't find ds3231, comment this out
    # if [ -d /run/udev ] || [ -d /dev/.udev ]; then
    # return 0
    # fi
...

Then we have to remove the I2C module blacklist entry (by commenting it out) so that it can be loaded on boot. The Raspberry Pi team think that their users won’t use I2C or SPI functions normally, so they’re preemptively disabled.

sudo sed -i 's/blacklist i2c-bcm2708/#blacklist i2c-bcm2708/' /etc/modprobe.d/raspi-blacklist.conf

The final thing left is to remove the fake hardware clock function by typing this command from the shell.

sudo update-rc.d fake-hwclock remove

The reboot the Raspberry Pi and check that you can see the /etc/rtc0 and that the hwclock function returns a valid time. By studying the boot log messages relating to the RTC can also be seen. Check that you’re getting no errors. You should see something like this.

[ 10.631809] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
[ 10.650126] i2c i2c-1: new_device: Instantiated device ds3231 at 0x68

Arduino

Update on using the DS3231 in freeRTOS here soon.

Goldilocks Analogue – Prototyping 3

Following my initial design article, and the follow up design article, I’ve put quite a lot of thought into how I can make this Goldilocks Analogue device best achieve my stated goals. Pictured is the 2nd Goldilocks Analogue Prototype.

This is the working design document. It will grow as I get more stuff done, and notes added here. I’ve pretty much finished the paper design now, and will let it settle for a few weeks over the holiday season. It is sometimes good to do things again, with a few weeks perspective from the original decisions.

Existing Goldilocks Analogue Prototype

Existing Goldilocks Analogue Prototype 2

Major Revision in Strategy

Over the past months I’ve been spending time writing code to go along with the latest revision of the Goldilocks Analogue. I have successfully implemented a version of the NASA EEFS simple flash file system, to use to buffer data either for acquisition or for analogue playback, and I’ve been working on streaming functions to get data off the SD card and off the EEFS flash file system. The outcome is that it is not possible to do everything with just one SPI bus, and keep generality when needed. The SD card is just too slow, and can’t be easily interrupted. The FRAM/SRAM/EEPROM doesn’t have enough storage to effectively stream GigaBytes of data, as a uSD card can achieve.

So, what to do? Adafruit uses a software bit-banged SPI outcome to drive their MCP4921 and doesn’t get close to the maximum speed I want to achieve. Fortunately, with the ATmega1284p there is a simple answer at hand. I have decided to move the MCP4822 off the standard SPI pins, and connect it to the USART1 TX and XCK pins, using the USART in its Master SPI mode.

This is a major revision in strategy. Previously I have been very adverse to putting anything on the standards Arduino pins, preferring to keep all of the Goldilocks extra features off the Arduino footprint. However, the outcome is well worth using the USART1 to drive the MCP4822, and nothing is compromised.

USART MSPI mode is available on any ATmega device. On the UNO platform, using the ATmega328p, there is only one USART and so of course it is reserved for serial communications. The Goldilocks ATmega1284p has two USART interfaces, and usually the second one (USART 1) goes unused. Therefore connecting its XCK and TX pins to the MCP4822 is the simplest and best outcome to achieve high throughput and regularity SPI output on a non-shared SPI interface. And, as the MCP4822 DAC has high impedence (~10kOhm) inputs, having the DAC sharing the pins won’t affect normal pin usage to any extent.

And, there’s more win. The USART MSPI has double buffering for the transmit function. This means that we can actually achieve a higher throughput using the USART MSPI than we can using the standard SPI bus! These logic traces demonstrate that the my best implementation of the SPI interface requires 4.58us to transmit a “frame” of information, consisting of two 12 bit samples. Using the USART MSPI interface we can achieve 4.25us per frame.

DAC control using SPI bus.

DAC control using SPI bus.

DAC control using SPI bus.

DAC control using USART MSPI bus.

Either way, achieving 44.1kHz stereo output is not an issue. This trace shows the time spent in the DAC-out interrupt for a simple function, with the samples being played out at 44.1kHz.

44.1kHz samples using USART MSPI output.

44.1kHz samples using USART MSPI output.

Guessing that this would be a great outcome, I ordered new PCBs from Seeed which implement the new pin assignments for the MCP4822. They will be here shortly.

My Revision Plans

Revert the uSD card 3V SPI bus drivers back to the quad and single buffers. The TXB/TXS story remains unresolved, and I can’t be bothered to work out why, when a simple answer is at hand. – DONE

Connect the uSD _CARD_DETECT to PC2 which has no other function except JTAG. – DONE

Remove the FTDI 6 pin for USART0. Or, better to move it to connect to USART1, so that USART1 can be addressed by an external FTDI device. Move it to the end of the board, so it doesn’t block Shield usage. Note the RTS/CTS Reset is not connected because this is replaced by a DAC A/B channel. – DONE

Remove the Analogue outputs from centre of board. Move them to the end of the board and integrate them into the FTDI USART1 socket on the RTS and CTS pin positions (obviously not on Tx or Rx pins, or on Vcc or GND either). – DONE

Connect the MCP4822 _LDAC pin to enable sychronisation of the A and B channels. Connect to PC3 which has no other function except JTAG. Remember the _LDAC is pulled to GND by default. – DONE

Have another look at the output filtering on the DAC, perhaps it could be a little stronger than the prototype with the corner at 23kHz. Single pole R1=68Ω C1=100nF. – DONE

This 2nd order filter is still linear, but filters significantly more (6dB rather than 3dB per decade) than the single pole version on the prototype.

2nd Order RC Low Pass Filter

Using standard Resistor and Capacitor values R1=47Ω C1=100nF R2=47Ω C2=100nF in a 2nd order CR Low-pass Filter Design Tool.

Extend the prototyping area by three columns. – DONE

Add a pin-out to allow the DS3231 RasPi module (battery or super capacitor) from Seeed Studio to be easily attached. Unfortunately, the devices I have don’t implement an _INT/SQW output, so alarms and wake on alarm won’t be possible. – DONE

Push the JTAG pads to the back of the board, without forgetting to flip the pin layout around. – DONE

Add SRAM or FRAM SPI storage. FRAM is non volatile storage, that has no delay. With a reasonable amount of storage we can use it to provide short audio samples, and get them back relatively easily, without file system and uSD card overheads. But FRAM is pretty expensive, and SRAM chips with same pin-out are available for much cheaper, that might fulfil the job of buffering or capturing samples.

MB85RS64V FRAM is the only reasonable device available for 5V supply. And it is a reasonable price of $1.80 per unit. But it is much too small to use as an analogue sample store. Need to use the 128kB MB85RS1MT FRAM version, but this required being driven from Vcc 3V3. At 8kHz sampling, 128kB gives us 16 seconds of sound, which is quite a lot. It costs around $6 which seems to be the sweet spot in pricing now. Will have to add another 3V3 to 5V MISO buffer. Use PC4 as the MB85RS1MT SPI _SS line.

Alternatively, just make the pinout for SPI 5V and implement SRAM using the Microchip 23LC1024 device, which is $2.50 each. We can choose FRAM or SRAM at assembly. Or even both, as there is a spare _SS available. So let’s do two devices at Vcc 5V supply.

Put 10kOhm pull-up resistors on all of these _SS lines, _CARD_DETECT and _HOLD. – DONE

Add 10kOhm pull-down resistors on _LDAC allowing active _LDAC control but not requiring it. – DONE

Convert the 3.3V regulator to AP1117 type in SOT89-3 package. No space for SOT223. Upgrades the 3.3V supply from 150mA to 1000mA. Heat spread on Layer 2 GND and on Layer 15. – DONE

Initial Board Layout

I’ve finished the schematic and the board layout, and now I just have the detailed work of checking all the things, again, and again. I’ve come back to this after letting it stew for a few days with the thought of changing just one component. But, as usual have made a host of minor adjustments that should make it better. These include further clearance of the ground plane under the analogue components, and untangling and straightening signals and vias where possible.

The Goldilocks Analogue Schematic  in PDF format.

Front of board (All Layers)

The board is now pretty tightly packed. But, there is still a large number of options for prototyping on the board, or to exit the board with 8-pin headers. Each of Port A, Port B and Port D can be taken off board with one header each. Alternatively, a 2×8 connector can be attached, with the pins assigned and connected as desired.

The DAC A (L) and DAC B (R) channels are integrated into the far right edge of the board, along with TX1 and RX1 pins in the form of a FTDI 6 pin interface (including 5V and GND).

The first 5 pins of Raspberry Pi IO are replicated, to allow DS3231 RTC modules (designed for RaspPi) to be connected. For permanent mounting, the module can be flipped on its back to show the battery, and be mounted over the DAC which keeps the prototyping area clear.

I have been able to fit 2x SPI SRAM (or FRAM or NVRAM or EEPROM) on the board, using the spare JTAG IO pins. It is very tight, but having the option to fit up to an extra 2Mbit of SRAM will be quite useful for buffering and storing large amounts of data (audio, or samples).

16th February

Major revision. Moved the DAC control to use the USART1 MSPI function. It will be connected to Arduino Pin 4 XCK1 and Pin 3 TX1. This will ensure that we can stream data from the uSD card or the FRAM/SRAM/EEPROM on the main SPI bus to the DAC on the USARTt1 MSPI bus with no contention issues.

PCB with the revised connections is on its way.

21st January

The boards are back. Everything looks in order. The concept of using the keep-out layer to write in silkscreen works as hoped, so the labels on the edge are legible.

Time to get to ordering the new components, and building.

Goldilocks Analogue - Prototype 3

Goldilocks Analogue – Prototype 3

31st December

Cleaned up the board to allow more labels to be applied, trying to make it self-documenting. Packed the analogue section a bit tighter, and improved the power routing.

Screenshot from 2014-12-31 15:47:28

21st December

Cleaned up many traces and cleared the Layer 2 GND plane even more. Discovered the DS3231 modules don’t implement the _INT/SQW function, but leaving the connection to PB2 (INT2) on the pin-out for the future.

Screenshot from 2014-12-21 17:36:10

16th December

Screenshot from 2014-12-16 22:12:43

Top Layer

Labels for the DAC A and DAC B and FTDI interface have been put into the keep-out layer in the silk screen on the edge. They will appear when the silk is printed.

Added Test Points for the 3.3V SPI signals, which are the only signals that can’t be tested off a pin-out somewhere.

31st December

Added labels for the I2C (Raspberry Pi IO1 through IO5) pin out, by moving the analogue section left.

Screenshot from 2014-12-31 15:45:41 Screenshot from 2014-12-31 15:45:55

21st December

Screenshot from 2014-12-21 17:22:27 Screenshot from 2014-12-21 17:22:52

16th December

Screenshot from 2014-12-16 22:10:31 Screenshot from 2014-12-16 22:12:18

Layer 2 – GND

The GND plane remains whole under the DAC and Amplifiers.

31st December

Moving the analogue section to the left and compressing it moves components more over the solid ground plane.

Screenshot from 2014-12-31 15:46:07 Screenshot from 2014-12-31 15:46:17

21st December

Improved the ground plane by moving traces out from under components, and re-routing AVCC line.

Screenshot from 2014-12-21 17:28:45 Screenshot from 2014-12-21 17:29:03

16th December

Screenshot from 2014-12-16 22:10:58 Screenshot from 2014-12-16 22:10:43

Layer 15 – 5V (and 3.3V)

The 5V layer, with the 3.3V and AVCC 5V supplies too.

31st December

Resolved the S-bend power to the I2C 5V pin out, and removed some dead traces.

Screenshot from 2014-12-31 15:46:30 Screenshot from 2014-12-31 15:46:44

21st December

Kept the 5V AVCC line on this layer which makes it longer, but avoids using vias. Tidied up some other power routing.

Screenshot from 2014-12-21 17:30:16 Screenshot from 2014-12-21 17:30:30

16th December

Screenshot from 2014-12-16 22:11:29 Screenshot from 2014-12-16 22:11:10

Bottom Layer

All the pin-outs are defined on the bottom. Unfortunately, there is no space on the top layer.

The JTAG is now pushed to the back of the board. This will make using the JTAG more difficult, but at least it will not interfere with shields, should the solution require testing when in a system.

21st January 2015

The back side is clean, and all of the labelling will ensure that the board is self documenting. I was unsure whether putting text in the keep-out layer would work, but it seems to work very well. That’s a win.

Goldilocks Analogue - Prototype 3

Goldilocks Analogue – Prototype 3

 

31st December

Added labels for the “FTDI like” pin out, combined with the DAC outputs, to improve self documentation.

Screenshot from 2014-12-31 15:47:01 Screenshot from 2014-12-31 15:47:15

21st December

Added more accurate descriptions, and tidied some routing.

Screenshot from 2014-12-21 17:33:28 Screenshot from 2014-12-21 17:34:33

16th December

Screenshot from 2014-12-16 22:11:57 Screenshot from 2014-12-16 22:11:43

Pin Mapping

This the map of the ATmega1284p pins to the Arduino physical platform, and their usage on the Goldilocks Analogue

Arduino
UNO R3
328p Feature 328p Pin 1284p Pin 1284p Feature Comment
Analog 0 PC0 PA0
Analog 1 PC1 PA1
Analog 2 PC2 PA2
Analog 3 PC3 PA3
Analog 4 SDA PC4 PA4 PC1 I2C -> Bridge Pads
Analog 5 SCL PC5 PA5 PC0 I2C -> Bridge Pads
Reset Reset PC6 RESET Separate Pin
Digital 0 RX PD0 PDO RX0
Digital 1 TX PD1 PD1 TX0
Digital 2 INT0 PD2 PD2 INT0 / RX1 USART1
Digital 3 INT1 / PWM2 PD3 PD3 INT1 / TX1 USART1
-> MCP4822 MOSI
Digital 4 PD4 PD4 PWM1 / XCK1 16bit PWM
-> MCP4822 SCK
Digital 5 PWM0 PD5 PD5 PWM1 16bit PWM
Digital 6 PWM0 PD6 PD6 PWM2
Digital 7 PD7 PD7 PWM2
Digital 8 PB0 PB2 INT2 <- _INT/SQW
Digital 9 PWM1 PB1 PB3 PWM0
Digital 10 _SS / PWM1 PB2 PB4 _SS / PWM0 SPI
Digital 11 MOSI / PWM2 PB3 PB5 MOSI SPI
Digital 12 MISO PB4 PB6 MISO SPI
Digital 13 SCK PB5 PB7 SCK SPI
 (Digital 14) PB0  T0 -> SDCard SPI _SS 3V3
 (Digital 15) PB1  T1 -> MCP4822 SPI _SS
SCL PC0 SCL I2C – Separate
SDA PC1 SDA I2C – Separate
PC2 TCK JTAG <- _CARD_DETECT
for uSD Card
PC3 TMS JTAG -> MCP4822 _LDAC
PC4 TDO JTAG -> RAM SPI _SS_RAM0
PC5 TDI JTAG -> RAM SPI _SS_RAM1
PC6 TOSC1 <- 32768Hz Crystal
PC7 TOSC2 -> 32768Hz Crystal
XTAL1 PB6
XTAL2 PB7
 (Analog 6) PA6 -> Pad / Hole
 (Analog 7) PA7 -> Pad / Hole

Discussion on RTC

At the end of the day, the DS3232 / DS3231 device is around $8 best case to me. But modules are available complete with super capacitors from Seeed for around $6. There’s no win here. Stick to the crystal and existing solution, but make it easier to use the Seeed RasPi solution.

Digikey has the DS3231 at $8 per piece. This is pretty expensive, for what it delivers. And there are solutions available with super capacitor backing for under $6 from Seeed.

Design in the DS3232 on the TOSC1 input for the TCXO 32kHz clock and PC5 input for the INT/SQW line. Supply from 3V3 Vcc. Read that the I2C lines can run to 5V5 without issue. INT/SQW outputs are open drain and the INT/SQW can be disabled (high impedance). Let the ATmega1284p switch on its pull-ups for INT/SQW to function. Make sure 20kOhm pull ups on the SCL/SDA lines too.

The DS3232 has 236 Bytes of SRAM, and a push-pull output on TCXO 32kHz line so this is better as an asynchronous clock input.There is an accurate (0.25°C) thermometer function included. It comes in an 20SOIC package which is quite large. Having some SRAM will be very useful for storing configurations that change often (where EEPROM would wear out).

The DS3232M has 236 Bytes of SRAM, and a push-pull output on 32kHz line so this is better as an asynchronous clock input. Having some SRAM will be very useful for storing configurations that change often (where EEPROM would wear out). But, it doesn’t have 5.5V capability on its I2C lines. – Deselect

The DS3231 version comes in an 16SOIC package, which might be better, but it doesn’t have any SRAM, and the TXCO is open drain. – If we need smaller then this is where we go.

The DS3231M MEMS version comes in an 8SOIC package, which might be better, but it is only +-5ppm (rather than +-2ppm). – Don’t need the small package, so go for XTAL version DS3231 in the SOIC16 package.

Digikey has the DS3232 at $8.60 per piece. This is pretty expensive, for what it delivers.

Delete the 32kHz crystal, and capacitors.

Add on a 3V Lithium battery holder. Or a Super Capacitor and a charging diode

Leave the TOSC2 pin floating, as it is not useable when the Timer 2 Asynchronous Clock Input is enabled on TOSC1.

Remove pull-up resistors from RST, as the DS3231 has pull-ups as does the ATmega1284p. The DS3231 has a debounce and 250ms delay function to manage the MCU start up.

Design Input from Angus

IC6 is missing silkscreen marking for pin 1. – DONE

Designator layer needs a cleanup. I had to spend a lot of time in
EAGLE checking which components were which, and what orientations
they had. On such a full board with close-spaced components this is
very important – ideally place each designator between the pads it
refers to, with a consistent orientation relative to the pads. – DONE

Some 0603/0402 components seemed to have wrong pad sizes compared to
BOM output, ie R17 & C13. I placed according to what parts were
supplied. I know this has been revised further but it might be worth
checking BOM output for any remaining anomalies. – CHECKED

If possible move components away from IC bodies, for example C36 is
very close. Even for a pick & place machine I suspect this would be
hard. – DONE

Labels on silkscreens would be very helpful. For instance the power
selection & DTR jumpers, other pin breakouts. For Freetronics boards
we aim to have all of these connections self-documenting, ie each
option labelled somehow. This can be difficult but part of the
appeal of a development board is being able to easily make
customisations without requiring an external reference. – DONE

It’d be great if you could find a way to better convey the offset
pin numbering for pins 8-13. – NO BETTER ANSWER

The MCU 1284p solder stencil paste layer has too large of an
aperture for the thermal pad. If you look at the paste layer of IC1
and compare to IC2 then you’ll see what I mean. The aperture needs
to be cut down in this way or the central pad gets too much paste
and “floats” up, leading to the outer connections not forming
correctly. – OK Can’t change Library

Suggest adding test points for likely problem connections. ie
analogue section power rails, 3.3V SPI connections, raw DAC
outputs. These can just be bare SMD pads on top or bottom of
board. Label with a designator (at least) or a descriptive label if
possible. For an example of what I mean, the OpenVizsla boards have
a really nice set of 4 power test points near the bottom of the
board. – DONE Power is easy off pins. Added 3.3V SPI test points. Other pins all have pin-outs.

Design Input from Freetronics Forum

Keep the JTAG header, but also distribute the pins to the 2nd Non-Arduino shield pins. – Going to push the JTAG to the back of the board. It will be inconvenient to use, but won’t block the use of Shields when it is actually being used so this is better. This also frees more space for a RTC and battery option. – DONE

Add a RTC option. – Using the 32kHz crystal on Timer 2 the RTC is working fine. Battery and power options can be off board, and as comprehensive and accurate as needed. – DONE

Other RTC options include using the DS3231, which would be more accurate than a 32kHz crystal, and includes an integrated RST debounce timer. Can use the 32kHz output to feed the ATmega1284p Timer 2 and therefore have both devices locked to the same clock. Chronodot as an example for using this RTC. – DONE

Goldilocks Analogue – Testing 3

Summary

I’m still working (slowly) on a new development for my ATmega1284p platform, called Goldilocks.

My initial design for the Goldilocks Analogue was flawed in several ways, so I revised the design and produced a new prototype.

Following up on the initial testing matched against the Stanford Analog Shield, I’m now testing against the Open Music Labs Audio Codec Shield.

Goldilocks Analogue & OML Audio Codec Shield

Goldilocks Analogue & OML Audio Codec Shield

Both devices output excellent looking 43.1Hz sine waves, at 44.1kHz reconstruction rate, from the previous 16 bit 1024 sample Sine Wave.

The Goldilocks Analogue produces 0V to 4.096V 1:1 buffered signals from its DC outputs, and an AC amplified headphone output in parallel. The Audio Codec Shield produces 0V to +3V line level signals into 10kOhm, together with an amplified headphone signal.

 

OML Audio Codec Shield 43.1Hz Sine wave, one channel inverted.

OML Audio Codec Shield 43.1Hz Sine wave, one channel inverted.

Open Media Labs – Audio Codec Shield

The Audio Codec Shield uses a very capable Wolfson Audio WM8731 device to generate its output. The WM8731 has stereo 24-bit multi-bit sigma delta ADCs and DACs complete with oversampling digital interpolation and decimation filters. Digital audio input word lengths from 16-32 bits and sampling rates from 8kHz to 96kHz are supported. The WM8731  has stereo audio outputs which are buffered for driving headphones from a programmable volume control and line level outputs are also provided complete with anti-thump mute and power up/down circuitry.

Nominally, it is unfair to compare the MCP4822 12 bit DAC against the 24 bit 96kHz WM8731 DAC, but let us see how this looks, when both are driven with 44.1kHz 16 bit inputs. But, based on pricing information from Digikey, they are available at around the same price range, so this has to be a reasonable test.

Head to Head

Testing was done using a 16 bit 1024 sample Sine Wave file. Outputs were generated by a timer triggered to interrupt every 22.7us (44.1kHz), and produce a new output level. Testing should show only a main signal at 43.1Hz, and the reproduction frequency of 44.1kHz. The Goldilocks Analogue discards the lower 4 bits of the samples and only outputs the 12 most significant bits. The WM8731 could produce 24 bit audio from its DAC, but in this test it will be run at 16 bits only.

OML Audio Codec Shield & Goldilocks Analogue with Red Pitaya

OML Audio Codec Shield & Goldilocks Analogue with Red Pitaya

All outputs generated by a 1024 sample 16 bit Sine wave, generated with a 44.1kHz reconstruction sample rate, triggered by an interrupt timer.

The OML Audio Codec Shield produces very nice Sine waves.

OML Audio Codec Shield 43.1Hz Sine wave, one channel inverted.

OML Audio Codec Shield 43.1Hz Sine wave, one channel inverted.

The top of the wave form

OML_43.1Hz_3V

and the bottom of the waveform. Show some high frequency noise. This could be removed by the on-board digital filters on the WM8731, but in this testing situation the have not been turned on.

OML_43.1Hz_0V

 

Looking at the spectra generated by both implementations up to 953Hz it is possible to see harmonics from the Sine Wave, and other low frequency noise.

OML_43.1Hz_Sine_953Hz

OML Audio Codec Shield – 43.1Hz Sine Wave – 953Hz Spectrum

GA_43.Hz_953Hz

Goldilocks Analogue – 43.1Hz Sine Wave – 953Hz Spectrum

 

The Audio Codec Shield has a significant noise present at 50Hz, which may be caused by noise leakage through the PC USB power supply not being completely filtered before the supply is provided to the WM8731. Other noise rises up to 80dB, and is present right across the spectrum.

OML Audio Codec Shield – 43.1Hz Sine Wave – 7.6kHz Spectrum

OML Audio Codec Shield – 43.1Hz Sine Wave – 7.6kHz Spectrum

GA_43.1Hz_7.6kHz

Goldilocks Analogue – 43.1Hz Sine Wave – 7.6kHz Spectrum

 

 

And here.

OML Audio Codec Shield  – 43.1Hz Sine Wave – 61kHz Spectrum

OML Audio Codec Shield – 43.1Hz Sine Wave – 61kHz Spectrum – Harmonics around 44.1kHz reconstruction frequency

Goldilocks Analogue – 43.1Hz Sine Wave – 61kHz Spectrum

Goldilocks Analogue – 43.1Hz Sine Wave – 61kHz Spectrum

 

And here.

OML_43.1Hz_Sine_976kHz

OML Audio Codec Shield – 43.1Hz Sine Wave – 976kHz Spectrum

GA_43.1Hz_976kHz

Goldilocks Analogue – 43.1Hz Sine Wave – 976kHz Spectrum

Algorithmic Symphonies

I’ve added some algorithmic symphony code to both solutions.

Here’s a short clip of one 8 bit algorithmic symphony played by the Goldilocks Analogue.

Wiznet W5500 and ioShield-A What’s old is new again!

It seems that the Wiznet W5100 Ethernet Shield has been around since the very beginning of the Arduino movement. Its integrated TCP and UDP IP stack enabling solid standardised networking since the very beginning.

The hardware implementation of BSD sockets interface abstracted the complex process of generating compliant IP and made sure that it was done correctly, and the buffering of network packets in integrated packet RAM, rather than on the host AVR micro-controller; was a great thing when you only have 1kB of RAM available as the original ATmega168 Arduino devices provided. For the current generation of Arduino devices, nothing has really changed.

Recently, I wrote about the new W5200 iteration of the Wiznet integrated IP controller, and how it is significantly better in performance and features than the older W5100 version.

Now, I have my hands on the latest version. The W5500 on an ioShield-A from Wiznet.

W5500 on ioShield-A from Wiznet

W5500 on ioShield-A from Wiznet

TL;DR. The W5500 is the latest and best iteration of hardware IP socket Ethernet devices from Wiznet, and also the easiest for hobbyists to implement. As usual, my code is here at AVRfreeRTOS.

So what are the key differences between the models, and how do they perform? I’ll try to look at three important aspects to using these devices; cost, implementation or how are they to use, and performance.

Cost

As Wiznet has iterated through the W5x00 series it has cost reduced the manufacturing significantly. The W5100 was produced in 0.18um process, as was the W5200. The new W5500 is produced in 0.13um process, with a 1.2v core, in comparison. Between the W5100 and W5200 Wiznet doubled the size of the internal packet RAM to 16kByte, but significantly reduced the number of IO pins and drivers, to make the W5200 (and W5500) SPI bus specialists.

The result of these cost reduction processes can be seen in the pricing information from Digikey. The price per 1,000 for W5100 is $4.32 each, whereas the W5500 is $2.64 each. In a commercial project, or even a significant crowd funded project, this can have a significant impact on the bill of materials.

Digikey W5100 Pricing

Digikey W5100 Pricing

Digikey W5200 Pricing

Digikey W5200 Pricing

Digikey W5500 Pricing

Digikey W5500 Pricing

Implementation

The W5500 is available in 48LQFP which is aimed squarely at low tech solutions. The W5200 was only available in 48QFN which made it more difficult to use the chip in low volume applications.  While most people will purchase the W5500 on an Arduino Shield or similar platform, having the LQFP package does make it easier for the companies producing the Shields and modules for the hobbyist.

The three Wiznet W5x00 Generations

The three Wiznet W5x00 Generations

In terms of implementation differences between the W5100 and the W5200, I’ve already written on the extensive improvements to the SPI bus interface, both in terms of outright speed, and in the protocol improvements, doubling the packet RAM to 16kBytes, and doubling the number of sockets available to 8. The W5500 takes these improvements and finesses them to get an even better result.

Wiznet have prepared a summary of the differences between W5500 and W5200. The SPI protocol for the W5500 has been simplified, omitting the frame length field. The end of transmission is simply indicated by deselecting the chip with the SPI Chip Select line. This is an obvious and simple improvement.

The packet RAM on the W5500 has been made available as general storage for the host MCU. Both Tx and Rx RAM is available for use as required. This means that it is possible to augment the RAM on an Arduino Uno by 16kBytes (8kB Tx and 8kB Rx) which is 8x more than the ATmega328p has in total, and still maintain the same sized buffers available in the W5100, for example.

The Tx and Rx RAM is arranged in blocks associated with the socket, and the entire 16 bit address space is rolled out onto the configured RAM for each socket. This means that when writing or reading the W5500 Tx and Rx RAM the user doesn’t need to be concerned with masking the maximum physical RAM, and addressing roll-over is gracefully handled. This is unlike the W5100 and W5200, where RAM addressing would have to be masked against the configured physical RAM. If this sounds complicated, just check the datasheet where it is explained in a nice diagram.

For use in the Arduino IDE environment Wiznet has prepared W5500 drivers which can simply be copied into the IDE directory structure and used as needed. For general implementations, Wiznet have prepared a new generation BSD Sockets based Socket driver which is much more flexible and better written than the previous iteration.

I’ve implemented my code based on the Wiznet transition driver, which maintains the legacy BSD Socket style interface used in W5100 and in W5200. That way I can maintain one socket.h and socket.c code base as an interface, and simply use the relevant hardware driver W5x00.h and W5x00.c as required. I was pleased that in taking this path, Internet code that I’ve written previously “just worked”. This included the hardware sockets dhcp (using IPRAW), ntp, http interfaces which work with the W5500 protocol engine, and the uIP implementation that uses the MACRAW mode inherent in all three devices.

Of note is the resolution of the errata in the ARP engine, which required off device storage of the subnet mask in some situations, which affected both W5100 and W5200. With the W5500 Wiznet have put that issue behind them. I imagine that many other issues and inefficiencies in the hardware socket engine have been redesigned and resolved in the W5500 too.

Performance

The performance improvements of the W5200 over the W5100 have been documented, and the enormous throughput improvement obtained by using the streaming SPI Interface shown.

While the W5500 does implement an improvement in the SPI interface, by removing the data length selection field, there is no noticeable improvement in throughput over the W5200 using an AVR ATmega1284p Goldilocks as the platform.

One design goal for the W5500 seems to have been to make the SPI interface much more friendly for 32 bit processors, particularly Cortex M0+ MCU with limited RAM, by packing the addressing, and control information into one 32 bit (4 x 8bits) register. It is possible to imagine that there are additional performance improvements in the SPI interface if driven close to its design maximum SCK of 80MHz, rather than at the lowly SCK rate of 11.05MHz off the Goldilocks platform.

Testing W5500 SPI throughput with Saleae Logic on the Goldilocks ATmega1284p

Testing W5500 SPI throughput with Saleae Logic on the Goldilocks ATmega1284p

I compared the W5500 running uIP in MACRAW mode to the W5200 running identical (except for the driver) code and using the ping function to test how quickly the SPI interface can transfer a received packet to the host MCU, and then transfer the processed packet back to the W5x00 buffer for transmission.

The ping results were slightly slower than previously seen on the w5200. But I believe that is an external issue, possibly resulting from a change in my network. I have repeated the test with the W5200, and now get similar performance too. I believe I may have some network issues to resolve.

1300 Byte ping packet transmitted from a host to the W5500 interface running uIP in MACRAW mode.

1300 Byte ping packet transmitted from a host to the W5500 interface running uIP in MACRAW mode.

Looking at the output of the Saleae Logic and comparing the time taken to transfer the Ethernet frame into the host MCU, we can see that the time required to transfer the 1300 Byte frame is almost identical at 1.52ms.

W5500 Rx Ethernet Frame transfer to the ATmega1284p

W5500 Rx Ethernet Frame transfer to the ATmega1284p

W5200 Rx Ethernet Frame transfer to the ATmega1284p

W5200 Rx Ethernet Frame transfer to the ATmega1284p

Not surprisingly, the time to process the frame, and produce a response frame are also identical.

Ethernet Frame processing on the AVR1284p (W5500)

Ethernet Frame processing on the AVR1284p (W5500)

Ethernet Frame processing on the AVR1284p (W5200)

Ethernet Frame processing on the AVR1284p (W5200)

Conclusion

The W5500 chip is an improved version of the W5200, which was a greatly improved version of the W5100 device. It is a welcome new addition to a long heritage of IP protocol engines from Wiznet.

I think that the improved implementation in 48LQFP packaging and reduced supporting device count will make it easier for hobbyists and low volume manufacturers to generate great Internet tools off the Arduino and small ARM MCU platforms. We’re starting to see some implementations already.

Three generations of Wiznet Internet Protocol Devices. Goldilocks 1284p for scale.

Three generations of Wiznet Internet Protocol Devices. Goldilocks 1284p for scale.

As usual, my code is here at AVRfreeRTOS in the lib_iinchip folder.

Wiznet have made this post Treasure #14.

Goldilocks Analogue – Testing 2

Recap

I’ve been working (slowly) on a new development for my ATmega1284p platform, called Goldilocks.

My initial design for the Goldilocks Analogue was flawed in several ways, so I revised the design and produced a new prototype.

Here it is:

P1010277

Goldilocks Analogue – Prototype 2

Now that the new prototype for the Goldilocks Analogue is completed, it is time to test it to see how successful the design was. And interestingly, in the time that I’ve been designing the Goldilocks Analogue, Stanford University in collaboration with Texas Instruments have produced their own Analog Shield.

So this test will compare the Goldilocks Analogue with its dual channel 12bit MCP4822 DAC with the Stanford Analog Shield quad channel 16bit DAC8564 DAC. In a later test sequence, using the same test tone, I compare the Goldilocks Analogue with the Open Music Labs Audio Codec Shield using a Wolfson Micro WM8731 24 bit Codec with ADC, DAC, and signal processing capabilities.

Summary (TL;DR)

The test platform is essentially the same ATmega1284p device, clocked at 22.1184MHz. For the Goldilocks Analogue it is integrated on to the main board. For the Analog Shield I used a Goldilocks device as provided in the Pozible project.

You don’t need a lot of space to have great tools. I’m using a Red Pitaya device, configured as an oscilloscope and as a spectrum analyser, together with a Saleae Logic to capture SPI transactions.

P1010271

Micro Test bench – Red Pitaya and Saleae Logic

Both Goldilocks Analogue and Analog Shield are comfortably capable of producing reasonable quality stereo signals at 44.1kHz sampling rate. Both devices output beautiful looking 43.1Hz sine waves, at 44.1kHz reconstruction rate, from a 16 bit 1024 sample Sine Wave.

The Goldilocks Analogue produces 0V to 4.096V 1:1 buffered signals from its DC outputs, and an AC amplified headphone output in parallel. The Analog Shield produces -5V to +5V balanced amplified signals from the 0 to 2.5V DAC.

GA&AS_Scope

Full Swing 43.1Hz Sine Wave Goldilocks Analogue – Blue 0V to +4.096V Analog Shield – Red -5v to +5V

The Analog Shield shows a lot of harmonics at high frequencies as shown. Comparing the two solutions, the Analog Shield doesn’t do justice to the extra 4 bits (theoretically 98dB SNR 16 bit DAC), over the Goldilocks Analogue (theoretically 74dB SNR 12 bit DAC). The BOM price difference between MCP4822 ($4.60) and DAC8564 ($20) is hard to justify given the performance demonstrated.

I think that using the platform of the AVR ATmega (Arduino) there is little point using a 16 bit DAC. There is too much noise (many mV) in the power supply and around Goldilocks or Arduino Uno or Mega boards to make more than 10 to 12 bits of DAC resolution (or ADC resolution) in any way relevant.

GA&AS_43Hz_976kHz

Overlaid 976kHz Spectrum – Analog Shield Red – Shows significant harmonics

Stanford – TI Analog Shield

As part of its microcontroller course, Stanford University required a platform to sample and generate analogue signals. The Standford – TI Analog Shield arose from this need.

The Analog Shield contains a Texas Instrument quad channel ADC and a quad channel DAC, together with a variable voltage supply. I have not tested the ADC.

The DAC capability is based on a Texas Instrument DAC8564 device. This device has many interesting features, including the ability to synchronise loading of updated digital outputs, and to maintain multiple power-down states. The DAC8564 has many great features, and it comes with a price tag to match its capabilities.

P1010273

Analog Shield – Quad 16bit DAC & Quad 16bit ADC – Stanford University & Texas Instruments

Signals generated by the DAC8564 (from 0v to 2.5V) are biased around 0V and amplified to produce a 10V full swing output. The output exhibits some “cramping” around 0x0000 (-5V) outputs.

AS_Schematic_RevD

Analog Shield – Quad DAC Schematic – -5V to +5V full swing

Head to Head

Testing was done using a 16 bit 1024 sample Sine Wave file. Outputs were generated by a timer triggered to interrupt every 22.7us (44.1kHz), and produce a new output level. Testing should show only a main signal at 43.1Hz, and the reproduction frequency of 44.1kHz. The Goldilocks Analogue discards the lower 4 bits of the samples and only outputs the 12 most significant bits.

Theoretically, the Goldilocks Analogue MCP4822 DAC should be able to achieve 74dB SNR, with its 12 bits of resolution, based on the rule of thumb SINAD = (6.02 x BITS) + 1.76. For the Analog Shield DAC8564 the number is 98db SNR.

P1010270

Head to Head Testing – Using Red Pitaya and Saleae Logic

All outputs generated by a 1024 sample 16bit Sine wave, generated with a 44.1kHz reconstruction sample rate, triggered by an interrupt timer.

GA_43.1Hz

Goldilocks Analogue – 43Hz Sine Wave – Two Channels – One Channel Inverted

AS_43.1Hz

Analog Shield – 43Hz Sine Wave – Two Channels – One Channel Inverted

In previous testing on the Goldilocks Analogue prototype I had found that my OpAmp devices were unable to achieve 0V properly. In this new prototype I have produced a stable -1.186V Vss supply for the OpAmp. The signals at 0x000 show that I’ve achieved the required result, with the output being smooth down to the 0x000 level, and up to 0xFFF as well.

GA_43.1Hz_4V

Goldilocks Analogue – 0xFFF Output

GA_43.1Hz_0V

Goldilocks Analogue – 0x000 Output

The Analog Shield also produces smooth signals, but it does display some compression around 0x0000 levels. Possibly because of some issues with generating the Vss rail for the OpAmps.

AS_43.1Hz_+5V

Analog Shield – 0xFFFF Output

AS_43.1Hz_-5V

Analog Shield – 0x0000 Output – Slight Clipping

Looking at the spectra generated by both implementations up to 953Hz it is possible to see harmonics from the Sine Wave, and other low frequency noise.

The spectra are not directly comparable, because the Goldilocks Analogue is producing a 4V full swing, or -4dBm, whilst the Analog Shield is producing a 10V full swing, or 3.7dBm. Distortions in the Analog Shield need to be reduced by 7.7dB to be equivalent to distortion in the Goldilocks Analogue.

The spectrum produced by the Goldilocks Analogue shows most distortion is below -70dB, and that the noise floor lies below -100dB.

GA_43.1Hz_953Hz

Goldilocks Analogue – 43.1Hz Sine Wave – 953Hz Spectrum

The Analog Shield has a significant noise present at 50Hz, which may be caused by noise leakage through the PC USB power supply not being completely filtered before the supply is provided to the DAC8564. Other noise rises above -80dB, and is present right across the spectrum.

AS_43.1Hz_953Kz

Analog Shield – 43.1Hz Sine Wave – 953Hz Spectrum

In the spectra out to 7.6kHz we are looking at the clearly audible range, which is the main use case for the devices.

The Goldilocks Analogue has noise carriers out to around 4.5kHz, but they are all below -80dB. After 4.5kHz the only noise remains below -100dB.

GA_43.1Hz_7.6kHz

Goldilocks Analogue – 43.1Hz Sine Wave – 7.6kHz Spectrum

The Analog Shield shows noise carriers out to only 2.5kHz, but on one channel these are above -80dB. Otherwise the test shows mainly background noise below -100dB beyond 2.5kHz.

AS_43.1Hz_7.6kHz

Analog Shield – 43.1Hz Sine Wave – 7.6kHz Spectrum

The spectra out to 61kHz should show a noise carrier generated by the reconstruction frequency of 44.1kHz.

The Goldilocks Analogue shows the spectrum maintains is low noise level below -90dB right out to the end of the audible range, and further out to the reconstruction carrier at 44.1kHz.

GA_43.1Hz_61kHz

Goldilocks Analogue – 43.1Hz Sine Wave – 61kHz Spectrum

Similarly, the Analog Shield is quiet out beyond the audible range. It exhibits a strong noise carrier at the reconstruction frequency. Also, it shows some beat frequencies generated by a small noise carrier at 10kHz, and the reconstruction carrier. These noise carriers might be caused by the TPS61093 boost power supply used to generate the +ve and -ve supplies for the output buffer OpAmps, although it has a characteristic frequency at 1.2MHz, or it might be leakage from some other device.

AS_43.1Hz_61kHz

Analog Shield – 43.1Hz Sine Wave – 61kHz Spectrum – Harmonics around 44.1kHz reconstruction frequency

The final two spectra show the signal out to 976kHz. We’d normally expect to simply see the noise floor, beyond the 44.1kHz reconstruction carrier noise.

The Goldilocks Analogue has a noise carrier at around 210kHz. This could be generated by one or both of the TPS60403 devices used to generate the negative AVss supply. These devices have a typical switching frequency of 250kHz, specified between 150kHz and 300kHz, so this is possible. Aside from the single carrier mentioned, there is no further noise out to 976kHz.

GA_43.1Hz_976kHz

Goldilocks Analogue – 43.1Hz Sine Wave – 976kHz Spectrum

The Analog Shield shows the reconstruction carrier noise at -50dB, and then harmonics of this carrier all the way out to 976kHz. Not sure why these artifacts are appearing. There is a chance that noise derived from these signals is impacting the overall outcome for the DAC8564.

AS_43.1Hz_976kHz

Analog Shield – 43.1Hz Sine Wave – 976kHz Spectrum

Using the Saleae Logic we can capture the SPI transactions generating the analogue result. To maintain the 44.1kHz reconstruction rate a set of samples needs to be transferred every 22.7us.

In the code I’ve used to generate the signal an interrupt timer triggers every 22.7us indicated by the rising edge of “Channel 6″. Once the interrupt has finished processing it lowers the Channel 6 line, indicating that control has returned to the main program. If required the main program has to use the remaining time to generate the required signal. Clearly the faster the SPI transaction to set up the transaction can be completed the more time available for other purposes.

The MCP4822 found in the Goldilocks Analogue has 4 control bits and 12 data bits, which are transferred in 2 8 bit transactions. To set two channels only 4 SPI transactions are required, taking 7.25us.

GA_43.1Hz_44.1kHz_sample_SPI_transaction

Goldilocks Analog SPI transaction – Interrupt duration 7.25us

The DAC8564 used in the Analog Shield has 8 control bits and 16 data bits, which are transferred in 3 8 bit transactions, or 24 SPI clock cycles. For two channels this takes 6 SPI transactions and 9.08us.

Both devices leave sufficient time for calculation of simple VCO, or other multiply based, effects in real time with 44.1kHz dual channel. Halving the sample rate to 22.05kHz would be necessary to provide more opportunity to retrieve data from uSD cards or other more complex data sources.

AS_43.1Hz_44.1kHz_sample_SPI_transaction

Analog Shield SPI Transaction – Interrupt duration 9.083us

The final reality check in this Head-to-Head comparison is provided by Digikey. I must say that some of the features of the DAC8564 had convinced me to look at migrating the production Goldilocks Analogue to use this new TI DAC. However, seeing that the BOM cost for the TI DAC is approximately 4 times greater than the MCP4822 device soon cooled those thoughts.

Given the cost sensitive nature of the Arduino environment it is not practical to use a device costing nearly US$20 on the Goldilocks Analogue platform, irrespective of its performance.

And, given that the Analog Shield provides no justification in terms of signal quality over the existing Goldilocks Analogue solution there seems to be no technical merit in changing the DAC specification, either.

The Microchip MCP4822 is available from US$4.60 at Digikey.

GA_MCP4822_digikey

Digikey MCP4822 Pricing

The Texas Instrument DAC8564 is available from US$18.60 at Digikey.

AS_DAC8564_digikey

Digikey DAC8464 Pricing

Design Review

The remaining features and functions of the Goldilocks Analogue have been tested, and resulting from these tests I’m going to make the following redesigns and changes.

  • Revert to tri-state buffers for uSD I/O logic conversion CMOS 5v to CMOS 3v3 – Bi-directional translators pure fail! I tried both TI TXB and TXS devices and they simply didn’t work as specified.
  • Remove USART pin-out – unnecessary feature and just takes board space.
  • Move DAC pin-out to right hand edge of the prototyping space – easier to use if not covered by UNO format shield. As the Goldilocks Analogue is slightly longer than standard Arduino UNO shields, putting the DAC DC output pins outside the shield outline on the right hand end of the board will allow easier access for connections.
  • Increase prototyping space – fill in space freed by pin-out removals.
  • Use smaller packages where possible – heading for production.
  • Increase bypass capacitors on uSD 3V supply – uSD cards consume significant current, potential for instability because of long 3V3 supply
  • Use a JTAG pin for MCP4822 LDAC – to enable synchronization of the DAC channels.