Ergogen: Rework layout for eepyBoard rev2

This commit is contained in:
Lexi / Zoe 2024-09-28 16:14:16 +02:00
parent 6924e8bee2
commit 31f680728b
Signed by: binaryDiv
GPG key ID: F8D4956E224DA232
3 changed files with 619 additions and 387 deletions

View file

@ -0,0 +1,182 @@
// Pin header footprint for a small RP2040-based controller board from AliExpress called "Pico Mini RP2040".
// It has a similar footprint to the Pro Micro (NOT pin-compatible though!), but has an additional row of pins
// on the short edge of the board (basically forming a "U").
// -------------------------------
// Params
// orientation: if up (default), the controller will be on the front side of the PCB, otherwise on the back side
module.exports = {
params: {
designator: 'MCU',
orientation: 'up',
// Left side of pins (with USB port at the top), top to bottom
GP0: {type: 'net', value: 'GP0'},
GP1: {type: 'net', value: 'GP1'},
GP2: {type: 'net', value: 'GP2'},
GP3: {type: 'net', value: 'GP3'},
GP4: {type: 'net', value: 'GP4'},
GP5: {type: 'net', value: 'GP5'},
GP6: {type: 'net', value: 'GP6'},
GP7: {type: 'net', value: 'GP7'},
GP8: {type: 'net', value: 'GP8'},
GP9: {type: 'net', value: 'GP9'},
GP10: {type: 'net', value: 'GP10'},
GP11: {type: 'net', value: 'GP11'},
GP12: {type: 'net', value: 'GP12'},
GP13: {type: 'net', value: 'GP13'},
// Bottom side of pins, left to right (i.e. between GP13 and GP19)
GP14: {type: 'net', value: 'GP14'},
GP15: {type: 'net', value: 'GP15'},
GP16: {type: 'net', value: 'GP16'},
GP17: {type: 'net', value: 'GP17'},
GP18: {type: 'net', value: 'GP18'},
// Right side of pins (with USB port at the top), top to bottom
'5V': {type: 'net', value: '5V'}, // 5V USB voltage
GND: {type: 'net', value: 'GND'},
RST: {type: 'net', value: 'RST'}, // Reset pin: Pull down to reset
'3V3': {type: 'net', value: '3V3'}, // 3.3V voltage used by the MCU
GP29: {type: 'net', value: 'GP29'}, // also: ADC4
GP28: {type: 'net', value: 'GP28'}, // also: ADC2
GP27: {type: 'net', value: 'GP27'}, // also: ADC1
GP26: {type: 'net', value: 'GP26'}, // also: ADC0
GP25: {type: 'net', value: 'GP25'},
GP23: {type: 'net', value: 'GP23'},
GP22: {type: 'net', value: 'GP22'},
GP21: {type: 'net', value: 'GP21'},
GP20: {type: 'net', value: 'GP20'},
GP19: {type: 'net', value: 'GP19'},
},
body: p => {
let sign, side, mirror;
if (p.orientation === 'down') {
sign = -1;
side = 'B';
mirror = 'mirror';
} else {
sign = 1;
side = 'F';
mirror = '';
}
const pins_left = [
'GP0', 'GP1', 'GP2', 'GP3', 'GP4', 'GP5', 'GP6', 'GP7', 'GP8', 'GP9', 'GP10', 'GP11', 'GP12', 'GP13',
];
const pins_bottom = [
'GP14', 'GP15', 'GP16', 'GP17', 'GP18',
];
const pins_right = [
'5V', 'GND', 'RST', '3V3', 'GP29', 'GP28', 'GP27', 'GP26', 'GP25', 'GP23', 'GP22', 'GP21', 'GP20', 'GP19',
];
// Functions to map coordinates from a "pin grid" to actual X/Y coordinates.
// The grid is defined as follows (assuming the board is in "up" orientation with the USB port on top):
// - The X coordinates go from 0 (left) to 6 (right)
// - The Y coordinates go from 0 (top) to 13 (bottom)
// This means the pin rows are on these coordinates:
// - Left side of pins: 0/0 to 0/13
// - Right side of pins: 6/0 to 6/13
// - Additional pins on the bottom (not counting the left and right pins): 1/13 to 5/13
// These grid coordinates have to be mapped to footprint coordinates so that the board is centered, meaning
// the grid position 3/6.5 needs to be mapped to footprint coordinates 0/0. The grid is a standard 2.54mm grid.
function pin_pos_x(pin_number) {
// Use integers to avoid floating point issues
return sign * (254 * (pin_number - 3)) / 100;
}
function pin_pos_y(pin_number) {
// Use integers to avoid floating point issues
return (254 * (pin_number - 7) + 127) / 100;
}
function pin_label(pin_name, pos_x, pos_y, pin_side) {
let offset_x = 0;
let offset_y = 0;
let offset_rotation = 0;
let justify = 'left';
if (pin_side === 'left') {
offset_x = -1.3 * sign;
justify = 'right';
} else if (pin_side === 'right') {
offset_x = 1.3 * sign;
} else if (pin_side === 'bottom') {
offset_y = 1.7;
offset_rotation = -90 * sign;
}
// Shorten the name of the "GPxx" pins to save a bit of space on the PCB
if (pin_name.startsWith('GP')) {
pin_name = pin_name.slice(2);
}
return `
(fp_text user ${pin_name}
(at ${pin_pos_x(pos_x) + offset_x} ${pin_pos_y(pos_y) + offset_y} ${p.r + offset_rotation})
(unlocked yes) (layer ${side}.SilkS)
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify ${justify} ${mirror}))
)`;
}
function pin_pad(pad_number, pos_x, pos_y, pin_name) {
return `
(pad ${pad_number} thru_hole circle
(at ${pin_pos_x(pos_x)} ${pin_pos_y(pos_y)} 0)
(size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.Mask)
${p[pin_name]}
)`;
}
function render_pins() {
let pin_label_body = '';
let pin_pad_body = '';
let pad_number = 1;
for (let i = 0; i < pins_left.length; i++) {
pin_label_body += pin_label(pins_left[i], 0, i, 'left');
pin_pad_body += pin_pad(pad_number++, 0, i, pins_left[i]);
}
for (let i = 0; i < pins_bottom.length; i++) {
pin_label_body += pin_label(pins_bottom[i], 1 + i, 13, 'bottom');
pin_pad_body += pin_pad(pad_number++, 1 + i, 13, pins_bottom[i]);
}
for (let i = 0; i < pins_right.length; i++) {
pin_label_body += pin_label(pins_right[i], 6, i, 'right');
pin_pad_body += pin_pad(pad_number++, 6, i, pins_right[i]);
}
return pin_pad_body + '\n' + pin_label_body;
}
return `
(module RP2040_PICO_MINI (layer F.Cu) (tedit 66FD3C6D)
${p.at /* parametric position */}
${'' /* footprint reference */}
(fp_text reference "${p.ref}" (at 0 0) (layer ${side}.SilkS) ${p.ref_hide}
(effects (font (size 1.27 1.27) (thickness 0.15)))
)
(fp_text value "" (at 0 0) (layer ${side}.SilkS) hide
(effects (font (size 1.27 1.27) (thickness 0.15)))
)
${'' /* component outline */}
(fp_line (start -8.8 -18.0) (end 8.8 -18.0) (layer ${side}.SilkS) (width 0.15))
(fp_line (start 8.8 -18.0) (end 8.8 18.0) (layer ${side}.SilkS) (width 0.15))
(fp_line (start 8.8 18.0) (end -8.8 18.0) (layer ${side}.SilkS) (width 0.15))
(fp_line (start -8.8 18.0) (end -8.8 -18.0) (layer ${side}.SilkS) (width 0.15))
${'' /* illustration of the USB port overhang */}
(fp_line (start -4.3 -18.8) (end 4.3 -18.8) (layer Dwgs.User) (width 0.15))
(fp_line (start 4.3 -18.8) (end 4.3 -11.8) (layer Dwgs.User) (width 0.15))
(fp_line (start 4.3 -11.8) (end -4.3 -11.8) (layer Dwgs.User) (width 0.15))
(fp_line (start -4.3 -11.8) (end -4.3 -18.8) (layer Dwgs.User) (width 0.15))
${'' /* pin labels and pads */}
${render_pins()}
)
`;
}
}

