From Papilio

Papilio: ZPUinoUserGuide

Contents
Overview

Reference

Libraries

ZAP IDE Usage

ZPUino Tutorials

ZPUino User Guide

The ZPUino is a 32 bit processor running at 100Mhz with a library of Wishbone peripherals. Everything is controlled by a sketch and easy Arduino style libraries. It is an Arduino compatible Soft Processor on steroids!

The ZPUino is the ZPU soft processor adapted for use with the Arduino IDE and it was conceived of and developed by Alvaro Lopes.


Quick Links

Operating Systems

Windows Vista
Windows XP
Windows 7
WIndows 8

Hardware this Guide Applies to:

ZPUino Technical Overview

What is ZPUino


Block Diagram


ZPUino System on Chip


Learn more technical details about the ZPUino by reading the ZPUino Technical Reference.


ZPUino System On Chip

The ZPUino is intended to make it easy to make System on Chip FPGA designs by adding Wishbone Peripherals to the ZPUino Wishbone slots. The RetroCade Synth is an example of a ZPUino System on Chip design.

RetroCade Block Diagram

RetroCade Presentation
Watch this presentation to learn the nitty gritty details of the RetroCade's internals.

ZPUino Bootloader

The ZPUino uses a bootloader that bootstraps code from SPI Flash into internal Block Ram for the Papilio One and external SDRAM for the Papilio Pro. Every ZPUino variant has a special mode that allows code to be programmed to SPI Flash to be run at the next reset. The ZAP IDE sends a special command at a specific baud rate to trigger the programming mode. After code is loaded to SPI Flash a reset is triggered and the bootloader shadows code from SPI FLash into the appropriate RAM location. This is why a ZPUino variant needs to be loaded to the Papilio board before a sketch is uploaded.

ZPUino Variants

A ZPUino variant is a custom ZPUino System on Chip design that we have pre-synthesized for a specific purpose. It contains all of the Wishbone peripherals that will be useful for a specific task, such as VGA output. A ZPUino variant is normally named after a deity from Greek Mythology which roughly indicates what type of peripherals it includes. For example the Hyperion variant includes the VGA peripheral and is named after Hyperion the "Lord of Light". Check out the ZPUino variant reference page to see all the pre-synthesized ZPUino variants that are currently available.

Upload to RAM

It is possible to speed up the process of writing sketches to the Papilio board by uploading to RAM instead of SPI Flash. To do this hold down the left shift button while pressing the Upload icon. SmallFS files will not be updated and the code changes will not persist after a power down.

ZPUino Reference

The majority of the information in this section comes from the ZPUino Technical Reference written by Alvaro Lopes. For more in depth information please refer to the technical reference.

GPIO

GPIO provides the basic input and output capabilities for the ZPUino pins connected to the Papilio FPGA board.
It uses the same Digital I/O functions that the Arduino does:

For more information refer to the GPIO section of the ZPUino Technical Reference.

Overview

The Papilio uses a "Wing" numbering scheme which allows the headers to be easily grouped into 16 or 8 bit Wing Slots.

16 Bit Wing Slots


16 Bit Wing Slots

Each 16 bit Wing slot is designated by letter. The Papilio One has three 16 bit Wing Slots that are designated as WA, WB, and WC.

Blink pin 4 on A

  1. int ledState = HIGH;
  2. void setup() {
  3.   pinMode(WA4, OUTPUT);
  4. }
  5. void loop() {
  6.   delay(200);
  7.   ledState = !ledState;
  8.   digitalWrite(WA4, ledState);
  9. }

Blink pin 4 on C

  1. int ledState = HIGH;
  2. void setup() {
  3.   pinMode(WC4, OUTPUT);
  4. }
  5. void loop() {
  6.   delay(200);
  7.   ledState = !ledState;
  8.   digitalWrite(WC4, ledState);
  9. }

8 Bit Wing Slots


8 Bit Wing Slots

