diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86a8483 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Build outputs (generated by `ato build`) +build/ + +# Dependency packages (fetched by `ato install`) +elec/src/generics/ + +# .ato cache/config +.ato/ + +# KiCAD temp & backup files +*.000 +*.bak +*.bck +*.kicad_pcb-bak +*.kicad_sch-bak +*-backups +*.kicad_prl +*.sch-bak +*~ +_autosave-* +*.tmp +*-save.pro +*-save.kicad_pcb +*.kicad_pcb.lck +fp-info-cache + +# Exported BOM / netlist +*.csv +*.net +*.xml +*.dsn +*.ses + +# OS junk +.DS_Store +Thumbs.db + +# Virtual environment +.venv/ +venv/ +__pycache__/ +*.pyc + +# IDE +.vscode/ +.idea/ diff --git a/ato.yaml b/ato.yaml new file mode 100644 index 0000000..9240559 --- /dev/null +++ b/ato.yaml @@ -0,0 +1,9 @@ +ato-version: ^0.2.0 +builds: + default: + entry: elec/src/ch9350-stm32.ato:App +dependencies: +- name: generics + version_spec: '@93de318f38c5acb079fb5cfc9d5a06dc5f02b157' + link_broken: true + path: elec/src/generics diff --git a/elec/footprints/footprints.kicad_sym b/elec/footprints/footprints.kicad_sym new file mode 100644 index 0000000..bbfd695 --- /dev/null +++ b/elec/footprints/footprints.kicad_sym @@ -0,0 +1,2 @@ +(kicad_symbol_lib +) \ No newline at end of file diff --git a/elec/layout/default/ch9350-stm32.kicad_pcb b/elec/layout/default/ch9350-stm32.kicad_pcb new file mode 100644 index 0000000..5f21575 --- /dev/null +++ b/elec/layout/default/ch9350-stm32.kicad_pcb @@ -0,0 +1,272 @@ +(kicad_pcb + (version 20240108) + (generator "pcbnew") + (generator_version "8.0") + (general + (thickness 1.6) + (legacy_teardrops no) + ) + (paper "A4") + (layers + (0 "F.Cu" signal) + (31 "B.Cu" signal) + (32 "B.Adhes" user "B.Adhesive") + (33 "F.Adhes" user "F.Adhesive") + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user "B.Silkscreen") + (37 "F.SilkS" user "F.Silkscreen") + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user "User.Drawings") + (41 "Cmts.User" user "User.Comments") + (42 "Eco1.User" user "User.Eco1") + (43 "Eco2.User" user "User.Eco2") + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user "B.Courtyard") + (47 "F.CrtYd" user "F.Courtyard") + (48 "B.Fab" user) + (49 "F.Fab" user) + (50 "User.1" user) + (51 "User.2" user) + (52 "User.3" user) + (53 "User.4" user) + (54 "User.5" user) + (55 "User.6" user) + (56 "User.7" user) + (57 "User.8" user) + (58 "User.9" user) + ) + (setup + (stackup + (layer "F.SilkS" + (type "Top Silk Screen") + ) + (layer "F.Paste" + (type "Top Solder Paste") + ) + (layer "F.Mask" + (type "Top Solder Mask") + (thickness 0.01) + ) + (layer "F.Cu" + (type "copper") + (thickness 0.035) + ) + (layer "dielectric 1" + (type "core") + (thickness 1.51) + (material "FR4") + (epsilon_r 4.5) + (loss_tangent 0.02) + ) + (layer "B.Cu" + (type "copper") + (thickness 0.035) + ) + (layer "B.Mask" + (type "Bottom Solder Mask") + (thickness 0.01) + ) + (layer "B.Paste" + (type "Bottom Solder Paste") + ) + (layer "B.SilkS" + (type "Bottom Silk Screen") + ) + (copper_finish "None") + (dielectric_constraints no) + ) + (pad_to_mask_clearance 0) + (allow_soldermask_bridges_in_footprints no) + (pcbplotparams + (layerselection 0x00010fc_ffffffff) + (plot_on_all_layers_selection 0x0000000_00000000) + (disableapertmacros no) + (usegerberextensions no) + (usegerberattributes yes) + (usegerberadvancedattributes yes) + (creategerberjobfile yes) + (dashed_line_dash_ratio 12.000000) + (dashed_line_gap_ratio 3.000000) + (svgprecision 4) + (plotframeref no) + (viasonmask no) + (mode 1) + (useauxorigin no) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (pdf_front_fp_property_popups yes) + (pdf_back_fp_property_popups yes) + (dxfpolygonmode yes) + (dxfimperialunits yes) + (dxfusepcbnewfont yes) + (psnegative no) + (psa4output no) + (plotreference yes) + (plotvalue yes) + (plotfptext yes) + (plotinvisibletext no) + (sketchpadsonfab no) + (subtractmaskfromsilk no) + (outputformat 1) + (mirror no) + (drillshape 1) + (scaleselection 1) + (outputdirectory "") + ) + ) + (net 0 "") + (gr_circle + (center 133.352 82.11) + (end 135.052 82.11) + (stroke + (width 0.1) + (type solid) + ) + (fill none) + (layer "Edge.Cuts") + (uuid "019c0a6d-9bb8-42f8-8584-8f200b71a27b") + ) + (gr_circle + (center 165.352 114.11) + (end 167.052 114.11) + (stroke + (width 0.1) + (type solid) + ) + (fill none) + (layer "Edge.Cuts") + (uuid "097c55d3-ce7a-4886-a7db-9a4e9fcd0127") + ) + (gr_circle + (center 165.352 82.11) + (end 167.052 82.11) + (stroke + (width 0.1) + (type solid) + ) + (fill none) + (layer "Edge.Cuts") + (uuid "0e8e5788-23b0-4e0e-993f-a94957498ae3") + ) + (gr_arc + (start 169.352 114.11) + (mid 168.180427 116.938427) + (end 165.352 118.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "178364bc-250e-4a39-b0ba-4262bbac4b46") + ) + (gr_arc + (start 133.352 118.11) + (mid 130.523573 116.938427) + (end 129.352 114.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "3d8baf97-c836-4397-867c-23e52ff05ce1") + ) + (gr_line + (start 169.352 114.11) + (end 169.352 82.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "871dfad9-a85d-42ce-9d2d-6520fae7f4c4") + ) + (gr_line + (start 129.352 82.11) + (end 129.352 114.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "8baef1cd-8e58-474a-b843-199aa0080763") + ) + (gr_arc + (start 165.352 78.11) + (mid 168.180427 79.281573) + (end 169.352 82.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "a7e36be5-cc10-4aad-836f-bde309666136") + ) + (gr_line + (start 165.352 78.11) + (end 133.352 78.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "b80e33ff-046b-4986-bc0d-6bc4865afc31") + ) + (gr_arc + (start 129.352 82.11) + (mid 130.523573 79.281573) + (end 133.352 78.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "cf226ff4-3173-434d-8c9b-3129470c1ce4") + ) + (gr_circle + (center 133.352 114.11) + (end 135.052 114.11) + (stroke + (width 0.1) + (type solid) + ) + (fill none) + (layer "Edge.Cuts") + (uuid "d6648504-8f45-4127-8704-34acfec9c9a4") + ) + (gr_line + (start 133.352 118.11) + (end 165.352 118.11) + (stroke + (width 0.1) + (type solid) + ) + (layer "Edge.Cuts") + (uuid "e1f36007-0f9d-4dc5-ae43-6b056652526f") + ) + (gr_text "{{"{{GITHASH}}"}}" + (at 140.240427 116.111573 0) + (layer "F.SilkS") + (uuid "d894e23f-c5ed-4336-947e-ac38e533f04c") + (effects + (font + (size 2 2) + (thickness 0.1) + ) + (justify left bottom) + ) + ) + (group "" + (uuid "deecda4f-8c94-4c72-8782-3da851560eb8") + (members "019c0a6d-9bb8-42f8-8584-8f200b71a27b" "097c55d3-ce7a-4886-a7db-9a4e9fcd0127" + "0e8e5788-23b0-4e0e-993f-a94957498ae3" "178364bc-250e-4a39-b0ba-4262bbac4b46" + "3d8baf97-c836-4397-867c-23e52ff05ce1" "871dfad9-a85d-42ce-9d2d-6520fae7f4c4" + "8baef1cd-8e58-474a-b843-199aa0080763" "a7e36be5-cc10-4aad-836f-bde309666136" + "b80e33ff-046b-4986-bc0d-6bc4865afc31" "cf226ff4-3173-434d-8c9b-3129470c1ce4" + "d6648504-8f45-4127-8704-34acfec9c9a4" "e1f36007-0f9d-4dc5-ae43-6b056652526f" + ) + ) +) diff --git a/elec/layout/default/ch9350-stm32.kicad_pro b/elec/layout/default/ch9350-stm32.kicad_pro new file mode 100644 index 0000000..d0a2e67 --- /dev/null +++ b/elec/layout/default/ch9350-stm32.kicad_pro @@ -0,0 +1,231 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "board_outline_line_width": 0.09999999999999999, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.15, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.762, + "height": 1.524, + "width": 1.524 + }, + "silk_line_width": 0.15, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15, + "silk_text_upright": false, + "zones": { + "min_clearance": 0.5 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_type_mismatch": "ignore", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "warning", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "warning", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, + "rules": { + "max_error": 0.005, + "min_clearance": 0.0, + "min_connection": 0.0, + "min_copper_edge_clearance": 0.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.7999999999999999, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.0, + "min_via_annular_width": 0.09999999999999999, + "min_via_diameter": 0.5, + "solder_mask_clearance": 0.0, + "solder_mask_min_width": 0.0, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true + }, + "teardrop_options": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 5, + "td_on_pad_in_zone": false, + "td_onpadsmd": true, + "td_onroundshapesonly": false, + "td_ontrackend": false, + "td_onviapad": true + } + ], + "teardrop_parameters": [ + { + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], + "track_widths": [], + "via_dimensions": [], + "zones_allow_external_fillets": false + }, + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "template123.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6 + } + ], + "meta": { + "version": 3 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "../../../build/default.net", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "legacy_lib_dir": "", + "legacy_lib_list": [] + }, + "sheets": [], + "text_variables": {} +} diff --git a/elec/layout/default/ch9350-stm32.kicad_sch b/elec/layout/default/ch9350-stm32.kicad_sch new file mode 100644 index 0000000..2e2aa2f --- /dev/null +++ b/elec/layout/default/ch9350-stm32.kicad_sch @@ -0,0 +1,5 @@ +(kicad_sch (version 20230121) (generator eeschema) + (paper "A4") + (lib_symbols) + (symbol_instances) +) diff --git a/elec/layout/default/fp-lib-table b/elec/layout/default/fp-lib-table new file mode 100644 index 0000000..2c80223 --- /dev/null +++ b/elec/layout/default/fp-lib-table @@ -0,0 +1,4 @@ +(fp_lib_table + (version 7) + (lib (name "lib")(type "KiCad")(uri "${KIPRJMOD}/../../../build/footprints/footprints.pretty")(options "")(descr "")) +) diff --git a/elec/src/ch9350-stm32.ato b/elec/src/ch9350-stm32.ato new file mode 100644 index 0000000..7f90999 --- /dev/null +++ b/elec/src/ch9350-stm32.ato @@ -0,0 +1,325 @@ +import Power from "generics/interfaces.ato" +import UART from "generics/interfaces.ato" +import USB2 from "generics/interfaces.ato" +import SWD from "generics/interfaces.ato" +import Pair from "generics/interfaces.ato" +import Capacitor from "generics/capacitors.ato" +import Resistor from "generics/resistors.ato" +import Oscillator from "generics/oscillators.ato" + + +# ============================================================ +# CH9350 - USB HID to UART Bridge +# ============================================================ + +component CH9350_IC: + mpn = "CH9350L" + footprint = "Package_QFP:LQFP-48_7x7mm_P0.5mm" + package = "LQFP-48" + + # Power + signal vcc ~ pin 1 + signal gnd ~ pin 2 + gnd ~ pin 13 + gnd ~ pin 20 + signal v33 ~ pin 3 + + # USB + signal udm ~ pin 9 + signal udp ~ pin 10 + + # Crystal (12MHz) + signal xi ~ pin 11 + signal xo ~ pin 12 + + # UART + signal txd ~ pin 18 + signal rxd ~ pin 19 + + # Control + signal rst_n ~ pin 4 + signal act ~ pin 5 + + # Mode/Config + signal mode0 ~ pin 16 + signal mode1 ~ pin 17 + signal cfg0 ~ pin 22 + signal cfg1 ~ pin 23 + signal cfg2 ~ pin 24 + + +module CH9350: + ic = new CH9350_IC + + # Power Interface + power = new Power + power.vcc ~ ic.vcc + power.gnd ~ ic.gnd + + # USB Interface + usb = new USB2 + usb.dp ~ ic.udp + usb.dm ~ ic.udm + usb.gnd ~ power.gnd + + # UART Interface + uart = new UART + uart.tx ~ ic.txd + uart.rx ~ ic.rxd + uart.gnd ~ power.gnd + + # V33 LDO decoupling + c_v33 = new Capacitor + c_v33.value = 1uF +/- 20% + c_v33.package = "0402" + ic.v33 ~ c_v33.p1; c_v33.p2 ~ power.gnd + + # 12 MHz crystal oscillator + osc = new Oscillator + osc.crystal.footprint = "Crystal-SMD_L5.0-W3.2" + osc.crystal.mpn = "12MHz-Crystal-SMD-3225" + osc.load_cap_1.value = 22pF +/- 20% + osc.load_cap_2.value = 22pF +/- 20% + ic.xi ~ osc.xin.io + ic.xo ~ osc.xout.io + osc.gnd ~ power.gnd + + # Power decoupling + c_dec_1 = new Capacitor + c_dec_1.value = 100nF +/- 20% + c_dec_1.package = "0402" + ic.vcc ~ c_dec_1.p1; c_dec_1.p2 ~ power.gnd + + c_dec_2 = new Capacitor + c_dec_2.value = 10uF +/- 20% + c_dec_2.package = "0603" + ic.vcc ~ c_dec_2.p1; c_dec_2.p2 ~ power.gnd + + # RESET pull-up (active low) + r_rst = new Resistor + r_rst.value = 10kohm +/- 20% + r_rst.package = "0402" + ic.rst_n ~ r_rst.p1; r_rst.p2 ~ power.vcc + + # ACT LED indicator + r_act = new Resistor + r_act.value = 1kohm +/- 20% + r_act.package = "0402" + signal act_led + + # Mode/Config default: UART mode, auto-detect + r_mode0 = new Resistor + r_mode0.value = 10kohm +/- 20% + r_mode0.package = "0402" + ic.mode0 ~ r_mode0.p1; r_mode0.p2 ~ power.gnd + + r_mode1 = new Resistor + r_mode1.value = 10kohm +/- 20% + r_mode1.package = "0402" + ic.mode1 ~ r_mode1.p1; r_mode1.p2 ~ power.gnd + + r_cfg0 = new Resistor + r_cfg0.value = 10kohm +/- 20% + r_cfg0.package = "0402" + ic.cfg0 ~ r_cfg0.p1; r_cfg0.p2 ~ power.gnd + + r_cfg1 = new Resistor + r_cfg1.value = 10kohm +/- 20% + r_cfg1.package = "0402" + ic.cfg1 ~ r_cfg1.p1; r_cfg1.p2 ~ power.gnd + + r_cfg2 = new Resistor + r_cfg2.value = 10kohm +/- 20% + r_cfg2.package = "0402" + ic.cfg2 ~ r_cfg2.p1; r_cfg2.p2 ~ power.gnd + + +# ============================================================ +# STM32F103C8T6 - ARM Cortex-M3 Microcontroller +# ============================================================ + +component STM32F103C8T6: + mpn = "STM32F103C8T6" + footprint = "Package_QFP:LQFP-48_7x7mm_P0.5mm" + package = "LQFP-48" + + # Power + signal vbat ~ pin 1 + signal vdd_1 ~ pin 9 + signal vss_1 ~ pin 8 + signal vdd_2 ~ pin 24 + signal vss_2 ~ pin 23 + signal vdd_3 ~ pin 36 + signal vss_3 ~ pin 35 + signal vdd_4 ~ pin 48 + signal vss_4 ~ pin 47 + + # HSE Crystal (8 MHz) + signal osc_in ~ pin 5 + signal osc_out ~ pin 6 + + # LSE Crystal (32.768 kHz) + signal osc32_in ~ pin 3 + signal osc32_out ~ pin 4 + + # Reset and Boot + signal nrst ~ pin 7 + signal boot0 ~ pin 44 + + # SWD Debug + signal swdio ~ pin 34 + signal swclk ~ pin 37 + + # USART1 (connected to CH9350) + signal pa9_tx ~ pin 30 + signal pa10_rx ~ pin 31 + + # User LED (PC13) + signal pc13 ~ pin 2 + + +module STM32F103_Minimal: + mcu = new STM32F103C8T6 + + # Power Interface + power = new Power + power.gnd ~ mcu.vss_1 + power.gnd ~ mcu.vss_2 + power.gnd ~ mcu.vss_3 + power.gnd ~ mcu.vss_4 + + # VDD Decoupling - one 100nF per VDD pin + c_d1 = new Capacitor + c_d1.value = 100nF +/- 20% + c_d1.package = "0402" + mcu.vdd_1 ~ c_d1.p1; c_d1.p2 ~ power.gnd + + c_d2 = new Capacitor + c_d2.value = 100nF +/- 20% + c_d2.package = "0402" + mcu.vdd_2 ~ c_d2.p1; c_d2.p2 ~ power.gnd + + c_d3 = new Capacitor + c_d3.value = 100nF +/- 20% + c_d3.package = "0402" + mcu.vdd_3 ~ c_d3.p1; c_d3.p2 ~ power.gnd + + c_d4 = new Capacitor + c_d4.value = 100nF +/- 20% + c_d4.package = "0402" + mcu.vdd_4 ~ c_d4.p1; c_d4.p2 ~ power.gnd + + # Bulk decoupling + c_bulk = new Capacitor + c_bulk.value = 10uF +/- 20% + c_bulk.package = "0603" + mcu.vdd_1 ~ c_bulk.p1; c_bulk.p2 ~ power.gnd + + # VDDA filtering + c_vdda = new Capacitor + c_vdda.value = 100nF +/- 20% + c_vdda.package = "0402" + mcu.vdd_1 ~ c_vdda.p1; c_vdda.p2 ~ power.gnd + + # 0R jumper for VDDA + r_vdda = new Resistor + r_vdda.value = 0ohm + r_vdda.package = "0402" + mcu.vdd_1 ~ r_vdda.p1; power.vcc ~ r_vdda.p2 + + # VBAT + c_vbat = new Capacitor + c_vbat.value = 100nF +/- 20% + c_vbat.package = "0402" + mcu.vbat ~ c_vbat.p1; c_vbat.p2 ~ power.gnd + mcu.vbat ~ power.vcc + + # HSE: 8 MHz external oscillator + hse = new Oscillator + hse.crystal.footprint = "Crystal-SMD_L5.0-W3.2" + hse.crystal.mpn = "8MHz-Crystal-SMD-3225" + hse.load_cap_1.value = 22pF +/- 20% + hse.load_cap_2.value = 22pF +/- 20% + mcu.osc_in ~ hse.xin.io + mcu.osc_out ~ hse.xout.io + hse.gnd ~ power.gnd + + # LSE: 32.768 kHz oscillator for RTC + lse = new Oscillator + lse.crystal.footprint = "Crystal-SMD_L3.2-W1.5" + lse.crystal.mpn = "32.768kHz-Crystal-SMD-3215" + lse.load_cap_1.value = 12pF +/- 20% + lse.load_cap_2.value = 12pF +/- 20% + mcu.osc32_in ~ lse.xin.io + mcu.osc32_out ~ lse.xout.io + lse.gnd ~ power.gnd + + # NRST: pull-up to VCC + r_nrst = new Resistor + r_nrst.value = 10kohm +/- 20% + r_nrst.package = "0402" + mcu.nrst ~ r_nrst.p1; r_nrst.p2 ~ power.vcc + + # NRST decoupling + c_nrst = new Capacitor + c_nrst.value = 100nF +/- 20% + c_nrst.package = "0402" + mcu.nrst ~ c_nrst.p1; c_nrst.p2 ~ power.gnd + + # BOOT0: pull-down to GND (boot from flash) + r_boot0 = new Resistor + r_boot0.value = 10kohm +/- 20% + r_boot0.package = "0402" + mcu.boot0 ~ r_boot0.p1; r_boot0.p2 ~ power.gnd + + # SWD interface + swd = new SWD + swd.swdio ~ mcu.swdio + swd.swclk ~ mcu.swclk + swd.swo ~ power.gnd + swd.gnd ~ power.gnd + + # UART interface to CH9350 + uart = new UART + uart.tx ~ mcu.pa9_tx + uart.rx ~ mcu.pa10_rx + uart.gnd ~ power.gnd + + # User LED on PC13 (active low, open-drain) + r_led = new Resistor + r_led.value = 510ohm +/- 20% + r_led.package = "0402" + signal user_led_anode + + +# ============================================================ +# Top-level Application +# ============================================================ + +module App: + ch9350 = new CH9350 + stm32 = new STM32F103_Minimal + + # Shared power rail + power = new Power + power.vcc ~ ch9350.power.vcc + power.vcc ~ stm32.power.vcc + power.gnd ~ ch9350.power.gnd + power.gnd ~ stm32.power.gnd + + # CH9350 UART -> STM32 USART1 (cross-connected) + ch9350.uart.tx ~ stm32.uart.rx + ch9350.uart.rx ~ stm32.uart.tx + ch9350.uart.gnd ~ stm32.uart.gnd + + # CH9350 USB goes to PC + usb = new USB2 + usb.dp ~ ch9350.usb.dp + usb.dm ~ ch9350.usb.dm + usb.gnd ~ power.gnd + + # Top-level SWD interface for programming/debug + swd = new SWD + swd.swdio ~ stm32.swd.swdio + swd.swclk ~ stm32.swd.swclk + swd.gnd ~ power.gnd diff --git a/metadata/pos-header b/metadata/pos-header new file mode 100644 index 0000000..2ef7f21 --- /dev/null +++ b/metadata/pos-header @@ -0,0 +1 @@ +Designator,Value,Package,Mid X,Mid Y,Rotation,Layer \ No newline at end of file