A Simple Audio Sketch for the Zpuino and Papilio One FPGA Board

As part of my effort to learn FPGA programming, I’ve been working with a Papilio One board and the Zpuino softcore available for it. The Papilio One is an open-source FPGA board based upon the Xilinx Spartan 3E. It’s available from Gadget Factory, Sparkfun, and others. The Zpuino is a 32-bit soft core compatible with the Arduino programming environment and sketches. The nice thing about it is the VHDL source used to build it is available so you can extend it by creating your modules using readily available Xilinx tools.

In the belief that the best way to learn a piece of hardware or programming language is to have a project to work on, I’ve been busily writing VHDL modules and building new wings (the Papilio equivalent equivalent of an Arduino shield) for the board. One of the first I built was an audio wing (basically the audio portion of the 4096 color VGA Wing) to use with the Zpuino sigma-delta DAC. However, despite the number of examples available in Gadget Factory and Zpuino forums, I couldn’t find a sample sketch to test it. It didn’t take long to put one together and I’m providing it here for anyone else who might find it useful.

int level = 0;

void _zpu_interrupt ()
  if ( TMR0CTL & (1 << TCTLIF))
    /* Interrupt comes from timer 0. */
    /* Change level from low to hi and back again. */
    if (level == 0)
      level = 0xFFFFFFFF;
      level = 0;

    /* Clear the interrupt flag on timer register */
    TMR0CTL &= ~ (1 << TCTLIF );

void setup ()
  // Configure sigma-delta output pin.
  // WINGA PIN0 and PIN1 are the outputs.
  pinMode(WING_A_0, OUTPUT);
  pinMode(WING_A_1, OUTPUT);
  pinModePPS(WING_A_0, HIGH);
  pinModePPS(WING_A_1, HIGH);
  outputPinForFunction(WING_A_0, 0);
  outputPinForFunction(WING_A_1, 0);

  // Enable channel 0 and 1.

  unsigned frequency = 1200;

  // Clear timer counter.
  TMR0CNT = 0;

  // Set up timer , no prescaler.
  TMR0CMP = ( CLK_FREQ / frequency ) - 1;
  TMR0CTL = (1 << TCTLENA)| (1 << TCTLCCM)| (1 << TCTLDIR)| (1 << TCTLIEN);

  // Enable timer 0 interrupt on mask.

  // Globally enable interrupts.
  INTRCTL = (1 << 0);

void loop()

Operation is very basic. WING_A_0 and WING_A_1 define the output pins for the DAC’s left and right channels. The Zpuino interrupt is configured to operate at a rate defined by the frequency variable. Each time through the interrupt routine the DAC level is changed from max to min or vice-versa. This produces a square wave of frequency/2 Hz that is clearly audible if you connect a set of amplified speakers.

Not a lot going on here but it does suit the purpose of producing a simple test tone quickly.


Comments are closed.

DuWayne's Place

Computers, Electronics, and Amateur Radio from KC3XM

QRP HomeBuilder - QRPHB -

Computers, Electronics, and Amateur Radio from KC3XM

Open Emitter

Computers, Electronics, and Amateur Radio from KC3XM

Ripples in the Ether

Emanations from Amateur Radio Station NT7S

m0xpd's 'Shack Nasties'

Computers, Electronics, and Amateur Radio from KC3XM

%d bloggers like this: