Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pixelwrangler board support and Winbond flash id #70

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 94 additions & 0 deletions boards/PixelWrangler/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Makefile borrowed from https://github.com/cliffordwolf/icestorm/blob/master/examples/icestick/Makefile
#
# The following license is from the icestorm project and specifically applies to this file only:
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

PROJ = bootloader

PIN_DEF = pins.pcf
DEVICE = up5k
PKG = sg48
SEED ?= 12345678

#all: $(PROJ).rpt multiboot.bin
all: multiboot.bin

%.json: %.v ../../common/*.v
yosys -q -p 'synth_ice40 -top $(PROJ) -json $@' $^
%.blif: %.v ../../common/*.v
yosys -q -p 'synth_ice40 -top $(PROJ) -blif $@' $^

%.asc: $(PIN_DEF) %.json
nextpnr-ice40 \
--seed $(SEED) \
--$(DEVICE) \
--package $(PKG) \
--json $(basename $@).json \
--pcf $(PIN_DEF) \
--asc $@ \

no-%.asc: $(PIN_DEF) %.blif
arachne-pnr -d 5k -P $(PKG) -o $@ -p $^

%.bin: %.asc
icepack -s $< $@

multiboot.bin: bootloader.bin
cp $< bootloader_0.bin
cp $< bootloader_1.bin
icemulti -v -o $@ -a16 -p0 bootloader_0.bin bootloader_1.bin
truncate -s 256K $@

%.rpt: %.asc
icetime -d $(DEVICE) -mtr $@ $<

%_syn.v: %.blif
yosys -p 'read_blif -wideports $^; write_verilog $@'

prog: multiboot.bin
iceprog $<

sudo-prog: multiboot.bin
@echo 'Executing prog as root!!!'
sudo iceprog $<

prog-boardmeta: boardmeta.json
tinyprog -a 1 --security $<
prog-bootmeta: bootmeta.json
tinyprog -a 2 --security $<
prog-meta:
-$(MAKE) prog-boardmeta
-$(MAKE) prog-bootmeta

# create a board meta file
HARDWARE_VERSION=v0.0
UUID=$(shell uuidgen)
BOARD=Pixel Wrangler
FPGA=$(DEVICE)-$(PKG)

boardmeta.json: FORCE
echo > $@ \
'{"boardmeta":{'\
'"name":"$(BOARD)",'\
'"fpga":"$(FPGA)",'\
'"hver":"$(HARDWARE_VERSION)",'\
'"uuid":"$(UUID)"'\
'}}'

clean:
rm -f $(PROJ).blif $(PROJ).asc $(PROJ).rpt $(PROJ).bin $(PROJ)_0.bin $(PROJ)_1.bin multiboot.bin

.SECONDARY:
.PHONY: all prog clean FORCE
FORCE:
154 changes: 154 additions & 0 deletions boards/PixelWrangler/bootloader.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
module bootloader (
//input pin_clk,

inout pin_usbp,
inout pin_usbn,
output pin_pu,

output pin_led_r,
output pin_led_g,
output pin_led_b,

inout flash_miso,
output flash_cs,
output flash_mosi,
output flash_sck
);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////
//////// generate 48 mhz clock
////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
wire clk_48mhz;
wire locked;

`define USE_HFOSC
`ifdef USE_HFOSC
SB_HFOSC u_hfosc (
.CLKHFPU(1'b1),
.CLKHFEN(1'b1),
.CLKHF(clk_48mhz)
);
assign locked = 1;
`else
// the Tomu hacker verison has an external 48 MHz oscillator
// so there is no need for a PLL.
assign locked = 1;
assign clk_48mhz = pin_clk;
`endif

reg clk_24mhz;
reg clk_12mhz;
wire clk = clk_12mhz;
always @(posedge clk_48mhz) clk_24mhz = !clk_24mhz;
always @(posedge clk_24mhz) clk_12mhz = !clk_12mhz;

/* tristate flash input pin to ensure it is an input */
wire flash_miso_in;
tristate flash_miso_buffer(
.pin(flash_miso),
.enable(1'b0),
.data_in(flash_miso_in),
.data_out(1'b0)
);

assign pin_led_g = 1;

/*
reg [23:0] counter;
always @(posedge clk_48mhz)
if (counter == 24'h7FFFFF)
pin_led_r <= 1;
else begin
counter <= counter + 1;
pin_led_r <= 0;
end
*/
assign pin_led_r = 1;


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////
//////// interface with iCE40 warmboot/multiboot capability
////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
wire boot;

SB_WARMBOOT warmboot_inst (
.S1(1'b0),
.S0(1'b1),
.BOOT(boot)
);

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////
//////// instantiate tinyfpga bootloader
////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
wire reset = !locked;
wire usb_p_tx;
wire usb_n_tx;
wire usb_p_rx;
wire usb_n_rx;
wire usb_tx_en;

tinyfpga_bootloader tinyfpga_bootloader_inst (
.clk_48mhz(clk_48mhz),
.clk(clk),
.reset(reset),
.usb_p_tx(usb_p_tx),
.usb_n_tx(usb_n_tx),
.usb_p_rx(usb_p_rx),
.usb_n_rx(usb_n_rx),
.usb_tx_en(usb_tx_en),
.led(pin_led_b),
.spi_miso(flash_miso_in),
.spi_cs(flash_cs),
.spi_mosi(flash_mosi),
.spi_sck(flash_sck),
.boot(boot)
);

assign pin_pu = 1'b1;

wire usb_p_rx_io;
wire usb_n_rx_io;
assign usb_p_rx = usb_tx_en ? 1'b1 : usb_p_rx_io;
assign usb_n_rx = usb_tx_en ? 1'b0 : usb_n_rx_io;

tristate usbn_buffer(
.pin(pin_usbn),
.enable(usb_tx_en),
.data_in(usb_n_rx_io),
.data_out(usb_n_tx)
);

tristate usbp_buffer(
.pin(pin_usbp),
.enable(usb_tx_en),
.data_in(usb_p_rx_io),
.data_out(usb_p_tx)
);
endmodule

module tristate(
inout pin,
input enable,
input data_out,
output data_in
);
SB_IO #(
.PIN_TYPE(6'b1010_01) // tristatable output
) buffer(
.PACKAGE_PIN(pin),
.OUTPUT_ENABLE(enable),
.D_IN_0(data_in),
.D_OUT_0(data_out)
);
endmodule
9 changes: 9 additions & 0 deletions boards/PixelWrangler/bootmeta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{"bootmeta" : {
"bootloader": "TinyFPGA USB Bootloader",
"bver": "2.0.0",
"update": "https://v.st/pixels/",
"addrmap": {
"bootloader": "0x000a0-0x20000",
"userimage": "0x20000-0x40000",
"userdata": "0x40000-0x100000"
}}}
17 changes: 17 additions & 0 deletions boards/PixelWrangler/pins.pcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Pinmap for the Pixel Wrangler v0
#
set_io -nowarn BTN_N 2 # IOB_6a / pin1
set_io -nowarn pin_led_r 41 # Red
set_io -nowarn pin_led_g 39 # Green
set_io -nowarn pin_led_b 40 # Blue

set_io -nowarn flash_sck 15 # IOB_34a
set_io -nowarn flash_cs 16 # IOB_35b
set_io -nowarn flash_mosi 14 # IOB_32a
set_io -nowarn flash_miso 17 # IOB_33b

set_io -nowarn pin_usbp 4 # IOB_8a
set_io -nowarn pin_usbn 3 # IOB_9b
set_io -nowarn pin_pu 6 # IOB_13b

7 changes: 6 additions & 1 deletion programmer/tinyprog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@ def __init__(self, ser, progress=None):
self.security_page_write_cmd = 0x62
self.security_page_read_cmd = 0x68
self.security_page_erase_cmd = 0x64

elif flash_id[0:2] == [0xEF, 0x40]:
# Winbond
self.security_page_bit_offset = 4
self.security_page_write_cmd = 0x42
self.security_page_read_cmd = 0x48
self.security_page_erase_cmd = 0x44
else:
# Adesto
self.security_page_bit_offset = 0
Expand Down