Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "@tscircuit/core"
export * from "@tscircuit/eval"
export type { ChipProps, PinLabelsProp, CommonLayoutProps } from "@tscircuit/props"
export { createDebugPortJsx } from "./lib/components/debug-port"
109 changes: 109 additions & 0 deletions lib/components/debug-port/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Debug Port Component

A drop-in debugging component for tscircuit that provides ~20 debug connections for monitoring board traces.

## Features

- **RP2040 Microcontroller**: Acts as the receiver board with powerful processing capabilities
- **ADC Module**: Converts analog signals to digital without requiring programming
- **SPI/I2C/UART Interfaces**: Multiple communication protocols supported
- **Configurable Pin Count**: Up to 20 debug pins (default: 20)
- **Power Regulation**: Built-in voltage regulation and filtering
- **External Connections**: Easy access to debug signals via ports

## Architecture

The debug port consists of:

1. **RP2040 Chip**: Raspberry Pi RP2040 microcontroller with 32 GPIO pins
2. **ADC Module**: Analog-to-digital converter for signal monitoring
3. **SPI Header**: 6-pin header for SPI/I2C/UART communication
4. **Debug Header**: Configurable pin header for debug connections
5. **Power Circuit**: Resistor and capacitor for power regulation

## Usage

```typescript
import { createDebugPortJsx } from "tscircuit"

const debugPortCode = createDebugPortJsx({
name: "DEBUG", // Component name
x: 60, // X position
y: 20, // Y position
pinCount: 16, // Number of debug pins (1-20)
width: 30, // Board width in mm
height: 20 // Board height in mm
})

// Use in your circuit
const circuit = (
<board width="100mm" height="80mm">
{/* Your circuit components */}
<resistor name="R1" resistance="1k" />

{/* Add debug port */}
{debugPortCode}
</board>
)
```

## Pin Mapping

- **RP2040 GPIOs 0-1**: Connected to ADC inputs
- **RP2040 GPIOs 2-5**: SPI/I2C/UART outputs (MOSI, MISO, SCK, CS)
- **RP2040 GPIOs 6-21**: Connected to debug pins D1-D16
- **External Ports**: Available as `DEBUG_EXT_D1`, `DEBUG_EXT_D2`, etc.

## Connections

The debug port provides these external connection points:

- **SPI Header** (6 pins): GND, 3.3V, MOSI, MISO, SCK, CS
- **Debug Pins** (configurable): D1, D2, ..., D20
- **Power**: 3.3V and GND available on SPI header

## Example Circuit

```typescript
import { createDebugPortJsx } from "tscircuit"

export const MyBoard = () => (
<board width="100mm" height="80mm">
{/* Main circuit */}
<chip name="MAIN_MCU" footprint="qfp32" />
<resistor name="R1" resistance="10k" />

{/* Debug port for monitoring signals */}
{createDebugPortJsx({
name: "DEBUG",
x: 60,
y: 20,
pinCount: 12
})}

{/* Connect debug pins to circuit traces */}
<trace path={[".MAIN_MCU > .GPIO0", ".DEBUG > .DEBUG_EXT_D1"]} />
<trace path={[".MAIN_MCU > .GPIO1", ".DEBUG > .DEBUG_EXT_D2"]} />
</board>
)
```

## Default Configuration

- **Name**: "DEBUG_PORT"
- **Position**: (0, 0)
- **Dimensions**: 30mm × 20mm
- **Pins**: 20 debug pins
- **RP2040 Footprint**: QFN32
- **ADC Footprint**: SOIC8

## Customization

All aspects of the debug port can be customized:

- Component name and positioning
- Board dimensions
- Number of debug pins (1-20)
- All internal component parameters

This provides a complete debugging solution that can be dropped into any tscircuit design with minimal configuration.
106 changes: 106 additions & 0 deletions lib/components/debug-port/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@


export interface DebugPortConfig {
name?: string
x?: number
y?: number
width?: number
height?: number
pinCount?: number
}