Each 16 Bit Wing slot can be divided into two 8 bit Wing slots by separating them into an upper and lower portion. Wing slot A can be broken down into WAL and WAH, B into WBL and WBH, and C into WCL and WCH.

Blink pin 4 on AL

  1. int ledState = HIGH;
  2. void setup() {
  3.   pinMode(WAL4, OUTPUT);
  4. }
  5. void loop() {
  6.   delay(200);
  7.   ledState = !ledState;
  8.   digitalWrite(WAL4, ledState);
  9. }

Blink pin 4 on AH which is also A12 or 12

  1. int ledState = HIGH;
  2. void setup() {
  3.   pinMode(WAH4, OUTPUT);
  4. }
  5. void loop() {
  6.   delay(200);
  7.   ledState = !ledState;
  8.   digitalWrite(WAH4, ledState);
  9. }

Arduino Numbering


Arduino Numbering

Pins can also be addressed using the standard Arduino convention of using a number.

Example sketch using Arduino referencing

  1. int ledState = HIGH;
  2. void setup() {
  3.   pinMode(4, OUTPUT);
  4. }
  5. void loop() {
  6.   delay(200);
  7.   ledState = !ledState;
  8.   digitalWrite(4, ledState);
  9. }

PPS (Peripheral Pin Select)

ZPUino includes a feature which is called Peripheral Pin Select (in short, PPS). PPS allows you to map every device input or output pin (such as SPI clock and SPI datalines) to each individual pin (GPIO), thus not requiring you to perform synthesis and P&R each time you want to use a device on a different IO pin.

To determine which PPS pins are available in your ZPUino variant, take a look at the PPS section for your variant. For example, here are all of the PPS pins available for the Hyperion variant.

To simplify things, three methods are supplied to manipulate PPS:

void pinModePPS ( int pin , int value );
void outputPinForFunction ( unsigned int pin , unsigned int function );
void inputPinForFunction ( unsigned int pin , unsigned int function );

Three register blocks exist to configure how pin selection is done.

Redirecting Output

In order to direct any peripheral output to a GPIO pin, you have to:

Example
The following example maps Sigma Delta 1st channel into GPIO pin number 30:

void setup ( void )
{
   // Configure pin as output
   pinMode (30 , OUTPUT );
   // enable PPS on this pin
   pinModePPS (30 , HIGH );
   // Map SigmaDelta channel 1 to pin 30
   outputPinForFunction (30 , IOPIN_SIGMADELTA1 );
}

Note that you can use GPIO aliases for your board instead of GPIO number. Refer to the GPIO section for more details.

Redirecting Input

In order to direct GPIO input into any peripheral, you have to:

Note that for input you don't need to enable PPS on the pin using pinModePPS.

Example
The following example maps USPI MISO signal (Master-In Slave-out) to GPIO pin number 10:

void setup ( void )
{
  // Configure pin as input
  pinMode (10 , INPUT );
  // Map pin 30 to USPI MISO
  inputPinForFunction (10 , IOPIN_USPI_MISO );
}

Timers

For more information refer to the Timers section of the ZPUino Technical Reference.

Timer Instantiation Example

