Initial commit

This commit is contained in:
Dennis Brentjes 2025-09-14 19:55:43 +02:00
commit 7b5ecda692
17 changed files with 361 additions and 0 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
docs/media/SP1-picture-with-pin-numbers.jpg filter=lfs diff=lfs merge=lfs -text

1
docs/.obsidian/app.json vendored Normal file
View File

@ -0,0 +1 @@
{}

3
docs/.obsidian/appearance.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"theme": "obsidian"
}

33
docs/.obsidian/core-plugins.json vendored Normal file
View File

@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"properties": false,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}

22
docs/.obsidian/graph.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
"collapse-filter": true,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": true,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": true,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 1,
"close": true
}

186
docs/.obsidian/workspace.json vendored Normal file
View File

@ -0,0 +1,186 @@
{
"main": {
"id": "b1126f19eadfbccd",
"type": "split",
"children": [
{
"id": "26583ad05e41a8d5",
"type": "tabs",
"children": [
{
"id": "be20a2e02f2b6437",
"type": "leaf",
"state": {
"type": "empty",
"state": {},
"icon": "lucide-file",
"title": "New tab"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "41928e7bfa033c12",
"type": "split",
"children": [
{
"id": "20b81aa7e9da9056",
"type": "tabs",
"children": [
{
"id": "c9cf1762af2fc6d1",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Files"
}
},
{
"id": "41e707cc40e380be",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Search"
}
},
{
"id": "7efd4428cb796566",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Bookmarks"
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "564b72f12544e8fb",
"type": "split",
"children": [
{
"id": "27b51e3cbd5b64f2",
"type": "tabs",
"children": [
{
"id": "08ff37c167cba8a6",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "Welcome.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "Backlinks for Welcome"
}
},
{
"id": "f0d6e734ee929213",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "Welcome.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Outgoing links from Welcome"
}
},
{
"id": "58c9a6253aa57492",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "Tags"
}
},
{
"id": "2feb030bc67ed9a4",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "Welcome.md",
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "Outline of Welcome"
}
}
]
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
},
"left-ribbon": {
"hiddenItems": {
"switcher:Open quick switcher": false,
"graph:Open graph view": false,
"canvas:Create new canvas": false,
"daily-notes:Open today's daily note": false,
"templates:Insert template": false,
"command-palette:Open command palette": false,
"bases:Create new base": false
}
},
"active": "c9cf1762af2fc6d1",
"lastOpenFiles": [
"GameCube/SP1.md",
"GameCube/Sp1 physical connector.canvas",
"media/SP1-picture-with-pin-numbers.jpg",
"media/Unconfirmed 13874.crdownload",
"media",
"Environment/Amaranth-Hdl project setup.md",
"ReBbarb.md",
"GameCube/EXI protocol.md",
"GameCube/GameCube.md",
"GameCube",
"Investigations/external clocks.md",
"Investigations.md",
"Investigations",
"Environment",
"Untitled.base"
]
}

View File

@ -0,0 +1,10 @@
Create a venv
`python -m venv .venv`
Activate the venv
`. .vent/bin/activate`
Install the dependencies
`pip install -r requirements.txt`
You will potentially need more tooling to create the bitstream and flash the bitstream for the specific FPGA. In my case I'm working with an IceBreaker. So I've installed the `nextpnr-ice40` toolchain. Yosys is builtin to amaranth, that is why I'm running it within an venv to ensure it doesn't mess with system installed packages.

View File

View File

1
docs/GameCube/SP1.md Normal file
View File

@ -0,0 +1 @@
Is a serial port located underneath the gamecube, used for the Modem and BroadBandAdapter. it uses the following pinout.

View File

@ -0,0 +1,9 @@
{
"nodes":[
{"id":"9baad18d22c3c798","type":"file","file":"media/SP1-picture-with-pin-numbers.jpg","x":-260,"y":-220,"width":359,"height":400},
{"id":"71e43c20f72fa2ad","type":"text","text":"https://www.gc-forever.com/yagcd/chap2.html#sec2.4.1.4\n2.4.1.4 BBA/Modem Connector (P6) \npin\tSignal\n1\tEXTIN\n2\tGround (Shield)\n3\tINT\n4\tCLK\n5\t12V\n6\tDO\n7\t3.3V\n8\t3.3V\n9\tDI\n10\tCS\n11\tGround\n12\tGround\n","x":180,"y":-250,"width":224,"height":460}
],
"edges":[
{"id":"d1b694360b443139","fromNode":"71e43c20f72fa2ad","fromSide":"left","toNode":"9baad18d22c3c798","toSide":"right"}
]
}

View File

24
docs/ReBbarb.md Normal file
View File

@ -0,0 +1,24 @@
This project attempts to emulate the Gamecube BroadBand Adapter in an FPGA. The following things need to happen.
- [x] [[Amaranth-Hdl project setup]]
- [x] Setup venv
- [x] Install packages
- [x] Flash Blinky on icebreaker
- [ ] Figuring out how to deal with [[external clocks]].
- [x] How to get a clock greater than 12Mhz needed to interface with 32Mhz EXI
- [x] PLL configured to 48Mhz
- [ ] ~~48Mhz oscillator onboard? ~~
- [ ] Check if Clock Domain Crossing is possible.
- [ ] Oversampeling approach was tedious but worked
- [ ] Interfacing with [[GameCube]]
- [ ] Figuring pinout of SP1.
- [ ] Unofficial gamecube docs?
- [ ] Make sure connecting [[SP1]] to IceBreaker is safe.
- [ ] Can we power the FPGA with the SP1?
- [ ] How much voltage do we get from SP1.
- [ ] How much current can we source?
- [ ] Figuring out basic [[EXI protocol]]
- [ ] What is the structure of the messages?
- [ ] How to know how long the message is
- [ ] Integrity checks?
- [ ] How fast do we need to respond to a message.

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

1
rebbarb/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

60
rebbarb/rebbarb.py Normal file
View File

@ -0,0 +1,60 @@
from amaranth import *
class LEDBlinker(Elaboratable):
def elaborate(self, platform):
m = Module()
cd_sync = ClockDomain("sync")
m.domains += cd_sync
platform.lookup(platform.default_clk).attrs['GLOBAL'] = False
locked = Signal()
pllout = Signal()
m.submodules.pll = Instance("SB_PLL40_PAD",
p_FEEDBACK_PATH = "SIMPLE",
p_DIVR = 0,
p_DIVF = 7,
p_DIVQ = 1,
p_FILTER_RANGE = 1,
o_LOCK = locked,
i_RESETB = 1,
i_BYPASS = 0,
i_PACKAGEPIN = platform.request("clk12", dir="-").io,
o_PLLOUTCORE = cd_sync.clk
)
ledr0 = platform.request("led_r")
ledg0 = platform.request("led_g")
ledr1 = platform.request("led_r", 1)
ledg1 = platform.request("led_g", 1)
ledg2 = platform.request("led_g", 2)
ledg3 = platform.request("led_g", 3)
ledg4 = platform.request("led_g", 4)
half_freq = int(42e6 // 2)
timer = Signal(range(half_freq + 1))
init = Signal()
with m.If(init == 0):
m.d.sync += ledg0.o.eq(255)
m.d.sync += init.eq(1)
with m.If(timer == half_freq):
m.d.sync += ledr0.o.eq(~ledr0.o)
m.d.sync += ledg0.o.eq(~ledg0.o)
m.d.sync += timer.eq(0)
with m.Else():
m.d.sync += timer.eq(timer + 1)
return m
from amaranth_boards.icebreaker import ICEBreakerPlatform
from amaranth.vendor import SiliconBluePlatform;
platform = ICEBreakerPlatform()
platform.add_resources(platform.break_off_pmod)
platform.build(LEDBlinker(), do_program=True, verbose=True, nextpnr_opts='--freq 48')

10
requirements.txt Normal file
View File

@ -0,0 +1,10 @@
amaranth==0.5.7
amaranth-boards @ git+https://github.com/amaranth-lang/amaranth-boards.git@7e24efe2f6e95afddd0c1b56f1a9423c48caa472
amaranth-yosys==0.50.0.0.post115
importlib_resources==6.5.2
Jinja2==3.1.6
jschon==0.11.1
MarkupSafe==3.0.2
pyvcd==0.4.1
rfc3986==2.0.0
wasmtime==36.0.0