Created
April 30, 2021 17:09
-
-
Save enjoy-digital/74f2d8cf0f7a1966428e930602f6705d to your computer and use it in GitHub Desktop.
Raspberry Pi Pico <> LiteX SoC (on GoWin FPGA) proof of concept.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Raspberry Pi Pico <> LiteX SoC (on GoWin FPGA) proof of concept. | |
# | |
# Copyright (c) 2021 Florent Kermarrec <florent@enjoy-digital.fr> | |
# SPDX-License-Identifier: BSD-2-Clause | |
import os | |
import argparse | |
from migen import * | |
from litex.build.generic_platform import * | |
from litex.soc.cores.clock.gowin_gw1n import GW1NPLL | |
from litex.soc.integration.soc_core import * | |
from litex.soc.integration.builder import * | |
from litex.soc.cores.led import LedChaser | |
from litex_boards.platforms import tec0117 | |
# IOs ---------------------------------------------------------------------------------------------- | |
_pico_spi_ios = [ | |
("pico_spi", 0, | |
Subsignal("clk", Pins("29")), # SPI SCK. | |
Subsignal("cs_n", Pins("31")), # SPI CSn. | |
Subsignal("mosi", Pins("28")), # SPI TX. | |
Subsignal("miso", Pins("32")), # SPI RX. | |
IOStandard("LVCMOS33"), | |
) | |
] | |
# CRG ---------------------------------------------------------------------------------------------- | |
class _CRG(Module): | |
def __init__(self, platform, sys_clk_freq): | |
self.clock_domains.cd_sys = ClockDomain() | |
# # # | |
# Clk / Rst | |
clk100 = platform.request("clk100") | |
# PLL | |
self.submodules.pll = pll = GW1NPLL(device="GW1N9K") | |
pll.register_clkin(clk100, 100e6) | |
pll.create_clkout(self.cd_sys, sys_clk_freq) | |
# BaseSoC ------------------------------------------------------------------------------------------ | |
class BaseSoC(SoCCore): | |
def __init__(self, sys_clk_freq=int(50e6)): | |
platform = tec0117.Platform() | |
platform.add_extension(_pico_spi_ios) | |
# CRG -------------------------------------------------------------------------------------- | |
self.submodules.crg = _CRG(platform, sys_clk_freq) | |
# SoCMini ---------------------------------------------------------------------------------- | |
SoCMini.__init__(self, platform, sys_clk_freq, | |
ident = "Raspberry Pi Pico <> LiteX SoC proof of concept.", | |
ident_version = True) | |
# SPI -------------------------------------------------------------------------------------- | |
if not os.path.exists("spibone.py"): | |
os.system("wget https://raw.githubusercontent.com/xobs/spibone/master/spibone.py") | |
import spibone | |
self.submodules.spibone = spibone.SpiWishboneBridge(platform.request("pico_spi")) | |
self.add_wb_master(self.spibone.wishbone) | |
# Leds ------------------------------------------------------------------------------------- | |
self.submodules.leds = LedChaser( | |
pads = platform.request_all("user_led"), | |
sys_clk_freq = sys_clk_freq) | |
# Build -------------------------------------------------------------------------------------------- | |
def main(): | |
parser = argparse.ArgumentParser(description="Raspberry Pi Pico <> LiteX SoC proof of concept.") | |
parser.add_argument("--build", action="store_true", help="Build bitstream") | |
parser.add_argument("--load", action="store_true", help="Load bitstream") | |
parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default: 50MHz)") | |
args = parser.parse_args() | |
soc = BaseSoC(sys_clk_freq=int(float(args.sys_clk_freq))) | |
builder = Builder(soc, csr_csv="csv.csv") | |
builder.build(run=args.build) | |
if args.load: | |
prog = soc.platform.create_programmer() | |
prog.load_bitstream(os.path.join(builder.gateware_dir, "impl", "pnr", "project.fs")) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Raspberry Pi Pico <> LiteX SoC (on GoWin FPGA) proof of concept. | |
# | |
# Copyright (c) 2021 Florent Kermarrec <florent@enjoy-digital.fr> | |
# SPDX-License-Identifier: BSD-2-Clause | |
import time | |
from machine import Pin, SPI | |
# Registers ---------------------------------------------------------------------------------------- | |
CSR_LEDS = 0x00001000 | |
CSR_BTNS = 0x00001000 | |
CSR_IDENTIFIER = 0x00000800 | |
# SPI Bone ----------------------------------------------------------------------------------------- | |
class SPIBone: | |
def __init__(self, pins={"sck": 18, "csn": 17, "mosi": 19, "miso": 16}, clk_freq=1e6): | |
self.csn = Pin(pins["csn"], Pin.OUT, value=1) | |
self.spi = SPI(0, baudrate=int(clk_freq), polarity=0, phase=0, | |
sck = Pin(pins["sck"]), | |
mosi = Pin(pins["mosi"]), | |
miso = Pin(pins["miso"]) | |
) | |
def write(self, address, value): | |
self.csn.low() | |
self.spi.write(int(0x0).to_bytes(1, "big")) | |
self.spi.write( address.to_bytes(4, "big")) | |
self.spi.write( value.to_bytes(4, "big")) | |
self.spi.read(1) | |
self.csn.high() | |
def read(self, address): | |
self.csn.low() | |
self.spi.write(int(0x1).to_bytes(1, "big")) | |
self.spi.write( address.to_bytes(4, "big")) | |
self.spi.read(1) | |
value = int.from_bytes(self.spi.read(4), 4, "big") | |
self.csn.high() | |
return value | |
bus = SPIBone() | |
# Demo --------------------------------------------------------------------------------------------- | |
def identifier_demo(): | |
print("Identifier:") | |
identifier = "" | |
for i in range(256): | |
c = chr(bus.read(CSR_IDENTIFIER + 4*i) & 0xff) | |
identifier += c | |
if c == "\0": | |
break | |
print(identifier) | |
def led_demo(): | |
print("Led Demo:") | |
print("Counter mode...") | |
for i in range(16): | |
bus.write(CSR_LEDS, i) | |
time.sleep(0.1) | |
print("Shift mode...") | |
for i in range(8): | |
bus.write(CSR_LEDS, 1<<i) | |
time.sleep(0.1) | |
for i in reversed(range(8)): | |
bus.write(CSR_LEDS, 1<<i) | |
time.sleep(0.1) | |
print("Dance mode...\n"); | |
for i in range(4): | |
bus.write(CSR_LEDS, 0x55) | |
time.sleep(0.2) | |
bus.write(CSR_LEDS, 0xaa) | |
time.sleep(0.2) | |
identifier_demo() | |
led_demo() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment