Contents
Overview
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.
Attach:zpuino.png Δ What is ZPUino
Block Diagram
ZPUino System on Chip
Learn more technical details about the ZPUino by reading the ZPUino Technical Reference.
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
http://youtu.be/6E-USsejc5o
Watch this presentation to learn the nitty gritty details of the RetroCade's internals.
The Papilio uses a "Wing" numbering scheme which allows the headers to be easily grouped into 16 or 8 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 (:source lang=c highlight='3,8':) int ledState = HIGH; void setup() {
pinMode(WA4, OUTPUT);
} void loop() {
delay(200); ledState = !ledState; digitalWrite(WA4, ledState);
} (:sourcend:) Blink pin 4 on C (:source lang=c highlight='3,8':) int ledState = HIGH; void setup() {
pinMode(WC4, OUTPUT);
} void loop() {
delay(200); ledState = !ledState; digitalWrite(WC4, ledState);
} (:sourcend:)
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 (:source lang=c highlight='3,8':) int ledState = HIGH; void setup() {
pinMode(WAL4, OUTPUT);
} void loop() {
delay(200); ledState = !ledState; digitalWrite(WAL4, ledState);
} (:sourcend:) Blink pin 4 on AH which is also A12 or 12 (:source lang=c highlight='3,8':) int ledState = HIGH; void setup() {
pinMode(WAH4, OUTPUT);
} void loop() {
delay(200); ledState = !ledState; digitalWrite(WAH4, ledState);
} (:sourcend:)
Pins can also be addressed using the standard Arduino convention of using a number.
Example sketch using Arduino referencing (:source lang=c highlight='3,8':) int ledState = HIGH; void setup() {
pinMode(4, OUTPUT);
} void loop() {
delay(200); ledState = !ledState; digitalWrite(4, ledState);
} (:sourcend:)
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: (:source lang=c :) void pinModePPS ( int pin , int value ); void outputPinForFunction ( unsigned int pin , unsigned int function ); void inputPinForFunction ( unsigned int pin , unsigned int function ); (:sourceend:)
Three register blocks exist to configure how pin selection is done.
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:
(:source lang=c :)
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 );
} (:sourceend:) Note that you can use GPIO aliases for your board instead of GPIO number. Refer to the GPIO section for more details.
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:
(:source lang=c :)
void setup ( void )
{
// Configure pin as input pinMode (10 , INPUT ); // Map pin 30 to USPI MISO inputPinForFunction (10 , IOPIN_USPI_MISO );
} (:sourceend:)
For more information refer to the Timers section of the ZPUino Technical Reference.
Signal Section -
Put this code in the signal section (search for #Signal)
(:source lang=vhdl :)
signal timers_pwm1: std_logic_vector(1 downto 0);
(:sourceend:)
Wishbone Section -
Put this code in the Wishbone component section (search for #Wishbone)
(:source lang=vhdl :)
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) );
(:sourceend:)
PPS Section -
Put this code in the PPS section (search for #PPS)
(:source lang=vhdl :)
gpio_spp_data(6) <= timers_pwm1(0); -- PPS6 : TIMER2 gpio_spp_data(7) <= timers_pwm1(1); -- PPS7 : TIMER3
(:sourceend:)
For more information refer to the UART section of the ZPUino Technical Reference.
Signal Section -
Put this code in the signal section (search for #Signal)
(:source lang=vhdl :)
signal uart2_tx, uart2_rx: std_logic;
(:sourceend:)
Wishbone Section -
Put this code in the Wishbone component section (search for #Wishbone)
(:source lang=vhdl :)
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 );
(:sourceend:)
PPS Section -
Put this code in the PPS section (search for #PPS)
(:source lang=vhdl :)
gpio_spp_data(6) <= uart2_tx; -- PPS6 : UART2 DATA uart2_rx <= gpio_spp_read(1); -- PPS0 : USPI MISO
(:sourceend:)
Signal Section -
Put this code in the signal section (search for #Signal)
(:source lang=vhdl :)
signal sigmadelta1_spp_en: std_logic_vector(1 downto 0); signal sigmadelta1_spp_data: std_logic_vector(1 downto 0);
(:sourceend:)
Wishbone Section -
Put this code in the Wishbone component section (search for #Wishbone)
(:source lang=vhdl :)
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' );
(:sourceend:)
PPS Section -
Put this code in the PPS section (search for #PPS)
(:source lang=vhdl :)
gpio_spp_data(6) <= sigmadelta1_spp_data(0); -- PPS6 : SIGMADELTA DATA gpio_spp_data(7) <= sigmadelta1_spp_data(1); -- PPS7 : SIGMADELTA DATA
(:sourceend:)
Signal Section -
Put this code in the signal section (search for #Signal)
(:source lang=vhdl :)
signal spi3_enabled: std_logic; signal spi3_mosi: std_logic; signal spi3_miso: std_logic; signal spi3_sck: std_logic;
(:sourceend:)
Wishbone Section -
Put this code in the Wishbone component section (search for #Wishbone)
(:source lang=vhdl :)
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 );
(:sourceend:)
PPS Section -
Put this code in the PPS section (search for #PPS)
(:source lang=vhdl :)
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
(:sourceend:)
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.
Hello World Code Example (:source lang=c :) 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!");
} (:sourcend:)
http://youtu.be/MocpV6b5FYs 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.
(:source lang=c :)
void setup() {
VGA.clear(); VGA.setBackgroundColor(BLACK); VGA.setColor(RED); VGA.printtext(30,0,"Papilio/ZPUino"); VGA.printtext(35,10,"Hello World");
}
void loop() {
} (:sourcend:)
(:source lang=c:) //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);
} (:sourceend:)