Signal Section - Put this code in the signal section (search for #Signal)

signal timers_pwm1: std_logic_vector(1 downto 0);

These signal names need to be unique and match what you put in the Wishbone section.

Wishbone Section - Put this code in the Wishbone component section (search for #Wishbone)

timers2_inst: zpuino_timers
  generic map (
    A_TSCENABLED        => true,
    A_PWMCOUNT          => 1,
    A_WIDTH             => 16,
    A_PRESCALER_ENABLED => true,
    A_BUFFERS           => true,
    B_TSCENABLED        => false,
    B_PWMCOUNT          => 1,
    B_WIDTH             => 24,
    B_PRESCALER_ENABLED => false,
    B_BUFFERS           => false
  )
  port map (
    wb_clk_i       => wb_clk_i,
                wb_rst_i    => wb_rst_i,
    wb_dat_o      => slot_read(8),
    wb_dat_i     => slot_write(8),
    wb_adr_i   => slot_address(8),
    wb_we_i        => slot_we(8),
    wb_cyc_i        => slot_cyc(8),
    wb_stb_i        => slot_stb(8),
    wb_ack_o      => slot_ack(8),

    wb_inta_o => slot_interrupt(8), -- We use two interrupt lines
    wb_intb_o => slot_interrupt(9), -- so we borrow intr line from wishbone slot 9, do not use wishbone slot 9 for anything else

    pwm_a_out   => timers_pwm1(0 downto 0),
    pwm_b_out   => timers_pwm1(1 downto 1)
  );

Be sure to change the slot numbers to match your design.

PPS Section - Put this code in the PPS section (search for #PPS)

gpio_spp_data(6) <= timers_pwm1(0);          -- PPS6 : TIMER2
    gpio_spp_data(7) <= timers_pwm1(1);          -- PPS7 : TIMER3

Be sure to change the PPS numbers to match your design.

UARTs

For more information refer to the UART section of the ZPUino Technical Reference.

UART Instantiation Example

Signal Section - Put this code in the signal section (search for #Signal)

signal uart2_tx, uart2_rx: std_logic;

These signal names need to be unique and match what you put in the Wishbone section.

Wishbone Section - Put this code in the Wishbone component section (search for #Wishbone)

uart2_inst: zpuino_uart
  generic map (
    bits => 4
  )
  port map (
    wb_clk_i       => wb_clk_i,
    wb_rst_i    => wb_rst_i,
    wb_dat_o      => slot_read(8),
    wb_dat_i     => slot_write(8),
    wb_adr_i   => slot_address(8),
    wb_we_i      => slot_we(8),
    wb_cyc_i       => slot_cyc(8),
    wb_stb_i       => slot_stb(8),
    wb_ack_o      => slot_ack(8),

    wb_inta_o => slot_interrupt(8),

    tx        => uart2_tx,
    rx        => uart2_rx
  );

Be sure to change the slot numbers to match your design.

PPS Section - Put this code in the PPS section (search for #PPS)

gpio_spp_data(6) <= uart2_tx;              -- PPS6 : UART2 DATA
  uart2_rx <= gpio_spp_read(1);              -- PPS0 : USPI MISO

Be sure to change the PPS numbers to match your design.

CRC16

For more information refer to the CRC16 section of the ZPUino Technical Reference.

Interrupts

For more information refer to the Interrupts section of the ZPUino Technical Reference.

SigmaDelta DAC

For more information refer to the SigmaDelta DAC section of the ZPUino Technical Reference.

SigmaDelta DAC Instantiation Example

Signal Section - Put this code in the signal section (search for #Signal)

signal sigmadelta1_spp_en:  std_logic_vector(1 downto 0);
  signal sigmadelta1_spp_data:  std_logic_vector(1 downto 0);

These signal names need to be unique and match what you put in the Wishbone section.

Wishbone Section - Put this code in the Wishbone component section (search for #Wishbone)

sigmadelta2_inst: zpuino_sigmadelta
  port map (
    wb_clk_i       => wb_clk_i,
                wb_rst_i    => wb_rst_i,
    wb_dat_o      => slot_read(8),
    wb_dat_i     => slot_write(8),
    wb_adr_i   => slot_address(8),
    wb_we_i        => slot_we(8),
    wb_cyc_i        => slot_cyc(8),
    wb_stb_i        => slot_stb(8),
    wb_ack_o      => slot_ack(8),
    wb_inta_o => slot_interrupt(8),

    spp_data  => sigmadelta1_spp_data,
    spp_en    => sigmadelta1_spp_en,
    sync_in   => '1'
  );

Be sure to change the slot numbers to match your design.

PPS Section - Put this code in the PPS section (search for #PPS)

gpio_spp_data(6) <= sigmadelta1_spp_data(0); -- PPS6 : SIGMADELTA DATA
    gpio_spp_data(7) <= sigmadelta1_spp_data(1); -- PPS7 : SIGMADELTA DATA

Be sure to change the PPS numbers to match your design.

SPI

For more information refer to the SPI section of the ZPUino Technical Reference.

SPI Instantiation Example

Signal Section - Put this code in the signal section (search for #Signal)

signal spi3_enabled:  std_logic;
  signal spi3_mosi:  std_logic;
  signal spi3_miso:  std_logic;
  signal spi3_sck:  std_logic;

These signal names need to be unique and match what you put in the Wishbone section.

Wishbone Section - Put this code in the Wishbone component section (search for #Wishbone)

spi2_inst: zpuino_spi
  port map (
    wb_clk_i       => wb_clk_i,
                wb_rst_i    => wb_rst_i,
    wb_dat_o      => slot_read(8),
    wb_dat_i     => slot_write(8),
    wb_adr_i   => slot_address(8),
    wb_we_i        => slot_we(8),
    wb_cyc_i        => slot_cyc(8),
    wb_stb_i        => slot_stb(8),
    wb_ack_o      => slot_ack(8),
    wb_inta_o => slot_interrupt(8),

    mosi      => spi3_mosi,
    miso      => spi3_miso,
    sck       => spi3_sck,
    enabled   => open
  );

Be sure to change the slot numbers to match your design.

PPS Section - Put this code in the PPS section (search for #PPS)

gpio_spp_data(6) <= spi3_mosi;              -- PPS6 : USPI MOSI
    gpio_spp_data(7) <= spi3_sck;               -- PPS7 : USPI SCK
    spi3_miso <= gpio_spp_read(1);              -- PPS1 : USPI MISO

Be sure to change the PPS numbers to match your design.

Libraries

SmallFS Library

For more information refer to the SmallFS Library section of the ZPUino Technical Reference.

HQVGA Library

VGALiquidCrystal Library


Setup ZPUino Environment

To write code for the ZPUino we have a specially modified version of the Arduino IDE called the ZAP IDE. ZAP is short for ZPUino Arduino Papilio Soft Processor IDE. Please visit the ZAP IDE QuickStart page to setup the ZPUino Environment.

Run Hello World Example

Hello World Code Example

void setup() {
  //Setup Serial port
  Serial.begin(9600);
  // prints Hello World
  Serial.println("Hello World!");
}

void loop(){
  // prints Hello World over and over
  Serial.println("Hello World!");
}







Getting Started with Hello World VGA Sketch on the ZPUino.

Alvaro added a VGA controller to the ZPUino and wrote an easy to use VGA Library. His amazing work makes it easy for anyone to output VGA graphics with the Papilio.


#include "VGA.h"

void setup() {

  VGA.clear();
  VGA.setBackgroundColor(BLACK);
  VGA.setColor(RED);
  VGA.printtext(30,0,"Papilio/ZPUino");
  VGA.printtext(35,10,"Hello World");
}

void loop() {

}



ZPUino Tutorials

Adding extra serial ports and synthesizing a custom ZPUino SOC

Links

Video

Sketch used in the video

//This sketch assumes a jumper wire between pin 0 and 1 on the Papilio

HardwareSerial mySerial1(8);
HardwareSerial mySerial2(9);

void setup() {

  //Connect the tx pin of mySerial1 to pin 0 of the Papilio
  pinMode(0, OUTPUT);
  pinModePPS(0, HIGH);
  outputPinForFunction(0,6);

  //Connect the rx pin of mySerial2 to pin 1 of the Papilio
  pinMode(1,INPUT);
  inputPinForFunction(1,2);

  Serial.begin(9600);
  mySerial1.begin(9600);
  mySerial2.begin(9600);
}

void loop() {

  //Send a 1 out of mySerial1, read it on mySerial2, and send it out the USB serial port.
  mySerial1.write(1);
  if (mySerial2.available()) {
   Serial.println(mySerial2.read());
  }
  delay(500);
}
Retrieved from http://papilio.cc/index.php?n=Papilio.ZPUinoUserGuide
Page last modified on July 19, 2013, at 11:49 AM