1 Commits

Author SHA1 Message Date
dbisu
ed9becce03 Add PCB design files 2022-06-18 22:15:43 -05:00
29 changed files with 3501 additions and 1433 deletions

View File

@@ -1 +0,0 @@
blank_issues_enabled: false

View File

@@ -1,29 +0,0 @@
---
name: Not Working
about: Create a report if something is not working correctly
title: ''
labels: ''
assignees: ''
---
**Describe the issue**
A clear and concise description of the symptoms
**To Reproduce**
Steps to reproduce the behavior:
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Debug info**
If possible, include debug serial data.
On Windows, use PuTTY, connect to the debug serial port (commonly COM3, but could vary)
On Linux, use minicom (minicom -b 115200 -o -D /dev/ttyACM0, where ttyACM0 corresponds to your device)
**Additional context**
Add any other context about the problem here.

View File

@@ -1,6 +0,0 @@
# Instructions on how to collect debug logs
* On Windows, use [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) to connect to the debug serial port (commonly COM3, but could vary on your machine).
* On Linux, use minicom (minicom -b 115200 -o -D /dev/ttyACM0, where ttyACM0 corresponds to your device).
* On Ubuntu: `sudo apt install minicom`

162
README.md
View File

@@ -16,156 +16,48 @@
<br /> <br />
## Quick Start Guide ## Install
Install and have your USB Rubber Ducky working in less than 5 minutes.
1. Download the latest release from the [Releases](https://github.com/dbisu/pico-ducky/releases) page.
2. Plug the device into a USB port while holding the boot button. It will show up as a removable media device named RPI-RP2.
3. Install CircutlPython on the Pico or Pico W
If using a Pico board:
Copy the adafruit-circuitpython-raspberry_pi_pico-en_US-9.2.1.uf2 file to the root of the Pico (RPI-RP2). The device will reboot and after a second or so, it will reconnect as CIRCUITPY.
If using a Pico W board:
Copy the adafruit-circuitpython-raspberry_pi_pico_w-en_US-9.2.1.uf2 file to the root of the Pico (RPI-RP2). The device will reboot and after a second or so, it will reconnect as CIRCUITPY.
If using a Pico 2 board:
Copy the adafruit-circuitpython-raspberry_pi_pico2-en_US-9.2.1.uf2 file to the root of the Pico (RPI-RP2). The device will reboot and after a second or so, it will reconnect as CIRCUITPY.
If using a Pico 2W board:
Copy the adafruit-circuitpython-raspberry_pi_pico2_w-en_US-9.2.1.uf2 file to the root of the Pico (RPI-RP2). The device will reboot and after a second or so, it will reconnect as CIRCUITPY.
4. Copy the lib folder to the root of the CIRCUITPY
5. Copy *.py to the root of the CIRCUITPY
6. Follow the instructions in README.md to enter setup mode
7. Copy your payload as payload.dd to the root of the CIRCUITPY
8. Unplug the device from the USB port and remove the setup jumper.
Enjoy your Pico-Ducky.
## Setup mode
To edit the payload, enter setup mode by connecting the pin 1 (`GP0`) to pin 3 (`GND`), this will stop the pico-ducky from injecting the payload in your own machine.
The easiest way to do so is by using a jumper wire between those pins as seen bellow.
![Setup mode with a jumper](images/setup-mode.png)
## USB enable/disable mode
If you need the pico-ducky to not show up as a USB mass storage device for stealth, follow these instructions.
- Enter setup mode.
- Copy your payload script to the pico-ducky.
- Disconnect the pico from your host PC.
- Connect a jumper wire between pin 18 (`GND`) and pin 20 (`GPIO15`).
This will prevent the pico-ducky from showing up as a USB drive when plugged into the target computer.
- Remove the jumper and reconnect to your PC to reprogram.
Pico: The default mode is USB mass storage enabled.
Pico W: The default mode is USB mass storage **disabled**
![USB enable/disable mode](images/usb-boot-mode.png)
-----
# Full Install Instructions
Install and have your USB Rubber Ducky working in less than 5 minutes. Install and have your USB Rubber Ducky working in less than 5 minutes.
1. Clone the repo to get a local copy of the files. `git clone https://github.com/dbisu/pico-ducky.git` 1. Download [CircuitPython for the Raspberry Pi Pico](https://circuitpython.org/board/raspberry_pi_pico/). *Updated to 7.0.0
2. Download [CircuitPython for the Raspberry Pi Pico](https://circuitpython.org/board/raspberry_pi_pico/). *Updated to 9.2.1 2. Plug the device into a USB port while holding the boot button. It will show up as a removable media device named `RPI-RP2`.
Download [CircuitPython for the Raspberry Pi Pico W](https://circuitpython.org/board/raspberry_pi_pico_w/). *Updated to 9.2.1
Download [CircuitPython for the Raspberry Pi Pico 2](https://circuitpython.org/board/raspberry_pi_pico2/). *Updated to 9.2.1
Download [CircuitPython for the Raspberry Pi Pico 2W](https://circuitpython.org/board/raspberry_pi_pico2_w/). *Updated to 9.2.1
3. Plug the device into a USB port while holding the boot button. It will show up as a removable media device named `RPI-RP2`. 3. Copy the downloaded `.uf2` file to the root of the Pico (`RPI-RP2`). The device will reboot and after a second or so, it will reconnect as `CIRCUITPY`.
4. Copy the downloaded `.uf2` file to the root of the Pico (`RPI-RP2`). The device will reboot and after a second or so, it will reconnect as `CIRCUITPY`. 4. Download `adafruit-circuitpython-bundle-7.x-mpy-YYYYMMDD.zip` [here](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest) and extract it outside the device.
5. Download `adafruit-circuitpython-bundle-9.x-mpy-YYYYMMDD.zip` [here](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest) and extract it outside the device. 5. Navigate to `lib` in the recently extracted folder and copy `adafruit_hid` to the `lib` folder in your Raspberry Pi Pico.
6. Navigate to `lib` in the recently extracted folder and copy `adafruit_hid` to the `lib` folder on your Raspberry Pi Pico. 6. Click [here](https://raw.githubusercontent.com/dbisu/pico-ducky/main/duckyinpython.py), press CTRL + S and save the file as `code.py` in the root of the Raspberry Pi Pico, overwriting the previous file.
7. Copy `adafruit_debouncer.mpy` and `adafruit_ticks.mpy` to the `lib` folder on your Raspberry Pi Pico. 7. Find a script [here](https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Payloads) or [create your own one using Ducky Script](https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript) and save it as `payload.dd` in the Pico.
8. Copy `asyncio` to the `lib` folder on your Pico. 8. Be careful, if your device isn't in [setup mode](#setup-mode), the device will reboot and after half a second, the script will run.
9. Copy `adafruit_wsgi` to the `lib` folder on your Pico. ### Setup mode
10. Copy `boot.py` from your clone to the root of your Pico.
11. Copy `duckyinpython.py`, `code.py`, `webapp.py`, `wsgiserver.py` to the root folder of the Pico.
12. *For Pico W Only* Create the file `secrets.py` in the root of the Pico W. This contains the AP name and password to be created by the Pico W.
`secrets = { 'ssid' : "BadAPName", 'password' : "badpassword" }`
13. Find a script [here](https://github.com/hak5/usbrubberducky-payloads) or [create your own one using Ducky Script](https://docs.hak5.org/hak5-usb-rubber-ducky/ducky-script-basics/hello-world) and save it as `payload.dd` in the Pico. Currently, pico-ducky only supports DuckyScript 1.0, and some of 3.0.
14. Be careful, if your device isn't in [setup mode](#setup-mode), the device will reboot and after half a second, the script will run.
15. **Please note:** by default Pico W will not show as a USB drive
### Pico W Web Service
The Pico W AP defaults to ip address `192.168.4.1`. You should be able to find the webservice at `http://192.168.4.1:80`
The following endpoints are available on the webservice:
```
/
/new
/ducky
/edit/<filename>
/write/<filename>
/run/<filename>
```
API endpoints
```
/api/run/<filenumber>
```
## Setup mode
To edit the payload, enter setup mode by connecting the pin 1 (`GP0`) to pin 3 (`GND`), this will stop the pico-ducky from injecting the payload in your own machine. To edit the payload, enter setup mode by connecting the pin 1 (`GP0`) to pin 3 (`GND`), this will stop the pico-ducky from injecting the payload in your own machine.
The easiest way to do so is by using a jumper wire between those pins as seen bellow. The easiest way to so is by using a jumper wire between those pins as seen bellow.
![Setup mode with a jumper](images/setup-mode.png) ![Setup mode with a jumper](images/setup-mode.png)
## USB enable/disable mode ### USB enable/disable mode
If you need the pico-ducky to not show up as a USB mass storage device for stealth, follow these instructions. If you need the pico-ducky to not show up as a USB mass storage device for stealth, follow these instructions.
- Enter setup mode. Enter setup mode.
- Copy your payload script to the pico-ducky. Copy boot.py to the root of the pico-ducky.
- Disconnect the pico from your host PC. Copy your payload script to the pico-ducky.
- Connect a jumper wire between pin 18 (`GND`) and pin 20 (`GPIO15`). Disconnect the pico from your host PC.
Connect a jumper wire between pin 18 (`GND`) and pin 20 (`GPIO15`).
This will prevent the pico-ducky from showing up as a USB drive when plugged into the target computer. This will prevent the pico-ducky from showing up as a USB drive when plugged into the target computer.
- Remove the jumper and reconnect to your PC to reprogram. Remove the jumper and reconnect to your PC to reprogram.
The default mode is USB mass storage enabled.
Pico: The default mode is USB mass storage enabled.
Pico W: The default mode is USB mass storage **disabled**
![USB enable/disable mode](images/usb-boot-mode.png) ![USB enable/disable mode](images/usb-boot-mode.png)
## Multiple payloads ### Changing Keyboard Layouts
Multiple payloads can be stored on the Pico and Pico W.
To select a payload, ground one of these pins:
- GP4 - payload.dd
- GP5 - payload2.dd
- GP10 - payload3.dd
- GP11 - payload4.dd
## Changing Keyboard Layouts
Copied from [Neradoc/Circuitpython_Keyboard_Layouts](https://github.com/Neradoc/Circuitpython_Keyboard_Layouts/blob/main/PICODUCKY.md) Copied from [Neradoc/Circuitpython_Keyboard_Layouts](https://github.com/Neradoc/Circuitpython_Keyboard_Layouts/blob/main/PICODUCKY.md)
@@ -237,14 +129,10 @@ keycode_win_de.mpy
## Useful links and resources ## Useful links and resources
### How to recover your Pico if it becomes corrupted or doesn't boot.
[Reset Instructions](RESET.md)
### Installation Tool ### Installation Tool
[ryo-yamada](https://github.com/ryo-yamada) Created a tool to convert a blank RPi Pico to a ducky. [raspberrypi5621](https://github.com/raspberrypi5621) Created a tool to convert a blank RPi Pico to a ducky.
You can find the tool [here](https://github.com/ryo-yamada/PicoDuckyBuilder) You can find the tool [here](https://github.com/raspberrypi5621/pyducky)
### Docs ### Docs
@@ -261,9 +149,3 @@ You can find the tool [here](https://github.com/ryo-yamada/PicoDuckyBuilder)
[USB Rubber Ducky playlist by **Hak5**](https://www.youtube.com/playlist?list=PLW5y1tjAOzI0YaJslcjcI4zKI366tMBYk) [USB Rubber Ducky playlist by **Hak5**](https://www.youtube.com/playlist?list=PLW5y1tjAOzI0YaJslcjcI4zKI366tMBYk)
[CircuitPython tutorial on the Raspberry Pi Pico by **DroneBot Workshop**](https://www.youtube.com/watch?v=07vG-_CcDG0) [CircuitPython tutorial on the Raspberry Pi Pico by **DroneBot Workshop**](https://www.youtube.com/watch?v=07vG-_CcDG0)
## Related Projects
[Defcon31-ducky](https://github.com/iot-pwn/defcon31-ducky)
There are still a few of these available to purchase, US only.

View File

@@ -1,7 +0,0 @@
# Instructions on how to reset a Raspberry Pi Pico
Follow these instructions if your Pico ends up in an odd state
1. Download the reset firmware from [flash_nuke.uf2](https://datasheets.raspberrypi.com/soft/flash_nuke.uf2)
2. While holding the BOOTSEL button on the Pico, plug in the USB cable to your computer.
3. When the RPI-RP2 drive shows up on your computer, copy the flash_nuke.uf2 file to the Pico
4. After the device reboots, follow the Install instructions [here](https://github.com/dbisu/pico-ducky/blob/main/README.md)

View File

@@ -0,0 +1,209 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:31-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Copper,L2,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:31*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%TA.AperFunction,ComponentPad*%
%ADD10C,1.320800*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD11C,1.752600*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD12R,1.700000X1.700000*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD13O,1.700000X1.700000*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD14R,1.308000X1.308000*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD15C,1.308000*%
%TD*%
G04 APERTURE END LIST*
D10*
%TO.P,SW3,1,1*%
%TO.N,Net-(J1-Pad6)*%
X105400000Y-71800000D03*
%TO.P,SW3,2,2*%
%TO.N,Net-(J1-Pad7)*%
X105400000Y-73800001D03*
%TO.P,SW3,3,3*%
%TO.N,Net-(J1-Pad8)*%
X105400000Y-75800000D03*
%TO.P,SW3,4,4*%
%TO.N,Net-(J1-Pad13)*%
X105400000Y-77800001D03*
%TO.P,SW3,5,5*%
%TO.N,Net-(J1-Pad14)*%
X105400000Y-79799999D03*
%TO.P,SW3,6,6*%
%TO.N,Net-(J1-Pad15)*%
X105400000Y-81800000D03*
D11*
%TO.P,SW3,7*%
%TO.N,N/C*%
X105400000Y-69700000D03*
%TO.P,SW3,8*%
X105400000Y-83900000D03*
%TD*%
D12*
%TO.P,J2,1,Pin_1*%
%TO.N,unconnected-(J2-Pad1)*%
X131000000Y-53400000D03*
D13*
%TO.P,J2,2,Pin_2*%
%TO.N,unconnected-(J2-Pad2)*%
X131000000Y-55940000D03*
%TO.P,J2,3,Pin_3*%
%TO.N,unconnected-(J2-Pad3)*%
X131000000Y-58480000D03*
%TO.P,J2,4,Pin_4*%
%TO.N,unconnected-(J2-Pad4)*%
X131000000Y-61020000D03*
%TO.P,J2,5,Pin_5*%
%TO.N,unconnected-(J2-Pad5)*%
X131000000Y-63560000D03*
%TO.P,J2,6,Pin_6*%
%TO.N,unconnected-(J2-Pad6)*%
X131000000Y-66100000D03*
%TO.P,J2,7,Pin_7*%
%TO.N,unconnected-(J2-Pad7)*%
X131000000Y-68640000D03*
%TO.P,J2,8,Pin_8*%
%TO.N,unconnected-(J2-Pad8)*%
X131000000Y-71180000D03*
%TO.P,J2,9,Pin_9*%
%TO.N,unconnected-(J2-Pad9)*%
X131000000Y-73720000D03*
%TO.P,J2,10,Pin_10*%
%TO.N,unconnected-(J2-Pad10)*%
X131000000Y-76260000D03*
%TO.P,J2,11,Pin_11*%
%TO.N,unconnected-(J2-Pad11)*%
X131000000Y-78800000D03*
%TO.P,J2,12,Pin_12*%
%TO.N,unconnected-(J2-Pad12)*%
X131000000Y-81340000D03*
%TO.P,J2,13,Pin_13*%
%TO.N,unconnected-(J2-Pad13)*%
X131000000Y-83880000D03*
%TO.P,J2,14,Pin_14*%
%TO.N,unconnected-(J2-Pad14)*%
X131000000Y-86420000D03*
%TO.P,J2,15,Pin_15*%
%TO.N,unconnected-(J2-Pad15)*%
X131000000Y-88960000D03*
%TO.P,J2,16,Pin_16*%
%TO.N,unconnected-(J2-Pad16)*%
X131000000Y-91500000D03*
%TO.P,J2,17,Pin_17*%
%TO.N,unconnected-(J2-Pad17)*%
X131000000Y-94040000D03*
%TO.P,J2,18,Pin_18*%
%TO.N,unconnected-(J2-Pad18)*%
X131000000Y-96580000D03*
%TO.P,J2,19,Pin_19*%
%TO.N,unconnected-(J2-Pad19)*%
X131000000Y-99120000D03*
%TO.P,J2,20,Pin_20*%
%TO.N,unconnected-(J2-Pad20)*%
X131000000Y-101660000D03*
%TD*%
D14*
%TO.P,S1,1*%
%TO.N,Net-(J1-Pad18)*%
X105200000Y-98000000D03*
D15*
%TO.P,S1,2*%
%TO.N,unconnected-(S1-Pad2)*%
X105200000Y-95460000D03*
%TO.P,S1,3*%
%TO.N,Net-(J1-Pad20)*%
X105200000Y-100540000D03*
%TD*%
D12*
%TO.P,J1,1,Pin_1*%
%TO.N,Net-(J1-Pad1)*%
X112950000Y-53205000D03*
D13*
%TO.P,J1,2,Pin_2*%
%TO.N,unconnected-(J1-Pad2)*%
X112950000Y-55745000D03*
%TO.P,J1,3,Pin_3*%
%TO.N,Net-(J1-Pad3)*%
X112950000Y-58285000D03*
%TO.P,J1,4,Pin_4*%
%TO.N,unconnected-(J1-Pad4)*%
X112950000Y-60825000D03*
%TO.P,J1,5,Pin_5*%
%TO.N,unconnected-(J1-Pad5)*%
X112950000Y-63365000D03*
%TO.P,J1,6,Pin_6*%
%TO.N,Net-(J1-Pad6)*%
X112950000Y-65905000D03*
%TO.P,J1,7,Pin_7*%
%TO.N,Net-(J1-Pad7)*%
X112950000Y-68445000D03*
%TO.P,J1,8,Pin_8*%
%TO.N,Net-(J1-Pad8)*%
X112950000Y-70985000D03*
%TO.P,J1,9,Pin_9*%
%TO.N,unconnected-(J1-Pad9)*%
X112950000Y-73525000D03*
%TO.P,J1,10,Pin_10*%
%TO.N,unconnected-(J1-Pad10)*%
X112950000Y-76065000D03*
%TO.P,J1,11,Pin_11*%
%TO.N,unconnected-(J1-Pad11)*%
X112950000Y-78605000D03*
%TO.P,J1,12,Pin_12*%
%TO.N,unconnected-(J1-Pad12)*%
X112950000Y-81145000D03*
%TO.P,J1,13,Pin_13*%
%TO.N,Net-(J1-Pad13)*%
X112950000Y-83685000D03*
%TO.P,J1,14,Pin_14*%
%TO.N,Net-(J1-Pad14)*%
X112950000Y-86225000D03*
%TO.P,J1,15,Pin_15*%
%TO.N,Net-(J1-Pad15)*%
X112950000Y-88765000D03*
%TO.P,J1,16,Pin_16*%
%TO.N,unconnected-(J1-Pad16)*%
X112950000Y-91305000D03*
%TO.P,J1,17,Pin_17*%
%TO.N,unconnected-(J1-Pad17)*%
X112950000Y-93845000D03*
%TO.P,J1,18,Pin_18*%
%TO.N,Net-(J1-Pad18)*%
X112950000Y-96385000D03*
%TO.P,J1,19,Pin_19*%
%TO.N,unconnected-(J1-Pad19)*%
X112950000Y-98925000D03*
%TO.P,J1,20,Pin_20*%
%TO.N,Net-(J1-Pad20)*%
X112950000Y-101465000D03*
%TD*%
D14*
%TO.P,S2,1*%
%TO.N,Net-(J1-Pad3)*%
X105700000Y-56740000D03*
D15*
%TO.P,S2,2*%
%TO.N,Net-(J1-Pad1)*%
X105700000Y-54200000D03*
%TO.P,S2,3*%
%TO.N,unconnected-(S2-Pad3)*%
X105700000Y-59280000D03*
%TD*%
M02*

View File

@@ -0,0 +1,110 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:33-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Bot*%
%TF.FilePolarity,Negative*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:33*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,1.320800*%
%ADD11C,1.752600*%
%ADD12R,1.700000X1.700000*%
%ADD13O,1.700000X1.700000*%
%ADD14R,1.308000X1.308000*%
%ADD15C,1.308000*%
%ADD16C,3.200000*%
G04 APERTURE END LIST*
D10*
%TO.C,SW3*%
X105400000Y-71800000D03*
X105400000Y-73800001D03*
X105400000Y-75800000D03*
X105400000Y-77800001D03*
X105400000Y-79799999D03*
X105400000Y-81800000D03*
D11*
X105400000Y-69700000D03*
X105400000Y-83900000D03*
%TD*%
D12*
%TO.C,J2*%
X131000000Y-53400000D03*
D13*
X131000000Y-55940000D03*
X131000000Y-58480000D03*
X131000000Y-61020000D03*
X131000000Y-63560000D03*
X131000000Y-66100000D03*
X131000000Y-68640000D03*
X131000000Y-71180000D03*
X131000000Y-73720000D03*
X131000000Y-76260000D03*
X131000000Y-78800000D03*
X131000000Y-81340000D03*
X131000000Y-83880000D03*
X131000000Y-86420000D03*
X131000000Y-88960000D03*
X131000000Y-91500000D03*
X131000000Y-94040000D03*
X131000000Y-96580000D03*
X131000000Y-99120000D03*
X131000000Y-101660000D03*
%TD*%
D14*
%TO.C,S1*%
X105200000Y-98000000D03*
D15*
X105200000Y-95460000D03*
X105200000Y-100540000D03*
%TD*%
D16*
%TO.C,REF\u002A\u002A*%
X105500000Y-46600000D03*
%TD*%
D12*
%TO.C,J1*%
X112950000Y-53205000D03*
D13*
X112950000Y-55745000D03*
X112950000Y-58285000D03*
X112950000Y-60825000D03*
X112950000Y-63365000D03*
X112950000Y-65905000D03*
X112950000Y-68445000D03*
X112950000Y-70985000D03*
X112950000Y-73525000D03*
X112950000Y-76065000D03*
X112950000Y-78605000D03*
X112950000Y-81145000D03*
X112950000Y-83685000D03*
X112950000Y-86225000D03*
X112950000Y-88765000D03*
X112950000Y-91305000D03*
X112950000Y-93845000D03*
X112950000Y-96385000D03*
X112950000Y-98925000D03*
X112950000Y-101465000D03*
%TD*%
D14*
%TO.C,S2*%
X105700000Y-56740000D03*
D15*
X105700000Y-54200000D03*
X105700000Y-59280000D03*
%TD*%
D16*
%TO.C,REF\u002A\u002A*%
X135400000Y-46700000D03*
%TD*%
%TO.C,REF\u002A\u002A*%
X135500000Y-107300000D03*
%TD*%
%TO.C,REF\u002A\u002A*%
X105800000Y-107400000D03*
%TD*%
M02*

View File

@@ -0,0 +1,15 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:32-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Paste,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:32*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@@ -0,0 +1,15 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:32-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Legend,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:32*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@@ -0,0 +1,26 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:33-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Profile,NP*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:33*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%TA.AperFunction,Profile*%
%ADD10C,0.100000*%
%TD*%
G04 APERTURE END LIST*
D10*
X102120000Y-43060000D02*
X139030000Y-43060000D01*
X139030000Y-43060000D02*
X139030000Y-111080000D01*
X139030000Y-111080000D02*
X102120000Y-111080000D01*
X102120000Y-111080000D02*
X102120000Y-43060000D01*
M02*

View File

@@ -0,0 +1,264 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:31-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Copper,L1,Top*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:31*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%TA.AperFunction,ComponentPad*%
%ADD10C,1.320800*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD11C,1.752600*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD12R,1.700000X1.700000*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD13O,1.700000X1.700000*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD14R,1.308000X1.308000*%
%TD*%
%TA.AperFunction,ComponentPad*%
%ADD15C,1.308000*%
%TD*%
%TA.AperFunction,Conductor*%
%ADD16C,0.250000*%
%TD*%
G04 APERTURE END LIST*
D10*
%TO.P,SW3,1,1*%
%TO.N,Net-(J1-Pad6)*%
X105400000Y-71800000D03*
%TO.P,SW3,2,2*%
%TO.N,Net-(J1-Pad7)*%
X105400000Y-73800001D03*
%TO.P,SW3,3,3*%
%TO.N,Net-(J1-Pad8)*%
X105400000Y-75800000D03*
%TO.P,SW3,4,4*%
%TO.N,Net-(J1-Pad13)*%
X105400000Y-77800001D03*
%TO.P,SW3,5,5*%
%TO.N,Net-(J1-Pad14)*%
X105400000Y-79799999D03*
%TO.P,SW3,6,6*%
%TO.N,Net-(J1-Pad15)*%
X105400000Y-81800000D03*
D11*
%TO.P,SW3,7*%
%TO.N,N/C*%
X105400000Y-69700000D03*
%TO.P,SW3,8*%
X105400000Y-83900000D03*
%TD*%
D12*
%TO.P,J2,1,Pin_1*%
%TO.N,unconnected-(J2-Pad1)*%
X131000000Y-53400000D03*
D13*
%TO.P,J2,2,Pin_2*%
%TO.N,unconnected-(J2-Pad2)*%
X131000000Y-55940000D03*
%TO.P,J2,3,Pin_3*%
%TO.N,unconnected-(J2-Pad3)*%
X131000000Y-58480000D03*
%TO.P,J2,4,Pin_4*%
%TO.N,unconnected-(J2-Pad4)*%
X131000000Y-61020000D03*
%TO.P,J2,5,Pin_5*%
%TO.N,unconnected-(J2-Pad5)*%
X131000000Y-63560000D03*
%TO.P,J2,6,Pin_6*%
%TO.N,unconnected-(J2-Pad6)*%
X131000000Y-66100000D03*
%TO.P,J2,7,Pin_7*%
%TO.N,unconnected-(J2-Pad7)*%
X131000000Y-68640000D03*
%TO.P,J2,8,Pin_8*%
%TO.N,unconnected-(J2-Pad8)*%
X131000000Y-71180000D03*
%TO.P,J2,9,Pin_9*%
%TO.N,unconnected-(J2-Pad9)*%
X131000000Y-73720000D03*
%TO.P,J2,10,Pin_10*%
%TO.N,unconnected-(J2-Pad10)*%
X131000000Y-76260000D03*
%TO.P,J2,11,Pin_11*%
%TO.N,unconnected-(J2-Pad11)*%
X131000000Y-78800000D03*
%TO.P,J2,12,Pin_12*%
%TO.N,unconnected-(J2-Pad12)*%
X131000000Y-81340000D03*
%TO.P,J2,13,Pin_13*%
%TO.N,unconnected-(J2-Pad13)*%
X131000000Y-83880000D03*
%TO.P,J2,14,Pin_14*%
%TO.N,unconnected-(J2-Pad14)*%
X131000000Y-86420000D03*
%TO.P,J2,15,Pin_15*%
%TO.N,unconnected-(J2-Pad15)*%
X131000000Y-88960000D03*
%TO.P,J2,16,Pin_16*%
%TO.N,unconnected-(J2-Pad16)*%
X131000000Y-91500000D03*
%TO.P,J2,17,Pin_17*%
%TO.N,unconnected-(J2-Pad17)*%
X131000000Y-94040000D03*
%TO.P,J2,18,Pin_18*%
%TO.N,unconnected-(J2-Pad18)*%
X131000000Y-96580000D03*
%TO.P,J2,19,Pin_19*%
%TO.N,unconnected-(J2-Pad19)*%
X131000000Y-99120000D03*
%TO.P,J2,20,Pin_20*%
%TO.N,unconnected-(J2-Pad20)*%
X131000000Y-101660000D03*
%TD*%
D14*
%TO.P,S1,1*%
%TO.N,Net-(J1-Pad18)*%
X105200000Y-98000000D03*
D15*
%TO.P,S1,2*%
%TO.N,unconnected-(S1-Pad2)*%
X105200000Y-95460000D03*
%TO.P,S1,3*%
%TO.N,Net-(J1-Pad20)*%
X105200000Y-100540000D03*
%TD*%
D12*
%TO.P,J1,1,Pin_1*%
%TO.N,Net-(J1-Pad1)*%
X112950000Y-53205000D03*
D13*
%TO.P,J1,2,Pin_2*%
%TO.N,unconnected-(J1-Pad2)*%
X112950000Y-55745000D03*
%TO.P,J1,3,Pin_3*%
%TO.N,Net-(J1-Pad3)*%
X112950000Y-58285000D03*
%TO.P,J1,4,Pin_4*%
%TO.N,unconnected-(J1-Pad4)*%
X112950000Y-60825000D03*
%TO.P,J1,5,Pin_5*%
%TO.N,unconnected-(J1-Pad5)*%
X112950000Y-63365000D03*
%TO.P,J1,6,Pin_6*%
%TO.N,Net-(J1-Pad6)*%
X112950000Y-65905000D03*
%TO.P,J1,7,Pin_7*%
%TO.N,Net-(J1-Pad7)*%
X112950000Y-68445000D03*
%TO.P,J1,8,Pin_8*%
%TO.N,Net-(J1-Pad8)*%
X112950000Y-70985000D03*
%TO.P,J1,9,Pin_9*%
%TO.N,unconnected-(J1-Pad9)*%
X112950000Y-73525000D03*
%TO.P,J1,10,Pin_10*%
%TO.N,unconnected-(J1-Pad10)*%
X112950000Y-76065000D03*
%TO.P,J1,11,Pin_11*%
%TO.N,unconnected-(J1-Pad11)*%
X112950000Y-78605000D03*
%TO.P,J1,12,Pin_12*%
%TO.N,unconnected-(J1-Pad12)*%
X112950000Y-81145000D03*
%TO.P,J1,13,Pin_13*%
%TO.N,Net-(J1-Pad13)*%
X112950000Y-83685000D03*
%TO.P,J1,14,Pin_14*%
%TO.N,Net-(J1-Pad14)*%
X112950000Y-86225000D03*
%TO.P,J1,15,Pin_15*%
%TO.N,Net-(J1-Pad15)*%
X112950000Y-88765000D03*
%TO.P,J1,16,Pin_16*%
%TO.N,unconnected-(J1-Pad16)*%
X112950000Y-91305000D03*
%TO.P,J1,17,Pin_17*%
%TO.N,unconnected-(J1-Pad17)*%
X112950000Y-93845000D03*
%TO.P,J1,18,Pin_18*%
%TO.N,Net-(J1-Pad18)*%
X112950000Y-96385000D03*
%TO.P,J1,19,Pin_19*%
%TO.N,unconnected-(J1-Pad19)*%
X112950000Y-98925000D03*
%TO.P,J1,20,Pin_20*%
%TO.N,Net-(J1-Pad20)*%
X112950000Y-101465000D03*
%TD*%
D14*
%TO.P,S2,1*%
%TO.N,Net-(J1-Pad3)*%
X105700000Y-56740000D03*
D15*
%TO.P,S2,2*%
%TO.N,Net-(J1-Pad1)*%
X105700000Y-54200000D03*
%TO.P,S2,3*%
%TO.N,unconnected-(S2-Pad3)*%
X105700000Y-59280000D03*
%TD*%
D16*
%TO.N,Net-(J1-Pad3)*%
X105700000Y-56740000D02*
X111405000Y-56740000D01*
X111405000Y-56740000D02*
X112950000Y-58285000D01*
%TO.N,Net-(J1-Pad6)*%
X111295000Y-65905000D02*
X112950000Y-65905000D01*
X105400000Y-71800000D02*
X111295000Y-65905000D01*
%TO.N,Net-(J1-Pad7)*%
X107594999Y-73800001D02*
X112950000Y-68445000D01*
X105400000Y-73800001D02*
X107594999Y-73800001D01*
%TO.N,Net-(J1-Pad14)*%
X105400000Y-79799999D02*
X106524999Y-79799999D01*
X106524999Y-79799999D02*
X112950000Y-86225000D01*
%TO.N,Net-(J1-Pad15)*%
X112365000Y-88765000D02*
X112950000Y-88765000D01*
X105400000Y-81800000D02*
X112365000Y-88765000D01*
%TO.N,Net-(J1-Pad18)*%
X111335000Y-98000000D02*
X112950000Y-96385000D01*
X105200000Y-98000000D02*
X111335000Y-98000000D01*
%TO.N,Net-(J1-Pad20)*%
X105200000Y-100540000D02*
X112025000Y-100540000D01*
X112025000Y-100540000D02*
X112950000Y-101465000D01*
%TO.N,Net-(J1-Pad8)*%
X105400000Y-75800000D02*
X108135000Y-75800000D01*
X108135000Y-75800000D02*
X112950000Y-70985000D01*
%TO.N,Net-(J1-Pad13)*%
X107065001Y-77800001D02*
X112950000Y-83685000D01*
X105400000Y-77800001D02*
X107065001Y-77800001D01*
%TO.N,Net-(J1-Pad1)*%
X106695000Y-53205000D02*
X105700000Y-54200000D01*
X112950000Y-53205000D02*
X106695000Y-53205000D01*
%TD*%
M02*

View File

@@ -0,0 +1,110 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:33-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Top*%
%TF.FilePolarity,Negative*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:33*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,1.320800*%
%ADD11C,1.752600*%
%ADD12R,1.700000X1.700000*%
%ADD13O,1.700000X1.700000*%
%ADD14R,1.308000X1.308000*%
%ADD15C,1.308000*%
%ADD16C,3.200000*%
G04 APERTURE END LIST*
D10*
%TO.C,SW3*%
X105400000Y-71800000D03*
X105400000Y-73800001D03*
X105400000Y-75800000D03*
X105400000Y-77800001D03*
X105400000Y-79799999D03*
X105400000Y-81800000D03*
D11*
X105400000Y-69700000D03*
X105400000Y-83900000D03*
%TD*%
D12*
%TO.C,J2*%
X131000000Y-53400000D03*
D13*
X131000000Y-55940000D03*
X131000000Y-58480000D03*
X131000000Y-61020000D03*
X131000000Y-63560000D03*
X131000000Y-66100000D03*
X131000000Y-68640000D03*
X131000000Y-71180000D03*
X131000000Y-73720000D03*
X131000000Y-76260000D03*
X131000000Y-78800000D03*
X131000000Y-81340000D03*
X131000000Y-83880000D03*
X131000000Y-86420000D03*
X131000000Y-88960000D03*
X131000000Y-91500000D03*
X131000000Y-94040000D03*
X131000000Y-96580000D03*
X131000000Y-99120000D03*
X131000000Y-101660000D03*
%TD*%
D14*
%TO.C,S1*%
X105200000Y-98000000D03*
D15*
X105200000Y-95460000D03*
X105200000Y-100540000D03*
%TD*%
D16*
%TO.C,REF\u002A\u002A*%
X105500000Y-46600000D03*
%TD*%
D12*
%TO.C,J1*%
X112950000Y-53205000D03*
D13*
X112950000Y-55745000D03*
X112950000Y-58285000D03*
X112950000Y-60825000D03*
X112950000Y-63365000D03*
X112950000Y-65905000D03*
X112950000Y-68445000D03*
X112950000Y-70985000D03*
X112950000Y-73525000D03*
X112950000Y-76065000D03*
X112950000Y-78605000D03*
X112950000Y-81145000D03*
X112950000Y-83685000D03*
X112950000Y-86225000D03*
X112950000Y-88765000D03*
X112950000Y-91305000D03*
X112950000Y-93845000D03*
X112950000Y-96385000D03*
X112950000Y-98925000D03*
X112950000Y-101465000D03*
%TD*%
D14*
%TO.C,S2*%
X105700000Y-56740000D03*
D15*
X105700000Y-54200000D03*
X105700000Y-59280000D03*
%TD*%
D16*
%TO.C,REF\u002A\u002A*%
X135400000Y-46700000D03*
%TD*%
%TO.C,REF\u002A\u002A*%
X135500000Y-107300000D03*
%TD*%
%TO.C,REF\u002A\u002A*%
X105800000Y-107400000D03*
%TD*%
M02*

View File

@@ -0,0 +1,15 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:31-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Paste,Top*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:31*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@@ -0,0 +1,188 @@
%TF.GenerationSoftware,KiCad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1*%
%TF.CreationDate,2022-02-10T07:45:32-06:00*%
%TF.ProjectId,pico-ducky,7069636f-2d64-4756-936b-792e6b696361,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Legend,Top*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 6.0.1-79c1e3a40b~116~ubuntu20.04.1) date 2022-02-10 07:45:32*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.150000*%
%ADD11C,0.120000*%
%ADD12C,0.127000*%
%ADD13C,0.200000*%
G04 APERTURE END LIST*
D10*
%TO.C,J2*%
X130666666Y-50082380D02*
X130666666Y-50796666D01*
X130619047Y-50939523D01*
X130523809Y-51034761D01*
X130380952Y-51082380D01*
X130285714Y-51082380D01*
X131095238Y-50177619D02*
X131142857Y-50130000D01*
X131238095Y-50082380D01*
X131476190Y-50082380D01*
X131571428Y-50130000D01*
X131619047Y-50177619D01*
X131666666Y-50272857D01*
X131666666Y-50368095D01*
X131619047Y-50510952D01*
X131047619Y-51082380D01*
X131666666Y-51082380D01*
%TO.C,S1*%
X108239761Y-96936904D02*
X108287380Y-96794047D01*
X108287380Y-96555952D01*
X108239761Y-96460714D01*
X108192142Y-96413095D01*
X108096904Y-96365476D01*
X108001666Y-96365476D01*
X107906428Y-96413095D01*
X107858809Y-96460714D01*
X107811190Y-96555952D01*
X107763571Y-96746428D01*
X107715952Y-96841666D01*
X107668333Y-96889285D01*
X107573095Y-96936904D01*
X107477857Y-96936904D01*
X107382619Y-96889285D01*
X107335000Y-96841666D01*
X107287380Y-96746428D01*
X107287380Y-96508333D01*
X107335000Y-96365476D01*
X108287380Y-95413095D02*
X108287380Y-95984523D01*
X108287380Y-95698809D02*
X107287380Y-95698809D01*
X107430238Y-95794047D01*
X107525476Y-95889285D01*
X107573095Y-95984523D01*
%TO.C,J1*%
X112616666Y-49887380D02*
X112616666Y-50601666D01*
X112569047Y-50744523D01*
X112473809Y-50839761D01*
X112330952Y-50887380D01*
X112235714Y-50887380D01*
X113616666Y-50887380D02*
X113045238Y-50887380D01*
X113330952Y-50887380D02*
X113330952Y-49887380D01*
X113235714Y-50030238D01*
X113140476Y-50125476D01*
X113045238Y-50173095D01*
%TO.C,S2*%
X108739761Y-55676904D02*
X108787380Y-55534047D01*
X108787380Y-55295952D01*
X108739761Y-55200714D01*
X108692142Y-55153095D01*
X108596904Y-55105476D01*
X108501666Y-55105476D01*
X108406428Y-55153095D01*
X108358809Y-55200714D01*
X108311190Y-55295952D01*
X108263571Y-55486428D01*
X108215952Y-55581666D01*
X108168333Y-55629285D01*
X108073095Y-55676904D01*
X107977857Y-55676904D01*
X107882619Y-55629285D01*
X107835000Y-55581666D01*
X107787380Y-55486428D01*
X107787380Y-55248333D01*
X107835000Y-55105476D01*
X107882619Y-54724523D02*
X107835000Y-54676904D01*
X107787380Y-54581666D01*
X107787380Y-54343571D01*
X107835000Y-54248333D01*
X107882619Y-54200714D01*
X107977857Y-54153095D01*
X108073095Y-54153095D01*
X108215952Y-54200714D01*
X108787380Y-54772142D01*
X108787380Y-54153095D01*
D11*
%TO.C,SW3*%
X103126700Y-84229500D02*
X103126700Y-78933600D01*
X106563274Y-69370500D02*
X107673300Y-69370500D01*
X103126700Y-76673000D02*
X103126700Y-69370500D01*
X107673300Y-84229500D02*
X106563274Y-84229500D01*
X107673300Y-69370500D02*
X107673300Y-84229500D01*
X103126700Y-69370500D02*
X104236726Y-69370500D01*
X104236726Y-84229500D02*
X103126700Y-84229500D01*
%TO.C,J2*%
X132330000Y-54670000D02*
X132330000Y-102990000D01*
X129670000Y-102990000D02*
X132330000Y-102990000D01*
X129670000Y-54670000D02*
X132330000Y-54670000D01*
X132330000Y-52070000D02*
X132330000Y-53400000D01*
X129670000Y-54670000D02*
X129670000Y-102990000D01*
X131000000Y-52070000D02*
X132330000Y-52070000D01*
D12*
%TO.C,S1*%
X106450000Y-103000000D02*
X106450000Y-93000000D01*
X103950000Y-93000000D02*
X103950000Y-103000000D01*
X103950000Y-103000000D02*
X106450000Y-103000000D01*
X106450000Y-93000000D02*
X103950000Y-93000000D01*
D13*
X103450000Y-98000000D02*
G75*
G03*
X103450000Y-98000000I-100000J0D01*
G01*
D11*
%TO.C,J1*%
X111620000Y-102795000D02*
X114280000Y-102795000D01*
X111620000Y-54475000D02*
X114280000Y-54475000D01*
X114280000Y-51875000D02*
X114280000Y-53205000D01*
X112950000Y-51875000D02*
X114280000Y-51875000D01*
X111620000Y-54475000D02*
X111620000Y-102795000D01*
X114280000Y-54475000D02*
X114280000Y-102795000D01*
D12*
%TO.C,S2*%
X104450000Y-61740000D02*
X106950000Y-61740000D01*
X104450000Y-51740000D02*
X104450000Y-61740000D01*
X106950000Y-61740000D02*
X106950000Y-51740000D01*
X106950000Y-51740000D02*
X104450000Y-51740000D01*
D13*
X103950000Y-56740000D02*
G75*
G03*
X103950000Y-56740000I-100000J0D01*
G01*
%TD*%
M02*

View File

@@ -0,0 +1,20 @@
M48
; DRILL file {KiCad 6.0.1-79c1e3a40b~116~ubuntu20.04.1} date Thu 10 Feb 2022 07:45:38 AM CST
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2022-02-10T07:45:38-06:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1
; #@! TF.FileFunction,NonPlated,1,2,NPTH
FMAT,2
INCH
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
T1C0.1260
%
G90
G05
T1
X4.1535Y-1.8346
X4.1654Y-4.2283
X5.3307Y-1.8386
X5.3346Y-4.2244
T0
M30

View File

@@ -0,0 +1,79 @@
M48
; DRILL file {KiCad 6.0.1-79c1e3a40b~116~ubuntu20.04.1} date Thu 10 Feb 2022 07:45:38 AM CST
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2022-02-10T07:45:38-06:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,6.0.1-79c1e3a40b~116~ubuntu20.04.1
; #@! TF.FileFunction,Plated,1,2,PTH
FMAT,2
INCH
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T1C0.0315
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T2C0.0320
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T3C0.0394
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T4C0.0490
%
G90
G05
T1
X4.1417Y-3.7583
X4.1417Y-3.8583
X4.1417Y-3.9583
X4.1614Y-2.1339
X4.1614Y-2.2339
X4.1614Y-2.3339
T2
X4.1496Y-2.8268
X4.1496Y-2.9055
X4.1496Y-2.9843
X4.1496Y-3.063
X4.1496Y-3.1417
X4.1496Y-3.2205
T3
X4.4469Y-2.0947
X4.4469Y-2.1947
X4.4469Y-2.2947
X4.4469Y-2.3947
X4.4469Y-2.4947
X4.4469Y-2.5947
X4.4469Y-2.6947
X4.4469Y-2.7947
X4.4469Y-2.8947
X4.4469Y-2.9947
X4.4469Y-3.0947
X4.4469Y-3.1947
X4.4469Y-3.2947
X4.4469Y-3.3947
X4.4469Y-3.4947
X4.4469Y-3.5947
X4.4469Y-3.6947
X4.4469Y-3.7947
X4.4469Y-3.8947
X4.4469Y-3.9947
X5.1575Y-2.1024
X5.1575Y-2.2024
X5.1575Y-2.3024
X5.1575Y-2.4024
X5.1575Y-2.5024
X5.1575Y-2.6024
X5.1575Y-2.7024
X5.1575Y-2.8024
X5.1575Y-2.9024
X5.1575Y-3.0024
X5.1575Y-3.1024
X5.1575Y-3.2024
X5.1575Y-3.3024
X5.1575Y-3.4024
X5.1575Y-3.5024
X5.1575Y-3.6024
X5.1575Y-3.7024
X5.1575Y-3.8024
X5.1575Y-3.9024
X5.1575Y-4.0024
T4
X4.1496Y-2.7441
X4.1496Y-3.3031
T0
M30

View File

@@ -0,0 +1,125 @@
{
"Header": {
"GenerationSoftware": {
"Vendor": "KiCad",
"Application": "Pcbnew",
"Version": "6.0.1-79c1e3a40b~116~ubuntu20.04.1"
},
"CreationDate": "2022-02-10T07:45:34-06:00"
},
"GeneralSpecs": {
"ProjectId": {
"Name": "pico-ducky",
"GUID": "7069636f-2d64-4756-936b-792e6b696361",
"Revision": "rev?"
},
"Size": {
"X": 37.01,
"Y": 68.12
},
"LayerNumber": 2,
"BoardThickness": 1.6,
"Finish": "None"
},
"DesignRules": [
{
"Layers": "Outer",
"PadToPad": 0.0,
"PadToTrack": 0.0,
"TrackToTrack": 0.2,
"MinLineWidth": 0.25
}
],
"FilesAttributes": [
{
"Path": "pico-ducky-F_Cu.gbr",
"FileFunction": "Copper,L1,Top",
"FilePolarity": "Positive"
},
{
"Path": "pico-ducky-B_Cu.gbr",
"FileFunction": "Copper,L2,Bot",
"FilePolarity": "Positive"
},
{
"Path": "pico-ducky-F_Paste.gbr",
"FileFunction": "SolderPaste,Top",
"FilePolarity": "Positive"
},
{
"Path": "pico-ducky-B_Paste.gbr",
"FileFunction": "SolderPaste,Bot",
"FilePolarity": "Positive"
},
{
"Path": "pico-ducky-F_Silkscreen.gbr",
"FileFunction": "Legend,Top",
"FilePolarity": "Positive"
},
{
"Path": "pico-ducky-B_Silkscreen.gbr",
"FileFunction": "Legend,Bot",
"FilePolarity": "Positive"
},
{
"Path": "pico-ducky-F_Mask.gbr",
"FileFunction": "SolderMask,Top",
"FilePolarity": "Negative"
},
{
"Path": "pico-ducky-B_Mask.gbr",
"FileFunction": "SolderMask,Bot",
"FilePolarity": "Negative"
},
{
"Path": "pico-ducky-Edge_Cuts.gbr",
"FileFunction": "Profile",
"FilePolarity": "Positive"
}
],
"MaterialStackup": [
{
"Type": "Legend",
"Name": "Top Silk Screen"
},
{
"Type": "SolderPaste",
"Name": "Top Solder Paste"
},
{
"Type": "SolderMask",
"Thickness": 0.01,
"Name": "Top Solder Mask"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "F.Cu"
},
{
"Type": "Dielectric",
"Thickness": 1.51,
"Material": "FR4",
"Name": "F.Cu/B.Cu",
"Notes": "Type: dielectric layer 1 (from F.Cu to B.Cu)"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "B.Cu"
},
{
"Type": "SolderMask",
"Thickness": 0.01,
"Name": "Bottom Solder Mask"
},
{
"Type": "SolderPaste",
"Name": "Bottom Solder Paste"
},
{
"Type": "Legend",
"Name": "Bottom Silk Screen"
}
]
}

View File

@@ -0,0 +1,578 @@
(kicad_pcb (version 20211014) (generator pcbnew)
(general
(thickness 1.6)
)
(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)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(disableapertmacros false)
(usegerberextensions false)
(usegerberattributes true)
(usegerberadvancedattributes true)
(creategerberjobfile true)
(svguseinch false)
(svgprecision 6)
(excludeedgelayer true)
(plotframeref false)
(viasonmask false)
(mode 1)
(useauxorigin false)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(dxfpolygonmode true)
(dxfimperialunits true)
(dxfusepcbnewfont true)
(psnegative false)
(psa4output false)
(plotreference true)
(plotvalue true)
(plotinvisibletext false)
(sketchpadsonfab false)
(subtractmaskfromsilk false)
(outputformat 1)
(mirror false)
(drillshape 0)
(scaleselection 1)
(outputdirectory "cad/")
)
)
(net 0 "")
(net 1 "unconnected-(J1-Pad2)")
(net 2 "unconnected-(J1-Pad4)")
(net 3 "unconnected-(J1-Pad5)")
(net 4 "unconnected-(J1-Pad9)")
(net 5 "unconnected-(J1-Pad10)")
(net 6 "unconnected-(J1-Pad11)")
(net 7 "unconnected-(J1-Pad12)")
(net 8 "unconnected-(J1-Pad16)")
(net 9 "unconnected-(J1-Pad17)")
(net 10 "unconnected-(J1-Pad19)")
(net 11 "unconnected-(J2-Pad1)")
(net 12 "unconnected-(J2-Pad2)")
(net 13 "unconnected-(J2-Pad3)")
(net 14 "unconnected-(J2-Pad4)")
(net 15 "unconnected-(J2-Pad5)")
(net 16 "unconnected-(J2-Pad6)")
(net 17 "unconnected-(J2-Pad7)")
(net 18 "unconnected-(J2-Pad8)")
(net 19 "unconnected-(J2-Pad9)")
(net 20 "unconnected-(J2-Pad10)")
(net 21 "unconnected-(J2-Pad11)")
(net 22 "unconnected-(J2-Pad12)")
(net 23 "unconnected-(J2-Pad13)")
(net 24 "unconnected-(J2-Pad14)")
(net 25 "unconnected-(J2-Pad15)")
(net 26 "unconnected-(J2-Pad16)")
(net 27 "unconnected-(J2-Pad17)")
(net 28 "unconnected-(J2-Pad18)")
(net 29 "unconnected-(J2-Pad19)")
(net 30 "unconnected-(J2-Pad20)")
(net 31 "Net-(J1-Pad3)")
(net 32 "Net-(J1-Pad6)")
(net 33 "Net-(J1-Pad7)")
(net 34 "Net-(J1-Pad14)")
(net 35 "Net-(J1-Pad15)")
(net 36 "Net-(J1-Pad18)")
(net 37 "Net-(J1-Pad20)")
(net 38 "Net-(J1-Pad8)")
(net 39 "Net-(J1-Pad13)")
(net 40 "Net-(J1-Pad1)")
(net 41 "unconnected-(S1-Pad2)")
(net 42 "unconnected-(S2-Pad3)")
(footprint "Connector_PinSocket_2.54mm:PinSocket_1x20_P2.54mm_Vertical" (layer "F.Cu")
(tedit 5A19A41E) (tstamp 31e895e5-7b36-4827-b794-b5b947f2801b)
(at 131 53.4)
(descr "Through hole straight socket strip, 1x20, 2.54mm pitch, single row (from Kicad 4.0.7), script generated")
(tags "Through hole socket strip THT 1x20 2.54mm single row")
(property "Sheetfile" "pico-ducky.kicad_sch")
(property "Sheetname" "")
(path "/60ef5d45-ab54-4614-8417-f29731f193e9")
(attr through_hole)
(fp_text reference "J2" (at 0 -2.77) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 13666891-0874-46d5-8b1f-5f8a3d2e3667)
)
(fp_text value "Conn_01x20_Female" (at 0 51.03) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 826e5a92-f4a7-481c-a810-e691fb4242fa)
)
(fp_text user "${REFERENCE}" (at 0 24.13 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp faaede8c-2aeb-4f9f-951c-9e98aefd8353)
)
(fp_line (start 1.33 1.27) (end 1.33 49.59) (layer "F.SilkS") (width 0.12) (tstamp 73d985f0-c578-40ca-ab9b-537d56fc30c2))
(fp_line (start -1.33 49.59) (end 1.33 49.59) (layer "F.SilkS") (width 0.12) (tstamp 8edc9dab-270b-46ce-86c7-43d2ea9d2561))
(fp_line (start -1.33 1.27) (end 1.33 1.27) (layer "F.SilkS") (width 0.12) (tstamp 906e14b4-a894-4fb8-92ce-dc27c4d28378))
(fp_line (start 1.33 -1.33) (end 1.33 0) (layer "F.SilkS") (width 0.12) (tstamp a9c07e71-f8a5-403b-8e00-562e3cd133e0))
(fp_line (start -1.33 1.27) (end -1.33 49.59) (layer "F.SilkS") (width 0.12) (tstamp ac998646-16d3-4146-971c-4cb50e1f3fdb))
(fp_line (start 0 -1.33) (end 1.33 -1.33) (layer "F.SilkS") (width 0.12) (tstamp b55ffde1-3db6-44e1-8a25-d5de2cc37fea))
(fp_line (start 1.75 50) (end -1.8 50) (layer "F.CrtYd") (width 0.05) (tstamp 2622f595-7ff0-453e-9b78-19125b1110e8))
(fp_line (start -1.8 -1.8) (end 1.75 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 7bb67499-9a91-41e1-afe8-7eef34869d71))
(fp_line (start -1.8 50) (end -1.8 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 7bfd21eb-4ee9-42ce-8900-a93d825953d0))
(fp_line (start 1.75 -1.8) (end 1.75 50) (layer "F.CrtYd") (width 0.05) (tstamp 900716a9-2103-4663-a7b4-094a39ecb871))
(fp_line (start 1.27 49.53) (end -1.27 49.53) (layer "F.Fab") (width 0.1) (tstamp 071715f0-4a79-4e1a-8718-9cffdd92cf95))
(fp_line (start 1.27 -0.635) (end 1.27 49.53) (layer "F.Fab") (width 0.1) (tstamp 18f447e2-259c-4c3c-b887-9d9c6df88167))
(fp_line (start -1.27 49.53) (end -1.27 -1.27) (layer "F.Fab") (width 0.1) (tstamp 2e306457-a203-45bd-8828-39a6fc7884b5))
(fp_line (start -1.27 -1.27) (end 0.635 -1.27) (layer "F.Fab") (width 0.1) (tstamp 46aecb8d-9ecb-45b1-85b3-c48114c449a4))
(fp_line (start 0.635 -1.27) (end 1.27 -0.635) (layer "F.Fab") (width 0.1) (tstamp c587cddf-70f7-45f9-a743-257eda0ecb2b))
(pad "1" thru_hole rect locked (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 11 "unconnected-(J2-Pad1)") (pinfunction "Pin_1") (pintype "passive") (tstamp 133696af-8bcb-4f2a-918a-966f6f31bafd))
(pad "2" thru_hole oval locked (at 0 2.54) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 12 "unconnected-(J2-Pad2)") (pinfunction "Pin_2") (pintype "passive") (tstamp 9b86eb10-9f20-4c99-95e9-2380fe3f9b14))
(pad "3" thru_hole oval locked (at 0 5.08) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 13 "unconnected-(J2-Pad3)") (pinfunction "Pin_3") (pintype "passive") (tstamp 1dd65e06-1b19-42b2-9e48-aa593ac50db3))
(pad "4" thru_hole oval locked (at 0 7.62) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 14 "unconnected-(J2-Pad4)") (pinfunction "Pin_4") (pintype "passive") (tstamp 9a2a4879-e6b7-4350-b86b-5104d34e2a80))
(pad "5" thru_hole oval locked (at 0 10.16) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 15 "unconnected-(J2-Pad5)") (pinfunction "Pin_5") (pintype "passive") (tstamp a49a4d82-48bd-42b8-95c9-1c983664fc79))
(pad "6" thru_hole oval locked (at 0 12.7) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 16 "unconnected-(J2-Pad6)") (pinfunction "Pin_6") (pintype "passive") (tstamp 1d44b2aa-9869-4de8-b803-3ac1829b85dc))
(pad "7" thru_hole oval locked (at 0 15.24) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 17 "unconnected-(J2-Pad7)") (pinfunction "Pin_7") (pintype "passive") (tstamp fd35caac-7fa3-4ae4-adc7-7771f7f34b82))
(pad "8" thru_hole oval locked (at 0 17.78) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 18 "unconnected-(J2-Pad8)") (pinfunction "Pin_8") (pintype "passive") (tstamp a23fda0c-76b9-4947-9d26-721683d9824c))
(pad "9" thru_hole oval locked (at 0 20.32) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 19 "unconnected-(J2-Pad9)") (pinfunction "Pin_9") (pintype "passive") (tstamp 3634acc5-1d40-409a-b593-f224d9318583))
(pad "10" thru_hole oval locked (at 0 22.86) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 20 "unconnected-(J2-Pad10)") (pinfunction "Pin_10") (pintype "passive") (tstamp f5b3ac78-e150-4b32-bc84-9d75c87fb341))
(pad "11" thru_hole oval locked (at 0 25.4) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 21 "unconnected-(J2-Pad11)") (pinfunction "Pin_11") (pintype "passive") (tstamp 2f21e29d-624e-4cb4-9a3c-1a75369755aa))
(pad "12" thru_hole oval locked (at 0 27.94) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 22 "unconnected-(J2-Pad12)") (pinfunction "Pin_12") (pintype "passive") (tstamp 95ec8c15-617f-40e1-a3f7-7e9eb27d7908))
(pad "13" thru_hole oval locked (at 0 30.48) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 23 "unconnected-(J2-Pad13)") (pinfunction "Pin_13") (pintype "passive") (tstamp 325a060a-bb55-4a28-b469-3ff109457870))
(pad "14" thru_hole oval locked (at 0 33.02) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 24 "unconnected-(J2-Pad14)") (pinfunction "Pin_14") (pintype "passive") (tstamp d0064f4c-eaa8-4fc1-8c95-5edfe18ce9e5))
(pad "15" thru_hole oval locked (at 0 35.56) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 25 "unconnected-(J2-Pad15)") (pinfunction "Pin_15") (pintype "passive") (tstamp 4a7017bb-a698-433b-a0be-587786fcc0bb))
(pad "16" thru_hole oval locked (at 0 38.1) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 26 "unconnected-(J2-Pad16)") (pinfunction "Pin_16") (pintype "passive") (tstamp 6d65a827-125f-4e46-bf64-3cc60fd414e5))
(pad "17" thru_hole oval locked (at 0 40.64) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 27 "unconnected-(J2-Pad17)") (pinfunction "Pin_17") (pintype "passive") (tstamp 08522cb4-e044-4d86-a062-8eb79a22f851))
(pad "18" thru_hole oval locked (at 0 43.18) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 28 "unconnected-(J2-Pad18)") (pinfunction "Pin_18") (pintype "passive") (tstamp 66fc6b30-d33c-405d-9170-5e4e3b401c64))
(pad "19" thru_hole oval locked (at 0 45.72) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 29 "unconnected-(J2-Pad19)") (pinfunction "Pin_19") (pintype "passive") (tstamp 8f9a72c7-905a-4381-80e3-5385498e2e49))
(pad "20" thru_hole oval locked (at 0 48.26) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 30 "unconnected-(J2-Pad20)") (pinfunction "Pin_20") (pintype "passive") (tstamp 1b2eb90f-4916-4496-934c-ebfaf59fd7d2))
(model "${KICAD6_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_1x20_P2.54mm_Vertical.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(footprint "MSS-102545-14A-D:SW_MSS-102545-14A-D" (layer "F.Cu")
(tedit 61F6FABF) (tstamp 477892a1-722e-4cda-bb6c-fcdb8ba5f93e)
(at 105.2 98 -90)
(property "MANUFACTURER" "CUI Devices")
(property "MAXIMUM_PACKAGE_HEIGHT" "6.5 mm")
(property "PARTREV" "1.0")
(property "STANDARD" "Manufacturer Recommendations")
(property "Sheetfile" "pico-ducky.kicad_sch")
(property "Sheetname" "")
(path "/6d421685-6187-4a3c-8570-78b8305b32fe")
(attr through_hole)
(fp_text reference "S1" (at -1.825 -2.635 90) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 560d05a7-84e4-403a-80d1-f287a4032b8a)
)
(fp_text value "MSS-102545-14A-D" (at 7.065 2.635 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 2a4111b7-8149-4814-9344-3b8119cd75e4)
)
(fp_line (start 5 -1.25) (end -5 -1.25) (layer "F.SilkS") (width 0.127) (tstamp 66ca01b3-51ff-4294-9b77-4492e98f6aec))
(fp_line (start -5 1.25) (end 5 1.25) (layer "F.SilkS") (width 0.127) (tstamp 9f969b13-1795-4747-8326-93bdc304ed56))
(fp_line (start 5 1.25) (end 5 -1.25) (layer "F.SilkS") (width 0.127) (tstamp b9d4de74-d246-495d-8b63-12ab2133d6d6))
(fp_line (start -5 -1.25) (end -5 1.25) (layer "F.SilkS") (width 0.127) (tstamp fb0bf2a0-d317-42f7-b022-b5e05481f6be))
(fp_circle (center 0 1.85) (end 0.1 1.85) (layer "F.SilkS") (width 0.2) (fill none) (tstamp 0fb27e11-fde6-4a25-adbb-e9684771b369))
(fp_line (start 5.25 -1.5) (end -5.25 -1.5) (layer "F.CrtYd") (width 0.05) (tstamp 0e32af77-726b-4e11-9f99-2e2484ba9e9b))
(fp_line (start -5.25 1.5) (end 5.25 1.5) (layer "F.CrtYd") (width 0.05) (tstamp 152cd84e-bbed-4df5-a866-d1ab977b0966))
(fp_line (start 5.25 1.5) (end 5.25 -1.5) (layer "F.CrtYd") (width 0.05) (tstamp 2ee28fa9-d785-45a1-9a1b-1be02ad8cd0b))
(fp_line (start -5.25 -1.5) (end -5.25 1.5) (layer "F.CrtYd") (width 0.05) (tstamp 8a427111-6480-4b0c-b097-d8b6a0ee1819))
(fp_line (start -5 -1.25) (end -5 1.25) (layer "F.Fab") (width 0.127) (tstamp 022502e0-e724-4b75-bc35-3c5984dbeb76))
(fp_line (start 5 1.25) (end 5 -1.25) (layer "F.Fab") (width 0.127) (tstamp 2eea20e6-112c-411a-b615-885ae773135a))
(fp_line (start 5 -1.25) (end -5 -1.25) (layer "F.Fab") (width 0.127) (tstamp 49fec31e-3712-4229-8142-b191d90a97d0))
(fp_line (start -5 1.25) (end 5 1.25) (layer "F.Fab") (width 0.127) (tstamp d655bb0a-cbf9-4908-ad60-7024ff468fbd))
(fp_circle (center 0 1.85) (end 0.1 1.85) (layer "F.Fab") (width 0.2) (fill none) (tstamp 08ec951f-e7eb-41cf-9589-697107a98e88))
(pad "1" thru_hole rect locked (at 0 0 270) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask)
(net 36 "Net-(J1-Pad18)") (pintype "passive") (tstamp 56d2bc5d-fd72-4542-ab0f-053a5fd60efa))
(pad "2" thru_hole circle locked (at -2.54 0 270) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask)
(net 41 "unconnected-(S1-Pad2)") (pintype "passive") (tstamp 09bbea88-8bd7-48ec-baae-1b4a9a11a40e))
(pad "3" thru_hole circle locked (at 2.54 0 270) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask)
(net 37 "Net-(J1-Pad20)") (pintype "passive") (tstamp 41c18011-40db-4384-9ba4-c0158d0d9d6a))
)
(footprint "SK-14D01-G6:SK-14D01-G 6" (layer "F.Cu")
(tedit 620516C0) (tstamp 8174b4de-74b1-48db-ab8e-c8432251095b)
(at 105.4 71.8 -90)
(property "Sheetfile" "pico-ducky.kicad_sch")
(property "Sheetname" "")
(path "/7c48a97b-1931-421f-af9d-e88a00997ace")
(attr through_hole)
(fp_text reference "SW3" (at 5 -2.1463 90) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 7edc9030-db7b-43ac-a1b3-b87eeacb4c2d)
)
(fp_text value "SK-14D01-G_6" (at 5 -2.1463 90) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 08a7c925-7fae-4530-b0c9-120e185cb318)
)
(fp_text user "*" (at -1 -0.635 90) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 03c52831-5dc5-43c5-a442-8d23643b46fb)
)
(fp_text user "*" (at -1 -0.635 90) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 0b21a65d-d20b-411e-920a-75c343ac5136)
)
(fp_text user "Copyright 2021 Accelerated Designs. All rights reserved." (at 0 0 90) (layer "Cmts.User") hide
(effects (font (size 0.127 0.127) (thickness 0.002)))
(tstamp fe8d9267-7834-48d6-a191-c8724b2ee78d)
)
(fp_text user "*" (at -1 0.635 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 3cd1bda0-18db-417d-b581-a0c50623df68)
)
(fp_text user "*" (at -1 0.635 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp d57dcfee-5058-4fc2-a68b-05f9a48f685b)
)
(fp_line (start 12.4295 2.2733) (end 7.1336 2.2733) (layer "F.SilkS") (width 0.12) (tstamp 1a1ab354-5f85-45f9-938c-9f6c4c8c3ea2))
(fp_line (start -2.4295 -1.163274) (end -2.4295 -2.2733) (layer "F.SilkS") (width 0.12) (tstamp 2d210a96-f81f-42a9-8bf4-1b43c11086f3))
(fp_line (start 4.873 2.2733) (end -2.4295 2.2733) (layer "F.SilkS") (width 0.12) (tstamp 4c8eb964-bdf4-44de-90e9-e2ab82dd5313))
(fp_line (start 12.4295 -2.2733) (end 12.4295 -1.163274) (layer "F.SilkS") (width 0.12) (tstamp 7aed3a71-054b-4aaa-9c0a-030523c32827))
(fp_line (start -2.4295 -2.2733) (end 12.4295 -2.2733) (layer "F.SilkS") (width 0.12) (tstamp 9bb20359-0f8b-45bc-9d38-6626ed3a939d))
(fp_line (start -2.4295 2.2733) (end -2.4295 1.163274) (layer "F.SilkS") (width 0.12) (tstamp aa14c3bd-4acc-4908-9d28-228585a22a9d))
(fp_line (start 12.4295 1.163274) (end 12.4295 2.2733) (layer "F.SilkS") (width 0.12) (tstamp e857610b-4434-4144-b04e-43c1ebdc5ceb))
(fp_line (start 7.2606 8.3947) (end 7.2606 2.4003) (layer "F.CrtYd") (width 0.05) (tstamp 0f54db53-a272-4955-88fb-d7ab00657bb0))
(fp_line (start -2.5565 -1.1303) (end -3.2303 -1.1303) (layer "F.CrtYd") (width 0.05) (tstamp 2d6db888-4e40-41c8-b701-07170fc894bc))
(fp_line (start 13.2303 -1.1303) (end 12.5565 -1.1303) (layer "F.CrtYd") (width 0.05) (tstamp 31e08896-1992-4725-96d9-9d2728bca7a3))
(fp_line (start -2.5565 1.1303) (end -2.5565 2.4003) (layer "F.CrtYd") (width 0.05) (tstamp 3aaee4c4-dbf7-49a5-a620-9465d8cc3ae7))
(fp_line (start -3.2303 1.1303) (end -2.5565 1.1303) (layer "F.CrtYd") (width 0.05) (tstamp 5528bcad-2950-4673-90eb-c37e6952c475))
(fp_line (start 13.2303 1.1303) (end 13.2303 -1.1303) (layer "F.CrtYd") (width 0.05) (tstamp 6441b183-b8f2-458f-a23d-60e2b1f66dd6))
(fp_line (start -2.5565 -2.4003) (end -2.5565 -1.1303) (layer "F.CrtYd") (width 0.05) (tstamp 66043bca-a260-4915-9fce-8a51d324c687))
(fp_line (start -3.2303 -1.1303) (end -3.2303 1.1303) (layer "F.CrtYd") (width 0.05) (tstamp 7bbf981c-a063-4e30-8911-e4228e1c0743))
(fp_line (start 7.2606 2.4003) (end 12.5565 2.4003) (layer "F.CrtYd") (width 0.05) (tstamp 80094b70-85ab-4ff6-934b-60d5ee65023a))
(fp_line (start 12.5565 -2.4003) (end -2.5565 -2.4003) (layer "F.CrtYd") (width 0.05) (tstamp 852dabbf-de45-4470-8176-59d37a754407))
(fp_line (start 4.746 8.3947) (end 7.2606 8.3947) (layer "F.CrtYd") (width 0.05) (tstamp 922058ca-d09a-45fd-8394-05f3e2c1e03a))
(fp_line (start 4.746 2.4003) (end 4.746 8.3947) (layer "F.CrtYd") (width 0.05) (tstamp 97fe9c60-586f-4895-8504-4d3729f5f81a))
(fp_line (start 12.5565 -1.1303) (end 12.5565 -2.4003) (layer "F.CrtYd") (width 0.05) (tstamp b5352a33-563a-4ffe-a231-2e68fb54afa3))
(fp_line (start -2.5565 2.4003) (end 4.746 2.4003) (layer "F.CrtYd") (width 0.05) (tstamp bdc7face-9f7c-4701-80bb-4cc144448db1))
(fp_line (start 12.5565 1.1303) (end 13.2303 1.1303) (layer "F.CrtYd") (width 0.05) (tstamp bfc0aadc-38cf-466e-a642-68fdc3138c78))
(fp_line (start 12.5565 2.4003) (end 12.5565 1.1303) (layer "F.CrtYd") (width 0.05) (tstamp d4a1d3c4-b315-4bec-9220-d12a9eab51e0))
(fp_line (start 5 2.1463) (end 5 8.1407) (layer "F.Fab") (width 0.1) (tstamp 29e78086-2175-405e-9ba3-c48766d2f50c))
(fp_line (start 12.3025 -2.1463) (end 12.3025 2.1463) (layer "F.Fab") (width 0.1) (tstamp 666713b0-70f4-42df-8761-f65bc212d03b))
(fp_line (start -2.3025 -2.1463) (end 12.3025 -2.1463) (layer "F.Fab") (width 0.1) (tstamp 6c2e273e-743c-4f1e-a647-4171f8122550))
(fp_line (start 12.3025 2.1463) (end -2.3025 2.1463) (layer "F.Fab") (width 0.1) (tstamp 7dc880bc-e7eb-4cce-8d8c-0b65a9dd788e))
(fp_line (start -2.3025 2.1463) (end -2.3025 -2.1463) (layer "F.Fab") (width 0.1) (tstamp 9157f4ae-0244-4ff1-9f73-3cb4cbb5f280))
(fp_line (start 5 8.1407) (end 7.0066 8.1407) (layer "F.Fab") (width 0.1) (tstamp 94a873dc-af67-4ef9-8159-1f7c93eeb3d7))
(fp_line (start 7.0066 2.1463) (end 7.0066 8.1407) (layer "F.Fab") (width 0.1) (tstamp a1823eb2-fb0d-4ed8-8b96-04184ac3a9d5))
(pad "1" thru_hole circle (at 0 0 270) (size 1.3208 1.3208) (drill 0.8128) (layers *.Cu *.Mask)
(net 32 "Net-(J1-Pad6)") (pinfunction "1") (pintype "unspecified") (tstamp 704d6d51-bb34-4cbf-83d8-841e208048d8))
(pad "2" thru_hole circle (at 2.000001 0 270) (size 1.3208 1.3208) (drill 0.8128) (layers *.Cu *.Mask)
(net 33 "Net-(J1-Pad7)") (pinfunction "2") (pintype "unspecified") (tstamp 0eaa98f0-9565-4637-ace3-42a5231b07f7))
(pad "3" thru_hole circle (at 4 0 270) (size 1.3208 1.3208) (drill 0.8128) (layers *.Cu *.Mask)
(net 38 "Net-(J1-Pad8)") (pinfunction "3") (pintype "unspecified") (tstamp 181abe7a-f941-42b6-bd46-aaa3131f90fb))
(pad "4" thru_hole circle (at 6.000001 0 270) (size 1.3208 1.3208) (drill 0.8128) (layers *.Cu *.Mask)
(net 39 "Net-(J1-Pad13)") (pinfunction "4") (pintype "unspecified") (tstamp ce83728b-bebd-48c2-8734-b6a50d837931))
(pad "5" thru_hole circle (at 7.999999 0 270) (size 1.3208 1.3208) (drill 0.8128) (layers *.Cu *.Mask)
(net 34 "Net-(J1-Pad14)") (pinfunction "5") (pintype "unspecified") (tstamp c41b3c8b-634e-435a-b582-96b83bbd4032))
(pad "6" thru_hole circle (at 10 0 270) (size 1.3208 1.3208) (drill 0.8128) (layers *.Cu *.Mask)
(net 35 "Net-(J1-Pad15)") (pinfunction "6") (pintype "unspecified") (tstamp 9340c285-5767-42d5-8b6d-63fe2a40ddf3))
(pad "7" thru_hole circle (at -2.1 0 270) (size 1.7526 1.7526) (drill 1.2446) (layers *.Cu *.Mask) (tstamp 1831fb37-1c5d-42c4-b898-151be6fca9dc))
(pad "8" thru_hole circle (at 12.1 0 270) (size 1.7526 1.7526) (drill 1.2446) (layers *.Cu *.Mask) (tstamp 0f22151c-f260-4674-b486-4710a2c42a55))
)
(footprint "MountingHole:MountingHole_3.2mm_M3" (layer "F.Cu")
(tedit 56D1B4CB) (tstamp 981ff4de-0330-4757-b746-0cb983df5e7c)
(at 105.5 46.6)
(descr "Mounting Hole 3.2mm, no annular, M3")
(tags "mounting hole 3.2mm no annular m3")
(attr exclude_from_pos_files exclude_from_bom)
(fp_text reference "REF**" (at 0 -4.2) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 9505be36-b21c-4db8-9484-dd0861395d26)
)
(fp_text value "MountingHole_3.2mm_M3" (at 0 4.2) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 49d97c73-e37a-4154-9d0a-88037e40cc11)
)
(fp_text user "${REFERENCE}" (at 0.3 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 7943ed8c-e760-4ace-9c5f-baf5589fae39)
)
(fp_circle (center 0 0) (end 3.2 0) (layer "Cmts.User") (width 0.15) (fill none) (tstamp 59e09498-d26e-4ba7-b47d-fece2ea7c274))
(fp_circle (center 0 0) (end 3.45 0) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp ea4f0afc-785b-40cf-8ef1-cbe20404c18b))
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (drill 3.2) (layers *.Cu *.Mask) (tstamp fead07ab-5a70-40db-ada8-c72dcc827bfc))
)
(footprint "Connector_PinSocket_2.54mm:PinSocket_1x20_P2.54mm_Vertical" (layer "F.Cu")
(tedit 5A19A41E) (tstamp a0db2c5f-7239-49ae-ba47-437c621e7ff8)
(at 112.95 53.205)
(descr "Through hole straight socket strip, 1x20, 2.54mm pitch, single row (from Kicad 4.0.7), script generated")
(tags "Through hole socket strip THT 1x20 2.54mm single row")
(property "Sheetfile" "pico-ducky.kicad_sch")
(property "Sheetname" "")
(path "/5493e8cd-8323-4518-b41a-1736b1fae7d0")
(attr through_hole)
(fp_text reference "J1" (at 0 -2.77) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 5e597a99-b966-40ca-93cf-60af0be59632)
)
(fp_text value "Conn_01x20_Female" (at 0 51.03) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 62785fc4-216d-4983-9ac2-0f8d21d68772)
)
(fp_text user "${REFERENCE}" (at 0 24.13 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 76011dd7-642b-438a-bb90-b324383a7851)
)
(fp_line (start -1.33 49.59) (end 1.33 49.59) (layer "F.SilkS") (width 0.12) (tstamp 016969ab-09a8-471c-ace6-1bdaa379b509))
(fp_line (start -1.33 1.27) (end 1.33 1.27) (layer "F.SilkS") (width 0.12) (tstamp 05f453e1-e6ac-4725-ac6f-c737cb237871))
(fp_line (start 1.33 -1.33) (end 1.33 0) (layer "F.SilkS") (width 0.12) (tstamp d539fbf6-d474-41de-bda0-19ba022ca66a))
(fp_line (start 0 -1.33) (end 1.33 -1.33) (layer "F.SilkS") (width 0.12) (tstamp df232253-71d7-4d83-a4f3-12da054a77bd))
(fp_line (start -1.33 1.27) (end -1.33 49.59) (layer "F.SilkS") (width 0.12) (tstamp ec54d593-d947-40d5-9ce4-01090f07d42f))
(fp_line (start 1.33 1.27) (end 1.33 49.59) (layer "F.SilkS") (width 0.12) (tstamp f12847bd-98ae-41f9-b585-95021b3ae723))
(fp_line (start -1.8 50) (end -1.8 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 070365ef-242a-4d41-bc0a-b8ed9b91feca))
(fp_line (start -1.8 -1.8) (end 1.75 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 40950b1d-ca89-4396-b2fc-a613e266e57c))
(fp_line (start 1.75 -1.8) (end 1.75 50) (layer "F.CrtYd") (width 0.05) (tstamp be6525b4-e91c-443a-b608-161699ca5e45))
(fp_line (start 1.75 50) (end -1.8 50) (layer "F.CrtYd") (width 0.05) (tstamp daf121ec-2c00-4e96-96aa-2bc6f7a0fed5))
(fp_line (start -1.27 49.53) (end -1.27 -1.27) (layer "F.Fab") (width 0.1) (tstamp 181a4764-a462-4b4f-82ec-35df94857db0))
(fp_line (start 1.27 49.53) (end -1.27 49.53) (layer "F.Fab") (width 0.1) (tstamp 44d072f9-64e1-459e-80d1-c82fa5b6cb3e))
(fp_line (start 0.635 -1.27) (end 1.27 -0.635) (layer "F.Fab") (width 0.1) (tstamp 790e6361-4226-4a79-a7b2-5b2ee8aee9e8))
(fp_line (start 1.27 -0.635) (end 1.27 49.53) (layer "F.Fab") (width 0.1) (tstamp ec1f1e1b-be42-4866-9a6b-b89e6e88f2c5))
(fp_line (start -1.27 -1.27) (end 0.635 -1.27) (layer "F.Fab") (width 0.1) (tstamp f891c330-6d8a-4428-9e37-e8db48c0cba9))
(pad "1" thru_hole rect locked (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 40 "Net-(J1-Pad1)") (pinfunction "Pin_1") (pintype "passive") (tstamp feb0929e-d283-4515-ba6d-4fb6ed542932))
(pad "2" thru_hole oval locked (at 0 2.54) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 1 "unconnected-(J1-Pad2)") (pinfunction "Pin_2") (pintype "passive") (tstamp 3febc2fd-da92-4b4c-94c6-7e9024943f53))
(pad "3" thru_hole oval locked (at 0 5.08) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 31 "Net-(J1-Pad3)") (pinfunction "Pin_3") (pintype "passive") (tstamp 2a4b2c44-d6a9-4780-82b0-ca745511a184))
(pad "4" thru_hole oval locked (at 0 7.62) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 2 "unconnected-(J1-Pad4)") (pinfunction "Pin_4") (pintype "passive") (tstamp 629d43c1-9248-4504-bcc8-0325e1994502))
(pad "5" thru_hole oval locked (at 0 10.16) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 3 "unconnected-(J1-Pad5)") (pinfunction "Pin_5") (pintype "passive") (tstamp 71c421cf-b82d-4b3a-b6f7-ad75b4b97b86))
(pad "6" thru_hole oval locked (at 0 12.7) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 32 "Net-(J1-Pad6)") (pinfunction "Pin_6") (pintype "passive") (tstamp 121a20b0-ed40-482c-8ad3-5ff84667baa9))
(pad "7" thru_hole oval locked (at 0 15.24) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 33 "Net-(J1-Pad7)") (pinfunction "Pin_7") (pintype "passive") (tstamp 39dfcc95-5a6d-4987-a05e-ce056d625d10))
(pad "8" thru_hole oval locked (at 0 17.78) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 38 "Net-(J1-Pad8)") (pinfunction "Pin_8") (pintype "passive") (tstamp b0896365-9965-4303-b601-ab1270a33206))
(pad "9" thru_hole oval locked (at 0 20.32) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 4 "unconnected-(J1-Pad9)") (pinfunction "Pin_9") (pintype "passive") (tstamp fcb90f38-f221-4e19-8961-a534ced69fbc))
(pad "10" thru_hole oval locked (at 0 22.86) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 5 "unconnected-(J1-Pad10)") (pinfunction "Pin_10") (pintype "passive") (tstamp c54eec57-39ef-41e4-bbaf-4eee6a3ff4b2))
(pad "11" thru_hole oval locked (at 0 25.4) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 6 "unconnected-(J1-Pad11)") (pinfunction "Pin_11") (pintype "passive") (tstamp 1576d8d0-12c8-4054-834f-2c4176251961))
(pad "12" thru_hole oval locked (at 0 27.94) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 7 "unconnected-(J1-Pad12)") (pinfunction "Pin_12") (pintype "passive") (tstamp 02eee15d-cf8f-4967-9a10-3f1e76e39294))
(pad "13" thru_hole oval locked (at 0 30.48) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 39 "Net-(J1-Pad13)") (pinfunction "Pin_13") (pintype "passive") (tstamp a96926a0-932a-4907-aecc-0b46506674fc))
(pad "14" thru_hole oval locked (at 0 33.02) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 34 "Net-(J1-Pad14)") (pinfunction "Pin_14") (pintype "passive") (tstamp 97550abf-a4e2-491b-8c4b-fc5bcb83e111))
(pad "15" thru_hole oval locked (at 0 35.56) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 35 "Net-(J1-Pad15)") (pinfunction "Pin_15") (pintype "passive") (tstamp c85a30cd-7820-4060-a4c2-50ec142d23a1))
(pad "16" thru_hole oval locked (at 0 38.1) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 8 "unconnected-(J1-Pad16)") (pinfunction "Pin_16") (pintype "passive") (tstamp f68d080c-0841-4795-a272-fd003222b937))
(pad "17" thru_hole oval locked (at 0 40.64) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 9 "unconnected-(J1-Pad17)") (pinfunction "Pin_17") (pintype "passive") (tstamp bd8df187-444b-4819-a289-8ba5ff2e46b6))
(pad "18" thru_hole oval locked (at 0 43.18) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 36 "Net-(J1-Pad18)") (pinfunction "Pin_18") (pintype "passive") (tstamp c39baa4e-3aa1-4edc-bd10-b789a33040d0))
(pad "19" thru_hole oval locked (at 0 45.72) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 10 "unconnected-(J1-Pad19)") (pinfunction "Pin_19") (pintype "passive") (tstamp f5435e42-c1ee-4a96-ab1d-cf405c5546eb))
(pad "20" thru_hole oval locked (at 0 48.26) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask)
(net 37 "Net-(J1-Pad20)") (pinfunction "Pin_20") (pintype "passive") (tstamp b65f6395-d469-4afb-9d3b-bc71d62896fd))
(model "${KICAD6_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_1x20_P2.54mm_Vertical.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(footprint "MSS-102545-14A-D:SW_MSS-102545-14A-D" (layer "F.Cu")
(tedit 61F6FABF) (tstamp ae77c3c8-1144-468e-ad5b-a0b4090735bd)
(at 105.7 56.74 -90)
(property "MANUFACTURER" "CUI Devices")
(property "MAXIMUM_PACKAGE_HEIGHT" "6.5 mm")
(property "PARTREV" "1.0")
(property "STANDARD" "Manufacturer Recommendations")
(property "Sheetfile" "pico-ducky.kicad_sch")
(property "Sheetname" "")
(path "/100847e3-630c-4c13-ba45-180e92370805")
(attr through_hole)
(fp_text reference "S2" (at -1.825 -2.635 90) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 49a65079-57a9-46fc-8711-1d7f2cab8dbf)
)
(fp_text value "MSS-102545-14A-D" (at 7.065 2.635 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 87ba184f-bff5-4989-8217-6af375cc3dd8)
)
(fp_line (start 5 1.25) (end 5 -1.25) (layer "F.SilkS") (width 0.127) (tstamp 25c663ff-96b6-4263-a06e-d1829409cf73))
(fp_line (start -5 1.25) (end 5 1.25) (layer "F.SilkS") (width 0.127) (tstamp 34ce7009-187e-4541-a14e-708b3a2903d9))
(fp_line (start 5 -1.25) (end -5 -1.25) (layer "F.SilkS") (width 0.127) (tstamp 637e9edf-ffed-49a2-8408-fa110c9a4c79))
(fp_line (start -5 -1.25) (end -5 1.25) (layer "F.SilkS") (width 0.127) (tstamp b456cffc-d9d7-4c91-91f2-36ec9a65dd1b))
(fp_circle (center 0 1.85) (end 0.1 1.85) (layer "F.SilkS") (width 0.2) (fill none) (tstamp aa8663be-9516-4b07-84d2-4c4d668b8596))
(fp_line (start -5.25 1.5) (end 5.25 1.5) (layer "F.CrtYd") (width 0.05) (tstamp 291935ec-f8ff-41f0-8717-e68b8af7b8c1))
(fp_line (start 5.25 -1.5) (end -5.25 -1.5) (layer "F.CrtYd") (width 0.05) (tstamp 35fb7c56-dc85-43f7-b954-81b8040a8500))
(fp_line (start 5.25 1.5) (end 5.25 -1.5) (layer "F.CrtYd") (width 0.05) (tstamp 4e677390-a246-4ca0-954c-746e0870f88f))
(fp_line (start -5.25 -1.5) (end -5.25 1.5) (layer "F.CrtYd") (width 0.05) (tstamp 73ee7e03-97a8-4121-b568-c25f3934a935))
(fp_line (start 5 -1.25) (end -5 -1.25) (layer "F.Fab") (width 0.127) (tstamp 1a22eb2d-f625-4371-a918-ff1b97dc8219))
(fp_line (start 5 1.25) (end 5 -1.25) (layer "F.Fab") (width 0.127) (tstamp 6ff9bb63-d6fd-4e32-bb60-7ac65509c2e9))
(fp_line (start -5 1.25) (end 5 1.25) (layer "F.Fab") (width 0.127) (tstamp d767f2ff-12ec-4778-96cb-3fdd7a473d60))
(fp_line (start -5 -1.25) (end -5 1.25) (layer "F.Fab") (width 0.127) (tstamp f674b8e7-203d-419e-988a-58e0f9ae4fad))
(fp_circle (center 0 1.85) (end 0.1 1.85) (layer "F.Fab") (width 0.2) (fill none) (tstamp dfcef016-1bf5-4158-8a79-72d38a522877))
(pad "1" thru_hole rect locked (at 0 0 270) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask)
(net 31 "Net-(J1-Pad3)") (pintype "passive") (tstamp 9fdca5c2-1fbd-4774-a9c3-8795a40c206d))
(pad "2" thru_hole circle locked (at -2.54 0 270) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask)
(net 40 "Net-(J1-Pad1)") (pintype "passive") (tstamp a0d52767-051a-423c-a600-928281f27952))
(pad "3" thru_hole circle locked (at 2.54 0 270) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask)
(net 42 "unconnected-(S2-Pad3)") (pintype "passive") (tstamp 178ae27e-edb9-4ffb-bd13-c0a6dd659606))
)
(footprint "MountingHole:MountingHole_3.2mm_M3" (layer "F.Cu")
(tedit 56D1B4CB) (tstamp caa42d03-8d73-4d57-b233-e69949da956a)
(at 135.4 46.7)
(descr "Mounting Hole 3.2mm, no annular, M3")
(tags "mounting hole 3.2mm no annular m3")
(attr exclude_from_pos_files exclude_from_bom)
(fp_text reference "REF**" (at 0 -4.2) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp c76d4423-ef1b-4a6f-8176-33d65f2877bb)
)
(fp_text value "MountingHole_3.2mm_M3" (at 0 4.2) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp f7667b23-296e-4362-a7e3-949632c8954b)
)
(fp_text user "${REFERENCE}" (at 0.3 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp b873bc5d-a9af-4bd9-afcb-87ce4d417120)
)
(fp_circle (center 0 0) (end 3.2 0) (layer "Cmts.User") (width 0.15) (fill none) (tstamp 03c7f780-fc1b-487a-b30d-567d6c09fdc8))
(fp_circle (center 0 0) (end 3.45 0) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp c04386e0-b49e-4fff-b380-675af13a62cb))
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (drill 3.2) (layers *.Cu *.Mask) (tstamp 700e8b73-5976-423f-a3f3-ab3d9f3e9760))
)
(footprint "MountingHole:MountingHole_3.2mm_M3" (layer "F.Cu")
(tedit 56D1B4CB) (tstamp e5659af8-1b07-414b-b4ba-77ce52c44317)
(at 135.5 107.3)
(descr "Mounting Hole 3.2mm, no annular, M3")
(tags "mounting hole 3.2mm no annular m3")
(attr exclude_from_pos_files exclude_from_bom)
(fp_text reference "REF**" (at 0 -4.2) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp b9bb0e73-161a-4d06-b6eb-a9f66d8a95f5)
)
(fp_text value "MountingHole_3.2mm_M3" (at 0 4.2) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 4107d40a-e5df-4255-aacc-13f9928e090c)
)
(fp_text user "${REFERENCE}" (at 0.3 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 0fdc6f30-77bc-4e9b-8665-c8aa9acf5bf9)
)
(fp_circle (center 0 0) (end 3.2 0) (layer "Cmts.User") (width 0.15) (fill none) (tstamp 0ae82096-0994-4fb0-9a2a-d4ac4804abac))
(fp_circle (center 0 0) (end 3.45 0) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp e0f06b5c-de63-4833-a591-ca9e19217a35))
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (drill 3.2) (layers *.Cu *.Mask) (tstamp b4300db7-1220-431a-b7c3-2edbdf8fa6fc))
)
(footprint "MountingHole:MountingHole_3.2mm_M3" (layer "F.Cu")
(tedit 56D1B4CB) (tstamp ee0468cc-9675-4b75-be39-8b2679523f9a)
(at 105.8 107.4)
(descr "Mounting Hole 3.2mm, no annular, M3")
(tags "mounting hole 3.2mm no annular m3")
(attr exclude_from_pos_files exclude_from_bom)
(fp_text reference "REF**" (at 0 -4.2) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 8195a7cf-4576-44dd-9e0e-ee048fdb93dd)
)
(fp_text value "MountingHole_3.2mm_M3" (at 0 4.2) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp e7bb7815-0d52-4bb8-b29a-8cf960bd2905)
)
(fp_text user "${REFERENCE}" (at 0.3 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp d2d7bea6-0c22-495f-8666-323b30e03150)
)
(fp_circle (center 0 0) (end 3.2 0) (layer "Cmts.User") (width 0.15) (fill none) (tstamp 0f324b67-75ef-407f-8dbc-3c1fc5c2abba))
(fp_circle (center 0 0) (end 3.45 0) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp 1c68b844-c861-46b7-b734-0242168a4220))
(pad "" np_thru_hole circle (at 0 0) (size 3.2 3.2) (drill 3.2) (layers *.Cu *.Mask) (tstamp 79e31048-072a-4a40-a625-26bb0b5f046b))
)
(gr_rect (start 102.12 43.06) (end 139.03 111.08) (layer "Edge.Cuts") (width 0.1) (fill none) (tstamp dbfb14d7-1f97-4dd2-9004-1d129d3b4221))
(segment (start 105.7 56.74) (end 111.405 56.74) (width 0.25) (layer "F.Cu") (net 31) (tstamp 04ad2464-115f-4e51-85ef-62527f6f730f))
(segment (start 111.405 56.74) (end 112.95 58.285) (width 0.25) (layer "F.Cu") (net 31) (tstamp 107eba14-98d9-4afc-9bd1-f9918704065d))
(segment (start 111.295 65.905) (end 112.95 65.905) (width 0.25) (layer "F.Cu") (net 32) (tstamp 50adc7ba-3b83-472b-8dfc-b74684357a6c))
(segment (start 105.4 71.8) (end 111.295 65.905) (width 0.25) (layer "F.Cu") (net 32) (tstamp ed8e419c-3e02-45bc-a398-dfef73bb479d))
(segment (start 107.594999 73.800001) (end 112.95 68.445) (width 0.25) (layer "F.Cu") (net 33) (tstamp 0e5e24d7-3dc5-4e1e-8769-7c7ae1c9e8a6))
(segment (start 105.4 73.800001) (end 107.594999 73.800001) (width 0.25) (layer "F.Cu") (net 33) (tstamp 586ef98a-572a-4c28-8086-49f602b4ce1a))
(segment (start 105.4 79.799999) (end 106.524999 79.799999) (width 0.25) (layer "F.Cu") (net 34) (tstamp 083b2527-e405-49bd-a309-2cdb85cd9a7a))
(segment (start 106.524999 79.799999) (end 112.95 86.225) (width 0.25) (layer "F.Cu") (net 34) (tstamp a4b2ea54-8955-488f-827f-865f41cd460f))
(segment (start 112.365 88.765) (end 112.95 88.765) (width 0.25) (layer "F.Cu") (net 35) (tstamp 550980db-668a-4cd5-b944-6f8f90a64b92))
(segment (start 105.4 81.8) (end 112.365 88.765) (width 0.25) (layer "F.Cu") (net 35) (tstamp 8cb3cc65-5125-4b26-8805-a87acd967839))
(segment (start 111.335 98) (end 112.95 96.385) (width 0.25) (layer "F.Cu") (net 36) (tstamp b11de678-5a1b-4645-977e-d01fbb62650b))
(segment (start 105.2 98) (end 111.335 98) (width 0.25) (layer "F.Cu") (net 36) (tstamp c49e1f14-c2a8-457b-b542-3379c6ba9356))
(segment (start 105.2 100.54) (end 112.025 100.54) (width 0.25) (layer "F.Cu") (net 37) (tstamp 6a66fc9e-c892-4458-921d-87615fa3a44a))
(segment (start 112.025 100.54) (end 112.95 101.465) (width 0.25) (layer "F.Cu") (net 37) (tstamp 9f9df658-76f9-4492-a345-d51805669b23))
(segment (start 105.4 75.8) (end 108.135 75.8) (width 0.25) (layer "F.Cu") (net 38) (tstamp 4aba0570-361a-43a1-8475-4e31d3442aa1))
(segment (start 108.135 75.8) (end 112.95 70.985) (width 0.25) (layer "F.Cu") (net 38) (tstamp ac902824-adcb-4fe8-b2b9-74384e4a02b2))
(segment (start 107.065001 77.800001) (end 112.95 83.685) (width 0.25) (layer "F.Cu") (net 39) (tstamp 14a5d740-983d-4a64-b3ba-76fb523ba838))
(segment (start 105.4 77.800001) (end 107.065001 77.800001) (width 0.25) (layer "F.Cu") (net 39) (tstamp bcf37e83-ac07-479a-9d97-44519b68796f))
(segment (start 106.695 53.205) (end 105.7 54.2) (width 0.25) (layer "F.Cu") (net 40) (tstamp 5c706984-8543-460e-8fea-862f0cc5a54d))
(segment (start 112.95 53.205) (end 106.695 53.205) (width 0.25) (layer "F.Cu") (net 40) (tstamp d6bd5cd5-1aab-4e14-a87e-6b0202d3c68c))
)

