1
0
mirror of synced 2026-03-09 03:49:24 +00:00

start working on some form of how-to, improve backplate for V1.2

This commit is contained in:
Romain Dolbeau
2021-10-03 11:19:11 +02:00
parent 07256fda8a
commit 455acac0c1
3 changed files with 21709 additions and 39744 deletions

29
USAGE.md Normal file
View File

@@ -0,0 +1,29 @@
# How to use A FPGA on a SBus card...
## What do you need ?
* a SPARCstation or compatible with a free SBus slot, high enough to accomodate the taller-than-the standard board. Only SPARCstation 20s have been tested so far. I'd recommend against a SPARCstation 1-class machine (1, 1+, SLC, ...) as they have many quirks in their early SBus implementation. OpenBoot 2.x or newer is also a requirement (i.e. a recent 2.x or newer PROM).
* [NetBSD](https://www.netbsd.org/) 9.0 running on the SPARCstation, presumably newer version would work as well but have not yet been tested. No other OS (SunOS 4.1, Solaris 2.x, ...) have drivers (it is theoretically possible to write some, but it isn't planned).
* The ability to [rebuild the NetBSD kernel from source](https://www.netbsd.org/docs/guide/en/chap-kernel.html), as extra drivers are needed. It is well documented by the NetBSD team. This can be done in a QEmu virtual machine running NetBSD/sparc as an alternative to doing it on the real hardware.
* An adequate FPGA board, namely a [ZTex USB-to-FPGA 2.13](https://www.ztex.de/usb-fpga-2/usb-fpga-2.13.e.html). It provides the actual FPGA, a Xilinx Artix-7, and 256 MiB of on-board DDR3 SDRAM. Any of the 2.13 should work, but only the 2.13a (smallest and slowest FPGA, cheapest board) has been tested and it enough to fit quite a lot of stuff already. Other non-2.13 boards from ZTex will not work due to pin assignement (e.g. restriction on which pin can take the SBus clock as input), voltage (some boards require strictly more than 5V as input), ...
* An adequate power supply to power the FPGA board out of the SPARCstation so it can be programmed, and either an install of the FOSS ZTex software to program the board via USB (recommended!) or an adequate JTAG programmer to program the board from Vivado
* The [Xilinx Vivado toolchain](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/2020-2.html) to work with the FPGA. I use 2020.1, newer should work as well (and maybe some older). The free (as in no money needed, not as in FOSS)version is enough for the Artix-7 FPGA.
* A SBusFPGA SBus board. There's no supplier for those. Mine were manufactured by SeeedStudio. Other suppliers of PCB and PCB assembly are available - it's just the one I'm used to.
* A working [Litex](https://github.com/enjoy-digital/litex/) installation. It supplies the basis and many functionalities of the gateware in the FPGA.
* The ability to 3D-print the extension (and associated backplate), so that the board can be installed cleanly in a SBus system
* ???
## How to rebuild
TBD

View File

@@ -1,3 +1,6 @@
add_fan = 0; // not really compatible with USB...
add_vga = 1;
SBUS_WIDTH = 83.82;
SBUS_LENGTH = 146.7;
SBUS_THICKNESS = 1.6;
@@ -41,6 +44,7 @@ SMALL_STRUT_HEIGHT = 5;
SMALL_STRUT_WIDTH = 2;
SMALL_STRUT_LENGTH = 20;
USB_PLUG_OFFSET = (add_vga!=0 ? 65 : 30);
fan_depth=8;
fan_height=25;
@@ -55,18 +59,23 @@ echo(carrier_offset);
module
primary ()
{
union ()
USBCABLE_HOLLOWOUT_WIDTH = 10;
USBCABLE_HOLLOWOUT_LENGTH = 16;
USBCABLE_HOLLOWOUT_OFFSETX = -7.5+0.001;
USBCABLE_HOLLOWOUT_OFFSETY = -16;
USBCABLE_HOLLOWOUT2_WIDTH = 21;
USBCABLE_HOLLOWOUT2_LENGTH = 6;
USBCABLE_HOLLOWOUT2_OFFSETX = -12.5;
USBCABLE_HOLLOWOUT2_OFFSETY = -16;
union () // A
{
difference() { // B
union() { // C
color ("green") cube ([SBUS_WIDTH, MY_FULL_LENGTH, SBUS_THICKNESS], center = true);
if (0) for (i =[-2: 1:2]) {
translate ([i * 15 + 2.5, 0, STRUT_HEIGHT / 2 - 0.1]) color ("red") cube ([STRUT_WIDTH, MY_FULL_LENGTH, STRUT_HEIGHT], center = true);
}
//translate ([SBUS_WIDTH/2-18,7+(MY_FULL_LENGTH-SMALL_STRUT_LENGTH)/2,SMALL_STRUT_HEIGHT/2]) color("red") cube([SMALL_STRUT_WIDTH, SMALL_STRUT_LENGTH, SMALL_STRUT_HEIGHT], center = true);
//translate ([-SBUS_WIDTH/2+24,7+(MY_FULL_LENGTH-SMALL_STRUT_LENGTH)/2,SMALL_STRUT_HEIGHT/2]) color("red") cube([SMALL_STRUT_WIDTH, SMALL_STRUT_LENGTH, SMALL_STRUT_HEIGHT], center = true);
translate ([0, -MY_FULL_LENGTH / 2 + SBUS_BACKPLATE_THICKNESS / 2, SBUS_BACKPLATE_HEIGHT / 2 - SBUS_THICKNESS / 2 - SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM]) {
union ()
{
@@ -76,8 +85,54 @@ primary ()
color ("black")
cube ([SBUS_BACKPLATE_PROTUSION_WIDTH, SBUS_BACKPLATE_THICKNESS, SBUS_BACKPLATE_FULLHEIGHT], center = true);
}
}
} // union
}
/* USB plug (StarTech cable) */
union() {
color ("grey")
translate ([-SBUS_WIDTH/2+USB_PLUG_OFFSET,
0.001-MY_FULL_LENGTH/2+4,
14.8/2-SBUS_THICKNESS/2-SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM-SBUS_BACKPLATE_PROTUSION_HEIGHT + 3.12])
cube ([16.5+4, 12, 9.5+4 /* 14.8 max */], center = true);
}
if (0) for (i =[-2: 1:2]) {
translate ([i * 15 + 2.5, 0, STRUT_HEIGHT / 2 - 0.1]) color ("red") cube ([STRUT_WIDTH, MY_FULL_LENGTH, STRUT_HEIGHT], center = true);
}
} // union C
union() { // Z
translate ([SBUS_WIDTH / 2 - USBCABLE_HOLLOWOUT_WIDTH / 2 + 5+ USBCABLE_HOLLOWOUT_OFFSETX,
MY_FULL_LENGTH / 2 + USBCABLE_HOLLOWOUT_LENGTH / 2 + USBCABLE_HOLLOWOUT_OFFSETY,
0]) {
color ("yellow")
cube ([USBCABLE_HOLLOWOUT_WIDTH, USBCABLE_HOLLOWOUT_LENGTH, 50], center = true);
}
translate ([SBUS_WIDTH / 2 - USBCABLE_HOLLOWOUT2_WIDTH / 2 + 5+ USBCABLE_HOLLOWOUT2_OFFSETX,
MY_FULL_LENGTH / 2 + USBCABLE_HOLLOWOUT2_LENGTH / 2 + USBCABLE_HOLLOWOUT2_OFFSETY,
0]) {
color ("yellow")
cube ([USBCABLE_HOLLOWOUT2_WIDTH, USBCABLE_HOLLOWOUT2_LENGTH, 50], center = true);
}
/* USB plug (StarTech cable) */
union() {
color ("yellow")
translate ([-SBUS_WIDTH/2+USB_PLUG_OFFSET,
0.001-MY_FULL_LENGTH/2+4,
14.8/2-SBUS_THICKNESS/2-SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM-SBUS_BACKPLATE_PROTUSION_HEIGHT + 3.12])
cube ([16.5, 20, 9.5], center = true);
}
} // union Z
}// difference B
//translate ([SBUS_WIDTH/2-18,7+(MY_FULL_LENGTH-SMALL_STRUT_LENGTH)/2,SMALL_STRUT_HEIGHT/2]) color("red") cube([SMALL_STRUT_WIDTH, SMALL_STRUT_LENGTH, SMALL_STRUT_HEIGHT], center = true);
//translate ([-SBUS_WIDTH/2+24,7+(MY_FULL_LENGTH-SMALL_STRUT_LENGTH)/2,SMALL_STRUT_HEIGHT/2]) color("red") cube([SMALL_STRUT_WIDTH, SMALL_STRUT_LENGTH, SMALL_STRUT_HEIGHT], center = true);
MY_BOARD_OVERLAP_LENGTH = 20;
MY_BACKPLATE_OVERLAP_LENGTH = 12;
@@ -95,17 +150,17 @@ primary ()
SERIAL_HOLLOWOUT_OFFSET = 3;
PMOD_HOLLOWOUT_WIDTH = 18;
PMOD_HOLLOWOUT_LENGTH = 8;
PMOD_HOLLOWOUT_OFFSETX = -59.12 -7 + 16.3 / 2 + PMOD_HOLLOWOUT_WIDTH / 2;
PMOD_HOLLOWOUT_OFFSETY = 9;
PMOD_HOLLOWOUT_LENGTH = 9;
PMOD_HOLLOWOUT_OFFSETX = (31 - SBUS_WIDTH) + PMOD_HOLLOWOUT_WIDTH / 2;
PMOD_HOLLOWOUT_OFFSETY = 10;
USB_HOLLOWOUT_WIDTH = 10;
USB_HOLLOWOUT_LENGTH = 10;
USB_HOLLOWOUT_OFFSETX = -USB_HOLLOWOUT_WIDTH/2+0.001;
USB_HOLLOWOUT_OFFSETY = 0;
USB_HOLLOWOUT_WIDTH = 14;
USB_HOLLOWOUT_LENGTH = 5;
USB_HOLLOWOUT_OFFSETX = -5+0.001;
USB_HOLLOWOUT_OFFSETY = 6;
SDCARD_HOLLOWOUT_WIDTH = 3;
SDCARD_HOLLOWOUT_LENGTH = 3;
SDCARD_HOLLOWOUT_WIDTH = 5;
SDCARD_HOLLOWOUT_LENGTH = 5;
SDCARD_HOLLOWOUT_OFFSETX = -36+SDCARD_HOLLOWOUT_WIDTH/2+0.001;
SDCARD_HOLLOWOUT_OFFSETY = 2.501;
@@ -114,7 +169,8 @@ primary ()
JTAG_HOLLOWOUT_LENGTH = 16;
JTAG_HOLLOWOUT_OFFSET = 6;
difference () {
difference () { // I
union () {
translate ([0,
MY_FULL_LENGTH / 2 + MY_OVERLAP_LENGTH / 2 -
MY_BACKPLATE_OVERLAP_LENGTH, 0.00000000001 - SBUS_THICKNESS / 2 - (SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM) / 2]) {
@@ -122,9 +178,22 @@ primary ()
cube ([SBUS_WIDTH, MY_OVERLAP_LENGTH, /*SBUS_THICKNESS */
SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM], center = true);
}
STRUT_WIDTH=2;
translate ([
SBUS_WIDTH/2-STRUT_WIDTH/2,
-12+MY_FULL_LENGTH / 2 + MY_OVERLAP_LENGTH / 2 -
MY_BACKPLATE_OVERLAP_LENGTH, 0.00000000001 - SBUS_THICKNESS / 2 - (SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM) / 2]) {
color ("blue")
cube ([STRUT_WIDTH, MY_OVERLAP_LENGTH, /*SBUS_THICKNESS */
SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM], center = true);
}
}
union ()
union () // J
{
/* fixing holes */
translate ([-SBUS_WIDTH / 2 + FIXHOLE1_Y_OFFSET, MY_FULL_LENGTH / 2 + FIXHOLE_X_OFFSET, 0]) {
color ("yellow") cylinder (h = 50, r1 = FIXHOLE_RAD, r2 = FIXHOLE_RAD, center = true);
}
@@ -142,7 +211,7 @@ primary ()
cube ([SERIAL_HOLLOWOUT_WIDTH + 10, SERIAL_HOLLOWOUT_LENGTH, 50], center = true);
}
*/
translate ([SBUS_WIDTH / 2 - PMOD_HOLLOWOUT_WIDTH / 2 + 5+ PMOD_HOLLOWOUT_OFFSETX,
translate ([SBUS_WIDTH / 2 - PMOD_HOLLOWOUT_WIDTH / 2 + PMOD_HOLLOWOUT_OFFSETX,
MY_FULL_LENGTH / 2 + PMOD_HOLLOWOUT_LENGTH / 2 + PMOD_HOLLOWOUT_OFFSETY,
0]) {
color ("yellow")
@@ -166,10 +235,20 @@ primary ()
color ("yellow")
cube ([JTAG_HOLLOWOUT_WIDTH, JTAG_HOLLOWOUT_LENGTH, 50], center = true);
}
}
}
/* USB */
translate ([SBUS_WIDTH / 2 - USBCABLE_HOLLOWOUT_WIDTH / 2 + 5+ USBCABLE_HOLLOWOUT_OFFSETX,
MY_FULL_LENGTH / 2 + USBCABLE_HOLLOWOUT_LENGTH / 2 + USBCABLE_HOLLOWOUT_OFFSETY,
0]) {
color ("yellow")
cube ([USBCABLE_HOLLOWOUT_WIDTH, USBCABLE_HOLLOWOUT_LENGTH, 50], center = true);
}
} // union J
} // difference I
}
} // union A
}
module
@@ -178,16 +257,10 @@ extra_holes ()
EXTRA_RAD = 2;
union ()
{
/* border line (fan side) */
/* border line (fan & jtag sides) */
for (i =[-8: 16:8]) {
for (j =[-4: 1:5]) {
translate ([i * 5, j * 5, 0])
color ("pink") cylinder (h = 50, r1 = 1.5, r2 = 1.5, center = true);
}
}
/* border line (JTAG side) */
for (i =[-8: 16:8]) {
for (j =[6: 1:8]) {
for (j =[-4: 1:8]) {
if ((i!=8) || (j < 1))
translate ([i * 5, j * 5, 0])
color ("pink") cylinder (h = 50, r1 = 1.5, r2 = 1.5, center = true);
}
@@ -196,6 +269,9 @@ extra_holes ()
/* holes in extension */
for (i =[-6: 2:6]) {
for (j =[-4: 1:5]) {
if (((i<-4) || (i>0)) || (add_vga==0))
if (((i<=2) || i>=8) || (j>-3)) // USB plug
if (!((i>=5) && (j>=4))) // USB weakness
translate ([i * 5, j * 5, 0])
color ("pink") cylinder (h = 50, r1 = EXTRA_RAD, r2 = EXTRA_RAD, center = true);
}
@@ -203,6 +279,8 @@ extra_holes ()
/* holes in extension */
for (i =[-7: 2:7]) {
for (j =[-4.5: 1:4.5]) {
if (((i<-5) || (i>1)) || (j>0 && j<4 ) || (add_vga==0))
if (((i<=2) || i>=7) || (j>-3)) // USB plug
translate ([i * 5, j * 5, 0])
color ("pink") cylinder (h = 50, r1 = EXTRA_RAD, r2 = EXTRA_RAD, center = true);
}
@@ -210,6 +288,8 @@ extra_holes ()
/* holes in support */
for (i =[-4: 2:6]) {
for (j =[5: 1:8]) {
if (((i<-4) || (i>0)) || (j>5) || (add_vga==0))
if (!((i==6) && (j>=5) && (j<=8))) // USB weakness
translate ([i * 5, j * 5, 0])
color ("pink") cylinder (h = 50, r1 = EXTRA_RAD, r2 = EXTRA_RAD, center = true);
}
@@ -218,6 +298,7 @@ extra_holes ()
for (i =[-5: 2:7]) {
for (j =[5.5: 1:8.5]) {
if (!((i==5) && (j > 7)) && !((i==-5) && (j > 7))) // fixation holes are there
if (!((i==7) && (j>=5.5) && (j<=7.5))) // USB weakness
translate ([i * 5, j * 5, 0])
color ("pink") cylinder (h = 50, r1 = EXTRA_RAD, r2 = EXTRA_RAD, center = true);
}
@@ -256,6 +337,87 @@ fan_25mm_carveout() {
}
}
module vga_support() {
/* plug */
union() {
color ("grey")
translate ([-SBUS_WIDTH/2+31,
0.001-MY_FULL_LENGTH/2-1/2,
14.8/2-SBUS_THICKNESS/2-SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM-SBUS_BACKPLATE_PROTUSION_HEIGHT + 3.12])
cube ([31.8+10, 2, 14.8], center = true);
}
/* pcb */
if (0) color ("violet")
translate ([-SBUS_WIDTH/2+31,
0,
0.00000000001 - SBUS_THICKNESS / 2 - (SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM) / 2])
cube ([19.2+4, MY_FULL_LENGTH,
SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM], center = true);
if (0) color ("violet")
translate ([-SBUS_WIDTH/2+31,
-MY_FULL_LENGTH/2+22/2,
0.00000000001 - SBUS_THICKNESS / 2 - (SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM) / 2])
cube ([31.8+4, 22, /*SBUS_THICKNESS */
SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM], center = true);
color ("violet")
translate ([-SBUS_WIDTH/2+31,
-MY_FULL_LENGTH/2+5/2,
0.00000000001 - SBUS_THICKNESS / 2 - (SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM) / 2])
cube ([31.8+8, 5, /*SBUS_THICKNESS */
SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM], center = true);
color ("violet")
translate ([-SBUS_WIDTH/2+31,
-MY_FULL_LENGTH/2+5/2+15,
0.00000000001 - SBUS_THICKNESS / 2 - (SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM) / 2])
cube ([31.8+8, 4, /*SBUS_THICKNESS */
SBUS_BACKPLATE_PROTUSION_HEIGHT + SBUS_BACKPLATE_BOTTOM_TO_BOARD_BOTTOM], center = true);
}
module vga_carveout() {
union() {
/* plug */
color ("yellow")
translate ([-SBUS_WIDTH/2+31,
-0-MY_FULL_LENGTH/2-1/2,
0.001/2+14.5/2])
cube ([18, 5+0.001, 10], center = true); // hole big enough for the cable shield
translate ([-SBUS_WIDTH/2+31-12.5,
-MY_FULL_LENGTH/2-1/2,
6.3+SBUS_THICKNESS/2]) rotate([90,0,0]) color ("yellow") cylinder (h = 10, r1 = 1.6, r2 = 1.6, center = true);
translate ([-SBUS_WIDTH/2+31+12.5,
-MY_FULL_LENGTH/2-1/2,
6.3+SBUS_THICKNESS/2]) rotate([90,0,0]) color ("yellow") cylinder (h = 10, r1 = 1.6, r2 = 1.6, center = true);
/* pcb */
color ("yellow")
translate ([-SBUS_WIDTH/2+31,
0,
-0.001])
cube ([19.2+0.8, MY_FULL_LENGTH+0.001, SBUS_THICKNESS + 0.003], center = true);
color ("yellow")
translate ([-SBUS_WIDTH/2+31,
0.5-MY_FULL_LENGTH/2+23/2,
-0.001+14.5/2-0.5])
cube ([32+0.8, 1+23+0.001, SBUS_THICKNESS + 0.003+14.5-1], center = true);
color ("yellow")
translate ([-SBUS_WIDTH/2+31,
MY_FULL_LENGTH/2-10-2,
0])
cube ([19.2+0.8, 20, 50], center = true);
}
}
screw_hole_r=1.55;
triangle_width=4;
triangle_height=12;
@@ -291,8 +453,10 @@ difference ()
}
}
//fan_25mm_support();
if (add_fan!=0) fan_25mm_support();
if (add_vga!=0) vga_support();
}
//fan_25mm_carveout();
if (add_fan!=0) fan_25mm_carveout();
if (add_vga!=0) vga_carveout();
}

File diff suppressed because it is too large Load Diff