Tutorial: Build circuits with code¶
Before starting this tutorial
You should have already installed JITX and created your first design.
This document contains the code examples and product actions from Quickstart 2, in a format that’s easy to follow alongside the video. Use it as a companion while you watch.
Resources¶
- Awesome JITX – a collection of shared libraries
- Stanza Library Manager (SLM) – manages dependencies for your JITX project
- JITX Statements – references for
pcb-*
statements - Starting code: from Your First Design Tutorial
- Finished code: Quickstart 2 Files
Development Tips¶
- Restart (“kill”) the terminal after modifying
slm.toml
so new libraries can be fetched. - Press Ctrl+Enter to run the current file.
- Press L in Board or Schematic views to toggle net labels on/off.
- Press e to examine a selected component’s metadata.
- Use “multi-cursor rename” (often Ctrl+D in many editors) to quickly rename repeated identifiers in your code.
- Verify package names and imports match your project structure.
View Design Explorer
From the terminal or command interface, run:
view-design-explorer()
net()
statements.
1. Project Setup¶
Update Main Module¶
First, rename the default module in main.stanza
pcb-module my-design:
...
set-main-module(my-design)
pcb-module top-level:
...
set-main-module(top-level)
Fast rename
In many code editors, you can use multi-cursor or “select next occurrence” to rename text quickly (often Ctrl+D).
View set-main-module
Reference
2. Creating the Communications Core 1:26¶
A. Initial Module Setup¶
Create a communications-core
module in main.stanza
:
pcb-module communications-core :
; Components will be added here
B. Add a Zener Diode from the Database¶
- Open “Find Components” in the JITX sidebar
- Enter
MMSZ4689T1G
- Click arrow → open detail
- Click “Copy to clipboard” for the part creation code
Then in main.stanza
:
pcb-module communications-core :
inst zener : create-part(mpn = "MMSZ4689T1G", manufacturer = "ON Semiconductor")
About create-part(...)
create-part(...)
fetches a fully modeled part from the online JITX database. If you need to customize it (e.g., adjusting a symbol or landpattern), press the “Create Component” button instead.
C. Instantiate in the Top-Level¶
Remove old code in top-level
and add an instance of communications-core
:
pcb-module top-level :
inst core : communications-core
Now the diode appears in the BOM Visualizer and in the Board view.
Use e
to examine a component
Select a part in Board view and press e to see its instance name, other details like MPN. This is useful for verifying net connections.
3. USB Interface Integration 3:42¶
A. Add Connectors Library Dependency¶
Add Connectors library in slm.toml
:
connectors = { git = "JITx-Inc/connectors", version = "0.4.1" }
Whenever slm.toml
changes
Kill the terminal so that Ctrl+Enter can reload dependencies.
B. Add USB Connector¶
Copy the USB 2.0 High-Speed code to communications-core
:
inst usb-if : connectors/components/USB/USBTypeC/USBC-HighSpeed-Iface()
C. Connect zener
to USB Power¶
The USB 2.0 High-Speed Interface docs show two ports:
- USB
(type usb-data
)
- VDD-USB
(type power
)
Where are power
and usb-data
defined?
power
and usb-data
are standard bundles in JSL. For instance, power
has two pins: V+
and V-
as shown in the Reference.
Use net (...)
to connect the Zener pins A
and K
to usb-if.VDD-USB.V-
and usb-if.VDD-USB.V+
respectively:
net (zener.A usb-if.VDD-USB.V-)
net (zener.K usb-if.VDD-USB.V+)
Check Board or schematic to confirm the connections.
4. Controller Module Development 7:41¶
A. Create the Controller Component¶
Create src/controller.stanza
and add the lines:
#use-added-syntax(jitx)
defpackage ethernet-io/controller :
import core
import jitx
import jitx/commands
import jitx/parts
import helpers
import jsl
public pcb-module controller :
name = "MCU"
B. Add to Project Configuration¶
In stanza.proj
, link all packages in src/
:
packages ethernet-io/* defined-in "src/"
C. Import & Instantiate¶
Add an import in main.stanza
:
import ethernet-io/controller
Then instantiate inside your top-level (or communications-core):
inst ctl : controller
5. FTDI Integration 9:47¶
A. Add the FTDI Library¶
# In slm.toml
FTDI = { git = "JITx-Inc/FTDI", version = "0.3.3" }
Kill and restart the terminal afterward.
B. Add the “Application Circuit” for FT2232HL¶
Inside controller
:
public pcb-module controller :
name = "MCU"
inst debug-if : FTDI/DebugIF/circuit(
FTDI/components/FT2232HL/FT2232H-MPSSE,
FTDI/components/FT2232HL/FT2232H-RS232
)
6. Debug Interface Connections10:51¶
A. Add Ports to the Controller, Make Internal Connections¶
public pcb-module controller :
name = "MCU"
inst debug-if : FTDI/DebugIF/circuit(
FTDI/components/FT2232HL/FT2232H-MPSSE,
FTDI/components/FT2232HL/FT2232H-RS232
)
public pcb-module controller :
name = "MCU"
port rail-3v3 : power
port USB : usb-data
port VDD-USB : power
inst debug-if : FTDI/DebugIF/circuit(
FTDI/components/FT2232HL/FT2232H-MPSSE,
FTDI/components/FT2232HL/FT2232H-RS232
)
net (rail-3v3 debug-if.VDD-3v3)
net (VDD-USB debug-if.VDD-USB)
net (USB debug-if.USB)
B. In communications-core
, connect ports to usb-if
¶
inst ctl : controller
net (ctl.USB usb-if.USB)
net (ctl.VDD-USB usb-if.VDD-USB)
7. EEPROM Component Creation 13:10¶
- Create the component via Create Component wizard in the JITX sidebar, naming it
MC-93LC46CT
.
This generatessrc/components/MC-93LC46CT.stanza
with a template and auto-adds a line instanza.proj
.
AI Assistance
You can paste the datasheet’s pin table into ChatGPT (or another LLM) to generate the pin-properties : [...]
section for you. And there are several projects offering more complete automated modeling from PDFs. Always double-check for correctness.
Final MC-93LC46CT model
public pcb-component component :
description = "1K Serial EEPROM with 8-bit/16-bit Organization"
mpn = "93LC46CT-I/SN"
manufacturer = "Microchip Technology"
datasheet = "https://ww1.microchip.com/downloads/en/DeviceDoc/20001749K.pdf"
reference-prefix = "U"
pin-properties :
[pin:Ref | pads:Int ... | side:Dir ]
[CS | 1 | Left ] ; Chip Select
[CLK | 2 | Left ] ; Serial Clock
[DI | 3 | Left ] ; Data Input
[DO | 4 | Left ] ; Data Output
[VSS | 5 | Left ] ; Ground
[ORG | 6 | Right] ; Organization Select
[NC | 7 | Right] ; No Connection
[VCC | 8 | Right] ; Power Supply
val box = BoxSymbol(self)
val symb = create-symbol(box)
assign-symbol(symb)
val pkg = SOIC-N(
num-leads = 8,
lead-span = min-max(5.8, 6.2),
package-length = min-max(4.8, 5.0)
density-level = DensityLevelC
)
val lp = create-landpattern(pkg)
assign-landpattern(lp)
8. Create the EEPROM Module 17:56¶
In MC-93LC46CT.stanza
, add:
public pcb-module module :
port VDD-3v3 : power
port cfg : microwire-4()
inst EEPROM : components/MC-93LC46CT/component
net (EEPROM.CS cfg.cs)
net (EEPROM.CLK cfg.clk)
net (EEPROM.DO cfg.do)
net (EEPROM.DI cfg.di)
net (EEPROM.VCC VDD-3v3.V+)
net (EEPROM.VSS VDD-3v3.V-)
Where is microwire-4
?
microwire-4
is another bundle in JSL (see Bundles Reference).
9. Add Parametric Parts 19:57¶
A. Dependency for jitx/parts
to main.stanza
¶
import jitx/parts
B. Insert Resistor & Capacitor¶
; Add a pull-up resistor
insert-resistor(
EEPROM.ORG EEPROM.VCC
helpers/R-query
resistance = 10.e3
)
; Add a bypass capacitor
insert-capacitor(
EEPROM.VCC EEPROM.VSS
helpers/C-query
capacitance = 2.2e-6
short-trace? = true
)
Parametric part selection
Both insert-resistor(...)
and insert-capacitor(...)
automate supply chain choices (e.g. multiple MPNs, different tolerances) so you don’t have to manually pick every resistor or capacitor. JITX solves for possible footprints to ensure they’re widely available.
10. Integrating EEPROM¶
A. Instantiate in controller
Module¶
inst EEPROM : components/MC-93LC46CT/module
net (EEPROM.VDD-3v3 rail-3v3)
net (EEPROM.cfg debug-if.CFG)
Key Concepts Learned¶
-
Component Management
- Pulling from the database with
create-part(...)
- Creating custom components from scratch
- Using library code from Awesome JITX
- Pulling from the database with
-
Circuit Organization
- Module hierarchy & file structure
inst
for adding components/modules- Packaging sub-circuits with ports and bundles
-
Connectivity
- Using
net(...)
statements - Defining and importing bundles (
power
,usb-data
,microwire-4
)
- Using
-
Library Usage & Parametric
- Adding dependencies in
slm.toml
- Parametric resistors/caps (
insert-resistor
,insert-capacitor
) ensure standard footprints, automating the supply chain
- Adding dependencies in
For reference, the final JITX Project (Quickstart 2 Files) is available on GitHub.
Continue to the next tutorial:
Tutorial: Organizing a schematic
Final Notes¶
- Keep verifying each step in Board/Schematic views. Press L to see net labels.
- If a net or part does not appear as expected, re-check your
import
statements and project files. - Re-run with Ctrl+Enter to ensure all changes compile correctly.
- Press e on a selected part to see pin names and confirm your connections.
- Make use of the “View Design Explorer” to quickly locate pins, nets, and instance paths.