View File

@@ -0,0 +1,75 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": true,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "pico-ducky.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@@ -0,0 +1,433 @@
{
"board": {
"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": {
"45_degree_only": false,
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"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_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"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",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 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_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "pico-ducky.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"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.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"9538e4ed-27e6-4c37-b989-9859dc0d49e8",
""
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

31
boot.py
View File

@@ -1,38 +1,13 @@
# License : GPLv2.0
# copyright (c) 2023 Dave Bailey
# Author: Dave Bailey (dbisu, @daveisu)
# Pico and Pico W board support
from board import * from board import *
import board
import digitalio import digitalio
import storage import storage
noStorage = False noStorageStatus = False
noStoragePin = digitalio.DigitalInOut(GP15) noStoragePin = digitalio.DigitalInOut(GP15)
noStoragePin.switch_to_input(pull=digitalio.Pull.UP) noStoragePin.switch_to_input(pull=digitalio.Pull.UP)
noStorageStatus = noStoragePin.value noStorageStatus = not noStoragePin.value
# If GP15 is not connected, it will default to being pulled high (True) if(noStorageStatus == True):
# If GP is connected to GND, it will be low (False)
# Pico:
# GP15 not connected == USB visible
# GP15 connected to GND == USB not visible
# Pico W:
# GP15 not connected == USB NOT visible
# GP15 connected to GND == USB visible
if(board.board_id == 'raspberry_pi_pico' or board.board_id == 'raspberry_pi_pico2'):
# On Pi Pico, default to USB visible
noStorage = not noStorageStatus
elif(board.board_id == 'raspberry_pi_pico_w' or board.board_id == 'raspberry_pi_pico2_w'):
# on Pi Pico W, default to USB hidden by default
# so webapp can access storage
noStorage = noStorageStatus
if(noStorage == True):
# don't show USB drive to host PC # don't show USB drive to host PC
storage.disable_usb_drive() storage.disable_usb_drive()
print("Disabling USB drive") print("Disabling USB drive")

View File

@@ -1,125 +0,0 @@
import os
import shutil
import re
import sys
import zipfile
languages = [ "MAC_FR",
"US_DVO",
"WIN_BR",
"WIN_CZ",
"WIN_CZ1",
"WIN_DA",
"WIN_DE",
"WIN_ES",
"WIN_FR",
"WIN_HU",
"WIN_IT",
"WIN_PO",
"WIN_SW",
"WIN_TR",
"WIN_UK" ]
supported_boards = ["raspberry_pi_pico",
"raspberry_pi_pico_w",
"raspberry_pi_pico2",
"raspberry_pi_pico2_w"]
files_to_bundle = ["boot.py",
"code.py",
"duckyinpython.py",
"wsgiserver.py",
"webapp.py",
"secrets.py",
"payload.dd",
"payload2.dd",
"payload3.dd",
"payload4.dd",
"INSTALL.txt"]
dirs_to_bundle = ["lib"]
def bundle_files_to_zip(source_dir, destination_dir, file_list, target_file, replacement_dict, version):
"""
Bundles files from a source directory into a new directory with a unique name.
Args:
source_dir: Path to the source directory containing the files.
destination_dir: Path to the destination directory where bundles will be created.
file_list: List of filenames to be included in the bundle.
target_file: Filename of the file to be modified.
replacement_dict: Dictionary containing key-value pairs for text replacements.
Returns:
None
"""
if not os.path.exists(destination_dir):
os.makedirs(destination_dir)
# Generate a unique bundle name (e.g., using a timestamp)
bundle_name = f"pico-ducky-{version}-{destination_dir}.zip"
bundle_path = os.path.join(destination_dir, bundle_name)
# Create a temporary directory for the bundle contents
temp_dir = os.path.join(destination_dir, "temp_bundle")
os.makedirs(temp_dir)
for filename in file_list:
source_file = os.path.join(source_dir, filename)
destination_file = os.path.join(temp_dir, filename)
if filename == target_file:
with open(source_file, 'r') as f:
file_content = f.read()
for key, value in replacement_dict.items():
file_content = re.sub(key, value, file_content)
with open(destination_file, 'w') as f:
f.write(file_content)
else:
shutil.copy2(source_file, destination_file)
for dir in dirs_to_bundle:
shutil.copytree(os.path.join(source_dir,dir),os.path.join(temp_dir,dir))
#find uf2 files for supported boards
for root, dirs, files in os.walk(source_dir):
for file in files:
for board in supported_boards:
if '-'+board+'-' in file:
source_file = os.path.join(source_dir, file)
destination_file = os.path.join(temp_dir, file)
shutil.copy2(source_file, destination_file)
# Create the ZIP archive
with zipfile.ZipFile(bundle_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, _, files in os.walk(temp_dir):
for file in files:
file_path = os.path.join(root, file)
archive_path = os.path.relpath(file_path, temp_dir)
zipf.write(file_path, archive_path)
# Remove the temporary directory
shutil.rmtree(temp_dir)
def main(argv):
version = argv[0]
for dest_dir in languages:
source_directory = "US"
target_file_to_modify = "duckyinpython.py"
replacements = {
"#from keyboard_layout_win_LANG": "from keyboard_layout_"+dest_dir.lower(),
"#from keycode_win_LANG": "from keycode_"+dest_dir.lower(),
"from adafruit_hid.keyboard_": "#from adafruit_hid.keyboard_",
"from adafruit_hid.keycode": "#from adafruit_hid.keycode"
}
bundle_files_to_zip(source_directory, dest_dir, files_to_bundle,
target_file_to_modify, replacements, version)
if __name__ == "__main__":
main(sys.argv[1:])

82
code.py
View File

@@ -1,82 +0,0 @@
# License : GPLv2.0
# copyright (c) 2023 Dave Bailey
# Author: Dave Bailey (dbisu, @daveisu)
# Pico and Pico W board support
import supervisor
import time
import digitalio
from board import *
import board
from duckyinpython import *
if(board.board_id == 'raspberry_pi_pico_w' or board.board_id == 'raspberry_pi_pico2_w'):
import wifi
from webapp import *
# sleep at the start to allow the device to be recognized by the host computer
time.sleep(.5)
def startWiFi():
import ipaddress
# Get wifi details and more from a secrets.py file
try:
from secrets import secrets
except ImportError:
print("WiFi secrets are kept in secrets.py, please add them there!")
raise
print("Connect wifi")
#wifi.radio.connect(secrets['ssid'],secrets['password'])
wifi.radio.start_ap(secrets['ssid'],secrets['password'])
HOST = repr(wifi.radio.ipv4_address_ap)
PORT = 80 # Port to listen on
print(HOST,PORT)
# turn off automatically reloading when files are written to the pico
#supervisor.disable_autoreload()
supervisor.runtime.autoreload = False
if(board.board_id == 'raspberry_pi_pico' or board.board_id == 'raspberry_pi_pico2'):
led = pwmio.PWMOut(board.LED, frequency=5000, duty_cycle=0)
elif(board.board_id == 'raspberry_pi_pico_w' or board.board_id == 'raspberry_pi_pico2_w'):
led = digitalio.DigitalInOut(board.LED)
led.switch_to_output()
progStatus = False
progStatus = getProgrammingStatus()
print("progStatus", progStatus)
if(progStatus == False):
print("Finding payload")
# not in setup mode, inject the payload
payload = selectPayload()
print("Running ", payload)
runScript(payload)
print("Done")
else:
print("Update your payload")
led_state = False
async def main_loop():
global led,button1
button_task = asyncio.create_task(monitor_buttons(button1))
if(board.board_id == 'raspberry_pi_pico_w' or board.board_id == 'raspberry_pi_pico2_w'):
pico_led_task = asyncio.create_task(blink_pico_w_led(led))
print("Starting Wifi")
startWiFi()
print("Starting Web Service")
webservice_task = asyncio.create_task(startWebService())
await asyncio.gather(pico_led_task, button_task, webservice_task)
else:
pico_led_task = asyncio.create_task(blink_pico_led(led))
await asyncio.gather(pico_led_task, button_task)
asyncio.run(main_loop())

View File

@@ -1,25 +1,9 @@
# License : GPLv2.0 # License : GPLv2.0
# copyright (c) 2023 Dave Bailey # copyright (c) 2021 Dave Bailey
# Author: Dave Bailey (dbisu, @daveisu) # Author: Dave Bailey (dbisu, @daveisu)
#
# TODO: ADD support for the following:
# Add jitter
# Add LED functionality
import re
import time
import random
import digitalio
from digitalio import DigitalInOut, Pull
from adafruit_debouncer import Debouncer
import board
from board import *
import pwmio
import asyncio
import usb_hid import usb_hid
from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard import Keyboard
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode
# comment out these lines for non_US keyboards # comment out these lines for non_US keyboards
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS as KeyboardLayout from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS as KeyboardLayout
@@ -27,22 +11,38 @@ from adafruit_hid.keycode import Keycode
# uncomment these lines for non_US keyboards # uncomment these lines for non_US keyboards
# replace LANG with appropriate language # replace LANG with appropriate language
#from keyboard_layout_win_LANG import KeyboardLayout as KeyboardLayout #from keyboard_layout_win_LANG import KeyboardLayout
#from keycode_win_LANG import Keycode #from keycode_win_LANG import Keycode
def _capsOn(): import supervisor
return kbd.led_on(Keyboard.LED_CAPS_LOCK)
def _numOn(): import time
return kbd.led_on(Keyboard.LED_NUM_LOCK) import digitalio
from board import *
import pwmio
def _scrollOn(): led = pwmio.PWMOut(LED, frequency=5000, duty_cycle=0)
return kbd.led_on(Keyboard.LED_SCROLL_LOCK)
duckyKeys = { def led_pwm_up(led):
'WINDOWS': Keycode.GUI, 'RWINDOWS': Keycode.RIGHT_GUI, 'GUI': Keycode.GUI, 'RGUI': Keycode.RIGHT_GUI, 'COMMAND': Keycode.GUI, 'RCOMMAND': Keycode.RIGHT_GUI, for i in range(100):
'APP': Keycode.APPLICATION, 'MENU': Keycode.APPLICATION, 'SHIFT': Keycode.SHIFT, 'RSHIFT': Keycode.RIGHT_SHIFT, # PWM LED up and down
'ALT': Keycode.ALT, 'RALT': Keycode.RIGHT_ALT, 'OPTION': Keycode.ALT, 'ROPTION': Keycode.RIGHT_ALT, 'CONTROL': Keycode.CONTROL, 'CTRL': Keycode.CONTROL, 'RCTRL': Keycode.RIGHT_CONTROL, if i < 50:
led.duty_cycle = int(i * 2 * 65535 / 100) # Up
time.sleep(0.01)
def led_pwm_down(led):
for i in range(100):
# PWM LED up and down
if i >= 50:
led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down
time.sleep(0.01)
# led = digitalio.DigitalInOut(LED)
# led.direction = digitalio.Direction.OUTPUT
duckyCommands = {
'WINDOWS': Keycode.WINDOWS, 'GUI': Keycode.GUI,
'APP': Keycode.APPLICATION, 'MENU': Keycode.APPLICATION, 'SHIFT': Keycode.SHIFT,
'ALT': Keycode.ALT, 'CONTROL': Keycode.CONTROL, 'CTRL': Keycode.CONTROL,
'DOWNARROW': Keycode.DOWN_ARROW, 'DOWN': Keycode.DOWN_ARROW, 'LEFTARROW': Keycode.LEFT_ARROW, 'DOWNARROW': Keycode.DOWN_ARROW, 'DOWN': Keycode.DOWN_ARROW, 'LEFTARROW': Keycode.LEFT_ARROW,
'LEFT': Keycode.LEFT_ARROW, 'RIGHTARROW': Keycode.RIGHT_ARROW, 'RIGHT': Keycode.RIGHT_ARROW, 'LEFT': Keycode.LEFT_ARROW, 'RIGHTARROW': Keycode.RIGHT_ARROW, 'RIGHT': Keycode.RIGHT_ARROW,
'UPARROW': Keycode.UP_ARROW, 'UP': Keycode.UP_ARROW, 'BREAK': Keycode.PAUSE, 'UPARROW': Keycode.UP_ARROW, 'UP': Keycode.UP_ARROW, 'BREAK': Keycode.PAUSE,
@@ -60,243 +60,48 @@ duckyKeys = {
'Z': Keycode.Z, 'F1': Keycode.F1, 'F2': Keycode.F2, 'F3': Keycode.F3, 'Z': Keycode.Z, 'F1': Keycode.F1, 'F2': Keycode.F2, 'F3': Keycode.F3,
'F4': Keycode.F4, 'F5': Keycode.F5, 'F6': Keycode.F6, 'F7': Keycode.F7, 'F4': Keycode.F4, 'F5': Keycode.F5, 'F6': Keycode.F6, 'F7': Keycode.F7,
'F8': Keycode.F8, 'F9': Keycode.F9, 'F10': Keycode.F10, 'F11': Keycode.F11, 'F8': Keycode.F8, 'F9': Keycode.F9, 'F10': Keycode.F10, 'F11': Keycode.F11,
'F12': Keycode.F12, 'F13': Keycode.F13, 'F14': Keycode.F14, 'F15': Keycode.F15, 'F12': Keycode.F12,
'F16': Keycode.F16, 'F17': Keycode.F17, 'F18': Keycode.F18, 'F19': Keycode.F19,
'F20': Keycode.F20, 'F21': Keycode.F21, 'F22': Keycode.F22, 'F23': Keycode.F23,
'F24': Keycode.F24
} }
duckyConsumerKeys = {
'MK_VOLUP': ConsumerControlCode.VOLUME_INCREMENT, 'MK_VOLDOWN': ConsumerControlCode.VOLUME_DECREMENT, 'MK_MUTE': ConsumerControlCode.MUTE,
'MK_NEXT': ConsumerControlCode.SCAN_NEXT_TRACK, 'MK_PREV': ConsumerControlCode.SCAN_PREVIOUS_TRACK,
'MK_PP': ConsumerControlCode.PLAY_PAUSE, 'MK_STOP': ConsumerControlCode.STOP
}
variables = {"$_RANDOM_MIN": 0, "$_RANDOM_MAX": 65535}
internalVariables = {"$_CAPSLOCK_ON": _capsOn, "$_NUMLOCK_ON": _numOn, "$_SCROLLLOCK_ON": _scrollOn}
defines = {}
functions = {}
letters = "abcdefghijklmnopqrstuvwxyz"
numbers = "0123456789"
specialChars = "!@#$%^&*()"
class IF:
def __init__(self, condition, codeIter):
self.condition = condition
self.codeIter = list(codeIter)
self.lastIfResult = None
def _exitIf(self):
_depth = 0
for line in self.codeIter:
line = self.codeIter.pop(0)
line = line.strip()
if line.upper().startswith("END_IF"):
_depth -= 1
elif line.upper().startswith("IF"):
_depth += 1
if _depth < 0:
print("No else, exiting" + str(list(self.codeIter)))
break
return(self.codeIter)
def runIf(self):
if isinstance(self.condition, str):
self.lastIfResult = evaluateExpression(self.condition)
elif isinstance(self.condition, bool):
self.lastIfResult = self.condition
else:
raise ValueError("Invalid condition type")
# print(f"condition {self.condition} result is {self.lastIfResult} since \"$VAR\" is {variables["$VAR"]}, code is {self.codeIter}")
depth = 0
for line in self.codeIter:
line = self.codeIter.pop(0)
line = line.strip()
if line == "":
continue
# print(line)
if line.startswith("IF"):
depth += 1
elif line.startswith("END_IF"):
if depth == 0:
return(self.codeIter, -1)
depth -=1
elif line.startswith("ELSE") and depth == 0:
# print(f"ELSE LINE {line}, lastIfResult: {self.lastIfResult}")
if self.lastIfResult is False:
line = line[4:].strip() # Remove 'ELSE' and strip whitespace
if line.startswith("IF"):
nestedCondition = _getIfCondition(line)
# print(f"nested IF {nestedCondition}")
self.codeIter, self.lastIfResult = IF(nestedCondition, self.codeIter).runIf()
if self.lastIfResult == -1 or self.lastIfResult == True:
# print(f"self.lastIfResult {self.lastIfResult}")
return(self.codeIter, True)
else:
return IF(True, self.codeIter).runIf() #< Regular ELSE block
else:
self._exitIf()
break
# Process regular lines
elif self.lastIfResult:
# print(f"running line {line}")
self.codeIter = list(parseLine(line, self.codeIter))
# print("end of if")
return(self.codeIter, self.lastIfResult)
def _getIfCondition(line):
return str(line)[2:-4].strip()
def _isCodeBlock(line):
line = line.upper().strip()
if line.startswith("IF") or line.startswith("WHILE"):
return True
return False
def _getCodeBlock(linesIter):
"""Returns the code block starting at the given line."""
code = []
depth = 1
for line in linesIter:
line = line.strip()
if line.upper().startswith("END_"):
depth -= 1
elif _isCodeBlock(line):
depth += 1
if depth <= 0:
break
code.append(line)
return code
def evaluateExpression(expression):
"""Evaluates an expression with variables and returns the result."""
# Replace variables (e.g., $FOO) in the expression with their values
expression = re.sub(r"\$(\w+)", lambda m: str(variables.get(f"${m.group(1)}", 0)), expression)
expression = expression.replace("^", "**") #< Replace ^ with ** for exponentiation
expression = expression.replace("&&", "and")
expression = expression.replace("||", "or")
return eval(expression, {}, variables)
def deepcopy(List):
return(List[:])
def convertLine(line): def convertLine(line):
commands = [] newline = []
# print(line) # print(line)
# loop on each key - the filter removes empty values # loop on each key - the filter removes empty values
for key in filter(None, line.split(" ")): for key in filter(None, line.split(" ")):
key = key.upper() key = key.upper()
# find the keycode for the command in the list # find the keycode for the command in the list
command_keycode = duckyKeys.get(key, None) command_keycode = duckyCommands.get(key, None)
command_consumer_keycode = duckyConsumerKeys.get(key, None)
if command_keycode is not None: if command_keycode is not None:
# if it exists in the list, use it # if it exists in the list, use it
commands.append(command_keycode) newline.append(command_keycode)
elif command_consumer_keycode is not None:
# if it exists in the list, use it
commands.append(1000+command_consumer_keycode)
elif hasattr(Keycode, key): elif hasattr(Keycode, key):
# if it's in the Keycode module, use it (allows any valid keycode) # if it's in the Keycode module, use it (allows any valid keycode)
commands.append(getattr(Keycode, key)) newline.append(getattr(Keycode, key))
else: else:
# if it's not a known key name, show the error for diagnosis # if it's not a known key name, show the error for diagnosis
print(f"Unknown key: <{key}>") print(f"Unknown key: <{key}>")
# print(commands) # print(newline)
return commands return newline
def runScriptLine(line): def runScriptLine(line):
keys = convertLine(line) for k in line:
for k in keys: kbd.press(k)
if k > 1000: kbd.release_all()
consumerControl.press(int(k-1000))
else:
kbd.press(k)
for k in reversed(keys):
if k > 1000:
consumerControl.release()
else:
kbd.release(k)
def sendString(line): def sendString(line):
layout.write(line) layout.write(line)
def replaceVariables(line): def parseLine(line):
for var in variables: global defaultDelay
line = line.replace(var, str(variables[var])) if(line[0:3] == "REM"):
for var in internalVariables: # ignore ducky script comments
line = line.replace(var, str(internalVariables[var]()))
return line
def replaceDefines(line):
for define, value in defines.items():
line = line.replace(define, value)
return line
def parseLine(line, script_lines):
global defaultDelay, variables, functions, defines
line = line.strip()
line = line.replace("$_RANDOM_INT", str(random.randint(int(variables.get("$_RANDOM_MIN", 0)), int(variables.get("$_RANDOM_MAX", 65535)))))
line = replaceDefines(line)
if line[:10] == "INJECT_MOD":
line = line[11:]
elif line.startswith("REM_BLOCK"):
while line.startswith("END_REM") == False:
line = next(script_lines).strip()
# print(line)
elif(line[0:3] == "REM"):
pass pass
elif line.startswith("HOLD"):
# HOLD command to press and hold a key
key = line[5:].strip().upper()
commandKeycode = duckyKeys.get(key, None)
if commandKeycode:
kbd.press(commandKeycode)
else:
print(f"Unknown key to HOLD: <{key}>")
elif line.startswith("RELEASE"):
# RELEASE command to release a held key
key = line[8:].strip().upper()
commandKeycode = duckyKeys.get(key, None)
if commandKeycode:
kbd.release(commandKeycode)
else:
print(f"Unknown key to RELEASE: <{key}>")
elif(line[0:5] == "DELAY"): elif(line[0:5] == "DELAY"):
line = replaceVariables(line)
time.sleep(float(line[6:])/1000) time.sleep(float(line[6:])/1000)
elif line == "STRINGLN": #< stringLN block
line = next(script_lines).strip()
line = replaceVariables(line)
while line.startswith("END_STRINGLN") == False:
sendString(line)
kbd.press(Keycode.ENTER)
kbd.release(Keycode.ENTER)
line = next(script_lines).strip()
line = replaceVariables(line)
line = replaceDefines(line)
elif(line[0:8] == "STRINGLN"):
sendString(replaceVariables(line[9:]))
kbd.press(Keycode.ENTER)
kbd.release(Keycode.ENTER)
elif line == "STRING": #< string block
line = next(script_lines).strip()
line = replaceVariables(line)
while line.startswith("END_STRING") == False:
sendString(line)
line = next(script_lines).strip()
line = replaceVariables(line)
line = replaceDefines(line)
elif(line[0:6] == "STRING"): elif(line[0:6] == "STRING"):
sendString(replaceVariables(line[7:])) sendString(line[7:])
elif(line[0:5] == "PRINT"): elif(line[0:5] == "PRINT"):
line = replaceVariables(line[6:]) print("[SCRIPT]: " + line[6:])
print("[SCRIPT]: " + line)
elif(line[0:6] == "IMPORT"): elif(line[0:6] == "IMPORT"):
runScript(line[7:]) runScript(line[7:])
elif(line[0:13] == "DEFAULT_DELAY"): elif(line[0:13] == "DEFAULT_DELAY"):
@@ -308,140 +113,20 @@ def parseLine(line, script_lines):
led.value = False led.value = False
else: else:
led.value = True led.value = True
elif(line[0:3] == "LED"):
if(led.value == True):
led.value = False
else:
led.value = True
elif(line[:7] == "LED_OFF"):
led.value = False
elif(line[:5] == "LED_R"):
led.value = True
elif(line[:5] == "LED_G"):
led.value = True
elif(line[0:21] == "WAIT_FOR_BUTTON_PRESS"):
button_pressed = False
# NOTE: we don't use assincio in this case because we want to block code execution
while not button_pressed:
button1.update()
button1Pushed = button1.fell
button1Released = button1.rose
button1Held = not button1.value
if(button1Pushed):
print("Button 1 pushed")
button_pressed = True
elif line.startswith("VAR"):
match = re.match(r"VAR\s+\$(\w+)\s*=\s*(.+)", line)
if match:
varName = f"${match.group(1)}"
value = evaluateExpression(match.group(2))
variables[varName] = value
else:
raise SyntaxError(f"Invalid variable declaration: {line}")
elif line.startswith("$"):
match = re.match(r"\$(\w+)\s*=\s*(.+)", line)
if match:
varName = f"${match.group(1)}"
expression = match.group(2)
value = evaluateExpression(expression)
variables[varName] = value
else:
raise SyntaxError(f"Invalid variable update, declare variable first: {line}")
elif line.startswith("DEFINE"):
defineLocation = line.find(" ")
valueLocation = line.find(" ", defineLocation + 1)
defineName = line[defineLocation+1:valueLocation]
defineValue = line[valueLocation+1:]
defines[defineName] = defineValue
elif line.startswith("FUNCTION"):
# print("ENTER FUNCTION")
func_name = line.split()[1]
functions[func_name] = []
line = next(script_lines).strip()
while line != "END_FUNCTION":
functions[func_name].append(line)
line = next(script_lines).strip()
elif line.startswith("WHILE"):
# print("ENTER WHILE LOOP")
condition = line[5:].strip()
loopCode = list(_getCodeBlock(script_lines))
while evaluateExpression(condition) == True:
currentIterCode = deepcopy(loopCode)
print(loopCode)
while currentIterCode:
loopLine = currentIterCode.pop(0)
currentIterCode = list(parseLine(loopLine, iter(currentIterCode))) #< very inefficient, should be replaced later.
elif line.upper().startswith("IF"):
# print("ENTER IF")
script_lines, ret = IF(_getIfCondition(line), script_lines).runIf()
print(f"IF returned {ret} code")
elif line.upper().startswith("END_IF"):
pass
elif line == "RANDOM_LOWERCASE_LETTER":
sendString(random.choice(letters))
elif line == "RANDOM_UPPERCASE_LETTER":
sendString(random.choice(letters.upper()))
elif line == "RANDOM_LETTER":
sendString(random.choice(letters + letters.upper()))
elif line == "RANDOM_NUMBER":
sendString(random.choice(numbers))
elif line == "RANDOM_SPECIAL":
sendString(random.choice(specialChars))
elif line == "RANDOM_CHAR":
sendString(random.choice(letters + letters.upper() + numbers + specialChars))
elif line == "VID_RANDOM" or line == "PID_RANDOM":
for _ in range(4):
sendString(random.choice("0123456789ABCDEF"))
elif line == "MAN_RANDOM" or line == "PROD_RANDOM":
for _ in range(12):
sendString(random.choice(letters + letters.upper() + numbers))
elif line == "SERIAL_RANDOM":
for _ in range(12):
sendString(random.choice(letters + letters.upper() + numbers + specialChars))
elif line == "RESET":
kbd.release_all()
elif line in functions:
updated_lines = []
inside_while_block = False
for func_line in functions[line]:
if func_line.startswith("WHILE"):
inside_while_block = True # Start skipping lines
updated_lines.append(func_line)
elif func_line.startswith("END_WHILE"):
inside_while_block = False # Stop skipping lines
updated_lines.append(func_line)
parseLine(updated_lines[0], iter(updated_lines))
updated_lines = [] # Clear updated_lines after parsing
elif inside_while_block:
updated_lines.append(func_line)
elif not (func_line.startswith("END_WHILE") or func_line.startswith("WHILE")):
parseLine(func_line, iter(functions[line]))
else: else:
runScriptLine(line) newScriptLine = convertLine(line)
runScriptLine(newScriptLine)
return(script_lines)
kbd = Keyboard(usb_hid.devices) kbd = Keyboard(usb_hid.devices)
consumerControl = ConsumerControl(usb_hid.devices)
layout = KeyboardLayout(kbd) layout = KeyboardLayout(kbd)
#init button # turn off automatically reloading when files are written to the pico
button1_pin = DigitalInOut(GP22) # defaults to input supervisor.disable_autoreload()
button1_pin.pull = Pull.UP # turn on internal pull-up resistor
button1 = Debouncer(button1_pin)
#init payload selection switch # sleep at the start to allow the device to be recognized by the host computer
payload1Pin = digitalio.DigitalInOut(GP4) time.sleep(.5)
payload1Pin.switch_to_input(pull=digitalio.Pull.UP)
payload2Pin = digitalio.DigitalInOut(GP5) led_pwm_up(led)
payload2Pin.switch_to_input(pull=digitalio.Pull.UP)
payload3Pin = digitalio.DigitalInOut(GP10)
payload3Pin.switch_to_input(pull=digitalio.Pull.UP)
payload4Pin = digitalio.DigitalInOut(GP11)
payload4Pin.switch_to_input(pull=digitalio.Pull.UP)
def getProgrammingStatus(): def getProgrammingStatus():
# check GP0 for setup mode # check GP0 for setup mode
@@ -458,46 +143,44 @@ def runScript(file):
global defaultDelay global defaultDelay
duckyScriptPath = file duckyScriptPath = file
restart = True
try: try:
while restart: f = open(duckyScriptPath,"r",encoding='utf-8')
restart = False previousLine = ""
with open(duckyScriptPath, "r", encoding='utf-8') as f: for line in f:
script_lines = iter(f.readlines()) line = line.rstrip()
previousLine = "" if(line[0:6] == "REPEAT"):
for line in script_lines: for i in range(int(line[7:])):
print(f"runScript: {line}") #repeat the last command
if(line[0:6] == "REPEAT"): parseLine(previousLine)
for i in range(int(line[7:])): time.sleep(float(defaultDelay)/1000)
#repeat the last command else:
parseLine(previousLine, script_lines) parseLine(line)
time.sleep(float(defaultDelay) / 1000) previousLine = line
elif line.startswith("RESTART_PAYLOAD"): time.sleep(float(defaultDelay)/1000)
restart = True
break
elif line.startswith("STOP_PAYLOAD"):
restart = False
break
else:
parseLine(line, script_lines)
previousLine = line
time.sleep(float(defaultDelay) / 1000)
except OSError as e: except OSError as e:
print("Unable to open file", file) print("Unable to open file ", file)
def selectPayload(): def selectPayload():
global payload1Pin, payload2Pin, payload3Pin, payload4Pin
payload = "payload.dd" payload = "payload.dd"
# check switch status # check switch status
# payload1 = GPIO4 to GND # payload1 = GPIO4 to GND
# payload2 = GPIO5 to GND # payload2 = GPIO5 to GND
# payload3 = GPIO10 to GND # payload3 = GPIO10 to GND
# payload4 = GPIO11 to GND # payload4 = GPIO11 to GND
payload1Pin = digitalio.DigitalInOut(GP4)
payload1Pin.switch_to_input(pull=digitalio.Pull.UP)
payload1State = not payload1Pin.value payload1State = not payload1Pin.value
payload2Pin = digitalio.DigitalInOut(GP5)
payload2Pin.switch_to_input(pull=digitalio.Pull.UP)
payload2State = not payload2Pin.value payload2State = not payload2Pin.value
payload3Pin = digitalio.DigitalInOut(GP10)
payload3Pin.switch_to_input(pull=digitalio.Pull.UP)
payload3State = not payload3Pin.value payload3State = not payload3Pin.value
payload4Pin = digitalio.DigitalInOut(GP11)
payload4Pin.switch_to_input(pull=digitalio.Pull.UP)
payload4State = not payload4Pin.value payload4State = not payload4Pin.value
if(payload1State == True): if(payload1State == True):
payload = "payload.dd" payload = "payload.dd"
@@ -515,81 +198,28 @@ def selectPayload():
# default to payload1 # default to payload1
payload = "payload.dd" payload = "payload.dd"
return payload return payload
async def blink_led(led): progStatus = False
print("Blink") progStatus = getProgrammingStatus()
if(board.board_id == 'raspberry_pi_pico' or board.board_id == 'raspberry_pi_pico2'):
blink_pico_led(led)
elif(board.board_id == 'raspberry_pi_pico_w' or board.board_id == 'raspberry_pi_pico2_w'):
blink_pico_w_led(led)
async def blink_pico_led(led): if(progStatus == False):
print("starting blink_pico_led") # not in setup mode, inject the payload
led_state = False payload = selectPayload()
while True: print("Running ", payload)
if led_state: runScript(payload)
#led_pwm_up(led)
#print("led up")
for i in range(100):
# PWM LED up and down
if i < 50:
led.duty_cycle = int(i * 2 * 65535 / 100) # Up
await asyncio.sleep(0.01)
led_state = False
else:
#led_pwm_down(led)
#print("led down")
for i in range(100):
# PWM LED up and down
if i >= 50:
led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down
await asyncio.sleep(0.01)
led_state = True
await asyncio.sleep(0)
async def blink_pico_w_led(led): print("Done")
print("starting blink_pico_w_led") else:
led_state = False print("Update your payload")
while True:
if led_state:
#print("led on")
led.value = 1
await asyncio.sleep(0.5)
led_state = False
else:
#print("led off")
led.value = 0
await asyncio.sleep(0.5)
led_state = True
await asyncio.sleep(0.5)
async def monitor_buttons(button1): led_state = False
global inBlinkeyMode, inMenu, enableRandomBeep, enableSirenMode,pixel while True:
print("starting monitor_buttons") if led_state:
button1Down = False led_pwm_up(led)
while True: led_state = False
button1.update() else:
led_pwm_down(led)
button1Pushed = button1.fell led_state = True
button1Released = button1.rose
button1Held = not button1.value
if(button1Pushed):
print("Button 1 pushed")
button1Down = True
if(button1Released):
print("Button 1 released")
if(button1Down):
print("push and released")
if(button1Released):
if(button1Down):
# Run selected payload
payload = selectPayload()
print("Running ", payload)
runScript(payload)
print("Done")
button1Down = False
await asyncio.sleep(0)

View File

@@ -1,13 +0,0 @@
REM Example Function
FUNCTION COUNTDOWN()
REM The next four lines open Notepad in Windows and type "Hello World!"
GUI r
DELAY 1000
STRING notepad
ENTER
DELAY 2000
STRING Hello World!
ENTER
END_FUNCTION
COUNTDOWN()

View File

@@ -1,7 +0,0 @@
VAR $TIME = 3
WHILE ($TIME > 0)
STRING .
DELAY 500
STRING While Looop!!
ENTER
END_WHILE

243
webapp.py
View File

@@ -1,243 +0,0 @@
# License : GPLv2.0
# copyright (c) 2023 Dave Bailey
# Author: Dave Bailey (dbisu, @daveisu)
# FeatherS2 board support
import socketpool
import time
import os
import storage
import wsgiserver as server
from adafruit_wsgi.wsgi_app import WSGIApp
import wifi
from duckyinpython import *
payload_html = """<!DOCTYPE html>
<html>
<head> <title>Pico W Ducky</title> </head>
<body> <h1>Pico W Ducky</h1>
<table border="1"> <tr><th>Payload</th><th>Actions</th></tr> {} </table>
<br>
<a href="/new">New Script</a>
</body>
</html>
"""
edit_html = """<!DOCTYPE html>
<html>
<head>
<title>Script Editor</title>
</head>
<body>
<form action="/write/{}" method="POST">
<textarea rows="5" cols="60" name="scriptData">{}</textarea>
<br/>
<input type="submit" value="submit"/>
</form>
<br>
<a href="/ducky">Home</a>
</body>
</html>
"""
new_html = """<!DOCTYPE html>
<html>
<head>
<title>New Script</title>
</head>
<body>
<form action="/new" method="POST">
Script Name<br>
<textarea rows="1" cols="60" name="scriptName"></textarea>
Script<br>
<textarea rows="5" cols="60" name="scriptData"></textarea>
<br/>
<input type="submit" value="submit"/>
</form>
<br>
<a href="/ducky">Home</a>
</body>
</html>
"""
response_html = """<!DOCTYPE html>
<html>
<head> <title>Pico W Ducky</title> </head>
<body> <h1>Pico W Ducky</h1>
{}
<br>
<a href="/ducky">Home</a>
</body>
</html>
"""
newrow_html = "<tr><td>{}</td><td><a href='/edit/{}'>Edit</a> / <a href='/run/{}'>Run</a></tr>"
def setPayload(payload_number):
if(payload_number == 1):
payload = "payload.dd"
else:
payload = "payload"+str(payload_number)+".dd"
return(payload)
def ducky_main(request):
print("Ducky main")
payloads = []
rows = ""
files = os.listdir()
#print(files)
for f in files:
if ('.dd' in f) == True:
payloads.append(f)
newrow = newrow_html.format(f,f,f)
#print(newrow)
rows = rows + newrow
response = payload_html.format(rows)
return(response)
_hexdig = '0123456789ABCDEFabcdef'
_hextobyte = None
def cleanup_text(string):
"""unquote('abc%20def') -> b'abc def'."""
global _hextobyte
if not string:
return b''
if isinstance(string, str):
string = string.encode('utf-8')
bits = string.split(b'%')
if len(bits) == 1:
return string
res = [bits[0]]
append = res.append
if _hextobyte is None:
_hextobyte = {(a + b).encode(): bytes([int(a + b, 16)])
for a in _hexdig for b in _hexdig}
for item in bits[1:]:
try:
append(_hextobyte[item[:2]])
append(item[2:])
except KeyError:
append(b'%')
append(item)
return b''.join(res).decode().replace('+',' ')
web_app = WSGIApp()
@web_app.route("/ducky")
def duck_main(request):
response = ducky_main(request)
return("200 OK", [('Content-Type', 'text/html')], response)
@web_app.route("/edit/<filename>")
def edit(request, filename):
print("Editing ", filename)
f = open(filename,"r",encoding='utf-8')
textbuffer = ''
for line in f:
textbuffer = textbuffer + line
f.close()
response = edit_html.format(filename,textbuffer)
#print(response)
return("200 OK",[('Content-Type', 'text/html')], response)
@web_app.route("/write/<filename>",methods=["POST"])
def write_script(request, filename):
data = request.body.getvalue()
fields = data.split("&")
form_data = {}
for field in fields:
key,value = field.split('=')
form_data[key] = value
#print(form_data)
storage.remount("/",readonly=False)
f = open(filename,"w",encoding='utf-8')
textbuffer = form_data['scriptData']
textbuffer = cleanup_text(textbuffer)
#print(textbuffer)
for line in textbuffer:
f.write(line)
f.close()
storage.remount("/",readonly=True)
response = response_html.format("Wrote script " + filename)
return("200 OK",[('Content-Type', 'text/html')], response)
@web_app.route("/new",methods=['GET','POST'])
def write_new_script(request):
response = ''
if(request.method == 'GET'):
response = new_html
else:
data = request.body.getvalue()
fields = data.split("&")
form_data = {}
for field in fields:
key,value = field.split('=')
form_data[key] = value
#print(form_data)
filename = form_data['scriptName']
textbuffer = form_data['scriptData']
textbuffer = cleanup_text(textbuffer)
storage.remount("/",readonly=False)
f = open(filename,"w",encoding='utf-8')
for line in textbuffer:
f.write(line)
f.close()
storage.remount("/",readonly=True)
response = response_html.format("Wrote script " + filename)
return("200 OK",[('Content-Type', 'text/html')], response)
@web_app.route("/run/<filename>")
def run_script(request, filename):
print("run_script ", filename)
response = response_html.format("Running script " + filename)
#print(response)
runScript(filename)
return("200 OK",[('Content-Type', 'text/html')], response)
@web_app.route("/")
def index(request):
response = ducky_main(request)
return("200 OK", [('Content-Type', 'text/html')], response)
@web_app.route("/api/run/<filenumber>")
def run_script(request, filenumber):
filename = setPayload(int(filenumber))
print("run_script ", filenumber)
response = response_html.format("Running script " + filename)
#print(response)
runScript(filename)
return("200 OK",[('Content-Type', 'text/html')], response)
async def startWebService():
HOST = repr(wifi.radio.ipv4_address_ap)
PORT = 80 # Port to listen on
print(HOST,PORT)
wsgiServer = server.WSGIServer(PORT, application=web_app)
print(f"open this IP in your browser: http://{HOST}:{PORT}/")
# Start the server
wsgiServer.start()
while True:
wsgiServer.update_poll()
await asyncio.sleep(0)

View File

@@ -1,286 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2019 Matt Costi for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`adafruit_esp32spi_wsgiserver`
================================================================================
A simple WSGI (Web Server Gateway Interface) server that interfaces with the ESP32 over SPI.
Opens a specified port on the ESP32 to listen for incoming HTTP Requests and
Accepts an Application object that must be callable, which gets called
whenever a new HTTP Request has been received.
The Application MUST accept 2 ordered parameters:
1. environ object (incoming request data)
2. start_response function. Must be called before the Application
callable returns, in order to set the response status and headers.
The Application MUST return a single string in a list,
which is the response data
Requires update_poll being called in the applications main event loop.
For more details about Python WSGI see:
https://www.python.org/dev/peps/pep-0333/
* Author(s): Matt Costi
"""
# pylint: disable=no-name-in-module
import io
import gc
from micropython import const
import socketpool
import wifi
class BadRequestError(Exception):
"""Raised when the client sends an unexpected empty line"""
pass
_BUFFER_SIZE = 32
buffer = bytearray(_BUFFER_SIZE)
def readline(socketin):
"""
Implement readline() for native wifi using recv_into
"""
data_string = b""
while True:
try:
num = socketin.recv_into(buffer, 1)
data_string += str(buffer, 'utf8')[:num]
if num == 0:
return data_string
if data_string[-2:] == b"\r\n":
return data_string[:-2]
except OSError as ex:
# if ex.errno == 9: # [Errno 9] EBADF
# return None
if ex.errno == 11: # [Errno 11] EAGAIN
continue
raise
def read(socketin,length = -1):
total = 0
data_string = b""
try:
if length > 0:
while total < length:
reste = length - total
num = socketin.recv_into(buffer, min(_BUFFER_SIZE, reste))
#
if num == 0:
# timeout
# raise OSError(110)
return data_string
#
data_string += buffer[:num]
total = total + num
return data_string
else:
while True:
num = socketin.recv_into(buffer, 1)
data_string += str(buffer, 'utf8')[:num]
if num == 0:
return data_string
except OSError as ex:
if ex.errno == 11: # [Errno 11] EAGAIN
return data_string
raise
def parse_headers(sock):
"""
Parses the header portion of an HTTP request/response from the socket.
Expects first line of HTTP request/response to have been read already
return: header dictionary
rtype: Dict
"""
headers = {}
while True:
line = readline(sock)
if not line or line == b"\r\n":
break
#print("**line: ", line)
title, content = line.split(b': ', 1)
if title and content:
title = str(title.lower(), 'utf-8')
content = str(content, 'utf-8')
headers[title] = content
return headers
pool = socketpool.SocketPool(wifi.radio)
NO_SOCK_AVAIL = const(255)
# pylint: disable=invalid-name
class WSGIServer:
"""
A simple server that implements the WSGI interface
"""
def __init__(self, port=80, debug=False, application=None):
self.application = application
self.port = port
self._server_sock = None
self._client_sock = None
self._debug = debug
self._response_status = None
self._response_headers = []
def start(self):
"""
starts the server and begins listening for incoming connections.
Call update_poll in the main loop for the application callable to be
invoked on receiving an incoming request.
"""
self._server_sock = pool.socket(pool.AF_INET,pool.SOCK_STREAM)
HOST = repr(wifi.radio.ipv4_address_ap)
self._server_sock.bind((repr(wifi.radio.ipv4_address_ap), self.port))
self._server_sock.listen(1)
# if self._debug:
# ip = _the_interface.pretty_ip(_the_interface.ip_address)
# print("Server available at {0}:{1}".format(ip, self.port))
# print(
# "Sever status: ",
# _the_interface.get_server_state(self._server_sock.socknum),
# )
def pretty_ip(self):
return f"http://{wifi.radio.ipv4_address_ap}:{self.port}"
def update_poll(self):
"""
Call this method inside your main event loop to get the server
check for new incoming client requests. When a request comes in,
the application callable will be invoked.
"""
self.client_available()
if self._client_sock:
try:
environ = self._get_environ(self._client_sock)
result = self.application(environ, self._start_response)
self.finish_response(result)
except BadRequestError:
self._start_response("400 Bad Request", [])
self.finish_response([])
def finish_response(self, result):
"""
Called after the application callbile returns result data to respond with.
Creates the HTTP Response payload from the response_headers and results data,
and sends it back to client.
:param string result: the data string to send back in the response to the client.
"""
try:
response = "HTTP/1.1 {0}\r\n".format(self._response_status)
for header in self._response_headers:
response += "{0}: {1}\r\n".format(*header)
response += "\r\n"
self._client_sock.send(response.encode("utf-8"))
for data in result:
if isinstance(data, str):
data = data.encode("utf-8")
elif not isinstance(data, bytes):
data = str(data).encode("utf-8")
bytes_sent = 0
while bytes_sent < len(data):
try:
bytes_sent += self._client_sock.send(data[bytes_sent:])
except OSError as ex:
if ex.errno != 11: # [Errno 11] EAGAIN
raise
gc.collect()
except OSError as ex:
if ex.errno != 104: # [Errno 104] ECONNRESET
raise
finally:
#print("closing")
self._client_sock.close()
self._client_sock = None
def client_available(self):
"""
returns a client socket connection if available.
Otherwise, returns None
:return: the client
:rtype: Socket
"""
sock = None
if not self._server_sock:
print("Server has not been started, cannot check for clients!")
elif not self._client_sock:
self._server_sock.setblocking(False)
try:
self._client_sock, addr = self._server_sock.accept()
except OSError as ex:
if ex.errno != 11: # [Errno 11] EAGAIN
raise
return None
def _start_response(self, status, response_headers):
"""
The application callable will be given this method as the second param
This is to be called before the application callable returns, to signify
the response can be started with the given status and headers.
:param string status: a status string including the code and reason. ex: "200 OK"
:param list response_headers: a list of tuples to represent the headers.
ex ("header-name", "header value")
"""
self._response_status = status
self._response_headers = [("Server", "esp32WSGIServer")] + response_headers
def _get_environ(self, client):
"""
The application callable will be given the resulting environ dictionary.
It contains metadata about the incoming request and the request body ("wsgi.input")
:param Socket client: socket to read the request from
"""
env = {}
line = readline(client).decode("utf-8")
try:
(method, path, ver) = line.rstrip("\r\n").split(None, 2)
except ValueError:
raise BadRequestError("Unknown request from client.")
env["wsgi.version"] = (1, 0)
env["wsgi.url_scheme"] = "http"
env["wsgi.multithread"] = False
env["wsgi.multiprocess"] = False
env["wsgi.run_once"] = False
env["REQUEST_METHOD"] = method
env["SCRIPT_NAME"] = ""
env["SERVER_NAME"] = str(wifi.radio.ipv4_address_ap)
env["SERVER_PROTOCOL"] = ver
env["SERVER_PORT"] = self.port
if path.find("?") >= 0:
env["PATH_INFO"] = path.split("?")[0]
env["QUERY_STRING"] = path.split("?")[1]
else:
env["PATH_INFO"] = path
headers = parse_headers(client)
if "content-type" in headers:
env["CONTENT_TYPE"] = headers.get("content-type")
if "content-length" in headers:
env["CONTENT_LENGTH"] = headers.get("content-length")
body = read(client, int(env["CONTENT_LENGTH"]))
env["wsgi.input"] = io.StringIO(body)
else:
body = read(client)
env["wsgi.input"] = io.StringIO(body)
for name, value in headers.items():
key = "HTTP_" + name.replace("-", "_").upper()
if key in env:
value = "{0},{1}".format(env[key], value)
env[key] = value
return env