View file

@ -1,140 +0,0 @@
// Pin header footprint for a RP2040-based controller board from AliExpress.
// Doesn't really have a name, it's just "the purple one with USB-C".
// The pinout differs from the Raspberry Pi Pico!
// -------------------------------
// Params
// orientation: if up (default), the controller will be on the front side of the PCB, otherwise on the back side
module.exports = {
params: {
designator: 'MCU',
orientation: 'up',
// Right side of pins (with USB port at the top), top to bottom
VBUS: {type: 'net', value: 'VBUS'},
VIN: {type: 'net', value: 'VIN'},
GND: {type: 'net', value: 'GND'},
'3V3_EN': {type: 'net', value: '3V3_EN'},
'3V3': {type: 'net', value: '3V3'},
// (GND pin)
RUN: {type: 'net', value: 'RUN'}, // Reset pin: Pull down to reset
GP29: {type: 'net', value: 'GP29'}, // also: ADC3
GP28: {type: 'net', value: 'GP28'}, // also: ADC2
GP27: {type: 'net', value: 'GP27'}, // also: ADC1
GP26: {type: 'net', value: 'GP26'}, // also: ADC0
AGND: {type: 'net', value: 'AGND'},
GP25: {type: 'net', value: 'GP25'},
GP24: {type: 'net', value: 'GP24'},
GP23: {type: 'net', value: 'GP23'},
GP22: {type: 'net', value: 'GP22'},
GP21: {type: 'net', value: 'GP21'},
GP20: {type: 'net', value: 'GP20'},
GP19: {type: 'net', value: 'GP19'},
GP18: {type: 'net', value: 'GP18'},
// Left side of pins (with USB port at the top), top to bottom
GP0: {type: 'net', value: 'GP0'},
GP1: {type: 'net', value: 'GP1'},
GP2: {type: 'net', value: 'GP2'},
GP3: {type: 'net', value: 'GP3'},
GP4: {type: 'net', value: 'GP4'},
// (GND pin)
GP5: {type: 'net', value: 'GP5'},
GP6: {type: 'net', value: 'GP6'},
GP7: {type: 'net', value: 'GP7'},
GP8: {type: 'net', value: 'GP8'},
GP9: {type: 'net', value: 'GP9'},
GP10: {type: 'net', value: 'GP10'},
GP11: {type: 'net', value: 'GP11'},
GP12: {type: 'net', value: 'GP12'},
// (GND pin)
GP13: {type: 'net', value: 'GP13'},
GP14: {type: 'net', value: 'GP14'},
GP15: {type: 'net', value: 'GP15'},
GP16: {type: 'net', value: 'GP16'},
GP17: {type: 'net', value: 'GP17'},
},
body: p => {
let def_neg, def_pos, side, mirror;
if (p.orientation === 'down') {
def_neg = '';
def_pos = '-';
side = 'B';
mirror = 'mirror';
} else {
def_neg = '-';
def_pos = '';
side = 'F';
mirror = '';
}
const PINS_PER_SIDE = 20;
const PINS_PER_SIDE_HALF = 10;
const pins_left = [
'GP0', 'GP1', 'GP2', 'GP3', 'GP4', 'GND', 'GP5', 'GP6', 'GP7', 'GP8',
'GP9', 'GP10', 'GP11', 'GP12', 'GND', 'GP13', 'GP14', 'GP15', 'GP16', 'GP17',
];
const pins_right = [
'VBUS', 'VIN', 'GND', '3V3_EN', '3V3', 'GND', 'RUN', 'GP29', 'GP28', 'GP27',
'GP26', 'AGND', 'GP25', 'GP24', 'GP23', 'GP22', 'GP21', 'GP20', 'GP19', 'GP18',
];
function pin_pos_y(pin_number) {
// Fucking floating points...
return (254 * (pin_number - PINS_PER_SIDE_HALF) + 127) / 100;
}
function pin_labels(pin_names, right_side) {
const sign = right_side ? def_pos : def_neg;
const justify = right_side ? 'right' : 'left';
let pin_label_body = '';
for (let i = 0; i < PINS_PER_SIDE; i++) {
pin_label_body += `
(fp_text user ${pin_names[i]} (at ${sign}7.62 ${pin_pos_y(i)} ${p.r}) (unlocked yes) (layer ${side}.SilkS)
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify ${justify} ${mirror}))
)`;
}
return pin_label_body;
}
function pin_pads(pin_names, right_side) {
const sign = right_side ? def_pos : def_neg;
const offset = right_side ? 21 : 1;
let pin_pad_body = '';
for (let i = 0; i < PINS_PER_SIDE; i++) {
pin_pad_body += `
(pad ${i + offset} thru_hole circle (at ${sign}8.89 ${pin_pos_y(i)} 0)
(size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.Mask) ${p[pin_names[i]]}
)`;
}
return pin_pad_body;
}
return `
(module RP2040_USB_C_Purple (layer F.Cu) (tedit 66A6C4CD)
${p.at /* parametric position */}
${'' /* footprint reference */}
(fp_text reference "${p.ref}" (at 0 0) (layer ${side}.SilkS) ${p.ref_hide} (effects (font (size 1.27 1.27) (thickness 0.15))))
(fp_text value "" (at 0 0) (layer ${side}.SilkS) hide (effects (font (size 1.27 1.27) (thickness 0.15))))
${'' /* component outline */}
(fp_line (start -10.16 -28.6) (end 10.16 -28.6) (layer ${side}.SilkS) (width 0.15))
(fp_line (start 10.16 -28.6) (end 10.16 25.4) (layer ${side}.SilkS) (width 0.15))
(fp_line (start 10.16 25.4) (end -10.16 25.4) (layer ${side}.SilkS) (width 0.15))
(fp_line (start -10.16 25.4) (end -10.16 -28.6) (layer ${side}.SilkS) (width 0.15))
${'' /* pin labels */}
${pin_labels(pins_left, false)}
${pin_labels(pins_right, true)}
${'' /* pin pads */}
${pin_pads(pins_left, false)}
${pin_pads(pins_right, true)}
)
`;
}
}