#!/usr/bin/env python3 # Raspberry Pi iceprog (piceprog) # Tool for programming iCE40 FPGAs with Pi GPIOs import sys import RPi.GPIO as gpio from time import sleep from math import ceil fpga_sclk = 19 fpga_sdi = 26 fpga_ss = 13 fpga_done = 6 fpga_rst = 5 gpio.setmode(gpio.BCM) gpio.setwarnings(False) for pin in [fpga_sclk, fpga_sdi, fpga_ss, fpga_rst]: gpio.setup(pin, gpio.OUT) gpio.setup(fpga_done, gpio.IN) def prog(fname): bitstream = list(open(fname, "rb").read()) print("{} bytes.".format(len(bitstream))) bits = [] for byte in bitstream: for i in range(8): bits.append(byte >> 7) byte = (byte << 1) & 0xff bits.extend(49 * [0]) # at least 49 dummy cycles required at end. print("Starting") gpio.output(fpga_rst, 0) gpio.output(fpga_ss, 0) gpio.output(fpga_sclk, 1) # CPOL = 1 (clock idle high) gpio.output(fpga_sdi, 0) sleep(0.001) gpio.output(fpga_rst, 1) sleep(0.001) gpio.output(fpga_ss, 1) for i in range(8): gpio.output(fpga_sclk, 0) gpio.output(fpga_sclk, 1) # CPHA = 1 (data captured on trailing edge of clock pulse) gpio.output(fpga_ss, 0) for bit in bits: gpio.output(fpga_sdi, bit) gpio.output(fpga_sclk, 0) gpio.output(fpga_sclk, 1) if gpio.input(fpga_done): print("CDONE high, yay!") else: print("CDONE not high, something may have gone wrong") if __name__ == "__main__": if len(sys.argv) != 2: exit("Usage: piceprog (file.bin)") prog(sys.argv[1])