export function createDebugPortJsx(config: DebugPortConfig = {}): string {
const {
name = "DEBUG_PORT",
x = 0,
y = 0,
width = 30,
height = 20,
pinCount = 20,
} = config

const pinLabels = Array.from({ length: pinCount }, (_, i) => `D${i + 1}`)

const maxTraces = Math.min(pinCount, 16)
const debugPinTraces = pinLabels.slice(0, maxTraces).map((pinLabel, index) =>
` <trace path={[".${name}_DEBUG_HEADER > .${pinLabel}", ".${name}_RP2040 > .GPIO${index + 6}"]} />`
).join('\n')

const externalPorts = pinLabels.map((pinLabel, index) =>
` <port name="${name}_EXT_${pinLabel}" x={${width + 2}} y={${index * 1.27}} pinLabel="${pinLabel}" />`
).join('\n')

return `
<group name="${name}" x={${x}} y={${y}}>
<board width="${width}mm" height="${height}mm" name="${name}_BOARD">
<chip
name="${name}_RP2040"
footprint="qfn32"
pinLabels={[
"GND", "GPIO0", "GPIO1", "GND",
"GPIO2", "GPIO3", "GPIO4", "GPIO5",
"GND", "GPIO6", "GPIO7", "GPIO8",
"GPIO9", "GND", "GPIO10", "GPIO11",
"GPIO12", "GND", "GPIO13", "GPIO14",
"GPIO15", "GPIO16", "GND", "GPIO17",
"GPIO18", "GPIO19", "GPIO20", "GPIO21",
"GND", "GPIO22", "GPIO23", "GPIO24"
]}
schX={5}
schY={8}
/>

<chip
name="${name}_ADC"
footprint="soic8"
pinLabels={["VDD", "AIN1", "AIN2", "GND", "CLK", "DOUT", "DIN", "CS"]}
schX={15}
schY={8}
/>

<pinHeader
name="${name}_SPI_HEADER"
pinCount={6}
schX={5}
schY={12}
pinLabels={["GND", "3.3V", "MOSI", "MISO", "SCK", "CS"]}
/>

<pinHeader
name="${name}_DEBUG_HEADER"
pinCount={${pinCount}}
schX={15}
schY={12}
pinLabels={${JSON.stringify(pinLabels)}}
/>

<resistor name="${name}_R1" resistance="10k" footprint="0805" schX={20} schY={5} />
<capacitor name="${name}_C1" capacitance="10uF" footprint="0805" schX={22} schY={5} />

<ground name="${name}_GND1" schX={2} schY={2} />
<ground name="${name}_GND2" schX={25} schY={2} />

<trace path={[".${name}_RP2040 > .GPIO0", ".${name}_ADC > .AIN1"]} />
<trace path={[".${name}_RP2040 > .GPIO1", ".${name}_ADC > .AIN2"]} />

<trace path={[".${name}_RP2040 > .GPIO2", ".${name}_SPI_HEADER > .MOSI"]} />
<trace path={[".${name}_RP2040 > .GPIO3", ".${name}_SPI_HEADER > .MISO"]} />
<trace path={[".${name}_RP2040 > .GPIO4", ".${name}_SPI_HEADER > .SCK"]} />
<trace path={[".${name}_RP2040 > .GPIO5", ".${name}_SPI_HEADER > .CS"]} />

${debugPinTraces}

<trace path={[".${name}_R1 > .pos", ".${name}_SPI_HEADER > .3V3"]} />
<trace path={[".${name}_R1 > .neg", ".${name}_GND1 > .gnd"]} />
<trace path={[".${name}_C1 > .pos", ".${name}_R1 > .pos"]} />
<trace path={[".${name}_C1 > .neg", ".${name}_GND1 > .gnd"]} />
<trace path={[".${name}_ADC > .VDD", ".${name}_SPI_HEADER > .3V3"]} />
<trace path={[".${name}_ADC > .GND", ".${name}_GND1 > .gnd"]} />
<trace path={[".${name}_RP2040 > .GND", ".${name}_GND1 > .gnd"]} />
</board>

<group name="${name}_CABLES">
${externalPorts}
</group>
</group>`
}
21 changes: 21 additions & 0 deletions tests/debug-port.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from "react"
import { test, expect } from "bun:test"
import { Circuit } from "../dist"
import { createDebugPortJsx } from "../lib/components/debug-port"

test("debug port jsx generator works", async () => {
const debugPortJsx = createDebugPortJsx({
name: "TEST_DEBUG",
x: 5,
y: 5,
pinCount: 10
})

expect(debugPortJsx).toBeTruthy()
expect(typeof debugPortJsx).toBe('string')
expect(debugPortJsx).toContain('TEST_DEBUG')
expect(debugPortJsx).toContain('RP2040')
expect(debugPortJsx).toContain('ADC')
expect(debugPortJsx).toContain('D1')
expect(debugPortJsx).toContain('D10')
})