This commit is contained in:
2026-03-13 19:58:28 +03:00
commit c938609393
87 changed files with 230200 additions and 0 deletions

1
BlockDiagram.drawio Normal file

File diff suppressed because one or more lines are too long

1
FUNDING.yml Normal file
View File

@@ -0,0 +1 @@
liberapay: hansfbaier

311
LICENSE Normal file
View File

@@ -0,0 +1,311 @@
CERN Open Hardware Licence Version 2 - Weakly Reciprocal
Preamble
CERN has developed this licence to promote collaboration among
hardware designers and to provide a legal tool which supports the
freedom to use, study, modify, share and distribute hardware designs
and products based on those designs. Version 2 of the CERN Open
Hardware Licence comes in three variants: CERN-OHL-P (permissive); and
two reciprocal licences: this licence, CERN-OHL-W (weakly reciprocal)
and CERN-OHL-S (strongly reciprocal).
The CERN-OHL-W is copyright CERN 2020. Anyone is welcome to use it, in
unmodified form only.
Use of this Licence does not imply any endorsement by CERN of any
Licensor or their designs nor does it imply any involvement by CERN in
their development.
1 Definitions
1.1 'Licence' means this CERN-OHL-W.
1.2 'Compatible Licence' means
a) any earlier version of the CERN Open Hardware licence, or
b) any version of the CERN-OHL-S or the CERN-OHL-W, or
c) any licence which permits You to treat the Source to which
it applies as licensed under CERN-OHL-S or CERN-OHL-W
provided that on Conveyance of any such Source, or any
associated Product You treat the Source in question as being
licensed under CERN-OHL-S or CERN-OHL-W as appropriate.
1.3 'Source' means information such as design materials or digital
code which can be applied to Make or test a Product or to
prepare a Product for use, Conveyance or sale, regardless of its
medium or how it is expressed. It may include Notices.
1.4 'Covered Source' means Source that is explicitly made available
under this Licence.
1.5 'Product' means any device, component, work or physical object,
whether in finished or intermediate form, arising from the use,
application or processing of Covered Source.
1.6 'Make' means to create or configure something, whether by
manufacture, assembly, compiling, loading or applying Covered
Source or another Product or otherwise.
1.7 'Available Component' means any part, sub-assembly, library or
code which:
a) is licensed to You as Complete Source under a Compatible
Licence; or
b) is available, at the time a Product or the Source containing
it is first Conveyed, to You and any other prospective
licensees
i) with sufficient rights and information (including any
configuration and programming files and information
about its characteristics and interfaces) to enable it
either to be Made itself, or to be sourced and used to
Make the Product; or
ii) as part of the normal distribution of a tool used to
design or Make the Product.
1.8 'External Material' means anything (including Source) which:
a) is only combined with Covered Source in such a way that it
interfaces with the Covered Source using a documented
interface which is described in the Covered Source; and
b) is not a derivative of or contains Covered Source, or, if it
is, it is solely to the extent necessary to facilitate such
interfacing.
1.9 'Complete Source' means the set of all Source necessary to Make
a Product, in the preferred form for making modifications,
including necessary installation and interfacing information
both for the Product, and for any included Available Components.
If the format is proprietary, it must also be made available in
a format (if the proprietary tool can create it) which is
viewable with a tool available to potential licensees and
licensed under a licence approved by the Free Software
Foundation or the Open Source Initiative. Complete Source need
not include the Source of any Available Component, provided that
You include in the Complete Source sufficient information to
enable a recipient to Make or source and use the Available
Component to Make the Product.
1.10 'Source Location' means a location where a Licensor has placed
Covered Source, and which that Licensor reasonably believes will
remain easily accessible for at least three years for anyone to
obtain a digital copy.
1.11 'Notice' means copyright, acknowledgement and trademark notices,
Source Location references, modification notices (subsection
3.3(b)) and all notices that refer to this Licence and to the
disclaimer of warranties that are included in the Covered
Source.
1.12 'Licensee' or 'You' means any person exercising rights under
this Licence.
1.13 'Licensor' means a natural or legal person who creates or
modifies Covered Source. A person may be a Licensee and a
Licensor at the same time.
1.14 'Convey' means to communicate to the public or distribute.
2 Applicability
2.1 This Licence governs the use, copying, modification, Conveying
of Covered Source and Products, and the Making of Products. By
exercising any right granted under this Licence, You irrevocably
accept these terms and conditions.
2.2 This Licence is granted by the Licensor directly to You, and
shall apply worldwide and without limitation in time.
2.3 You shall not attempt to restrict by contract or otherwise the
rights granted under this Licence to other Licensees.
2.4 This Licence is not intended to restrict fair use, fair dealing,
or any other similar right.
3 Copying, Modifying and Conveying Covered Source
3.1 You may copy and Convey verbatim copies of Covered Source, in
any medium, provided You retain all Notices.
3.2 You may modify Covered Source, other than Notices, provided that
You irrevocably undertake to make that modified Covered Source
available from a Source Location should You Convey a Product in
circumstances where the recipient does not otherwise receive a
copy of the modified Covered Source. In each case subsection 3.3
shall apply.
You may only delete Notices if they are no longer applicable to
the corresponding Covered Source as modified by You and You may
add additional Notices applicable to Your modifications.
3.3 You may Convey modified Covered Source (with the effect that You
shall also become a Licensor) provided that You:
a) retain Notices as required in subsection 3.2;
b) add a Notice to the modified Covered Source stating that You
have modified it, with the date and brief description of how
You have modified it;
c) add a Source Location Notice for the modified Covered Source
if You Convey in circumstances where the recipient does not
otherwise receive a copy of the modified Covered Source; and
d) license the modified Covered Source under the terms and
conditions of this Licence (or, as set out in subsection
8.3, a later version, if permitted by the licence of the
original Covered Source). Such modified Covered Source must
be licensed as a whole, but excluding Available Components
contained in it or External Material to which it is
interfaced, which remain licensed under their own applicable
licences.
4 Making and Conveying Products
4.1 You may Make Products, and/or Convey them, provided that You
either provide each recipient with a copy of the Complete Source
or ensure that each recipient is notified of the Source Location
of the Complete Source. That Complete Source includes Covered
Source and You must accordingly satisfy Your obligations set out
in subsection 3.3. If specified in a Notice, the Product must
visibly and securely display the Source Location on it or its
packaging or documentation in the manner specified in that
Notice.
4.2 Where You Convey a Product which incorporates External Material,
the Complete Source for that Product which You are required to
provide under subsection 4.1 need not include any Source for the
External Material.
4.3 You may license Products under terms of Your choice, provided
that such terms do not restrict or attempt to restrict any
recipients' rights under this Licence to the Covered Source.
5 Research and Development
You may Convey Covered Source, modified Covered Source or Products to
a legal entity carrying out development, testing or quality assurance
work on Your behalf provided that the work is performed on terms which
prevent the entity from both using the Source or Products for its own
internal purposes and Conveying the Source or Products or any
modifications to them to any person other than You. Any modifications
made by the entity shall be deemed to be made by You pursuant to
subsection 3.2.
6 DISCLAIMER AND LIABILITY
6.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
are provided 'as is' and any express or implied warranties,
including, but not limited to, implied warranties of
merchantability, of satisfactory quality, non-infringement of
third party rights, and fitness for a particular purpose or use
are disclaimed in respect of any Source or Product to the
maximum extent permitted by law. The Licensor makes no
representation that any Source or Product does not or will not
infringe any patent, copyright, trade secret or other
proprietary right. The entire risk as to the use, quality, and
performance of any Source or Product shall be with You and not
the Licensor. This disclaimer of warranty is an essential part
of this Licence and a condition for the grant of any rights
granted under this Licence.
6.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
the maximum extent permitted by law, have no liability for
direct, indirect, special, incidental, consequential, exemplary,
punitive or other damages of any character including, without
limitation, procurement of substitute goods or services, loss of
use, data or profits, or business interruption, however caused
and on any theory of contract, warranty, tort (including
negligence), product liability or otherwise, arising in any way
in relation to the Covered Source, modified Covered Source
and/or the Making or Conveyance of a Product, even if advised of
the possibility of such damages, and You shall hold the
Licensor(s) free and harmless from any liability, costs,
damages, fees and expenses, including claims by third parties,
in relation to such use.
7 Patents
7.1 Subject to the terms and conditions of this Licence, each
Licensor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in subsections 7.2 and 8.4) patent licence to Make, have
Made, use, offer to sell, sell, import, and otherwise transfer
the Covered Source and Products, where such licence applies only
to those patent claims licensable by such Licensor that are
necessarily infringed by exercising rights under the Covered
Source as Conveyed by that Licensor.
7.2 If You institute patent litigation against any entity (including
a cross-claim or counterclaim in a lawsuit) alleging that the
Covered Source or a Product constitutes direct or contributory
patent infringement, or You seek any declaration that a patent
licensed to You under this Licence is invalid or unenforceable
then any rights granted to You under this Licence shall
terminate as of the date such process is initiated.
8 General
8.1 If any provisions of this Licence are or subsequently become
invalid or unenforceable for any reason, the remaining
provisions shall remain effective.
8.2 You shall not use any of the name (including acronyms and
abbreviations), image, or logo by which the Licensor or CERN is
known, except where needed to comply with section 3, or where
the use is otherwise allowed by law. Any such permitted use
shall be factual and shall not be made so as to suggest any kind
of endorsement or implication of involvement by the Licensor or
its personnel.
8.3 CERN may publish updated versions and variants of this Licence
which it considers to be in the spirit of this version, but may
differ in detail to address new problems or concerns. New
versions will be published with a unique version number and a
variant identifier specifying the variant. If the Licensor has
specified that a given variant applies to the Covered Source
without specifying a version, You may treat that Covered Source
as being released under any version of the CERN-OHL with that
variant. If no variant is specified, the Covered Source shall be
treated as being released under CERN-OHL-S. The Licensor may
also specify that the Covered Source is subject to a specific
version of the CERN-OHL or any later version in which case You
may apply this or any later version of CERN-OHL with the same
variant identifier published by CERN.
You may treat Covered Source licensed under CERN-OHL-W as
licensed under CERN-OHL-S if and only if all Available
Components referenced in the Covered Source comply with the
corresponding definition of Available Component for CERN-OHL-S.
8.4 This Licence shall terminate with immediate effect if You fail
to comply with any of its terms and conditions.
8.5 However, if You cease all breaches of this Licence, then Your
Licence from any Licensor is reinstated unless such Licensor has
terminated this Licence by giving You, while You remain in
breach, a notice specifying the breach and requiring You to cure
it within 30 days, and You have failed to come into compliance
in all material respects by the end of the 30 day period. Should
You repeat the breach after receipt of a cure notice and
subsequent reinstatement, this Licence will terminate
immediately and permanently. Section 6 shall continue to apply
after any termination.
8.6 This Licence shall not be enforceable except by a Licensor
acting as such, and third party beneficiary rights are
specifically excluded.

71
README.md Normal file
View File

@@ -0,0 +1,71 @@
# ADAT USB Audio Interface
FPGA based USB 2.0 High Speed audio interface featuring multiple optical ADAT inputs and outputs
![BlockDiagram](https://user-images.githubusercontent.com/148607/149699910-284d7113-11b3-4edd-9c6e-68ed0b58e31d.png)
## Status / current limitations
* Enumerates as class compliant audio device on Windows and Linux (Mac OS not tested). 2 and 32 channel modes.
* Audio input and output seems to work glitch free.
* Only 48kHz sample rate supported
* Integrated USB2 high speed logic analyzer works
* Runs without dropouts with FlexASIO with a buffer size of 32 samples (0.67ms latency)
* Has a hardware roundtrip latency (USB out -> ADAT out -> cable -> ADAT in -> USB in)
of 2-3 USB2 microframes which is about 0.25ms to 0.375 ms
* Both headphone DACs on the board work now. In two channel mode, they are both wired to channels 0/1.
In 36 channel mode DAC1 is wired to channels 0/1 and DAC2 to channels 2/3
* Both USB PHYs now are operational. USB1 has access to all 32 ADAT I/Os and has 4 extra channels to/from USB2.
USB2 enumerates as a 4-channel sound card which sends/receives audio to/from USB1
* Both USB interfaces will also enumerate as USB MIDI devices and send each other MIDI
* The current board design has not been designed with the case in mind: In the current version of the case,
only ADAT-cables with thin connectors will fit into the holes. Cables with fat connectors will hit the case
wall before they can be fully inserted. This will be fixed in a future iteration of the PCB and case.
* The current case design lacks a guide channel for the LED light pipes. Therefore there is considerable bleed
from lightpipes into each other, and they also can't be positioned exactly over the LEDs.
Will be fixed in the next version of the case.
* Limitation: Currently audio input will not work properly when audio output is inactive.
This should not be a problem for most uses (VoIP, Videoconference, DAW recording).
If you have an important use case which needs this, please file an issue.
## Hardware
The current board design is a custom development board,
based on the QMTech core FPGA boards.
Once the chip shortage is over, it is planned to move to
a complete custom design, including the FPGA.
![P1173938](https://user-images.githubusercontent.com/148607/149684388-dc81b2b4-235a-4fb7-9b58-c8799dd494fb.jpg)
![image](https://user-images.githubusercontent.com/148607/149700539-21e60090-d90e-4338-9a27-27a406f1c2f6.png)
## How to build
1. Download and install [Intel Quartus Lite](https://fpgasoftware.intel.com/?edition=lite)
2. put the bin/ directory of Quartus into your PATH variable:
```bash
export PATH=$PATH:/opt/intelFPGA_lite/21.1/quartus/bin/
```
Of course you need to adjust this to the install directory and version of your particular installation.
3. Set up python venv and install requirements:
```bash
$ cd gateware/
$ ./initialize-python-environment.sh
$ cd ..
```
4. Activate the venv and build
```bash
$ source ./gateware/venv/bin/activate
$ python3 gateware/adat_usb2_audio_interface.py --keep
```
This will create a directory named build/ and after a successful build will directly
try to load the generated bitstream into the FPGA, if an USB-Blaster is connected.
Or, you can flash the bitstream manually, by opening the Quartus GUI with:
```bash
quartus build/*.qpf
```
and then open the programmer application from there.
Alternatively you could directly start the programmer with:
```bash
quartus_pgmw
```

39
firmware/Makefile Normal file
View File

@@ -0,0 +1,39 @@
TARGET = firmware
BAUDRATE = 115200
SERIALPORT ?= /dev/ttyACM0
CROSS ?= riscv64-unknown-elf-
CC = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
CFLAGS = -march=rv32i -mabi=ilp32 -g -Os -Wall -Werror
LDFLAGS = -Tsoc.ld -Triscv_standalone.ld -nostdlib
SOURCES = \
start.S \
$(TARGET).c
# By default, build our binary.
all: $(TARGET).bin
#
# Firmware binary.
#
$(TARGET).elf: $(SOURCES) soc.ld resources.h
$(CC) $(CFLAGS) $(LDFLAGS) $(SOURCES) -o $@
$(TARGET).bin: $(TARGET).elf
$(OBJCOPY) -O binary $< $@
#
# Virtual/command targets.
#
.PHONY: clean
clean:
rm -f $(TARGET).elf $(TARGET).bin

71
firmware/firmware.c Normal file
View File

@@ -0,0 +1,71 @@
/**
* Copyright (c) 2020 Great Scott Gadgets <info@greatscottgadgets.com>
* Copyright (c) 2022 Hans Baier <hansfbaier@gmail.com>
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>
#include <stdint.h>
#include "resources.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
//
// Support functions.
//
/**
* Transmits a single charater over our example UART.
*/
void print_char(char c)
{
while(!uart_tx_rdy_read());
uart_tx_data_write(c);
}
/**
* Transmits a string over our UART.
*/
void uart_puts(char *str)
{
for (char *c = str; *c; ++c) {
if (*c == '\n') {
print_char('\r');
}
print_char(*c);
}
}
/**
* Prints a hex character over our UART.
*/
void print_nibble(uint8_t nibble)
{
static const char hexits[] = "0123456789abcdef";
print_char(hexits[nibble & 0xf]);
}
/**
* Prints a single byte, in hex, over our UART.
*/
void print_byte(uint8_t byte)
{
print_nibble(byte >> 4);
print_nibble(byte & 0xf);
}
//
// Core application.
//
int main(void)
{
uart_puts("SoC started! (built: " __TIME__ ")\n");
while (1) {
for(int i=0; i<(1<<23); i++) ;
uart_puts("Ping...\r\n");
}
}

View File

@@ -0,0 +1,44 @@
OUTPUT_FORMAT("elf32-littleriscv")
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
/* Start of day code. */
.init :
{
*(.init) *(.init.*)
} > rom
.text :
{
*(.text) *(.text.*)
} > rom
.rodata :
{
*(.rodata) *(.rodata.*)
} > rom
.sdata :
{
PROVIDE(__global_pointer$ = .);
*(.sdata) *(.sdata.*)
}
.data :
{
*(.data) *(.data.*)
} > ram
.bss :
{
*(.bss) *(.bss.*)
} > ram
/DISCARD/ :
{
*(.eh_frame) *(.eh_frame.*)
}
}
PROVIDE(__stack_top = ORIGIN(ram) + LENGTH(ram));

35
firmware/start.S Normal file
View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020 Great Scott Gadgets <info@greatscottgadgets.com>
* SPDX-License-Identifier: BSD-3-Clause
*/
.section .init, "ax"
.global _start
_start:
.cfi_startproc
.cfi_undefined ra
/* Set up our global pointer. */
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* Set up our stack. */
la sp, __stack_top
add s0, sp, zero
/*
* NOTE: In most cases, we'd clear the BSS, here.
*
* In our case, our FPGA automaticaly starts with all of our RAM
* initialized to zero; so our BSS comes pre-cleared. We'll skip the
* formality of re-clearing it.
*/
/* Finally, start our main routine. */
jal zero, main
.cfi_endproc
.end

Binary file not shown.

View File

@@ -0,0 +1,775 @@
#!/usr/bin/env python3
#
# Copyright (c) 2021 Hans Baier <hansfbaier@gmail.com>
# SPDX-License-Identifier: CERN-OHL-W-2.0
import os
from amaranth import *
from amaranth.lib.fifo import AsyncFIFOBuffered, AsyncFIFO, SyncFIFOBuffered, SyncFIFO
from amaranth.lib.cdc import FFSynchronizer
from amlib.stream import connect_fifo_to_stream, connect_stream_to_fifo
from amlib.io.i2s import I2STransmitter
from amlib.io.debouncer import Debouncer
from amlib.dsp.convolution.mac import StereoConvolutionMAC, ConvolutionMode
from luna import top_level_cli
from luna.usb2 import USBDevice, \
USBStreamInEndpoint, \
USBStreamOutEndpoint, \
USBIsochronousInMemoryEndpoint, \
USBIsochronousOutStreamEndpoint, \
USBIsochronousInStreamEndpoint
from usb_protocol.types import USBRequestType, USBStandardRequests
from luna.gateware.usb.usb2.device import USBDevice
from adat import ADATTransmitter, ADATReceiver
from adat import EdgeToPulse
from usb_stream_to_channels import USBStreamToChannels
from channels_to_usb_stream import ChannelsToUSBStream
from channel_stream_combiner import ChannelStreamCombiner
from channel_stream_splitter import ChannelStreamSplitter
from bundle_multiplexer import BundleMultiplexer
from bundle_demultiplexer import BundleDemultiplexer
from stereopair_extractor import StereoPairExtractor
from requesthandlers import UAC2RequestHandlers
from debug import setup_ila, add_debug_led_array
from usb_descriptors import USBDescriptors
import wave
import numpy as np
class USB2AudioInterface(Elaboratable):
""" USB Audio Class v2 interface """
# one isochronous packet typically has 6 or 7 samples of 8 channels of 32 bit samples
# 6 samples * 8 channels * 4 bytes/sample = 192 bytes
# 7 samples * 8 channels * 4 bytes/sample = 224 bytes
USB2_NO_CHANNELS = 4
USB1_NO_CHANNELS = 32 + USB2_NO_CHANNELS
USB2_MAX_PACKET_SIZE = int(224 // 8 * USB2_NO_CHANNELS)
USB1_MAX_PACKET_SIZE = int(224 * 4 + USB2_MAX_PACKET_SIZE)
INPUT_CDC_FIFO_DEPTH = 256 * 4
USE_ILA = False
ILA_MAX_PACKET_SIZE = 512
USE_DEBUG_LED_ARRAY = False
USE_CONVOLUTION = False
USE_SOC = False
def __init__(self) -> None:
if self.USE_SOC:
from amlib.soc import SimpleSoC
from lambdasoc.periph.serial import AsyncSerialPeripheral, AsyncSerial
from lambdasoc.periph.timer import TimerPeripheral
self.soc = soc = SimpleSoC()
soc.add_rom("firmware/firmware.bin", 0x4000)
soc.add_ram(0x4000)
self.uart_pins = Record([
('rx', [('i', 1)]),
('tx', [('o', 1)])
])
uart = AsyncSerialPeripheral(core=AsyncSerial(divisor=int(60e6 // 115200), pins=self.uart_pins))
soc.add_peripheral(uart)
timer = TimerPeripheral(24)
soc.add_peripheral(timer)
with open("firmware/soc.ld", 'w') as ld:
soc.generate_ld_script(file=ld)
with open("firmware/resources.h", 'w') as res_header:
soc.generate_c_header(file=res_header)
result = os.system("(cd firmware; make)")
assert result == 0, "compilation failed, aborting...."
print("firmware compilation succeeded.")
super().__init__()
def elaborate(self, platform):
m = Module()
usb1_number_of_channels = self.USB1_NO_CHANNELS
usb1_number_of_channels_bits = Shape.cast(range(usb1_number_of_channels)).width
usb2_number_of_channels = self.USB2_NO_CHANNELS
usb2_number_of_channels_bits = Shape.cast(range(usb2_number_of_channels)).width
audio_bits = 24
samplerate = 48000
adat_number_of_channels = usb1_number_of_channels - usb2_number_of_channels
m.submodules.car = platform.clock_domain_generator()
#
# SoC
#
if self.USE_SOC:
m.submodules.soc = self.soc
uart_pads = platform.request("uart", 0)
m.d.comb += [
uart_pads.tx .eq(self.uart_pins.tx),
self.uart_pins.rx .eq(uart_pads.rx)
]
#
# USB
#
ulpi1 = platform.request("ulpi", 1)
ulpi2 = platform.request("ulpi", 2)
m.submodules.usb1 = usb1 = USBDevice(bus=ulpi1)
m.submodules.usb2 = usb2 = USBDevice(bus=ulpi2)
descriptors = USBDescriptors(ila_max_packet_size=self.ILA_MAX_PACKET_SIZE, \
use_ila=self.USE_ILA)
usb1_control_ep = usb1.add_control_endpoint()
usb1_descriptors = descriptors.create_usb1_descriptors(usb1_number_of_channels, self.USB1_MAX_PACKET_SIZE)
usb1_control_ep.add_standard_request_handlers(usb1_descriptors, blacklist=[
lambda setup: (setup.type == USBRequestType.STANDARD)
& (setup.request == USBStandardRequests.SET_INTERFACE)
])
usb1_class_request_handler = UAC2RequestHandlers()
usb1_control_ep.add_request_handler(usb1_class_request_handler)
usb2_control_ep = usb2.add_control_endpoint()
usb2_descriptors = descriptors.create_usb2_descriptors(usb2_number_of_channels, self.USB2_MAX_PACKET_SIZE)
usb2_control_ep.add_standard_request_handlers(usb2_descriptors, blacklist=[
lambda setup: (setup.type == USBRequestType.STANDARD)
& (setup.request == USBStandardRequests.SET_INTERFACE)
])
usb2_class_request_handler = UAC2RequestHandlers()
usb2_control_ep.add_request_handler(usb2_class_request_handler)
# audio out ports of the host
usb1_ep1_out = USBIsochronousOutStreamEndpoint(
endpoint_number=1, # EP 1 OUT
max_packet_size=self.USB1_MAX_PACKET_SIZE)
usb1.add_endpoint(usb1_ep1_out)
usb2_ep1_out = USBIsochronousOutStreamEndpoint(
endpoint_number=1, # EP 1 OUT
max_packet_size=self.USB2_MAX_PACKET_SIZE)
usb2.add_endpoint(usb2_ep1_out)
# audio rate feedback input ports of the host
usb1_ep1_in = USBIsochronousInMemoryEndpoint(
endpoint_number=1, # EP 1 IN
max_packet_size=4)
usb1.add_endpoint(usb1_ep1_in)
usb2_ep1_in = USBIsochronousInMemoryEndpoint(
endpoint_number=1, # EP 1 IN
max_packet_size=4)
usb2.add_endpoint(usb2_ep1_in)
# audio input ports of the host
usb1_ep2_in = USBIsochronousInStreamEndpoint(
endpoint_number=2, # EP 2 IN
max_packet_size=self.USB1_MAX_PACKET_SIZE)
usb1.add_endpoint(usb1_ep2_in)
usb2_ep2_in = USBIsochronousInStreamEndpoint(
endpoint_number=2, # EP 2 IN
max_packet_size=self.USB2_MAX_PACKET_SIZE)
usb2.add_endpoint(usb2_ep2_in)
# MIDI endpoints
usb1_ep3_out = USBStreamOutEndpoint(
endpoint_number=3, # EP 3 OUT
max_packet_size=USBDescriptors.MAX_PACKET_SIZE_MIDI)
usb1.add_endpoint(usb1_ep3_out)
usb2_ep3_out = USBStreamOutEndpoint(
endpoint_number=3, # EP 3 OUT
max_packet_size=USBDescriptors.MAX_PACKET_SIZE_MIDI)
usb2.add_endpoint(usb2_ep3_out)
usb1_ep3_in = USBStreamInEndpoint(
endpoint_number=3, # EP 3 IN
max_packet_size=USBDescriptors.MAX_PACKET_SIZE_MIDI)
usb1.add_endpoint(usb1_ep3_in)
usb2_ep3_in = USBStreamInEndpoint(
endpoint_number=3, # EP 3 IN
max_packet_size=USBDescriptors.MAX_PACKET_SIZE_MIDI)
usb2.add_endpoint(usb2_ep3_in)
m.d.comb += [
usb1.connect .eq(1),
usb2.connect .eq(1),
# Connect our device as a high speed device
usb1.full_speed_only .eq(0),
usb2.full_speed_only .eq(0),
]
usb1_audio_in_frame_bytes = \
self.calculate_usb_input_frame_size(m, "usb1", usb1_ep1_out, usb1_ep2_in, usb1_number_of_channels, self.USB1_MAX_PACKET_SIZE)
usb2_audio_in_frame_bytes = \
self.calculate_usb_input_frame_size(m, "usb2", usb2_ep1_out, usb2_ep2_in, usb2_number_of_channels, self.USB2_MAX_PACKET_SIZE)
usb1_sof_counter, usb1_to_output_fifo_level, usb1_to_output_fifo_depth, \
usb2_sof_counter, usb2_to_usb1_fifo_level, usb2_to_usb1_fifo_depth = \
self.create_sample_rate_feedback_circuit(m, usb1, usb1_ep1_in, usb2, usb2_ep1_in)
usb1_audio_in_active = self.detect_active_audio_in (m, "usb1", usb1, usb1_ep2_in)
usb2_audio_in_active = self.detect_active_audio_in (m, "usb2", usb2, usb2_ep2_in)
usb2_audio_out_active = self.detect_active_audio_out(m, "usb2", usb2, usb2_ep1_out)
#
# USB <-> Channel Stream conversion
#
m.submodules.usb1_to_channel_stream = usb1_to_channel_stream = \
DomainRenamer("usb")(USBStreamToChannels(usb1_number_of_channels))
m.submodules.usb2_to_channel_stream = usb2_to_channel_stream = \
DomainRenamer("usb")(USBStreamToChannels(usb2_number_of_channels))
m.submodules.usb1_channel_stream_combiner = usb1_channel_stream_combiner = \
DomainRenamer("usb")(ChannelStreamCombiner(adat_number_of_channels, usb2_number_of_channels))
m.submodules.usb1_channel_stream_splitter = usb1_channel_stream_splitter = \
DomainRenamer("usb")(ChannelStreamSplitter(adat_number_of_channels, usb2_number_of_channels))
m.submodules.channels_to_usb1_stream = channels_to_usb1_stream = \
DomainRenamer("usb")(ChannelsToUSBStream(usb1_number_of_channels, max_packet_size=self.USB1_MAX_PACKET_SIZE))
m.submodules.channels_to_usb2_stream = channels_to_usb2_stream = \
DomainRenamer("usb")(ChannelsToUSBStream(usb2_number_of_channels, max_packet_size=self.USB2_MAX_PACKET_SIZE))
usb1_no_channels = Signal(range(usb1_number_of_channels * 2), reset=2)
usb1_no_channels_sync = Signal.like(usb1_no_channels)
usb2_no_channels = Signal(range(usb2_number_of_channels * 2), reset=2)
m.submodules.no_channels_sync_synchronizer = FFSynchronizer(usb1_no_channels, usb1_no_channels_sync, o_domain="sync")
m.d.comb += [
usb1_to_channel_stream.no_channels_in.eq(usb1_no_channels),
channels_to_usb1_stream.no_channels_in.eq(usb1_no_channels),
channels_to_usb1_stream.audio_in_active.eq(usb1_audio_in_active),
usb2_to_channel_stream.no_channels_in.eq(usb2_no_channels),
channels_to_usb2_stream.no_channels_in.eq(usb2_no_channels),
channels_to_usb2_stream.audio_in_active.eq(usb2_audio_in_active),
]
with m.Switch(usb1_class_request_handler.output_interface_altsetting_nr):
with m.Case(2):
m.d.usb += usb1_no_channels.eq(usb1_number_of_channels)
with m.Default():
m.d.usb += usb1_no_channels.eq(2)
with m.Switch(usb2_class_request_handler.output_interface_altsetting_nr):
with m.Case(2):
m.d.usb += usb2_no_channels.eq(usb2_number_of_channels)
with m.Default():
m.d.usb += usb2_no_channels.eq(2)
m.submodules.usb_to_output_fifo = usb1_to_output_fifo = \
AsyncFIFO(width=audio_bits + usb1_number_of_channels_bits + 2, depth=usb1_to_output_fifo_depth, w_domain="usb", r_domain="sync")
m.submodules.usb2_to_usb1_fifo = usb2_to_usb1_fifo = \
DomainRenamer("usb")(SyncFIFOBuffered(width=audio_bits + usb2_number_of_channels_bits + 2, depth=usb2_to_usb1_fifo_depth))
m.submodules.bundle_demultiplexer = bundle_demultiplexer = BundleDemultiplexer()
m.submodules.bundle_multiplexer = bundle_multiplexer = DomainRenamer("fast")(BundleMultiplexer())
adat_transmitters = []
adat_receivers = []
adat_pads = []
for i in range(1, 5):
transmitter = ADATTransmitter(fifo_depth=9*4)
setattr(m.submodules, f"adat{i}_transmitter", transmitter)
adat_transmitters.append(transmitter)
receiver = DomainRenamer("fast")(ADATReceiver(platform.fast_domain_clock_freq))
setattr(m.submodules, f"adat{i}_receiver", receiver)
adat_receivers.append(receiver)
adat_pads.append(platform.request("toslink", i))
#
# signal path: USB ===> ADAT transmitters
#
audio_bits_end = audio_bits
channel_bits_start = audio_bits
usb1_channel_bits_end = channel_bits_start + usb1_number_of_channels_bits
usb1_first_bit_pos = usb1_channel_bits_end
usb1_last_bit_pos = usb1_first_bit_pos + 1
m.d.comb += [
# convert USB stream to channel splitter to (output audio, USB2 audio IN)
usb1_to_channel_stream.usb_stream_in.stream_eq(usb1_ep1_out.stream),
usb1_channel_stream_splitter.combined_channel_stream_in.stream_eq(usb1_to_channel_stream.channel_stream_out),
*connect_stream_to_fifo(usb1_channel_stream_splitter.lower_channel_stream_out, usb1_to_output_fifo),
usb1_to_output_fifo.w_data[channel_bits_start:usb1_channel_bits_end]
.eq(usb1_channel_stream_splitter.lower_channel_stream_out.channel_nr),
usb1_to_output_fifo.w_data[usb1_first_bit_pos]
.eq(usb1_channel_stream_splitter.lower_channel_stream_out.first),
usb1_to_output_fifo.w_data[usb1_last_bit_pos]
.eq(usb1_channel_stream_splitter.lower_channel_stream_out.last),
usb1_to_output_fifo.r_en .eq(bundle_demultiplexer.channel_stream_in.ready),
usb1_to_output_fifo_level .eq(usb1_to_output_fifo.w_level),
# demultiplex channel stream to the different transmitters
bundle_demultiplexer.channel_stream_in.payload.eq(usb1_to_output_fifo.r_data[0:audio_bits_end]),
bundle_demultiplexer.channel_stream_in.channel_nr.eq(usb1_to_output_fifo.r_data[channel_bits_start:usb1_channel_bits_end]),
bundle_demultiplexer.channel_stream_in.last.eq(usb1_to_output_fifo.r_data[-1]),
bundle_demultiplexer.channel_stream_in.valid.eq(usb1_to_output_fifo.r_rdy & usb1_to_output_fifo.r_en),
bundle_demultiplexer.no_channels_in.eq(usb1_no_channels_sync),
]
# wire up transmitters / receivers
for i in range(4):
m.d.comb += [
# transmitters
adat_transmitters[i].sample_in .eq(bundle_demultiplexer.bundles_out[i].payload),
adat_transmitters[i].addr_in .eq(bundle_demultiplexer.bundles_out[i].channel_nr),
adat_transmitters[i].last_in .eq(bundle_demultiplexer.bundles_out[i].last),
adat_transmitters[i].valid_in .eq(bundle_demultiplexer.bundles_out[i].valid),
bundle_demultiplexer.bundles_out[i].ready.eq(adat_transmitters[i].ready_out),
adat_transmitters[i].user_data_in .eq(0),
adat_pads[i].tx.eq(adat_transmitters[i].adat_out),
# receivers
adat_receivers[i].adat_in.eq(adat_pads[i].rx),
# wire up receive FIFO to ADAT receiver
bundle_multiplexer.no_channels_in[i] .eq(8),
bundle_multiplexer.bundles_in[i].payload .eq(adat_receivers[i].sample_out),
bundle_multiplexer.bundles_in[i].channel_nr .eq(adat_receivers[i].addr_out),
bundle_multiplexer.bundles_in[i].valid .eq(adat_receivers[i].output_enable),
bundle_multiplexer.bundles_in[i].last .eq(adat_receivers[i].addr_out == 7),
bundle_multiplexer.bundle_active_in[i] .eq(adat_receivers[i].synced_out),
]
#
# signal path: ADAT receivers ===> USB
#
m.submodules.input_to_usb_fifo = input_to_usb_fifo = \
AsyncFIFOBuffered(width=audio_bits + usb1_number_of_channels_bits + 2, depth=self.INPUT_CDC_FIFO_DEPTH, w_domain="fast", r_domain="usb")
chnr_start = audio_bits
input_chnr_end = chnr_start + adat_number_of_channels
input_channel_nr = input_to_usb_fifo.r_data[chnr_start:input_chnr_end]
first_channel = 0
input_last_channel = (adat_number_of_channels - 1)
m.d.comb += [
# wire up receive FIFO to bundle multiplexer
input_to_usb_fifo.w_data[0:chnr_start] .eq(bundle_multiplexer.channel_stream_out.payload),
input_to_usb_fifo.w_data[chnr_start:input_chnr_end] .eq(bundle_multiplexer.channel_stream_out.channel_nr),
input_to_usb_fifo.w_en .eq(bundle_multiplexer.channel_stream_out.valid & input_to_usb_fifo.w_rdy),
bundle_multiplexer.channel_stream_out.ready.eq(input_to_usb_fifo.w_rdy),
# convert audio stream to USB stream
# connect ADAT channels to combiner
usb1_channel_stream_combiner.lower_channel_stream_in.payload .eq(input_to_usb_fifo.r_data[0:chnr_start]),
usb1_channel_stream_combiner.lower_channel_stream_in.channel_nr .eq(input_channel_nr),
usb1_channel_stream_combiner.lower_channel_stream_in.first .eq(input_channel_nr == first_channel),
usb1_channel_stream_combiner.lower_channel_stream_in.last .eq(input_channel_nr == input_last_channel),
usb1_channel_stream_combiner.lower_channel_stream_in.valid .eq(input_to_usb_fifo.r_rdy),
input_to_usb_fifo.r_en.eq(usb1_channel_stream_combiner.lower_channel_stream_in.ready),
# connect combiner output to USB1
channels_to_usb1_stream.channel_stream_in.stream_eq(usb1_channel_stream_combiner.combined_channel_stream_out),
channels_to_usb1_stream.data_requested_in .eq(usb1_ep2_in.data_requested),
channels_to_usb1_stream.frame_finished_in .eq(usb1_ep2_in.frame_finished),
# wire up USB1 audio IN
usb1_ep2_in.stream.stream_eq(channels_to_usb1_stream.usb_stream_out),
]
#
# signal path: USB2 <-> USB1
#
usb2_channel_bits_end = channel_bits_start + usb2_number_of_channels_bits
usb2_first_bit_pos = usb2_channel_bits_end
usb2_last_bit_pos = usb2_first_bit_pos + 1
usb2_channel_nr = usb2_to_usb1_fifo.r_data[chnr_start:usb2_channel_bits_end]
m.d.comb +=[
usb2_to_channel_stream.usb_stream_in.stream_eq(usb2_ep1_out.stream),
*connect_stream_to_fifo(usb2_to_channel_stream.channel_stream_out, usb2_to_usb1_fifo),
usb2_to_usb1_fifo.w_data[channel_bits_start:usb2_channel_bits_end]
.eq(usb2_to_channel_stream.channel_stream_out.channel_nr),
usb2_to_usb1_fifo.w_data[usb2_first_bit_pos]
.eq(usb2_to_channel_stream.channel_stream_out.first),
usb2_to_usb1_fifo.w_data[usb2_last_bit_pos]
.eq(usb2_to_channel_stream.channel_stream_out.last),
usb2_to_usb1_fifo_level
.eq(usb2_to_usb1_fifo.w_level),
# connect USB2 OUT channels to USB1 IN
usb1_channel_stream_combiner.upper_channels_active_in .eq(~usb2.suspended & usb2_audio_out_active),
usb1_channel_stream_combiner.upper_channel_stream_in.payload .eq(usb2_to_usb1_fifo.r_data[0:chnr_start]),
usb1_channel_stream_combiner.upper_channel_stream_in.channel_nr .eq(usb2_channel_nr),
usb1_channel_stream_combiner.upper_channel_stream_in.first .eq(usb2_to_usb1_fifo.r_data[usb2_first_bit_pos]),
usb1_channel_stream_combiner.upper_channel_stream_in.last .eq(usb2_to_usb1_fifo.r_data[usb2_last_bit_pos]),
usb1_channel_stream_combiner.upper_channel_stream_in.valid .eq(usb2_to_usb1_fifo.r_rdy),
usb2_to_usb1_fifo.r_en.eq(usb1_channel_stream_combiner.upper_channel_stream_in.ready),
# connect USB2 IN channels to USB1 OUT
channels_to_usb2_stream.channel_stream_in.stream_eq(usb1_channel_stream_splitter.upper_channel_stream_out),
channels_to_usb2_stream.data_requested_in .eq(usb2_ep2_in.data_requested),
channels_to_usb2_stream.frame_finished_in .eq(usb2_ep2_in.frame_finished),
usb2_ep2_in.stream.stream_eq(channels_to_usb2_stream.usb_stream_out),
]
#
# I2S DACs
#
dac1_fifo_depth = 32 if self.USE_CONVOLUTION else 16 #when introducing delay with the convolver we need a larger fifo
m.submodules.dac1_transmitter = dac1 = DomainRenamer("usb")(I2STransmitter(sample_width=audio_bits, fifo_depth=dac1_fifo_depth))
m.submodules.dac2_transmitter = dac2 = DomainRenamer("usb")(I2STransmitter(sample_width=audio_bits))
m.submodules.dac1_extractor = dac1_extractor = DomainRenamer("usb")(StereoPairExtractor(usb1_number_of_channels, usb1_to_output_fifo_depth))
m.submodules.dac2_extractor = dac2_extractor = DomainRenamer("usb")(StereoPairExtractor(usb1_number_of_channels, usb1_to_output_fifo_depth))
dac1_pads = platform.request("i2s", 1)
dac2_pads = platform.request("i2s", 2)
# divide bitclock to get word clock
# each half cycle has 32 bits in it
lrclk = Signal(reset=1)
bit_counter = Signal(6)
m.d.dac += bit_counter.eq(bit_counter + 1)
m.d.comb += lrclk.eq(bit_counter[-1])
# hardwire DAC1 to channels 0/1 and DAC2 to 2/3
# until making it switchable via USB request
m.d.comb += [
dac1_extractor.selected_channel_in.eq(0),
# if stereo mode is enabled we want the second DAC to be wired
# to main lef/right channels, just as the first one
dac2_extractor.selected_channel_in.eq(Mux(usb1_no_channels == 2, 0, 2)),
]
if self.USE_CONVOLUTION:
enable_convolver = Signal()
# load the IR data
with wave.open('IRs/DT990_crossfeed_4800taps.wav', 'rb') as wav:
ir_data = wav.readframes(wav.getnframes())
ir_sample_rate = wav.getframerate()
ir_sig = np.zeros((len(ir_data) // 6, 2), dtype='int32')
for i in range(0, len(ir_sig), 6):
ir_sig[i // 6, 0] = int.from_bytes(ir_data[i:i + 3], byteorder='little', signed=True)
ir_sig[i // 6, 1] = int.from_bytes(ir_data[i + 3:i + 6], byteorder='little', signed=True)
# tapcount 4096 - more is failing to synthesize right now. 4800 would be the goal for 100ms.
taps = ir_sig[:4096,:]
m.submodules.convolver = convolver = DomainRenamer("usb")(StereoConvolutionMAC(taps=taps, samplerate=samplerate, clockfrequency=60e6,
bitwidth=audio_bits, convolutionMode=ConvolutionMode.CROSSFEED))
# validate the IR file
assert ir_sample_rate == samplerate, f"Unsupported samplerate {ir_sample_rate} for IR file. Required samplerate is {samplerate}"
for tap in range(len(taps)):
assert -1 * 2 ** (audio_bits - 1) <= taps[tap, 0] <= 1 * 2 ** (audio_bits - 1) - 1,\
f"Tap #{tap} is out of range for bitwidth {audio_bits}: {taps[tap, 0]}"
else:
convolver = None
enable_convolver = None
self.wire_up_dac(m, usb1_to_channel_stream, dac1_extractor, dac1, lrclk, dac1_pads, convolver, enable_convolver)
self.wire_up_dac(m, usb1_to_channel_stream, dac2_extractor, dac2, lrclk, dac2_pads)
if self.USE_CONVOLUTION:
# the convolver can be toggled in-/active either via the first button on the devboard or via the
# TOGGLE_CONVOLUTION(1) vendor request
m.submodules.button_debouncer = button_debouncer = Debouncer()
m.submodules.request_debouncer = request_debouncer = Debouncer()
m.d.comb += [
button_debouncer.btn_in.eq(platform.request("core_button")[0]),
request_debouncer.btn_in.eq(usb1_class_request_handler.enable_convolution)
]
with m.If(button_debouncer.btn_up_out | request_debouncer.btn_up_out): # toggle convolution on/off
m.d.sync += enable_convolver.eq(~enable_convolver)
m.d.comb += dac1.enable_in.eq(0) # reset the DAC once we toggle its signal source
#
# USB => output FIFO level debug signals
#
min_fifo_level = Signal.like(usb1_to_output_fifo_level, reset=usb1_to_output_fifo_depth)
max_fifo_level = Signal.like(usb1_to_output_fifo_level)
with m.If(usb1_to_output_fifo_level > max_fifo_level):
m.d.sync += max_fifo_level.eq(usb1_to_output_fifo_level)
with m.If(usb1_to_output_fifo_level < min_fifo_level):
m.d.sync += min_fifo_level.eq(usb1_to_output_fifo_level)
#
# USB MIDI
#
usb_midi_fifo_depth = USBDescriptors.MAX_PACKET_SIZE_MIDI
m.submodules.usb1_to_usb2_midi_fifo = usb1_to_usb2_midi_fifo = \
DomainRenamer("usb")(SyncFIFOBuffered(width=8+2, depth=usb_midi_fifo_depth))
m.submodules.usb2_to_usb1_midi_fifo = usb2_to_usb1_midi_fifo = \
DomainRenamer("usb")(SyncFIFOBuffered(width=8+2, depth=usb_midi_fifo_depth))
m.d.comb += [
*connect_stream_to_fifo(usb1_ep3_out.stream, usb1_to_usb2_midi_fifo, firstBit=-2, lastBit=-1),
*connect_fifo_to_stream(usb1_to_usb2_midi_fifo, usb2_ep3_in.stream, firstBit=-2, lastBit=-1),
*connect_stream_to_fifo(usb2_ep3_out.stream, usb2_to_usb1_midi_fifo, firstBit=-2, lastBit=-1),
*connect_fifo_to_stream(usb2_to_usb1_midi_fifo, usb1_ep3_in.stream, firstBit=-2, lastBit=-1),
]
# Internal Logic Analyzer
if self.USE_ILA:
setup_ila(locals(), self.ILA_MAX_PACKET_SIZE, self.USE_CONVOLUTION)
if self.USE_DEBUG_LED_ARRAY:
add_debug_led_array(locals())
usb_aux1 = platform.request("usb_aux", 1)
usb_aux2 = platform.request("usb_aux", 2)
#
# board status LEDs
#
leds = platform.request("leds")
m.d.comb += [
leds.active1.eq(usb1.tx_activity_led | usb1.rx_activity_led),
leds.suspended1.eq(usb1.suspended),
leds.active2.eq(usb2.tx_activity_led | usb2.rx_activity_led),
leds.suspended2.eq(usb2.suspended),
leds.usb1.eq(usb_aux1.vbus),
leds.usb2.eq(usb_aux2.vbus),
]
m.d.comb += [getattr(leds, f"sync{i + 1}").eq(adat_receivers[i].synced_out) for i in range(4)]
if self.USE_CONVOLUTION:
convolver_led = platform.request("core_led", 0)
m.d.comb += convolver_led.o.eq(enable_convolver)
return m
def detect_active_audio_in(self, m, name: str, usb, ep2_in):
audio_in_seen = Signal(name=f"{name}_audio_in_seen")
audio_in_active = Signal(name=f"{name}_audio_in_active")
# detect if we don't have a USB audio IN packet
with m.If(usb.sof_detected):
m.d.usb += [
audio_in_active.eq(audio_in_seen),
audio_in_seen.eq(0),
]
with m.If(ep2_in.data_requested):
m.d.usb += audio_in_seen.eq(1)
return audio_in_active
def detect_active_audio_out(self, m, name: str, usb, ep1_out):
audio_out_seen = Signal(name=f"{name}_audio_out_seen")
audio_out_active = Signal(name=f"{name}_audio_out_active")
# detect if we don't have a USB audio OUT packet
with m.If(usb.sof_detected):
m.d.usb += [
audio_out_active.eq(audio_out_seen),
audio_out_seen.eq(0),
]
with m.If(ep1_out.stream.last):
m.d.usb += audio_out_seen.eq(1)
return audio_out_active
def calculate_usb_input_frame_size(self, m: Module, usb_name: str, ep1_out, ep2_in, number_of_channels: int, max_packet_size: int):
"""calculate the number of bytes one packet of audio input contains"""
audio_in_frame_byte_counter = Signal(range(max_packet_size), name=f"{usb_name}_audio_in_frame_byte_counter", reset=24 * number_of_channels)
audio_in_frame_bytes_counting = Signal(name=f"{usb_name}_audio_in_frame_bytes_counting")
audio_in_frame_bytes = Signal.like(audio_in_frame_byte_counter, name=f"{usb_name}_audio_in_frame_bytes")
with m.If(ep1_out.stream.valid & ep1_out.stream.ready):
with m.If(audio_in_frame_bytes_counting):
m.d.usb += audio_in_frame_byte_counter.eq(audio_in_frame_byte_counter + 1)
with m.If(ep1_out.stream.first):
m.d.usb += [
audio_in_frame_byte_counter.eq(1),
audio_in_frame_bytes_counting.eq(1),
]
with m.If(ep1_out.stream.last):
m.d.usb += [
audio_in_frame_bytes_counting.eq(0),
audio_in_frame_bytes.eq(audio_in_frame_byte_counter + 1),
]
m.d.comb += ep2_in.bytes_in_frame.eq(audio_in_frame_bytes),
return audio_in_frame_bytes
def create_sample_rate_feedback_circuit(self, m: Module, usb1, usb1_ep1_in, usb2, usb2_ep1_in):
#
# USB rate feedback
#
adat_clock_usb = Signal()
m.submodules.adat_clock_usb_sync = FFSynchronizer(ClockSignal("adat"), adat_clock_usb, o_domain="usb")
m.submodules.adat_clock_usb_pulse = adat_clock_usb_pulse = DomainRenamer("usb")(EdgeToPulse())
adat_clock_tick = Signal()
m.d.usb += [
adat_clock_usb_pulse.edge_in.eq(adat_clock_usb),
adat_clock_tick.eq(adat_clock_usb_pulse.pulse_out),
]
usb1_feedback_value = Signal(32, reset=0x60000)
usb1_bit_pos = Signal(5)
usb2_feedback_value = Signal(32, reset=0x60000)
usb2_bit_pos = Signal(5)
# this tracks the number of ADAT frames in N microframes
# with 12.288MHz / 8kHz = 1536 samples per microframe
# we have N = 256, so we need
# math.ceil(math.log2(1536 * 256)) = 19 bits
usb1_adat_clock_counter = Signal(19)
usb2_adat_clock_counter = Signal(19)
# according to USB2 standard chapter 5.12.4.2
# we need at least 2**13 / 2**8 = 2**5 = 32 SOF-frames of
# sample master frequency counter to get the minimal
# precision for the sample frequency estimate
# / 2**8 because the ADAT-clock = 256 times = 2**8
# the sample frequency
# we average over 256 microframes, because that gives
# us the maximum precision needed by the feedback endpoint
usb1_sof_counter = Signal(8)
usb2_sof_counter = Signal(8)
# since samples are constantly consumed from the FIFO
# half the maximum USB packet size should be more than enough
usb1_to_output_fifo_depth = self.USB1_MAX_PACKET_SIZE // 2
usb1_to_output_fifo_level = Signal(range(usb1_to_output_fifo_depth + 1))
print("usb1_to_output_fifo_depth in bits: " + str(usb1_to_output_fifo_level.width))
usb1_fifo_level_feedback = Signal.like(usb1_to_output_fifo_level)
m.d.comb += usb1_fifo_level_feedback.eq(usb1_to_output_fifo_level >> (usb1_to_output_fifo_level.width - 7))
usb2_to_usb1_fifo_depth = self.USB2_MAX_PACKET_SIZE // 2
usb2_to_usb1_fifo_level = Signal(range(usb2_to_usb1_fifo_depth + 1))
print("usb2_to_usb1_fifo_depth in bits: " + str(usb2_to_usb1_fifo_level.width))
usb2_fifo_level_feedback = Signal.like(usb2_to_usb1_fifo_level)
m.d.comb += usb2_fifo_level_feedback.eq(usb2_to_usb1_fifo_level >> (usb2_to_usb1_fifo_level.width - 4))
with m.If(adat_clock_tick):
m.d.usb += [
usb1_adat_clock_counter.eq(usb1_adat_clock_counter + 1),
usb2_adat_clock_counter.eq(usb2_adat_clock_counter + 1),
]
with m.If(usb1.sof_detected):
m.d.usb += usb1_sof_counter.eq(usb1_sof_counter + 1)
with m.If(usb1_sof_counter == 0):
# when feedbackValue == adat_clock_counter the
# FIFO underflows slowly, but also when
# feedbackValue == adat_clock_counter + 1
# the FIFO slowly but surely fills to overflow.
# since both of those feedback values are only one apart,
# we need to start with the slowly overflowing value and
# provide negative feedback proportional to the fill level
# of the FIFO
m.d.usb += [
usb1_feedback_value.eq(usb1_adat_clock_counter + 1 - usb1_fifo_level_feedback),
usb1_adat_clock_counter.eq(0),
]
with m.If(usb2.sof_detected):
m.d.usb += usb2_sof_counter.eq(usb2_sof_counter + 1)
with m.If(usb2_sof_counter == 0):
m.d.usb += [
usb2_feedback_value.eq(usb2_adat_clock_counter + 1 - usb2_fifo_level_feedback),
usb2_adat_clock_counter.eq(0),
]
m.d.comb += [
usb1_ep1_in.bytes_in_frame.eq(4),
usb1_bit_pos.eq(usb1_ep1_in.address << 3),
usb1_ep1_in.value.eq(0xff & (usb1_feedback_value >> usb1_bit_pos)),
usb2_ep1_in.bytes_in_frame.eq(4),
usb2_bit_pos.eq(usb2_ep1_in.address << 3),
usb2_ep1_in.value.eq(0xff & (usb2_feedback_value >> usb2_bit_pos)),
]
return (usb1_sof_counter, usb1_to_output_fifo_level, usb1_to_output_fifo_depth, \
usb2_sof_counter, usb2_to_usb1_fifo_level, usb2_to_usb1_fifo_depth)
def wire_up_dac(self, m, usb_to_channel_stream, dac_extractor, dac, lrclk, dac_pads, convolver=None, enable_convolver=None):
# wire up DAC extractor
m.d.comb += [
dac_extractor.channel_stream_in.valid.eq( usb_to_channel_stream.channel_stream_out.valid
& usb_to_channel_stream.channel_stream_out.ready),
dac_extractor.channel_stream_in.payload.eq(usb_to_channel_stream.channel_stream_out.payload),
dac_extractor.channel_stream_in.channel_nr.eq(usb_to_channel_stream.channel_stream_out.channel_nr),
]
if convolver:
with m.If(enable_convolver):
m.d.comb += [
convolver.signal_in.stream_eq(dac_extractor.channel_stream_out),
dac.stream_in.stream_eq(convolver.signal_out)
]
with m.Else():
m.d.comb += dac.stream_in.stream_eq(dac_extractor.channel_stream_out)
else:
m.d.comb += dac.stream_in.stream_eq(dac_extractor.channel_stream_out)
# wire up DAC/ADC
m.d.comb += [
# wire up DAC/ADC
# in I2S, everything happens on the negedge
# the easiest way to achieve this, is to invert
# the clock signal
dac_pads.sclk.eq(~ClockSignal("adat")),
dac_pads.bclk.eq(~ClockSignal("dac")),
dac_pads.lrclk.eq(~lrclk),
dac_pads.data.eq(dac.serial_data_out),
dac.enable_in.eq(1),
# wire up I2S transmitter
dac.word_select_in.eq(~lrclk),
dac.serial_clock_in.eq(~ClockSignal("dac")),
]
if __name__ == "__main__":
os.environ["AMARANTH_verbose"] = "True"
#os.environ["LUNA_PLATFORM"] = "platforms:ADATFaceCycloneIV"
#os.environ["LUNA_PLATFORM"] = "platforms:ADATFaceCycloneV"
#os.environ["LUNA_PLATFORM"] = "platforms:ADATFaceCyclone10"
#os.environ["LUNA_PLATFORM"] = "platforms:ADATFaceArtix7"
# ECP5 platform
os.environ["AMARANTH_synth_opts"] = "-abc9"
os.environ["AMARANTH_nextpnr_opts"] = "--timing-allow-fail"
os.environ["LUNA_PLATFORM"] = "platforms:ADATFaceColorlight"
top_level_cli(USB2AudioInterface)

View File

@@ -0,0 +1,96 @@
from amaranth.build import *
from amaranth_boards.resources import *
class ADATFaceRev0Baseboard:
@staticmethod
def resources(attrs, colorlight=False):
return [
# LEDS
Resource("leds", 0,
Subsignal("host", Pins ("J_3:60", dir="o")),
Subsignal("usb1", Pins ("J_3:57", dir="o")),
Subsignal("usb2", Pins ("J_3:58", dir="o")),
Subsignal("sync1", Pins ("J_3:55", dir="o")),
Subsignal("sync2", Pins ("J_3:56", dir="o")),
Subsignal("sync3", Pins ("J_3:53", dir="o")),
Subsignal("sync4", Pins ("J_3:54", dir="o")),
Subsignal("active1", Pins ("J_3:51", dir="o")),
Subsignal("active2", Pins ("J_3:49", dir="o")),
Subsignal("suspended1", Pins ("J_3:52", dir="o")),
Subsignal("suspended2", Pins ("J_3:50", dir="o")),
attrs),
# USB
ULPIResource("ulpi", 1,
data="J_3:37 J_3:38 J_3:39 J_3:40 J_3:41 J_3:42 J_3:43 J_3:44",
clk="J_3:27", clk_dir="o", # this needs to be a clock pin of the FPGA or the core won't work
dir="J_3:31", nxt="J_3:33", stp="J_3:29", rst="J_3:34", rst_invert=True, # USB3320 reset is active low
attrs=attrs),
Resource("usb_aux", 1,
Subsignal("vbus", Pins("J_3:30", dir="i")),
Subsignal("id", Pins("J_3:32", dir="o")),
Subsignal("sbu1", Pins("J_3:45", dir="i")),
Subsignal("sbu2", Pins("J_3:46", dir="i")),
attrs),
ULPIResource("ulpi", 2,
data="J_3:17 J_3:18 J_3:19 J_3:20 J_3:21 J_3:22 J_3:23 J_3:24",
clk="J_3:7", clk_dir="o", # this needs to be a clock pin of the FPGA or the core won't work
dir="J_3:11", nxt="J_3:13", stp="J_3:9", rst="J_3:14", rst_invert=True, # USB3320 reset is active low
attrs=attrs),
Resource("usb_aux", 2,
Subsignal("vbus", Pins("J_3:10", dir="i")),
Subsignal("id", Pins("J_3:12", dir="o")),
Subsignal("sbu1", Pins("J_3:25", dir="i")),
Subsignal("sbu2", Pins("J_3:26", dir="i")),
attrs),
Resource("i2s", 1,
Subsignal("sclk", Pins("J_2:53", dir="o")),
Subsignal("bclk", Pins("J_2:54", dir="o")),
Subsignal("data", Pins("J_2:55", dir="o")),
Subsignal("lrclk", Pins("J_2:56", dir="o")),
attrs),
Resource("i2s", 2,
Subsignal("sclk", Pins("J_2:57", dir="o")),
Subsignal("bclk", Pins("J_2:58", dir="o")),
Subsignal("data", Pins("J_2:50", dir="o") if colorlight else Pins("J_2:59", dir="o")),
Subsignal("lrclk", Pins("J_2:52", dir="o") if colorlight else Pins("J_2:60", dir="o")),
attrs),
# TOSLINK
Resource("toslink", 1,
Subsignal("tx", Pins("J_2:49", dir="o")),
Subsignal("rx", Pins("J_2:51", dir="i")),
attrs),
Resource("toslink", 2,
Subsignal("tx", Pins("J_2:33", dir="o")),
Subsignal("rx", Pins("J_2:35", dir="i")),
attrs),
Resource("toslink", 3,
Subsignal("tx", Pins("J_2:23", dir="o")),
Subsignal("rx", Pins("J_2:25", dir="i")),
attrs),
Resource("toslink", 4,
Subsignal("tx", Pins("J_2:18", dir="o") if colorlight else Pins("J_2:7", dir="o")),
Subsignal("rx", Pins("J_2:9", dir="i")),
attrs),
# Debug
SPIResource(0, clk="J_2:12", copi="J_2:8", cipo=None, cs_n="J_2:10", attrs=attrs),
#UARTResource(0, tx="J_2:14", rx="J_2:16", attrs=attrs),
Resource("debug", 0, Pins("J_2:44", dir="o")),
Resource("debug", 1, Pins("J_2:46", dir="o")),
Resource("debug", 2, Pins("J_2:48", dir="o")),
Resource("debug", 3, Pins("J_2:42", dir="o")),
]

View File

@@ -0,0 +1,3 @@
This directory contains platform files which are not maintained
anymore, but still can serve as examples on how to run on
other boards.

View File

@@ -0,0 +1,216 @@
#
# This file is part of LUNA.
#
# Copyright (c) 2020 Great Scott Gadgets <info@greatscottgadgets.com>
# SPDX-License-Identifier: BSD-3-Clause
"""
The DE0 Nano does not have an explicit USB port. Instead, you'll need to connect an external ULPI PHY breakout,
such as https://www.waveshare.com/wiki/USB3300_USB_HS_Board.
See the pin definitions below for connection information (ULPIResource).
The DE0 Nano is an -unsupported- platform! To use it, you'll need to set your LUNA_PLATFORM variable:
> export LUNA_PLATFORM="luna.gateware.platform.de0_nano:DE0NanoPlatform"
"""
import os
import logging
import subprocess
from amaranth import *
from amaranth.build import *
from amaranth.vendor.intel import IntelPlatform
from amaranth_boards.resources import *
from luna.gateware.platform.core import LUNAPlatform
__all__ = ["DE0NanoPlatform"]
class DE0NanoClockAndResetController(Elaboratable):
""" Controller for de0_nano's clocking and global resets. """
def __init__(self, *, clock_frequencies=None, clock_signal_name=None):
pass
def elaborate(self, platform):
m = Module()
# Create our domains; but don't do anything else for them, for now.
m.domains.sync = ClockDomain()
m.domains.usb = ClockDomain()
m.domains.jt51 = ClockDomain()
m.domains.adat = ClockDomain()
m.submodules.mainpll = Instance("ALTPLL",
p_BANDWIDTH_TYPE = "AUTO",
p_CLK0_DIVIDE_BY = 1,
p_CLK0_DUTY_CYCLE = 50,
p_CLK0_MULTIPLY_BY = 1,
p_CLK0_PHASE_SHIFT = 0,
p_INCLK0_INPUT_FREQUENCY = 16666,
p_OPERATION_MODE = "NORMAL",
# Drive our clock from the USB clock
# coming from the USB clock pin of the USB3300
i_inclk = ClockSignal("usb"),
o_clk = ClockSignal("sync"),
)
m.submodules.jt51pll = Instance("ALTPLL",
p_BANDWIDTH_TYPE = "AUTO",
p_CLK0_DIVIDE_BY = 218,
p_CLK0_DUTY_CYCLE = 50,
p_CLK0_MULTIPLY_BY = 13,
p_CLK0_PHASE_SHIFT = 0,
p_INCLK0_INPUT_FREQUENCY = 16666,
p_OPERATION_MODE = "NORMAL",
# Drive our clock from the USB clock
# coming from the USB clock pin of the USB3300
i_inclk = ClockSignal("usb"),
o_clk = ClockSignal("jt51"),
)
m.submodules.adatpll = Instance("ALTPLL",
p_BANDWIDTH_TYPE = "AUTO",
p_CLK0_DIVIDE_BY = 83,
p_CLK0_DUTY_CYCLE = 50,
p_CLK0_MULTIPLY_BY = 17,
p_CLK0_PHASE_SHIFT = 0,
p_INCLK0_INPUT_FREQUENCY = 16666,
p_OPERATION_MODE = "NORMAL",
# Drive our clock from the USB clock
# coming from the USB clock pin of the USB3300
i_inclk = ClockSignal("usb"),
o_clk = ClockSignal("adat"),
)
# Use a blinky to see if the clock signal works
# from amaranth_boards.test.blinky import Blinky
# m.submodules += Blinky()
return m
class DE0NanoPlatform(IntelPlatform, LUNAPlatform):
""" This is a de0_nano board with an USB3300 PHY attached to JP_2 """
name = "de0_nano"
device = "EP4CE22"
package = "F17"
speed = "C6"
default_clk = "clk_50MHz"
clock_domain_generator = DE0NanoClockAndResetController
default_usb_connection = "ulpi"
ignore_phy_vbus = True
def __init__(self, *args, **kwargs):
logging.warning("This platform is not officially supported, and thus not tested. Your results may vary.")
logging.warning("Note also that this platform does not use the DE0 nano's main USB port!")
logging.warning("You'll need to connect a ULPI PHY breakout. See the platform file for more info.")
super().__init__(*args, **kwargs)
#
# I/O resources.
#
resources = [
# Primary clock generator clocks.
Resource("clk_50MHz", 0, Pins("R8", dir="i"), Clock(50e6), Attrs(io_standard="3.3-V LVTTL")),
# USB2 / ULPI section of the USB3300.
ULPIResource("ulpi", 0,
data="JP_2:27 JP_2:25 JP_2:23 JP_2:21 JP_2:19 JP_2:17 JP_2:15 JP_2:13",
clk="JP_2:1", # this needs to be a clock pin of the FPGA or the core won't work
dir="JP_2:18", nxt="JP_2:16", stp="JP_2:14", rst="JP_2:22",
attrs=Attrs(io_standard="3.3-V LVCMOS")
),
UARTResource(0,
# GND on JP1 Pin 12.
rx="JP_1:8", tx="JP_1:10",
attrs=Attrs(io_standard="3.3-V LVTTL")),
*LEDResources(
pins="A15 A13 B13 A11 D1 F3 B1 L3",
attrs=Attrs(io_standard="3.3-V LVTTL")),
*ButtonResources(
pins="J15 E1", invert=True,
attrs=Attrs(io_standard="3.3-V LVTTL")),
*SwitchResources(
pins="M1 T8 B9 M15",
attrs=Attrs(io_standard="3.3-V LVTTL")),
SDRAMResource(0,
clk="R4", cke="L7", cs_n="P6", we_n="C2", ras_n="L2", cas_n="L1",
ba="M7 M6", a="P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4",
dq="G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1", dqm="R6 T5",
attrs=Attrs(io_standard="3.3-V LVTTL")),
# Accelerometer
Resource("acc", 0,
Subsignal("cs_n", Pins("G5", dir="o")),
Subsignal("int", Pins("M2", dir="i")),
Attrs(io_standard="3.3-V LVTTL")),
# I2C is part of the Accelerometer
I2CResource(0,
scl="F2", sda="F1",
attrs=Attrs(io_standard="3.3-V LVTTL")),
# ADC
Resource("adc", 0,
Subsignal("cs_n", Pins("A10")),
Subsignal("saddr", Pins("B10")),
Subsignal("sclk", Pins("B14")),
Subsignal("sdat", Pins("A9")),
Attrs(io_standard="3.3-V LVTTL")),
# ECPS
Resource("epcs", 0,
Subsignal("data0", Pins("H2")),
Subsignal("dclk", Pins("H1")),
Subsignal("ncs0", Pins("D2")),
Subsignal("asd0", Pins("C1")),
Attrs(io_standard="3.3-V LVTTL")),
Resource("adat", 0,
Subsignal("tx", Pins("JP_3:5", dir="o")),
Subsignal("rx", Pins("JP_3:6", dir="i")),
Attrs(io_standard="3.3-V LVTTL")),
]
connectors = [
# PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
Connector("JP", 1, "A8 D3 B8 C3 A2 A3 B3 B4 A4 B5 - - A5 D5 B6 A6 B7 D6 A7 C6 C8 E6 E7 D8 E8 F8 F9 E9 - - C9 D9 E11 E10 C11 B11 A12 D11 D12 B12"),
Connector("JP", 2, "T9 F13 R9 T15 T14 T13 R13 T12 R12 T11 - - T10 R11 P11 R10 N12 P9 N9 N11 L16 K16 R16 L15 P15 P16 R14 N16 - - N15 P14 L14 N14 M10 L13 J16 K15 J13 J14"),
Connector("JP", 3, "- E15 E16 M16 A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15 - - - - - - - - -")
]
@property
def file_templates(self):
templates = super().file_templates
templates["{{name}}.qsf"] += r"""
set_global_assignment -name OPTIMIZATION_MODE "Aggressive Performance"
set_global_assignment -name FITTER_EFFORT "Standard Fit"
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT "Extra"
set_instance_assignment -name DECREASE_INPUT_DELAY_TO_INPUT_REGISTER OFF -to *ulpi*
set_instance_assignment -name INCREASE_DELAY_TO_OUTPUT_PIN OFF -to *ulpi*
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
"""
templates["{{name}}.sdc"] += r"""
create_clock -name "clk_60MHz" -period 16.667 [get_ports "ulpi_0__clk__io"]
"""
return templates
def toolchain_program(self, products, name):
""" Programs the attached de0_nano board via a Quartus programming cable. """
quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm")
with products.extract("{}.sof".format(name)) as bitstream_filename:
subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG",
"--operation", "P;" + bitstream_filename])

View File

@@ -0,0 +1,56 @@
"""
use the LUNA usb config for the tinyFPGA-Bx
add some pins (at random) for adat and debug
create an audio clock domain
Issues:
The audio clock is just a carbon copy of usb 12MHz because the Bx only has one PLL.
"""
import os
import logging
import subprocess
from amaranth import *
from amaranth.build import *
from amaranth_boards.resources import *
from luna.gateware.platform.tinyfpga import TinyFPGABxPlatform, TinyFPGABxDomainGenerator
class TinyBxAdatDomainGenerator(Elaboratable):
""" Creates audio clock domains on top of the LUNA domains for the TinyFPGA Bx. """
def elaborate(self, platform):
m = TinyFPGABxDomainGenerator.elaborate(self, platform)
# Create our domains...
m.domains.adat = ClockDomain()
m.d.comb += [
ClockSignal("adat").eq(ClockSignal("usb")),
ResetSignal("adat").eq(ResetSignal("usb")),
]
return m
class TinyBxAdatPlatform(TinyFPGABxPlatform):
clock_domain_generator = TinyBxAdatDomainGenerator
number_of_channels = 4
bitwidth = 24
def __init__(self):
self.resources += [
Resource("adat", 0,
Subsignal("tx", Pins("A2", dir="o")),
Subsignal("rx", Pins("A1", dir="i")),
Attrs(IO_STANDARD="SB_LVCMOS")),
Resource("debug_led", 0, Pins("C9 A9 B8 A8 B7 A7 B6 A6", dir="o"),
Attrs(IO_STANDARD="SB_LVCMOS")),
]
super().__init__(toolchain="IceStorm")

View File

@@ -0,0 +1,56 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Mon Dec 13 23:39:41 2021
[*]
[dumpfile] "test_BundleDemultiplexerTest_test_smoke.vcd"
[dumpfile_mtime] "Mon Dec 13 23:35:48 2021"
[dumpfile_size] 8023
[savefile] "gateware/bundle_demultiplexer-bench.gtkw"
[timestart] 0
[size] 3828 2090
[pos] -1 -1
*-15.000000 384000 384000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] top.
[sst_width] 65
[signals_width] 510
[sst_expanded] 0
[sst_vpaned_height] 658
@28
top.clk
top.channel_stream__ready
top.channel_stream__valid
@22
top.channel_stream__channel_nr[4:0]
top.channel_stream__payload[23:0]
@200
-Multiplexer
@22
top.bundle_nr[1:0]
top.channel_nr[2:0]
@200
-Output
@28
top.ready
@22
top.output_bundle_0__valid
top.output_bundle_0__channel_nr[2:0]
top.output_bundle_0__payload[23:0]
top.output_bundle_0__first
top.output_bundle_0__last
top.output_bundle_1__valid
top.output_bundle_1__channel_nr[2:0]
top.output_bundle_1__payload[23:0]
top.output_bundle_1__first
top.output_bundle_1__last
top.output_bundle_2__valid
top.output_bundle_2__channel_nr[2:0]
top.output_bundle_2__payload[23:0]
top.output_bundle_2__first
top.output_bundle_2__last
top.output_bundle_3__valid
top.output_bundle_3__channel_nr[2:0]
top.output_bundle_3__payload[23:0]
top.output_bundle_3__first
top.output_bundle_3__last
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,95 @@
import operator
from functools import reduce
from amaranth import *
from amaranth.build import Platform
from amlib.stream import StreamInterface
from amlib.test import GatewareTestCase, sync_test_case
class BundleDemultiplexer(Elaboratable):
NO_CHANNELS_ADAT = 8
SAMPLE_WIDTH = 24
def __init__(self, no_bundles=4):
# parameters
self._no_bundles = no_bundles
self._channel_bits = Shape.cast(range(no_bundles * self.NO_CHANNELS_ADAT)).width
self._bundle_channel_bits = Shape.cast(range(self.NO_CHANNELS_ADAT)).width
# ports
self.no_channels_in = Signal(range(32 + 1))
self.channel_stream_in = StreamInterface(name="channel_stream",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self._channel_bits)])
self.bundles_out = Array(StreamInterface(name=f"output_bundle_{i}",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self._bundle_channel_bits)])
for i in range(no_bundles))
# debug signals
self.bundle_nr = Signal(range(self._no_bundles))
def elaborate(self, platform: Platform) -> Module:
m = Module()
# this is necessary to keep the simulator happy
keep_sync = Signal()
m.d.sync += keep_sync.eq(1)
channel_stream = self.channel_stream_in
bundle_ready = Signal()
bundle_nr = Signal(range(self._no_bundles))
channel_nr = Signal(range(self.NO_CHANNELS_ADAT))
last_channel = Signal(3)
channel_mask = last_channel
m.d.comb += [
bundle_nr .eq(channel_stream.channel_nr >> channel_nr.width),
self.bundle_nr .eq(bundle_nr),
channel_nr .eq(channel_stream.channel_nr & channel_mask),
last_channel .eq(Mux(self.no_channels_in == 2, 1, 7)),
bundle_ready .eq(self.bundles_out[bundle_nr].ready),
channel_stream.ready .eq(bundle_ready),
]
with m.If(bundle_ready & channel_stream.valid):
m.d.comb += [
self.bundles_out[bundle_nr].valid.eq(1),
self.bundles_out[bundle_nr].payload.eq(channel_stream.payload),
self.bundles_out[bundle_nr].channel_nr.eq(channel_nr),
self.bundles_out[bundle_nr].first.eq(channel_nr == 0),
self.bundles_out[bundle_nr].last.eq(channel_nr == last_channel),
]
return m
class BundleDemultiplexerTest(GatewareTestCase):
FRAGMENT_UNDER_TEST = BundleDemultiplexer
FRAGMENT_ARGUMENTS = dict()
def send_one_frame(self, sample: int, channel: int, wait=True):
yield self.dut.channel_stream_in.channel_nr.eq(channel)
yield self.dut.channel_stream_in.payload.eq(sample)
yield self.dut.channel_stream_in.valid.eq(1)
yield
yield self.dut.channel_stream_in.valid.eq(0)
if wait:
yield
@sync_test_case
def test_smoke(self):
dut = self.dut
for bundle in range(4):
yield dut.bundles_out[bundle].ready.eq(1)
yield
yield
for sample in range(3):
for ch in range(4*BundleDemultiplexer.NO_CHANNELS_ADAT):
yield from self.send_one_frame((sample << 8) | ch, ch, wait=False)
yield
yield

View File

@@ -0,0 +1,88 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Tue Dec 14 22:59:41 2021
[*]
[dumpfile] "test_BundleMultiplexerTest_test_inactive_bundle.vcd"
[dumpfile_mtime] "Tue Dec 14 22:35:59 2021"
[dumpfile_size] 17202
[savefile] "gateware/bundle_multiplexer-bench.gtkw"
[timestart] 0
[size] 3828 2090
[pos] -1921 27
*-15.418433 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] top.
[sst_width] 562
[signals_width] 606
[sst_expanded] 1
[sst_vpaned_height] 658
@28
bench.top.clk
@200
-Inputs
@22
bench.top.no_channels0[3:0]
bench.top.no_channels1[3:0]
bench.top.no_channels2[3:0]
bench.top.no_channels3[3:0]
bench.top.input_bundle0__channel_nr[2:0]
bench.top.input_bundle0__last
bench.top.input_bundle0__payload[23:0]
bench.top.input_bundle0__valid
bench.top.input_bundle1__channel_nr[2:0]
bench.top.input_bundle1__last
bench.top.input_bundle1__payload[23:0]
bench.top.input_bundle1__valid
bench.top.input_bundle2__channel_nr[2:0]
bench.top.input_bundle2__last
bench.top.input_bundle2__payload[23:0]
bench.top.input_bundle2__valid
bench.top.input_bundle3__channel_nr[2:0]
bench.top.input_bundle3__last
bench.top.input_bundle3__payload[23:0]
bench.top.input_bundle3__valid
@200
-Module
@22
bench.top.current_bundle[1:0]
bench.top.current_channel[4:0]
@29
bench.top.bundle0_active
bench.top.bundle1_active
bench.top.bundle2_active
bench.top.bundle3_active
@22
bench.top.first_bundle_channel[4:0]
bench.top.bundle0_channel[2:0]
bench.top.bundle0_last
bench.top.bundle0_read_en
bench.top.bundle0_ready
bench.top.bundle0_sample[23:0]
bench.top.bundle1_channel[2:0]
bench.top.bundle1_last
bench.top.bundle1_read_en
bench.top.bundle1_ready
bench.top.bundle1_sample[23:0]
bench.top.bundle2_channel[2:0]
bench.top.bundle2_last
bench.top.bundle2_read_en
bench.top.bundle2_ready
bench.top.bundle2_sample[23:0]
bench.top.bundle3_channel[2:0]
bench.top.bundle3_last
bench.top.bundle3_read_en
bench.top.bundle3_ready
bench.top.bundle3_sample[23:0]
@200
-Output
@28
bench.top.channel_stream__first
bench.top.channel_stream__last
@23
bench.top.channel_stream__channel_nr[4:0]
@22
bench.top.channel_stream__payload[23:0]
@28
bench.top.channel_stream__ready
bench.top.channel_stream__valid
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,103 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Fri Dec 31 08:36:29 2021
[*]
[dumpfile] "test_BundleMultiplexerTest_test_all_sending.vcd"
[dumpfile_mtime] "Fri Dec 31 08:35:29 2021"
[dumpfile_size] 55739
[savefile] "gateware/bundle_multiplexer-bench.gtkw"
[timestart] 0
[size] 3828 2090
[pos] -1 -1
*-15.418433 151500 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] bench.
[treeopen] bench.top.
[sst_width] 562
[signals_width] 606
[sst_expanded] 1
[sst_vpaned_height] 650
@28
bench.top.clk
@200
-Inputs
@22
bench.top.no_channels0[3:0]
bench.top.no_channels1[3:0]
bench.top.no_channels2[3:0]
bench.top.no_channels3[3:0]
bench.top.input_bundle0__channel_nr[2:0]
@28
bench.top.input_bundle0__valid
@22
bench.top.input_bundle1__channel_nr[2:0]
bench.top.input_bundle1__valid
bench.top.input_bundle2__channel_nr[2:0]
bench.top.input_bundle2__valid
bench.top.input_bundle3__channel_nr[2:0]
bench.top.input_bundle3__valid
@200
-FIFOS
@22
bench.top.receive_fifo0.w_level[4:0]
bench.top.receive_fifo1.w_level[4:0]
bench.top.receive_fifo2.w_level[4:0]
@23
bench.top.receive_fifo3.w_level[4:0]
@200
-Module
@22
bench.top.current_bundle[1:0]
bench.top.current_channel[4:0]
@28
bench.top.bundle0_active
bench.top.bundle1_active
bench.top.bundle2_active
bench.top.bundle3_active
@22
bench.top.first_bundle_channel[4:0]
@200
-
@22
bench.top.bundle0_channel[2:0]
bench.top.bundle0_last
bench.top.bundle0_read_en
bench.top.bundle0_ready
bench.top.bundle0_sample[23:0]
@200
-
@22
bench.top.bundle1_channel[2:0]
bench.top.bundle1_last
bench.top.bundle1_read_en
bench.top.bundle1_ready
bench.top.bundle1_sample[23:0]
@200
-
@22
bench.top.bundle2_channel[2:0]
bench.top.bundle2_last
bench.top.bundle2_read_en
bench.top.bundle2_ready
bench.top.bundle2_sample[23:0]
@200
-
@22
bench.top.bundle3_channel[2:0]
bench.top.bundle3_last
bench.top.bundle3_read_en
bench.top.bundle3_ready
bench.top.bundle3_sample[23:0]
@200
-
-Output
@28
bench.top.channel_stream__first
bench.top.channel_stream__last
@22
bench.top.channel_stream__channel_nr[4:0]
bench.top.channel_stream__payload[23:0]
@28
bench.top.channel_stream__ready
bench.top.channel_stream__valid
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,233 @@
from amaranth import *
from amaranth.build import Platform
from amaranth.lib.fifo import SyncFIFO
from amlib.stream import StreamInterface, connect_stream_to_fifo
from amlib.test import GatewareTestCase, sync_test_case
class BundleMultiplexer(Elaboratable):
NO_CHANNELS_ADAT = 8
SAMPLE_WIDTH = 24
FIFO_DEPTH = 32 * NO_CHANNELS_ADAT
def __init__(self, no_bundles=4):
# parameters
self._no_bundles = no_bundles
self._channel_bits = Shape.cast(range(no_bundles * self.NO_CHANNELS_ADAT)).width
self._bundle_channel_bits = Shape.cast(range(self.NO_CHANNELS_ADAT)).width
# ports
self.channel_stream_out = StreamInterface(name="channel_stream",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self._channel_bits)])
self.bundles_in = Array(StreamInterface(name=f"input_bundle{i}",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self._bundle_channel_bits)])
for i in range(no_bundles))
self.bundle_active_in = Array(Signal(name=f"bundle{i}_active") for i in range(no_bundles))
self.no_channels_in = Array(Signal(self._bundle_channel_bits + 1, name=f"no_channels{i}") for i in range(no_bundles))
# debug ports
self.current_bundle = Signal(range(no_bundles))
self.last_bundle = Signal()
self.levels = Array(Signal(5, name=f"rx{i}_fifo_level") for i in range(1,5))
def elaborate(self, platform: Platform) -> Module:
m = Module()
sample_width = self.SAMPLE_WIDTH
bundle_bits = self._bundle_channel_bits
bundle_ready = Array(Signal( name=f"bundle{i}_ready") for i in range(self._no_bundles))
bundle_sample = Array(Signal(sample_width, name=f"bundle{i}_sample") for i in range(self._no_bundles))
bundle_channel = Array(Signal(bundle_bits, name=f"bundle{i}_channel") for i in range(self._no_bundles))
last = Array(Signal( name=f"bundle{i}_last") for i in range(self._no_bundles))
read_enable = Array(Signal( name=f"bundle{i}_read_en") for i in range(self._no_bundles))
for i in range(self._no_bundles):
fifo = SyncFIFO(width=sample_width + bundle_bits + 1, depth=self.FIFO_DEPTH)
setattr(m.submodules, f"receive_fifo{i}", fifo)
m.d.comb += [
*connect_stream_to_fifo(self.bundles_in[i], fifo),
fifo.w_data[sample_width:].eq(self.bundles_in[i].channel_nr),
fifo.w_data[-1].eq(self.bundles_in[i].last),
bundle_ready[i] .eq(fifo.r_rdy),
bundle_sample[i] .eq(fifo.r_data[:sample_width]),
bundle_channel[i] .eq(fifo.r_data[sample_width:sample_width + bundle_bits]),
self.levels[i] .eq(fifo.r_level),
last[i].eq(fifo.r_data[-1]),
fifo.r_en.eq(read_enable[i]),
]
current_bundle = Signal(range(self._no_bundles))
first_bundle_channel = Signal(self._channel_bits)
current_channel = Signal(self._channel_bits)
last_bundle = Signal(self._bundle_channel_bits)
m.d.comb += last_bundle.eq(current_bundle == (self._no_bundles - 1))
m.d.comb += [
self.current_bundle.eq(current_bundle),
self.last_bundle.eq(last_bundle),
]
def handle_last_channel():
with m.If(last_bundle):
m.d.comb += self.channel_stream_out.last.eq(1)
m.d.sync += [
current_bundle.eq(0),
first_bundle_channel.eq(0),
]
with m.Else():
m.d.sync += [
current_bundle.eq(current_bundle + 1),
first_bundle_channel.eq(first_bundle_channel + self.no_channels_in[current_bundle])
]
with m.If(self.channel_stream_out.ready):
# bundle is active (ie. ADAT cable plugged in and synced)
with m.If(self.bundle_active_in[current_bundle]):
with m.If(bundle_ready[current_bundle]):
m.d.comb += [
self.channel_stream_out.payload.eq(bundle_sample[current_bundle]),
self.channel_stream_out.channel_nr.eq(first_bundle_channel + bundle_channel[current_bundle]),
read_enable[current_bundle].eq(1),
self.channel_stream_out.valid.eq(1),
self.channel_stream_out.first.eq((current_bundle == 0) & (bundle_channel[current_bundle] == 0))
]
with m.If(last[current_bundle]):
handle_last_channel()
# bundle inactive (eg. no ADAT/SPDIF cable plugged in or not synced) => fill zeros
with m.Else():
last_channel = Signal()
m.d.comb += [
self.channel_stream_out.payload.eq(0),
self.channel_stream_out.channel_nr.eq(first_bundle_channel + current_channel),
self.channel_stream_out.valid.eq(1),
self.channel_stream_out.first.eq(0),
self.channel_stream_out.last.eq(0),
last_channel.eq(current_channel == (self.no_channels_in[current_bundle] - 1))
]
m.d.sync += current_channel.eq(current_channel + 1)
with m.If(last_channel):
m.d.sync += current_channel.eq(0)
handle_last_channel()
return m
class BundleMultiplexerTest(GatewareTestCase):
FRAGMENT_UNDER_TEST = BundleMultiplexer
FRAGMENT_ARGUMENTS = dict()
def send_one_frame(self, bundle: int, sample: int, channel: int, wait=False):
yield self.dut.bundles_in[bundle].channel_nr.eq(channel)
yield self.dut.bundles_in[bundle].payload.eq(sample)
yield self.dut.bundles_in[bundle].valid.eq(1)
yield self.dut.bundles_in[bundle].first.eq(channel == 0)
yield self.dut.bundles_in[bundle].last.eq(channel == 7)
yield
yield self.dut.bundles_in[bundle].valid.eq(0)
if wait:
yield
def send_bundle_frame(self, bundle: int, sample: int):
ch = list(range(self.dut.NO_CHANNELS_ADAT))
first = ch[0:4]
second = ch[4:]
for channel in first:
yield from self.send_one_frame(bundle, (sample << 8) + channel, channel)
yield self.dut.bundles_in[bundle].valid.eq(0)
yield
yield
for channel in second:
yield from self.send_one_frame(bundle, (sample << 8) + channel, channel)
@sync_test_case
def test_smoke(self):
dut = self.dut
yield
for bundle in range(4):
yield self.dut.no_channels_in[bundle].eq(8)
yield self.dut.bundle_active_in[bundle].eq(1)
yield dut.channel_stream_out.ready.eq(1)
yield
for bundle in range(4):
yield from self.send_bundle_frame(bundle, bundle)
yield
yield
yield
yield
@sync_test_case
def test_inactive_bundle(self):
dut = self.dut
yield
yield dut.channel_stream_out.ready.eq(1)
for bundle in range(4):
yield self.dut.no_channels_in[bundle].eq(8)
if (bundle != 2):
yield dut.bundle_active_in[bundle].eq(1)
yield
for bundle in range(4):
if bundle != 2:
yield from self.send_bundle_frame(bundle, bundle)
if bundle == 0:
yield from self.advance_cycles(8)
yield from self.advance_cycles(16)
@sync_test_case
def test_all_inactive(self):
dut = self.dut
yield
yield dut.channel_stream_out.ready.eq(1)
for bundle in range(4):
yield self.dut.no_channels_in[bundle].eq(8)
yield dut.bundle_active_in[bundle].eq(0)
yield
yield from self.advance_cycles(96)
def send_all_bundle_frame(self):
for channel in range(8):
for bundle in range(4):
yield self.dut.bundles_in[bundle].valid.eq(1)
yield self.dut.bundles_in[bundle].channel_nr.eq(channel)
yield self.dut.bundles_in[bundle].payload.eq((bundle << 16) | channel)
yield self.dut.bundles_in[bundle].first.eq(channel == 0)
yield self.dut.bundles_in[bundle].last.eq(channel == 7)
yield
for bundle in range(4):
yield self.dut.bundles_in[bundle].valid.eq(0)
yield
@sync_test_case
def test_all_sending(self):
dut = self.dut
yield
yield dut.channel_stream_out.ready.eq(1)
for bundle in range(4):
yield self.dut.no_channels_in[bundle].eq(8)
yield dut.bundle_active_in[bundle].eq(1)
yield
for _ in range(20):
yield from self.send_all_bundle_frame()
yield from self.advance_cycles(64)

566
gateware/car.py Normal file
View File

@@ -0,0 +1,566 @@
from amaranth import *
from amaranth.build import *
from amaranth.lib.cdc import ResetSynchronizer
from amaranth.lib.wiring import flipped
from amlib.utils import SimpleClockDivider
class ClockDomainGeneratorBase():
NO_PHASE_SHIFT = 0
def wire_up_reset(self, m, reset):
m.submodules.reset_sync_fast = ResetSynchronizer(reset, domain="fast")
m.submodules.reset_sync_usb = ResetSynchronizer(reset, domain="usb")
m.submodules.reset_sync_sync = ResetSynchronizer(reset, domain="sync")
m.submodules.reset_sync_dac = ResetSynchronizer(reset, domain="dac")
m.submodules.reset_sync_adat = ResetSynchronizer(reset, domain="adat")
class IntelCycloneIVClockDomainGenerator(Elaboratable, ClockDomainGeneratorBase):
ADAT_DIV_48k = 83
ADAT_MULT_48k = 17
ADAT_DIV_44_1k = 62
ADAT_MULT_44_1k = 14
DUTY_CYCLE = 50
def __init__(self, *, clock_frequencies=None, clock_signal_name=None):
pass
def elaborate(self, platform):
m = Module()
# Create our domains
m.domains.usb = ClockDomain("usb")
m.domains.sync = ClockDomain("sync")
m.domains.fast = ClockDomain("fast")
m.domains.adat = ClockDomain("adat")
m.domains.dac = ClockDomain("dac")
clk = flipped(platform.request(platform.default_clk))
main_clocks = Signal(5)
audio_clocks = Signal(4)
fast_clock_48k = Signal()
sys_locked = Signal()
audio_locked = Signal()
fast_locked = Signal()
reset = Signal()
m.submodules.mainpll = Instance("ALTPLL",
p_BANDWIDTH_TYPE = "AUTO",
# USB clock: 60MHz
p_CLK0_DIVIDE_BY = 5,
p_CLK0_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK0_MULTIPLY_BY = 6,
p_CLK0_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# 44.1k ADAT Clock 11.2896 MHz = 44.1kHz * 256
p_CLK1_DIVIDE_BY = self.ADAT_DIV_44_1k,
p_CLK1_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK1_MULTIPLY_BY = self.ADAT_MULT_44_1k,
p_CLK1_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# I2S DAC clock 44.1k = 3.072 MHz = 44.1kHz * 32 bit * 2 channels
p_CLK2_DIVIDE_BY = self.ADAT_DIV_44_1k * 4,
p_CLK2_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK2_MULTIPLY_BY = self.ADAT_MULT_44_1k,
p_CLK2_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# ADAT sampling clock = 44.1kHz * 256 * 8 times oversampling
p_CLK3_DIVIDE_BY = self.ADAT_DIV_44_1k,
p_CLK3_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK3_MULTIPLY_BY = self.ADAT_MULT_44_1k * 8,
p_CLK3_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# ADAT transmit domain clock = 44.1kHz * 5 output terminals
p_CLK4_DIVIDE_BY = self.ADAT_DIV_44_1k,
p_CLK4_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK4_MULTIPLY_BY = self.ADAT_MULT_44_1k * 5,
p_CLK4_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# 50MHz = 20000 picoseconds
p_INCLK0_INPUT_FREQUENCY = 20000,
p_OPERATION_MODE = "NORMAL",
# Drive our clock from the USB clock
# coming from the USB clock pin of the USB3300
i_inclk = clk,
o_clk = main_clocks,
o_locked = sys_locked,
)
m.submodules.audiopll = Instance("ALTPLL",
p_BANDWIDTH_TYPE = "AUTO",
# ADAT clock = 12.288 MHz = 48 kHz * 256
p_CLK0_DIVIDE_BY = self.ADAT_DIV_48k,
p_CLK0_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK0_MULTIPLY_BY = self.ADAT_MULT_48k,
p_CLK0_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# I2S DAC clock 48k = 3.072 MHz = 48 kHz * 32 bit * 2 channels
p_CLK1_DIVIDE_BY = self.ADAT_DIV_48k * 4,
p_CLK1_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK1_MULTIPLY_BY = self.ADAT_MULT_48k,
p_CLK1_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# ADAT sampling clock = 48 kHz * 256 * 8 times oversampling
p_CLK2_DIVIDE_BY = self.ADAT_DIV_48k,
p_CLK2_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK2_MULTIPLY_BY = self.ADAT_MULT_48k * 8,
p_CLK2_PHASE_SHIFT = self.NO_PHASE_SHIFT,
# ADAT transmit domain clock = 48 kHz * 256 * 5 output terminals
p_CLK3_DIVIDE_BY = self.ADAT_DIV_48k,
p_CLK3_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK3_MULTIPLY_BY = self.ADAT_MULT_48k * 5,
p_CLK3_PHASE_SHIFT = self.NO_PHASE_SHIFT,
p_INCLK0_INPUT_FREQUENCY = 16667,
p_OPERATION_MODE = "NORMAL",
i_inclk = main_clocks[0],
o_clk = audio_clocks,
o_locked = audio_locked,
)
m.submodules.fastpll = Instance("ALTPLL",
p_BANDWIDTH_TYPE = "AUTO",
# ADAT sampling clock = 48 kHz * 256 * 8 times oversampling
p_CLK0_DIVIDE_BY = 1,
p_CLK0_DUTY_CYCLE = self.DUTY_CYCLE,
p_CLK0_MULTIPLY_BY = platform.fast_multiplier,
p_CLK0_PHASE_SHIFT = self.NO_PHASE_SHIFT,
p_INCLK0_INPUT_FREQUENCY = 81395,
p_OPERATION_MODE = "NORMAL",
i_inclk = audio_clocks[0],
o_clk = fast_clock_48k,
o_locked = fast_locked,
)
m.d.comb += [
reset.eq(~(sys_locked & audio_locked & fast_locked)),
ClockSignal("fast").eq(fast_clock_48k),
ClockSignal("usb") .eq(main_clocks[0]),
ClockSignal("adat").eq(audio_clocks[0]),
ClockSignal("dac").eq(audio_clocks[1]),
ClockSignal("sync").eq(audio_clocks[3]),
]
self.wire_up_reset(m, reset)
return m
class IntelCycloneVClockDomainGenerator(Elaboratable, ClockDomainGeneratorBase):
def __init__(self, *, clock_frequencies=None, clock_signal_name=None):
pass
def elaborate(self, platform):
m = Module()
# Create our domains
# usb: USB clock: 60MHz
# adat: ADAT clock = 12.288 MHz = 48 kHz * 256
# dac: I2S DAC clock 48k = 3.072 MHz = 48 kHz * 32 bit * 2 channels
# sync: ADAT transmit domain clock = 61.44 MHz = 48 kHz * 256 * 5 output terminals
# fast: ADAT sampling clock = 98.304 MHz = 48 kHz * 256 * 8 times oversampling
m.domains.usb = ClockDomain("usb")
m.domains.sync = ClockDomain("sync")
m.domains.fast = ClockDomain("fast")
m.domains.adat = ClockDomain("adat")
m.domains.dac = ClockDomain("dac")
clk = flipped(platform.request(platform.default_clk))
main_clock = Signal()
audio_clocks = Signal(4)
sys_locked = Signal()
audio_locked = Signal()
reset = Signal()
m.submodules.mainpll = Instance("altera_pll",
p_pll_type="General",
p_pll_subtype="General",
p_fractional_vco_multiplier="false",
p_operation_mode="normal",
p_reference_clock_frequency="50.0 MHz",
p_number_of_clocks="1",
p_output_clock_frequency0="60.000000 MHz",
# Drive our clock from the internal 50MHz clock
i_refclk = clk,
o_outclk = main_clock,
o_locked = sys_locked
)
m.submodules.audiopll = Instance("altera_pll",
p_pll_type="General",
p_pll_subtype="General",
p_fractional_vco_multiplier="true",
p_operation_mode="normal",
p_reference_clock_frequency="60.0 MHz",
p_number_of_clocks="4",
p_output_clock_frequency0="12.288000 MHz",
p_output_clock_frequency1="3.072000 MHz",
p_output_clock_frequency2="61.440000 MHz",
p_output_clock_frequency3="98.304000 MHz",
# Drive our clock from the mainpll
i_refclk=main_clock,
o_outclk=audio_clocks,
o_locked=audio_locked
)
m.d.comb += [
reset.eq(~(sys_locked & audio_locked)),
ClockSignal("usb") .eq(main_clock),
ClockSignal("adat").eq(audio_clocks[0]),
ClockSignal("dac").eq(audio_clocks[1]),
ClockSignal("sync").eq(audio_clocks[2]),
ClockSignal("fast").eq(audio_clocks[3])
]
self.wire_up_reset(m, reset)
return m
class Xilinx7SeriesClockDomainGenerator(Elaboratable, ClockDomainGeneratorBase):
ADAT_DIV_48k = 83
ADAT_MULT_48k = 17
DUTY_CYCLE = 0.5
def __init__(self, *, clock_frequencies=None, clock_signal_name=None):
pass
def elaborate(self, platform):
m = Module()
# Create our domains
m.domains.usb = ClockDomain("usb")
m.domains.sync = ClockDomain("sync")
m.domains.fast = ClockDomain("fast")
m.domains.adat = ClockDomain("adat")
m.domains.dac = ClockDomain("dac")
clk = flipped(platform.request(platform.default_clk))
main_clocks = Signal()
audio_clocks = Signal(4)
fast_clock_48k = Signal()
sys_locked = Signal()
audio_locked = Signal()
fast_locked = Signal()
reset = Signal()
mainpll_feedback = Signal()
audiopll_feedback = Signal()
fastpll_feedback = Signal()
m.submodules.mainpll = Instance("PLLE2_ADV",
p_CLKIN1_PERIOD = 20,
p_BANDWIDTH = "OPTIMIZED",
p_COMPENSATION = "ZHOLD",
p_STARTUP_WAIT = "FALSE",
p_DIVCLK_DIVIDE = 1,
p_CLKFBOUT_MULT = 30,
p_CLKFBOUT_PHASE = self.NO_PHASE_SHIFT,
# 60MHz
p_CLKOUT0_DIVIDE = 25,
p_CLKOUT0_PHASE = self.NO_PHASE_SHIFT,
p_CLKOUT0_DUTY_CYCLE = self.DUTY_CYCLE,
i_CLKFBIN = mainpll_feedback,
o_CLKFBOUT = mainpll_feedback,
i_CLKIN1 = clk,
o_CLKOUT0 = main_clocks,
o_LOCKED = sys_locked,
)
m.submodules.audiopll = Instance("PLLE2_ADV",
p_CLKIN1_PERIOD = 16.666,
p_BANDWIDTH = "OPTIMIZED",
p_COMPENSATION = "ZHOLD",
p_STARTUP_WAIT = "FALSE",
p_DIVCLK_DIVIDE = 1,
p_CLKFBOUT_MULT = self.ADAT_MULT_48k,
p_CLKFBOUT_PHASE = self.NO_PHASE_SHIFT,
# ADAT clock = 12.288 MHz = 48 kHz * 256
p_CLKOUT2_DIVIDE = self.ADAT_DIV_48k,
p_CLKOUT2_PHASE = self.NO_PHASE_SHIFT,
p_CLKOUT2_DUTY_CYCLE = self.DUTY_CYCLE,
# ADAT sampling clock = 48 kHz * 256 * 8 times oversampling
p_CLKOUT0_DIVIDE = self.ADAT_DIV_48k / 8,
p_CLKOUT0_PHASE = self.NO_PHASE_SHIFT,
p_CLKOUT0_DUTY_CYCLE = self.DUTY_CYCLE,
# ADAT transmit domain clock = 48 kHz * 256 * 5 output terminals
p_CLKOUT3_DIVIDE = self.ADAT_DIV_48k / 5,
p_CLKOUT3_PHASE = self.NO_PHASE_SHIFT,
p_CLKOUT3_DUTY_CYCLE = self.DUTY_CYCLE,
i_CLKFBIN = audiopll_feedback,
o_CLKFBOUT = audiopll_feedback,
i_CLKIN1 = main_clocks[0],
o_CLKOUT0 = audio_clocks[2],
o_CLKOUT2 = audio_clocks[0],
o_CLKOUT3 = audio_clocks[3],
o_LOCKED = audio_locked,
)
VCO_SCALER_FAST = 1
m.submodules.fastpll = Instance("PLLE2_ADV",
p_CLKIN1_PERIOD = 10.172,
p_BANDWIDTH = "OPTIMIZED",
p_COMPENSATION = "ZHOLD",
p_STARTUP_WAIT = "FALSE",
p_DIVCLK_DIVIDE = 1,
p_CLKFBOUT_MULT = VCO_SCALER_FAST * platform.fast_multiplier,
p_CLKFBOUT_PHASE = self.NO_PHASE_SHIFT,
# Fast clock = 48 kHz * 256 * 9
p_CLKOUT0_DIVIDE = VCO_SCALER_FAST,
p_CLKOUT0_PHASE = self.NO_PHASE_SHIFT,
p_CLKOUT0_DUTY_CYCLE = self.DUTY_CYCLE,
# I2S DAC clock 48k = 3.072 MHz = 48 kHz * 32 bit * 2 channels
p_CLKOUT1_DIVIDE = VCO_SCALER_FAST * platform.fast_multiplier * 4,
p_CLKOUT1_PHASE = self.NO_PHASE_SHIFT,
p_CLKOUT1_DUTY_CYCLE = self.DUTY_CYCLE,
i_CLKFBIN = fastpll_feedback,
o_CLKFBOUT = fastpll_feedback,
i_CLKIN1 = audio_clocks[2],
o_CLKOUT0 = fast_clock_48k,
o_CLKOUT1 = audio_clocks[1],
o_LOCKED = fast_locked,
)
m.d.comb += [
reset.eq(~(sys_locked & audio_locked & fast_locked)),
ClockSignal("fast").eq(fast_clock_48k),
ClockSignal("usb") .eq(main_clocks[0]),
ClockSignal("adat").eq(audio_clocks[0]),
ClockSignal("dac").eq(audio_clocks[1]),
ClockSignal("sync").eq(audio_clocks[3]),
]
self.wire_up_reset(m, reset)
return m
class ColorlightDomainGenerator(Elaboratable, ClockDomainGeneratorBase):
""" Clock generator for the Colorlight I5 board. """
FastDomainDivider = 7
FastClockFreq = 25e6 * 29 / FastDomainDivider
def __init__(self, clock_frequencies=None):
pass
def elaborate(self, platform):
m = Module()
# Create our domains.
m.domains.sync = ClockDomain("sync")
m.domains.usb = ClockDomain("usb")
m.domains.fast = ClockDomain("fast")
m.domains.adat = ClockDomain("adat")
m.domains.dac = ClockDomain("dac")
# Grab our clock and global reset signals.
clk25 = flipped(platform.request(platform.default_clk))
main_clocks = Signal(5)
audio_clocks = Signal(4)
fast_clock_48k = Signal()
main_locked = Signal()
audio_locked = Signal()
fast_locked = Signal()
reset = Signal()
# USB PLL
main_feedback = Signal()
m.submodules.main_pll = Instance("EHXPLLL",
# Status.
o_LOCK=main_locked,
# PLL parameters...
p_PLLRST_ENA="DISABLED",
p_INTFB_WAKE="DISABLED",
p_STDBY_ENABLE="DISABLED",
p_DPHASE_SOURCE="DISABLED",
p_OUTDIVIDER_MUXA="DIVA",
p_OUTDIVIDER_MUXB="DIVB",
p_OUTDIVIDER_MUXC="DIVC",
p_OUTDIVIDER_MUXD="DIVD",
# 60 MHz
p_CLKI_DIV = 5,
p_CLKOP_ENABLE = "ENABLED",
p_CLKOP_DIV = 10,
p_CLKOP_CPHASE = 15,
p_CLKOP_FPHASE = 0,
p_FEEDBK_PATH = "CLKOP",
p_CLKFB_DIV = 12,
# Clock in.
i_CLKI=clk25,
# Internal feedback.
i_CLKFB=main_feedback,
# Control signals.
i_RST=reset,
i_PHASESEL0=0,
i_PHASESEL1=0,
i_PHASEDIR=1,
i_PHASESTEP=1,
i_PHASELOADREG=1,
i_STDBY=0,
i_PLLWAKESYNC=0,
# Output Enables.
i_ENCLKOP=0,
i_ENCLKOS=0,
# Generated clock outputs.
o_CLKOP=main_feedback,
# Synthesis attributes.
a_FREQUENCY_PIN_CLKI="25",
a_FREQUENCY_PIN_CLKOP="60",
a_ICP_CURRENT="6",
a_LPF_RESISTOR="16",
a_MFG_ENABLE_FILTEROPAMP="1",
a_MFG_GMCREF_SEL="2"
)
audio_feedback = Signal()
audio_locked = Signal()
m.submodules.audio_pll = Instance("EHXPLLL",
# Status.
o_LOCK=audio_locked,
# PLL parameters...
p_PLLRST_ENA="DISABLED",
p_INTFB_WAKE="DISABLED",
p_STDBY_ENABLE="DISABLED",
p_DPHASE_SOURCE="DISABLED",
p_OUTDIVIDER_MUXA="DIVA",
p_OUTDIVIDER_MUXB="DIVB",
p_OUTDIVIDER_MUXC="DIVC",
p_OUTDIVIDER_MUXD="DIVD",
# 25MHz * 29 = 725 MHz PLL freqency
p_CLKI_DIV = 1,
p_CLKOP_ENABLE = "ENABLED",
p_CLKOP_DIV = 29,
p_CLKOP_CPHASE = 0,
p_CLKOP_FPHASE = 0,
# 12.288 MHz = 725 MHz / 59
p_CLKOS_ENABLE = "ENABLED",
p_CLKOS_DIV = 59,
p_CLKOS_CPHASE = 0,
p_CLKOS_FPHASE = 0,
# fast domain clock
p_CLKOS3_ENABLE = "ENABLED",
p_CLKOS3_DIV = self.FastDomainDivider,
p_CLKOS3_CPHASE = 0,
p_CLKOS3_FPHASE = 0,
p_FEEDBK_PATH = "CLKOP",
p_CLKFB_DIV = 1,
# Clock in.
i_CLKI=clk25,
# Internal feedback.
i_CLKFB=audio_feedback,
# Control signals.
i_RST=reset,
i_PHASESEL0=0,
i_PHASESEL1=0,
i_PHASEDIR=1,
i_PHASESTEP=1,
i_PHASELOADREG=1,
i_STDBY=0,
i_PLLWAKESYNC=0,
# Output Enables.
i_ENCLKOP=0,
i_ENCLKOS=0,
i_ENCLKOS3=0,
# Generated clock outputs.
o_CLKOP=audio_feedback,
o_CLKOS=ClockSignal("adat"),
o_CLKOS3=ClockSignal("fast"),
# Synthesis attributes.
a_FREQUENCY_PIN_CLKI="25",
a_FREQUENCY_PIN_CLKOS="12.288",
a_ICP_CURRENT="6",
a_LPF_RESISTOR="16",
a_MFG_ENABLE_FILTEROPAMP="1",
a_MFG_GMCREF_SEL="2"
)
debug0 = platform.request("debug", 0)
debug1 = platform.request("debug", 1)
debug2 = platform.request("debug", 2)
debug3 = platform.request("debug", 3)
m.submodules.bclk_div = clk_div = DomainRenamer("adat")(SimpleClockDivider(4))
reset = Signal()
# Control our resets.
m.d.comb += [
ClockSignal("usb") .eq(main_feedback),
ClockSignal("sync") .eq(ClockSignal("usb")),
ClockSignal("dac") .eq(clk_div.clock_out),
clk_div.clock_enable_in.eq(1),
reset.eq(~(main_locked & audio_locked)),
debug0.eq(ClockSignal("usb")),
debug1.eq(ClockSignal("adat")),
debug2.eq(ClockSignal("fast")),
debug3.eq(reset),
]
self.wire_up_reset(m, reset)
return m

View File

@@ -0,0 +1,153 @@
from amaranth import *
from amaranth.build import Platform
from amlib.stream import StreamInterface
from amlib.test import GatewareTestCase, sync_test_case
class ChannelStreamCombiner(Elaboratable):
SAMPLE_WIDTH = 24
def __init__(self, no_lower_channels, no_upper_channels):
self.no_lower_channels = no_lower_channels
self.no_upper_channels = no_upper_channels
self.lower_channel_bits = Shape.cast(range(no_lower_channels)).width
self.upper_channel_bits = Shape.cast(range(no_upper_channels)).width
self.combined_channel_bits = Shape.cast(range(no_lower_channels + no_upper_channels)).width
self.lower_channel_stream_in = StreamInterface(name="lower_channels",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self.lower_channel_bits)])
self.upper_channels_active_in = Signal()
self.upper_channel_stream_in = StreamInterface(name="upper_channels",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self.lower_channel_bits)])
self.combined_channel_stream_out = StreamInterface(name="combined_channels",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self.combined_channel_bits)])
# debug signals
self.state = Signal(range(3))
self.upper_channel_counter = Signal(self.upper_channel_bits)
# debug signals
self.state = Signal(range(3))
def elaborate(self, platform: Platform) -> Module:
m = Module()
upper_channel_counter = Signal(self.upper_channel_bits)
m.d.comb += self.upper_channel_counter.eq(upper_channel_counter)
with m.FSM() as fsm:
m.d.comb += self.state.eq(fsm.state)
with m.State("LOWER_CHANNELS"):
with m.If( self.combined_channel_stream_out.ready
& self.lower_channel_stream_in.valid):
m.d.comb += [
self.combined_channel_stream_out.payload.eq(self.lower_channel_stream_in.payload),
self.combined_channel_stream_out.channel_nr.eq(self.lower_channel_stream_in.channel_nr),
self.lower_channel_stream_in.ready.eq(1),
self.combined_channel_stream_out.valid.eq(1),
self.combined_channel_stream_out.first.eq(self.lower_channel_stream_in.first),
self.combined_channel_stream_out.last.eq(0),
]
with m.If(self.lower_channel_stream_in.last):
m.d.sync += upper_channel_counter.eq(0)
with m.If(self.upper_channels_active_in):
m.next = "UPPER_CHANNELS"
with m.Else():
m.next = "FILL_UPPER"
with m.State("UPPER_CHANNELS"):
with m.If(self.combined_channel_stream_out.ready):
with m.If(self.upper_channels_active_in):
with m.If(self.upper_channel_stream_in.valid):
m.d.comb += [
self.combined_channel_stream_out.payload.eq(self.upper_channel_stream_in.payload),
self.combined_channel_stream_out.channel_nr.eq(\
self.no_lower_channels +
self.upper_channel_stream_in.channel_nr),
self.upper_channel_stream_in.ready.eq(1),
self.combined_channel_stream_out.valid.eq(1),
self.combined_channel_stream_out.first.eq(0),
self.combined_channel_stream_out.last.eq(self.upper_channel_stream_in.last),
]
with m.If(self.upper_channel_stream_in.last):
with m.If(self.upper_channel_stream_in.channel_nr == 1):
m.d.sync += upper_channel_counter.eq(2)
m.next = "FILL_UPPER"
with m.Else():
m.next = "LOWER_CHANNELS"
# USB is not active: Fill in zeros
with m.Else():
m.next = "FILL_UPPER"
with m.State("FILL_UPPER"):
with m.If(self.combined_channel_stream_out.ready):
with m.If( ~self.upper_channels_active_in
& self.upper_channel_stream_in.valid):
# we just drain all stale data from the upstream FIFOs
# if the upper channels are not active
m.d.comb += self.upper_channel_stream_in.ready.eq(1)
m.d.sync += upper_channel_counter.eq(upper_channel_counter + 1)
m.d.comb += [
self.combined_channel_stream_out.payload.eq(0),
self.combined_channel_stream_out.channel_nr.eq(\
self.no_lower_channels +
upper_channel_counter),
self.combined_channel_stream_out.valid.eq(1),
self.combined_channel_stream_out.first.eq(0),
self.combined_channel_stream_out.last.eq(0),
]
last_channel = upper_channel_counter >= (self.no_upper_channels - 1)
with m.If(last_channel):
m.d.comb += self.combined_channel_stream_out.last.eq(1)
m.next = "LOWER_CHANNELS"
return m
class ChannelStreamCombinerTest(GatewareTestCase):
FRAGMENT_UNDER_TEST = ChannelStreamCombiner
FRAGMENT_ARGUMENTS = dict(no_lower_channels=32, no_upper_channels=6)
def send_lower_frame(self, sample: int, channel: int, wait=False):
yield self.dut.lower_channel_stream_in.channel_nr.eq(channel)
yield self.dut.lower_channel_stream_in.payload.eq(sample)
yield self.dut.lower_channel_stream_in.valid.eq(1)
yield self.dut.lower_channel_stream_in.first.eq(channel == 0)
yield self.dut.lower_channel_stream_in.last.eq(channel == 31)
yield
yield self.dut.lower_channel_stream_in.valid.eq(0)
if wait:
yield
def send_upper_frame(self, sample: int, channel: int, last_channel: int=6, wait=False):
yield self.dut.upper_channel_stream_in.channel_nr.eq(channel)
yield self.dut.upper_channel_stream_in.payload.eq(sample)
yield self.dut.upper_channel_stream_in.valid.eq(1)
yield self.dut.upper_channel_stream_in.first.eq(channel == 0)
yield self.dut.upper_channel_stream_in.last.eq(channel == last_channel)
yield
yield self.dut.upper_channel_stream_in.valid.eq(0)
if wait:
yield
@sync_test_case
def test_smoke(self):
dut = self.dut
yield
yield dut.combined_channel_stream_out.ready.eq(1)
for channel in range(32):
yield from self.send_lower_frame(channel, channel)
yield from self.advance_cycles(13)
for channel in range(32):
yield from self.send_lower_frame(channel, channel)
yield from self.advance_cycles(13)

View File

@@ -0,0 +1,52 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Thu Jan 6 02:29:19 2022
[*]
[dumpfile] "test_ChannelStreamSplitterTest_test_smoke.vcd"
[dumpfile_mtime] "Thu Jan 6 02:28:21 2022"
[dumpfile_size] 5390
[savefile] "gateware/channel_stream_splitter-bench.gtkw"
[timestart] 0
[size] 3828 2090
[pos] -1 -1
*-16.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] bench.
[sst_width] 65
[signals_width] 540
[sst_expanded] 0
[sst_vpaned_height] 658
@28
bench.top.clk
@200
-Input
@22
bench.top.combined_channels__channel_nr[5:0]
bench.top.combined_channels__payload[23:0]
@28
bench.top.combined_channels__first
bench.top.combined_channels__last
bench.top.combined_channels__ready
bench.top.combined_channels__valid
@200
-Output 1
@22
bench.top.lower_channels__channel_nr[4:0]
bench.top.lower_channels__payload[23:0]
@28
bench.top.lower_channels__first
bench.top.lower_channels__last
bench.top.lower_channels__ready
bench.top.lower_channels__valid
@200
-Output 2
@22
bench.top.upper_channels__channel_nr[4:0]
@23
bench.top.upper_channels__payload[23:0]
@28
bench.top.upper_channels__first
bench.top.upper_channels__last
bench.top.upper_channels__ready
bench.top.upper_channels__valid
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,111 @@
from amaranth import *
from amaranth.build import Platform
from amlib.stream import StreamInterface
from amlib.test import GatewareTestCase, sync_test_case
class ChannelStreamSplitter(Elaboratable):
SAMPLE_WIDTH = 24
def __init__(self, no_lower_channels, no_upper_channels, test=False):
self.test = test
self.no_lower_channels = no_lower_channels
self.no_upper_channels = no_upper_channels
self.lower_channel_bits = Shape.cast(range(no_lower_channels)).width
self.upper_channel_bits = Shape.cast(range(no_upper_channels)).width
self.combined_channel_bits = Shape.cast(range(no_lower_channels + no_upper_channels)).width
self.lower_channel_stream_out = StreamInterface(name="lower_channels",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self.lower_channel_bits)])
self.upper_channel_stream_out = StreamInterface(name="upper_channels",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self.lower_channel_bits)])
self.combined_channel_stream_in = StreamInterface(name="combined_channels",
payload_width=self.SAMPLE_WIDTH,
extra_fields=[("channel_nr", self.combined_channel_bits)])
# debug signals
def elaborate(self, platform: Platform) -> Module:
m = Module()
if (self.test):
dummy = Signal()
m.d.sync += dummy.eq(1)
input_stream = self.combined_channel_stream_in
m.d.comb += [
input_stream.ready.eq(self.lower_channel_stream_out.ready & self.upper_channel_stream_out.ready),
]
with m.If(input_stream.valid & input_stream.ready):
with m.If(input_stream.channel_nr < self.no_lower_channels):
m.d.comb += [
self.lower_channel_stream_out.payload.eq(input_stream.payload),
self.lower_channel_stream_out.channel_nr.eq(input_stream.channel_nr),
self.lower_channel_stream_out.first.eq(input_stream.first),
self.lower_channel_stream_out.last.eq(input_stream.channel_nr == (self.no_lower_channels - 1)),
self.lower_channel_stream_out.valid.eq(1),
]
with m.Else():
m.d.comb += [
self.upper_channel_stream_out.payload.eq(input_stream.payload),
self.upper_channel_stream_out.channel_nr.eq(input_stream.channel_nr - self.no_lower_channels),
self.upper_channel_stream_out.first.eq(input_stream.channel_nr == self.no_lower_channels),
self.upper_channel_stream_out.last.eq(input_stream.last),
self.upper_channel_stream_out.valid.eq(1),
]
return m
class ChannelStreamSplitterTest(GatewareTestCase):
FRAGMENT_UNDER_TEST = ChannelStreamSplitter
FRAGMENT_ARGUMENTS = dict(no_lower_channels=32, no_upper_channels=6, test=True)
def send_frame(self, sample: int, channel: int, wait=False):
yield self.dut.combined_channel_stream_in.channel_nr.eq(channel)
yield self.dut.combined_channel_stream_in.payload.eq(sample)
yield self.dut.combined_channel_stream_in.valid.eq(1)
yield self.dut.combined_channel_stream_in.first.eq(channel == 0)
yield self.dut.combined_channel_stream_in.last.eq(channel == 35)
yield
yield self.dut.combined_channel_stream_in.valid.eq(0)
if wait:
yield
@sync_test_case
def test_smoke(self):
dut = self.dut
yield
channels = list(range(36))
yield from self.advance_cycles(3)
yield self.dut.lower_channel_stream_out.ready.eq(1)
yield self.dut.upper_channel_stream_out.ready.eq(1)
for channel in channels:
yield from self.send_frame(channel, channel)
yield from self.advance_cycles(3)
for channel in channels[:20]:
yield from self.send_frame(channel, channel)
yield self.dut.lower_channel_stream_out.ready.eq(0)
yield from self.send_frame(channels[20], channels[20])
yield self.dut.lower_channel_stream_out.ready.eq(1)
for channel in channels[20:32]:
yield from self.send_frame(channel, channel)
yield
for channel in channels[32:34]:
yield from self.send_frame(channel, channel)
yield self.dut.upper_channel_stream_out.ready.eq(0)
yield from self.send_frame(channels[34], channels[34])
yield self.dut.upper_channel_stream_out.ready.eq(1)
for channel in channels[34:]:
yield from self.send_frame(channel, channel)
yield

View File

@@ -0,0 +1,63 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Wed Jan 19 00:02:36 2022
[*]
[dumpfile] "test_ChannelsToUSBStreamTest_test_smoke.vcd"
[dumpfile_mtime] "Tue Jan 18 23:57:47 2022"
[dumpfile_size] 44363
[savefile] "channels_to_usb_stream.gtkw"
[timestart] 0
[size] 3828 2090
[pos] -1921 27
*-16.270115 48200 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] bench.
[treeopen] bench.top.
[treeopen] bench.top.out_fifo.
[sst_width] 447
[signals_width] 495
[sst_expanded] 1
[sst_vpaned_height] 650
@28
bench.top.clk
bench.top.channel_stream__ready
bench.top.channel_stream__valid
@22
bench.top.channel_stream__payload[23:0]
@24
bench.top.channel_stream__channel_nr[2:0]
@22
bench.top.no_channels_in[3:0]
@28
bench.top.data_requested_in
@200
-Channels To USB
@28
bench.top.current_byte[1:0]
bench.top.current_channel[2:0]
@22
bench.top.current_sample[31:0]
@28
bench.top.usb_byte_pos[1:0]
bench.top.feeder_state
@200
-Output FIFO
@28
bench.top.fifo_full
bench.top.fifo_level_insufficient
bench.top.fifo_level_sufficient
bench.top.fifo_postprocess_state
@200
-USB Stream
@28
bench.top.skipping
bench.top.filling
bench.top.usb_byte_pos[1:0]
bench.top.usb_channel[2:0]
@22
bench.top.usb_stream__payload[7:0]
@29
bench.top.usb_stream__valid
@28
bench.top.usb_stream__ready
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,293 @@
from amaranth import *
from amaranth.build import Platform
from amaranth.lib.fifo import SyncFIFO
from amlib.stream import StreamInterface, connect_fifo_to_stream
from amlib.test import GatewareTestCase, sync_test_case
class ChannelsToUSBStream(Elaboratable):
def __init__(self, max_nr_channels=2, sample_width=24, max_packet_size=256):
assert sample_width in [16, 24, 32]
# parameters
self._max_nr_channels = max_nr_channels
self._channel_bits = Shape.cast(range(max_nr_channels)).width
self._sample_width = sample_width
self._fifo_depth = 2 * max_packet_size
# ports
self.no_channels_in = Signal(self._channel_bits + 1)
self.channel_stream_in = StreamInterface(name="channel_stream", payload_width=self._sample_width, extra_fields=[("channel_nr", self._channel_bits)])
self.usb_stream_out = StreamInterface(name="usb_stream")
self.audio_in_active = Signal()
self.data_requested_in = Signal()
self.frame_finished_in = Signal()
# debug signals
self.feeder_state = Signal()
self.current_channel = Signal(self._channel_bits)
self.level = Signal(range(self._fifo_depth + 1))
self.fifo_read = Signal()
self.fifo_full = Signal()
self.fifo_level_insufficient = Signal()
self.done = Signal.like(self.level)
self.out_channel = Signal(self._channel_bits)
self.usb_channel = Signal.like(self.out_channel)
self.usb_byte_pos = Signal.like(2)
self.skipping = Signal()
self.filling = Signal()
def elaborate(self, platform: Platform) -> Module:
m = Module()
m.submodules.out_fifo = out_fifo = SyncFIFO(width=8 + self._channel_bits, depth=self._fifo_depth, fwft=True)
channel_stream = self.channel_stream_in
channel_valid = Signal()
channel_ready = Signal()
out_valid = Signal()
out_stream_ready = Signal()
# latch packet start and end
first_packet_seen = Signal()
frame_finished_seen = Signal()
with m.If(self.data_requested_in):
m.d.sync += [
first_packet_seen.eq(1),
frame_finished_seen.eq(0),
]
with m.If(self.frame_finished_in):
m.d.sync += [
frame_finished_seen.eq(1),
first_packet_seen.eq(0),
]
m.d.comb += [
self.usb_stream_out.payload.eq(out_fifo.r_data[:8]),
self.out_channel.eq(out_fifo.r_data[8:]),
self.usb_stream_out.valid.eq(out_valid),
out_stream_ready.eq(self.usb_stream_out.ready),
channel_valid.eq(channel_stream.valid),
channel_stream.ready.eq(channel_ready),
self.level.eq(out_fifo.r_level),
self.fifo_full.eq(self.level >= (self._fifo_depth - 4)),
self.fifo_read.eq(out_fifo.r_en),
]
with m.If(self.usb_stream_out.valid & self.usb_stream_out.ready):
m.d.sync += self.done.eq(self.done + 1)
with m.If(self.data_requested_in):
m.d.sync += self.done.eq(0)
current_sample = Signal(32 if self._sample_width > 16 else 16)
current_channel = Signal(self._channel_bits)
current_byte = Signal(2 if self._sample_width > 16 else 1)
m.d.comb += self.current_channel.eq(current_channel),
bytes_per_sample = 4
last_byte_of_sample = bytes_per_sample - 1
# USB audio still sends 32 bit samples,
# even if the descriptor says 24
shift = 8 if self._sample_width == 24 else 0
out_fifo_can_write_sample = Signal()
m.d.comb += out_fifo_can_write_sample.eq(
out_fifo.w_rdy
& (out_fifo.w_level < (out_fifo.depth - bytes_per_sample)))
# this FSM handles writing into the FIFO
with m.FSM(name="fifo_feeder") as fsm:
m.d.comb += self.feeder_state.eq(fsm.state)
with m.State("WAIT"):
m.d.comb += channel_ready.eq(out_fifo_can_write_sample)
# discard all channels above no_channels_in
# important for stereo operation
with m.If( out_fifo_can_write_sample
& channel_valid
& (channel_stream.channel_nr < self.no_channels_in)):
m.d.sync += [
current_sample.eq(channel_stream.payload << shift),
current_channel.eq(channel_stream.channel_nr),
]
m.next = "SEND"
with m.State("SEND"):
m.d.comb += [
out_fifo.w_data[:8].eq(current_sample[0:8]),
out_fifo.w_data[8:].eq(current_channel),
out_fifo.w_en.eq(1),
]
m.d.sync += [
current_byte.eq(current_byte + 1),
current_sample.eq(current_sample >> 8),
]
with m.If(current_byte == last_byte_of_sample):
m.d.sync += current_byte.eq(0)
m.next = "WAIT"
channel_counter = Signal.like(self.no_channels_in)
byte_pos = Signal(2)
first_byte = byte_pos == 0
last_byte = byte_pos == 3
with m.If(out_valid & out_stream_ready):
m.d.sync += byte_pos.eq(byte_pos + 1)
with m.If(last_byte):
m.d.sync += channel_counter.eq(channel_counter + 1)
with m.If(channel_counter == (self.no_channels_in - 1)):
m.d.sync += channel_counter.eq(0)
with m.If(self.data_requested_in):
m.d.sync += channel_counter.eq(0)
fifo_level_sufficient = Signal()
m.d.comb += [
self.usb_channel.eq(channel_counter),
self.usb_byte_pos.eq(byte_pos),
fifo_level_sufficient.eq(out_fifo.level >= (self.no_channels_in << 2)),
self.fifo_level_insufficient.eq(~fifo_level_sufficient),
]
with m.If(self.frame_finished_in):
m.d.sync += byte_pos.eq(0)
# this FSM handles reading fron the FIFO
# this FSM provides robustness against
# short reads. On next frame all bytes
# for nonzero channels will be discarded until
# we reach channel 0 again.
with m.FSM(name="fifo_postprocess") as fsm:
with m.State("NORMAL"):
m.d.comb += [
out_fifo.r_en.eq(self.usb_stream_out.ready),
out_valid.eq(out_fifo.r_rdy)
]
with m.If(~self.audio_in_active & out_fifo.r_rdy):
m.next = "DISCARD"
# frame ongoing
with m.Elif(~frame_finished_seen):
# start filling if there are not enough enough samples buffered
# for one channel set of audio samples
last_channel = self.out_channel == (self._max_nr_channels - 1)
with m.If(last_byte & last_channel & ~fifo_level_sufficient):
m.next = "FILL"
with m.If((self.out_channel != channel_counter)):
m.d.comb += [
out_fifo.r_en.eq(0),
self.usb_stream_out.payload.eq(0),
out_valid.eq(1),
self.filling.eq(1),
]
# frame finished: discard extraneous samples
with m.Else():
with m.If(out_fifo.r_rdy & (self.out_channel != 0)):
m.d.comb += [
out_fifo.r_en.eq(1),
out_valid.eq(0),
]
m.d.sync += [
frame_finished_seen.eq(0),
byte_pos.eq(0),
]
m.next = "DISCARD"
with m.State("DISCARD"):
with m.If(out_fifo.r_rdy):
m.d.comb += [
out_fifo.r_en.eq(1),
out_valid.eq(0),
self.skipping.eq(1),
]
with m.If(self.audio_in_active & (self.out_channel == 0)):
m.d.comb += out_fifo.r_en.eq(0)
m.next = "NORMAL"
with m.State("FILL"):
channel_is_ok = fifo_level_sufficient & (self.out_channel == channel_counter)
with m.If(self.frame_finished_in | channel_is_ok):
m.next = "NORMAL"
with m.Else():
m.d.comb += [
out_fifo.r_en.eq(0),
self.usb_stream_out.payload.eq(0),
out_valid.eq(1),
self.filling.eq(1),
]
return m
class ChannelsToUSBStreamTest(GatewareTestCase):
FRAGMENT_UNDER_TEST = ChannelsToUSBStream
FRAGMENT_ARGUMENTS = dict(max_nr_channels=8)
def send_one_frame(self, sample: int, channel: int, wait=True):
yield self.dut.channel_stream_in.channel_nr.eq(channel)
yield self.dut.channel_stream_in.payload.eq(sample)
yield self.dut.channel_stream_in.valid.eq(1)
yield
if wait:
yield
yield
yield
@sync_test_case
def test_smoke(self):
dut = self.dut
yield dut.usb_stream_out.ready.eq(0)
yield dut.frame_finished_in.eq(1)
yield
yield dut.frame_finished_in.eq(0)
yield
yield
yield
yield
yield
yield
yield dut.usb_stream_out.ready.eq(1)
yield from self.send_one_frame(0x030201, 0, wait=False)
yield from self.send_one_frame(0x131211, 1)
yield from self.send_one_frame(0x232221, 2)
yield from self.send_one_frame(0x333231, 3)
# source stream stalls, see if we wait
yield dut.channel_stream_in.valid.eq(0)
for _ in range(7): yield
yield from self.send_one_frame(0x434241, 4)
yield from self.send_one_frame(0x535251, 5)
yield from self.send_one_frame(0x636261, 6)
yield from self.send_one_frame(0x737271, 7, wait=False)
# out stream quits early, see if it
# consumes extraneous bytes
yield dut.usb_stream_out.ready.eq(0)
yield
for _ in range(15): yield
yield dut.frame_finished_in.eq(1)
yield
yield dut.frame_finished_in.eq(0)
for _ in range(35): yield
yield from self.send_one_frame(0x030201, 0)
yield from self.send_one_frame(0x131211, 1)
yield dut.usb_stream_out.ready.eq(1)
yield from self.send_one_frame(0x232221, 2)
yield from self.send_one_frame(0x333231, 3)
yield from self.send_one_frame(0x434241, 4)
yield from self.send_one_frame(0x535251, 5)
yield from self.send_one_frame(0x636261, 6)
yield from self.send_one_frame(0x737271, 7)
yield dut.channel_stream_in.valid.eq(0)
yield
for _ in range(45): yield

587
gateware/debug.py Normal file
View File

@@ -0,0 +1,587 @@
from amaranth import *
from amaranth.lib.cdc import FFSynchronizer, PulseSynchronizer
from amlib.debug.ila import StreamILA, ILACoreParameters
from amlib.stream import StreamInterface
from amlib.io.led import NumberToBitBar
from amlib.io.max7219 import SerialLEDArray
from luna.gateware.usb.usb2.endpoints.stream import USBMultibyteStreamInEndpoint
def add_debug_led_array(v):
self = v['self']
m = v['m']
platform = v['platform']
channels_to_usb1_stream = v['channels_to_usb1_stream']
input_to_usb_fifo = v['input_to_usb_fifo']
usb1_to_output_fifo_level = v['usb1_to_output_fifo_level']
usb1_to_output_fifo_depth = v['usb1_to_output_fifo_depth']
usb2_to_usb1_fifo_level = v['usb2_to_usb1_fifo_level']
usb2_to_usb1_fifo_depth = v['usb2_to_usb1_fifo_depth']
channels_to_usb2_stream = v['channels_to_usb2_stream']
usb2_audio_out_active = v['usb2_audio_out_active']
usb2_audio_in_active = v['usb2_audio_in_active']
bundle_multiplexer = v['bundle_multiplexer']
adat_transmitters = v['adat_transmitters']
usb1_to_usb2_midi_fifo = v['usb1_to_usb2_midi_fifo']
usb2_to_usb1_midi_fifo = v['usb2_to_usb1_midi_fifo']
usb_midi_fifo_depth = v['usb_midi_fifo_depth']
adat1_underflow_count = Signal(16)
with m.If(adat_transmitters[0].underflow_out):
m.d.sync += adat1_underflow_count.eq(adat1_underflow_count + 1)
spi = platform.request("spi")
m.submodules.led_display = led_display = SerialLEDArray(divisor=10, init_delay=24e6, no_modules=2)
rx_level_bars = []
for i in range(1, 5):
rx_level_bar = NumberToBitBar(0, bundle_multiplexer.FIFO_DEPTH, 8)
setattr(m.submodules, f"rx{i}_level_bar", rx_level_bar)
m.d.comb += rx_level_bar.value_in.eq(bundle_multiplexer.levels[i - 1])
rx_level_bars.append(rx_level_bar)
m.submodules.in_bar = in_to_usb_fifo_bar = NumberToBitBar(0, self.INPUT_CDC_FIFO_DEPTH, 8)
m.submodules.in_fifo_bar = channels_to_usb_bar = NumberToBitBar(0, 2 * self.USB1_MAX_PACKET_SIZE, 8)
m.submodules.out_fifo_bar = out_fifo_bar = NumberToBitBar(0, usb1_to_output_fifo_depth, 8)
m.d.comb += [
# LED bar displays
in_to_usb_fifo_bar.value_in.eq(input_to_usb_fifo.r_level),
channels_to_usb_bar.value_in.eq(channels_to_usb1_stream.level >> 3),
out_fifo_bar.value_in.eq(usb1_to_output_fifo_level >> 1),
*[led_display.digits_in[i].eq(Cat(reversed(rx_level_bars[i].bitbar_out))) for i in range(4)],
led_display.digits_in[4].eq(Cat(reversed(in_to_usb_fifo_bar.bitbar_out))),
led_display.digits_in[5].eq(Cat(reversed(channels_to_usb_bar.bitbar_out))),
led_display.digits_in[6].eq(Cat(reversed(out_fifo_bar.bitbar_out))),
led_display.digits_in[7].eq(adat1_underflow_count),
]
usb2 = lambda x: 8 + x
m.submodules.usb2_output_fifo_bar = usb2_output_fifo_bar = NumberToBitBar(0, usb2_to_usb1_fifo_depth, 8)
m.submodules.usb2_input_fifo_bar = usb2_input_fifo_bar = NumberToBitBar(0, channels_to_usb2_stream._fifo_depth, 8)
m.submodules.usb2_to_usb1_bar = usb2_to_usb1_bar = NumberToBitBar(0, usb_midi_fifo_depth, 8)
m.submodules.usb1_to_usb2_bar = usb1_to_usb2_bar = NumberToBitBar(0, usb_midi_fifo_depth, 8)
m.d.comb += [
usb2_output_fifo_bar.value_in.eq(usb2_to_usb1_fifo_level),
usb2_input_fifo_bar.value_in.eq(channels_to_usb2_stream.level),
led_display.digits_in[usb2(0)][0].eq(usb2_audio_out_active),
led_display.digits_in[usb2(0)][7].eq(usb2_audio_in_active),
led_display.digits_in[usb2(1)].eq(Cat(usb2_output_fifo_bar.bitbar_out)),
led_display.digits_in[usb2(2)].eq(Cat(reversed(usb2_input_fifo_bar.bitbar_out))),
led_display.digits_in[usb2(3)].eq(usb2_to_usb1_bar.bitbar_out),
led_display.digits_in[usb2(4)].eq(usb1_to_usb2_bar.bitbar_out),
]
m.d.comb += [
*led_display.connect_to_resource(spi),
led_display.valid_in.eq(1),
]
def setup_ila(v, ila_max_packet_size, use_convolution):
examined_usb = "usb1"
m = v['m']
usb1_sof_counter = v['usb1_sof_counter']
usb1 = v['usb1']
usb1_ep3_in = v['usb1_ep3_in']
usb1_ep3_out = v['usb1_ep3_out']
usb2_ep3_in = v['usb2_ep3_in']
usb2_ep3_out = v['usb2_ep3_out']
ep1_out = v[f'{examined_usb}_ep1_out']
ep2_in = v[f'{examined_usb}_ep2_in']
channels_to_usb_stream = v[f'channels_to_{examined_usb}_stream']
usb_to_channel_stream = v[f'{examined_usb}_to_channel_stream']
usb1_audio_in_active = v['usb1_audio_in_active']
usb2_audio_out_active = v['usb2_audio_out_active']
input_to_usb_fifo = v['input_to_usb_fifo']
usb1_to_output_fifo = v['usb1_to_output_fifo']
usb1_to_output_fifo_level = v['usb1_to_output_fifo_level']
usb1_to_output_fifo_depth = v['usb1_to_output_fifo_depth']
audio_in_frame_bytes = v['usb2_audio_in_frame_bytes']
min_fifo_level = v['min_fifo_level']
max_fifo_level = v['max_fifo_level']
adat_transmitters = v['adat_transmitters']
adat_receivers = v['adat_receivers']
bundle_demultiplexer = v['bundle_demultiplexer']
bundle_multiplexer = v['bundle_multiplexer']
usb1_channel_stream_combiner = v['usb1_channel_stream_combiner']
usb1_channel_stream_splitter = v['usb1_channel_stream_splitter']
usb1_to_usb2_midi_fifo = v['usb1_to_usb2_midi_fifo']
usb2_to_usb1_midi_fifo = v['usb2_to_usb1_midi_fifo']
dac1_extractor = v['dac1_extractor']
dac1 = v['dac1']
convolver = v['convolver']
enable_convolver = v['enable_convolver']
adat_clock = Signal()
m.d.comb += adat_clock.eq(ClockSignal("adat"))
sof_wrap = Signal()
m.d.comb += sof_wrap.eq(usb1_sof_counter == 0)
usb_packet_counter = Signal(10)
with m.If(ep1_out.stream.valid & ep1_out.stream.ready):
m.d.usb += usb_packet_counter.eq(usb_packet_counter + 1)
with m.If(ep1_out.stream.last):
m.d.usb += usb_packet_counter.eq(0)
weird_packet = Signal()
m.d.comb += weird_packet.eq(ep1_out.stream.last & (
usb_packet_counter[0:2] != Const(0b11, 2)
))
strange_input = Signal()
input_active = Signal()
output_active = Signal()
input_or_output_active = Signal()
garbage = Signal()
usb_frame_borders = Signal()
m.d.comb += [
input_active.eq ( channels_to_usb_stream.channel_stream_in.ready
& channels_to_usb_stream.channel_stream_in.valid),
output_active.eq( channels_to_usb_stream.usb_stream_out.ready
& channels_to_usb_stream.usb_stream_out.valid),
input_or_output_active.eq(input_active | output_active),
strange_input.eq( (channels_to_usb_stream.channel_stream_in.payload != 0)
& (channels_to_usb_stream.channel_stream_in.channel_nr > 1)),
garbage.eq(channels_to_usb_stream.skipping | channels_to_usb_stream.filling),
usb_frame_borders.eq(ep2_in.data_requested | ep2_in.frame_finished),
]
fill_count = Signal(16)
with m.If(channels_to_usb_stream.filling):
m.d.usb += fill_count.eq(fill_count + 1)
channels_to_usb_input_frame = [
usb1.sof_detected,
input_to_usb_fifo.r_level,
channels_to_usb_stream.channel_stream_in.channel_nr,
channels_to_usb_stream.channel_stream_in.first,
channels_to_usb_stream.channel_stream_in.last,
input_active,
#channels_to_usb_stream.channel_stream_in.payload,
]
weird_frame_size = Signal()
usb_outputting = Signal()
m.d.comb += usb_outputting.eq(ep1_out.stream.valid & ep1_out.stream.ready)
usb_out_level_maxed = Signal()
m.d.comb += usb_out_level_maxed.eq(usb1_to_output_fifo_level >= (usb1_to_output_fifo_depth - 1))
m.d.comb += weird_frame_size.eq((audio_in_frame_bytes & 0b11) != 0)
channels_to_usb_debug = [
usb2_audio_out_active,
audio_in_frame_bytes,
channels_to_usb_stream.current_channel,
channels_to_usb_stream.channel_stream_in.ready,
channels_to_usb_stream.level,
channels_to_usb_stream.fifo_full,
channels_to_usb_stream.fifo_level_insufficient,
channels_to_usb_stream.out_channel,
channels_to_usb_stream.fifo_read,
channels_to_usb_stream.usb_channel,
channels_to_usb_stream.done,
channels_to_usb_stream.usb_byte_pos,
channels_to_usb_stream.skipping,
channels_to_usb_stream.filling,
ep2_in.data_requested,
ep2_in.frame_finished,
channels_to_usb_stream.usb_stream_out.valid,
channels_to_usb_stream.usb_stream_out.ready,
channels_to_usb_stream.usb_stream_out.first,
channels_to_usb_stream.usb_stream_out.last,
channels_to_usb_stream.usb_stream_out.payload,
]
usb_out_debug = [
usb_to_channel_stream.channel_stream_out.payload,
usb_to_channel_stream.channel_stream_out.channel_nr,
usb_to_channel_stream.channel_stream_out.first,
usb_to_channel_stream.channel_stream_out.last,
#usb1_to_output_fifo_level,
#usb_out_level_maxed
]
usb_channel_outputting = Signal()
m.d.comb += usb_channel_outputting.eq(
usb_out_level_maxed |
usb_to_channel_stream.channel_stream_out.first |
usb_to_channel_stream.channel_stream_out.last |
( usb_to_channel_stream.channel_stream_out.ready &
usb_to_channel_stream.channel_stream_out.valid)
)
ep1_out_fifo_debug = [
audio_in_frame_bytes,
min_fifo_level,
usb1_to_output_fifo_level,
max_fifo_level,
usb1.sof_detected,
]
adat_nr = 0
receiver_debug = [
adat_receivers[adat_nr].sample_out,
adat_receivers[adat_nr].addr_out,
adat_receivers[adat_nr].output_enable,
#adat_receivers[adat_nr].recovered_clock_out,
]
adat_first = Signal()
m.d.comb += adat_first.eq(adat_receivers[adat_nr].output_enable & (adat_receivers[adat_nr].addr_out == 0))
adat_clock = Signal()
m.d.comb += adat_clock.eq(ClockSignal("adat"))
adat_debug = [
adat_clock,
adat_transmitters[adat_nr].adat_out,
adat_receivers[adat_nr].recovered_clock_out,
adat_receivers[adat_nr].adat_in,
adat_first,
adat_receivers[adat_nr].output_enable,
]
adat_transmitter_debug = [
adat_clock,
bundle_demultiplexer.bundles_out[adat_nr].channel_nr,
adat_transmitters[adat_nr].sample_in,
adat_transmitters[adat_nr].valid_in,
adat_transmitters[adat_nr].last_in,
adat_transmitters[adat_nr].ready_out,
adat_transmitters[adat_nr].fifo_level_out,
adat_transmitters[adat_nr].underflow_out,
adat_transmitters[adat_nr].adat_out,
]
bundle0_active = Signal()
bundle3_active = Signal()
bundle_multiplexer_active = Signal()
multiplexer_enable = Signal()
m.d.comb += [
bundle0_active.eq((bundle_multiplexer.bundles_in[0].valid &
bundle_multiplexer.bundles_in[0].ready)),
bundle3_active.eq((bundle_multiplexer.bundles_in[3].valid &
bundle_multiplexer.bundles_in[3].ready)),
bundle_multiplexer_active.eq((bundle_multiplexer.channel_stream_out.valid &
bundle_multiplexer.channel_stream_out.ready)),
multiplexer_enable.eq(bundle0_active | bundle3_active | bundle_multiplexer_active),
]
multiplexer_debug = [
bundle_multiplexer.current_bundle,
bundle_multiplexer.last_bundle,
bundle0_active,
#bundle_multiplexer.bundles_in[0].payload,
bundle_multiplexer.bundles_in[0].channel_nr,
bundle_multiplexer.bundles_in[0].last,
bundle3_active,
#bundle_multiplexer.bundles_in[3].payload,
bundle_multiplexer.bundles_in[3].channel_nr,
bundle_multiplexer.bundles_in[3].last,
#bundle_multiplexer.channel_stream_out.payload,
bundle_multiplexer_active,
bundle_multiplexer.channel_stream_out.channel_nr,
bundle_multiplexer.channel_stream_out.last,
input_to_usb_fifo.w_level,
]
demultiplexer_debug = [
bundle_demultiplexer.channel_stream_in.ready,
bundle_demultiplexer.channel_stream_in.valid,
bundle_demultiplexer.channel_stream_in.channel_nr,
#bundle_demultiplexer.channel_stream_in.payload,
*[bundle_demultiplexer.bundles_out[i].ready for i in range(4)],
*[bundle_demultiplexer.bundles_out[i].valid for i in range(4)],
*[bundle_demultiplexer.bundles_out[i].channel_nr for i in range(4)],
]
demultiplexer_enable = Signal()
m.d.comb += demultiplexer_enable.eq(
(bundle_demultiplexer.bundles_out[0].valid &
bundle_demultiplexer.bundles_out[0].ready) |
(bundle_demultiplexer.bundles_out[3].valid &
bundle_demultiplexer.bundles_out[3].ready) |
(bundle_demultiplexer.channel_stream_in.valid &
bundle_demultiplexer.channel_stream_in.ready)
)
levels = [
input_to_usb_fifo.r_level,
channels_to_usb_stream.level,
]
adat_transmit_count = Signal(8)
adat_transmit_frames = Signal.like(adat_transmit_count)
adat_receiver0_count = Signal.like(adat_transmit_count)
adat_receiver0_frames = Signal.like(adat_transmit_count)
adat_receiver3_count = Signal.like(adat_transmit_count)
adat_receiver3_frames = Signal.like(adat_transmit_count)
adat_multiplexer_count = Signal.like(adat_transmit_count)
adat_multiplexer_frames = Signal.like(adat_transmit_count)
adat_channels2usb_count = Signal.like(adat_transmit_count)
adat_channels2usb_frames = Signal.like(adat_transmit_count)
usb_receive_frames = Signal.like(adat_transmit_count)
m.submodules.sof_synchronizer = sof_synchronizer = PulseSynchronizer("usb", "fast")
sof_fast = Signal()
adat_receiver0_fast = Signal()
adat_receiver3_fast = Signal()
adat_multiplexer_out_fast = Signal()
m.d.comb += [
sof_synchronizer.i.eq(usb1.sof_detected),
sof_fast.eq(sof_synchronizer.o),
adat_receiver0_fast.eq((adat_receivers[0].addr_out == 7) & adat_receivers[0].output_enable),
adat_receiver3_fast.eq((adat_receivers[3].addr_out == 7) & adat_receivers[3].output_enable),
adat_multiplexer_out_fast.eq(bundle_multiplexer.channel_stream_out.ready & bundle_multiplexer.channel_stream_out.valid & bundle_multiplexer.channel_stream_out.last),
]
with m.If(sof_fast):
m.d.fast += [
adat_receiver0_frames.eq(adat_receiver0_count),
adat_receiver0_count.eq(0),
adat_receiver3_frames.eq(adat_receiver3_count),
adat_receiver3_count.eq(0),
adat_multiplexer_frames.eq(adat_multiplexer_count),
adat_multiplexer_count.eq(0),
]
with m.If(adat_receiver0_fast):
m.d.fast += adat_receiver0_count.eq(adat_receiver0_count + 1)
with m.If(adat_receiver3_fast):
m.d.fast += adat_receiver3_count.eq(adat_receiver3_count + 1)
with m.If(adat_multiplexer_out_fast):
m.d.fast += adat_multiplexer_count.eq(adat_multiplexer_count + 1)
frame_counts = [
adat_transmit_frames,
adat_receiver0_frames,
adat_receiver3_frames,
adat_multiplexer_frames,
adat_channels2usb_frames,
usb_receive_frames,
]
with m.If(channels_to_usb_stream.channel_stream_in.last & channels_to_usb_stream.channel_stream_in.valid & channels_to_usb_stream.channel_stream_in.ready):
m.d.usb += adat_channels2usb_count.eq(adat_channels2usb_count + 1)
with m.If(usb_to_channel_stream.channel_stream_out.last & usb_to_channel_stream.channel_stream_out.valid & usb_to_channel_stream.channel_stream_out.ready):
m.d.usb += adat_transmit_count.eq(adat_transmit_count + 1)
with m.If(usb1.sof_detected):
m.d.usb += [
adat_transmit_frames.eq(adat_transmit_count),
adat_transmit_count.eq(0),
adat_channels2usb_frames.eq(adat_channels2usb_count),
adat_channels2usb_count.eq(0),
usb_receive_frames.eq(audio_in_frame_bytes >> 7),
]
channel_stream_combiner_debug = [
#usb1_channel_stream_combiner.lower_channel_stream_in.valid,
#usb1_channel_stream_combiner.lower_channel_stream_in.ready,
#usb1_channel_stream_combiner.lower_channel_stream_in.payload,
#usb1_channel_stream_combiner.lower_channel_stream_in.channel_nr,
#usb1_channel_stream_combiner.lower_channel_stream_in.first,
#usb1_channel_stream_combiner.lower_channel_stream_in.last,
usb2_audio_out_active,
usb1_channel_stream_combiner.upper_channel_stream_in.valid,
usb1_channel_stream_combiner.upper_channel_stream_in.ready,
usb1_channel_stream_combiner.upper_channel_stream_in.payload,
usb1_channel_stream_combiner.upper_channel_stream_in.channel_nr,
usb1_channel_stream_combiner.upper_channel_stream_in.first,
usb1_channel_stream_combiner.upper_channel_stream_in.last,
usb1_channel_stream_combiner.upper_channel_counter,
usb1_channel_stream_combiner.state,
#usb1_channel_stream_combiner.combined_channel_stream_out.valid,
#usb1_channel_stream_combiner.combined_channel_stream_out.ready,
#usb1_channel_stream_combiner.combined_channel_stream_out.payload,
#usb1_channel_stream_combiner.combined_channel_stream_out.channel_nr,
#usb1_channel_stream_combiner.combined_channel_stream_out.first,
#usb1_channel_stream_combiner.combined_channel_stream_out.last,
]
upper_channel_active = Signal()
channel_stream_combiner_active = Signal()
m.d.comb += [
upper_channel_active.eq(usb1_channel_stream_combiner.upper_channel_stream_in.valid &
usb1_channel_stream_combiner.upper_channel_stream_in.ready),
channel_stream_combiner_active.eq(
upper_channel_active |
(usb1_channel_stream_combiner.combined_channel_stream_out.valid &
usb1_channel_stream_combiner.combined_channel_stream_out.ready) |
(usb1_channel_stream_combiner.lower_channel_stream_in.valid &
usb1_channel_stream_combiner.lower_channel_stream_in.ready))
]
channel_stream_splitter_debug = [
usb1_channel_stream_splitter.lower_channel_stream_out.valid,
usb1_channel_stream_splitter.lower_channel_stream_out.ready,
usb1_channel_stream_splitter.lower_channel_stream_out.payload,
usb1_channel_stream_splitter.lower_channel_stream_out.channel_nr,
usb1_channel_stream_splitter.lower_channel_stream_out.first,
usb1_channel_stream_splitter.lower_channel_stream_out.last,
usb2_audio_out_active,
usb1_channel_stream_splitter.upper_channel_stream_out.valid,
usb1_channel_stream_splitter.upper_channel_stream_out.ready,
usb1_channel_stream_splitter.upper_channel_stream_out.payload,
usb1_channel_stream_splitter.upper_channel_stream_out.channel_nr,
usb1_channel_stream_splitter.upper_channel_stream_out.first,
usb1_channel_stream_splitter.upper_channel_stream_out.last,
usb1_channel_stream_splitter.combined_channel_stream_in.valid,
usb1_channel_stream_splitter.combined_channel_stream_in.ready,
usb1_channel_stream_splitter.combined_channel_stream_in.payload,
usb1_channel_stream_splitter.combined_channel_stream_in.channel_nr,
usb1_channel_stream_splitter.combined_channel_stream_in.first,
usb1_channel_stream_splitter.combined_channel_stream_in.last,
]
splitter_upper_channel_active = Signal()
channel_stream_splitter_active = Signal()
m.d.comb += [
splitter_upper_channel_active.eq(usb1_channel_stream_splitter.upper_channel_stream_out.valid &
usb1_channel_stream_splitter.upper_channel_stream_out.ready),
channel_stream_splitter_active.eq(
splitter_upper_channel_active |
(usb1_channel_stream_splitter.combined_channel_stream_in.valid &
usb1_channel_stream_splitter.combined_channel_stream_in.ready) |
(usb1_channel_stream_splitter.lower_channel_stream_out.valid &
usb1_channel_stream_splitter.lower_channel_stream_out.ready))
]
midi_in_active = Signal()
m.d.comb += midi_in_active.eq(usb2_ep3_in.stream.valid & usb2_ep3_in.stream.ready)
midi_out_active = Signal()
m.d.comb += midi_out_active.eq(usb2_ep3_out.stream.valid & usb2_ep3_out.stream.ready)
midi_active = Signal()
m.d.comb += midi_active.eq(midi_in_active | midi_out_active)
midi_out_stream = StreamInterface(name="midi_out")
m.d.comb += midi_out_stream.stream_eq(usb2_ep3_out.stream, omit="ready")
midi_in_stream = StreamInterface(name="midi_in")
m.d.comb += midi_in_stream.stream_eq(usb1_ep3_in.stream, omit="ready")
in_ready = Signal()
m.d.comb += in_ready.eq(usb1_ep3_in.stream.ready)
midi_out = [
usb2_ep3_out.stream.ready,
usb2_ep3_out.stream.valid,
midi_out_stream.payload,
midi_out_stream.first,
midi_out_stream.last,
usb2_to_usb1_midi_fifo.r_level,
in_ready,
midi_in_stream.valid,
midi_in_stream.payload,
midi_in_stream.first,
midi_in_stream.last,
]
dac_extractor_debug = [
#dac1_extractor.selected_channel_in,
dac1_extractor.level,
dac1_extractor.channel_stream_in.channel_nr,
#dac1_extractor.channel_stream_in.payload,
dac1_extractor.channel_stream_in.valid,
#dac1_extractor.channel_stream_out.payload,
#dac1_extractor.channel_stream_out.valid,
dac1_extractor.channel_stream_out.ready,
dac1_extractor.channel_stream_out.first,
dac1_extractor.channel_stream_out.last,
dac1.underflow_out,
dac1.fifo_level_out,
enable_convolver,
]
convolver_signal_in_valid = Signal()
convolver_signal_in_first = Signal()
convolver_signal_in_last = Signal()
convolver_signal_in_ready = Signal()
convolver_signal_in_payload = Signal(signed(24))
convolver_signal_out_valid = Signal()
convolver_signal_out_first = Signal()
convolver_signal_out_last = Signal()
convolver_signal_out_payload = Signal(24)
convolver_signal_out_ready = Signal()
if use_convolution:
m.d.comb += [
convolver_signal_in_valid.eq(convolver.signal_in.valid),
convolver_signal_in_first.eq(convolver.signal_in.first),
convolver_signal_in_last.eq(convolver.signal_in.last),
convolver_signal_in_payload.eq(convolver.signal_in.payload),
convolver_signal_in_ready.eq(convolver.signal_in.ready),
convolver_signal_out_valid.eq(convolver.signal_out.valid),
convolver_signal_out_first.eq(convolver.signal_out.first),
convolver_signal_out_last.eq(convolver.signal_out.last),
convolver_signal_out_payload.eq(convolver.signal_out.payload),
convolver_signal_out_ready.eq(convolver.signal_out.ready),
]
convolution_debug = [
convolver_signal_in_ready,
convolver_signal_in_valid,
convolver_signal_in_first,
convolver_signal_in_last,
convolver_signal_in_payload,
convolver_signal_out_valid,
convolver_signal_out_first,
convolver_signal_out_last,
convolver_signal_out_payload,
convolver_signal_out_ready,
dac1_extractor.level,
enable_convolver,
]
#
# signals to trace
#
signals = adat_transmitter_debug
signals_bits = sum([s.width for s in signals])
m.submodules.ila = ila = \
StreamILA(
domain="usb", o_domain="usb",
#sample_rate=60e6, # usb domain
#sample_rate=48e3 * 256 * 5, # sync domain
#sample_rate=48e3 * 256 * 9, # fast domain
#sample_rate=25e6 * 29 / 7, # fast domain, ECP5
signals=signals,
sample_depth = int(10 * 8 * 1024 / signals_bits),
samples_pretrigger = 2, #int(78 * 8 * 1024 / signals_bits),
with_enable=True)
stream_ep = USBMultibyteStreamInEndpoint(
endpoint_number=4, # EP 4 IN
max_packet_size=ila_max_packet_size,
byte_width=ila.bytes_per_sample
)
usb1.add_endpoint(stream_ep)
m.d.comb += [
stream_ep.stream.stream_eq(ila.stream),
# ila.enable.eq(input_or_output_active | garbage | usb_frame_borders),
ila.trigger.eq(1),
ila.enable .eq(input_or_output_active),
]
ILACoreParameters(ila).pickle()

View File

@@ -0,0 +1,4 @@
#!/bin/bash
python3 -m venv venv
. venv/bin/activate
pip3 install -r requirements.txt

134
gateware/platforms.py Normal file
View File

@@ -0,0 +1,134 @@
from amaranth import *
from amaranth.build import *
from amaranth_boards.resources import *
from amaranth_boards.qmtech_ep4ce import QMTechEP4CEPlatform
from amaranth_boards.qmtech_5cefa2 import QMTech5CEFA2Platform
from amaranth_boards.qmtech_10cl006 import QMTech10CL006Platform
from amaranth_boards.qmtech_xc7a35t import QMTechXC7A35TPlatform
from amaranth_boards.colorlight_qmtech import ColorlightQMTechPlatform
from luna.gateware.platform.core import LUNAPlatform
from car import ColorlightDomainGenerator, IntelCycloneIVClockDomainGenerator, IntelCycloneVClockDomainGenerator, Xilinx7SeriesClockDomainGenerator
from adatface_rev0_baseboard import ADATFaceRev0Baseboard
class IntelFPGAParameters:
QSF_ADDITIONS = r"""
set_global_assignment -name OPTIMIZATION_MODE "Aggressive Performance"
set_global_assignment -name FITTER_EFFORT "Standard Fit"
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT "Extra"
set_instance_assignment -name DECREASE_INPUT_DELAY_TO_INPUT_REGISTER OFF -to *ulpi*
set_instance_assignment -name INCREASE_DELAY_TO_OUTPUT_PIN OFF -to *ulpi*
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
"""
SDC_ADDITIONS = r"""
derive_pll_clocks
derive_clock_uncertainty
# sync clock domain crossing to ADAT clock domain crossing
set_max_delay -from [get_clocks {car|audiopll|auto_generated|pll1|clk[3]}] -to [get_clocks {car|audiopll|auto_generated|pll1|clk[0]}] 5
# USB to fast clock domain crossing
set_max_delay -from [get_clocks {car|mainpll|auto_generated|pll1|clk[0]}] -to [get_clocks {car|fastopll|auto_generated|pll1|clk[0]}] 5
"""
class ADATFaceCycloneV(QMTech5CEFA2Platform, LUNAPlatform):
fast_multiplier = 9
clock_domain_generator = IntelCycloneVClockDomainGenerator
fast_domain_clock_freq = int(48e3 * 256 * fast_multiplier)
@property
def file_templates(self):
templates = super().file_templates
templates["{{name}}.qsf"] += IntelFPGAParameters.QSF_ADDITIONS
templates["{{name}}.sdc"] += IntelFPGAParameters.SDC_ADDITIONS
return templates
def __init__(self):
self.resources += ADATFaceRev0Baseboard.resources(Attrs(io_standard="3.3-V LVCMOS"))
# swap connector numbers, because on ADATface the connector
# names are swapped compared to the QMTech daughterboard
self.connectors[0].number = 3
self.connectors[1].number = 2
super().__init__(standalone=False)
class ADATFaceCycloneIV(QMTechEP4CEPlatform, LUNAPlatform):
fast_multiplier = 9
clock_domain_generator = IntelCycloneIVClockDomainGenerator
fast_domain_clock_freq = int(48e3 * 256 * fast_multiplier)
@property
def file_templates(self):
templates = super().file_templates
templates["{{name}}.qsf"] += IntelFPGAParameters.QSF_ADDITIONS
templates["{{name}}.sdc"] += IntelFPGAParameters.SDC_ADDITIONS
return templates
def __init__(self):
self.resources += ADATFaceRev0Baseboard.resources(Attrs(io_standard="3.3-V LVCMOS"))
# swap connector numbers, because on ADATface the connector
# names are swapped compared to the QMTech daughterboard
self.connectors[0].number = 3
self.connectors[1].number = 2
super().__init__(no_kluts=55, standalone=False)
# This is here just for experimental reasons.
# right now the design probably would not fit into this device anymore
class ADATFaceCyclone10(QMTech10CL006Platform, LUNAPlatform):
clock_domain_generator = IntelCycloneIVClockDomainGenerator
fast_multiplier = 9
fast_domain_clock_freq = int(48e3 * 256 * fast_multiplier)
@property
def file_templates(self):
templates = super().file_templates
templates["{{name}}.qsf"] += IntelFPGAParameters.QSF_ADDITIONS
templates["{{name}}.sdc"] += IntelFPGAParameters.SDC_ADDITIONS
return templates
def __init__(self):
self.resources += ADATFaceRev0Baseboard.resources(Attrs(io_standard="3.3-V LVCMOS"))
# swap connector numbers, because on ADATface the connector
# names are swapped compared to the QMTech daughterboard
self.connectors[0].number = 3
self.connectors[1].number = 2
super().__init__(standalone=False)
class ADATFaceArtix7(QMTechXC7A35TPlatform, LUNAPlatform):
clock_domain_generator = Xilinx7SeriesClockDomainGenerator
fast_multiplier = 9
fast_domain_clock_freq = int(48e3 * 256 * fast_multiplier)
@property
def file_templates(self):
templates = super().file_templates
return templates
def __init__(self):
self.resources += ADATFaceRev0Baseboard.resources(Attrs(IOSTANDARD="LVCMOS33"))
# swap connector numbers, because on ADATface the connector
# names are swapped compared to the QMTech daughterboard
self.connectors[0].number = 3
self.connectors[1].number = 2
super().__init__(standalone=False)
class ADATFaceColorlight(ColorlightQMTechPlatform, LUNAPlatform):
clock_domain_generator = ColorlightDomainGenerator
fast_domain_clock_freq = ColorlightDomainGenerator.FastClockFreq
@property
def file_templates(self):
templates = super().file_templates
return templates
def __init__(self):
adatface_resources = ADATFaceRev0Baseboard.resources(Attrs(IO_TYPE="LVCMOS33"), colorlight=True)
# swap connector numbers, because on ADATface the connector
# names are swapped compared to the QMTech daughterboard
self.connectors[0].number = 3
self.connectors[1].number = 2
from amaranth_boards.colorlight_i9 import ColorLightI9Platform
super().__init__(colorlight=ColorLightI9Platform, daughterboard=False, extra_resources=adatface_resources)

148
gateware/requesthandlers.py Normal file
View File

@@ -0,0 +1,148 @@
from enum import IntEnum
from amaranth import *
from luna.gateware.usb.usb2.request import USBRequestHandler
from luna.gateware.stream.generator import StreamSerializer
from usb_protocol.types import USBRequestType, USBRequestRecipient, USBStandardRequests
from usb_protocol.types.descriptors.uac2 import AudioClassSpecificRequestCodes, ClockSourceControlSelectors
from luna.gateware.usb.stream import USBInStreamInterface
from usb_descriptors import USBDescriptors
class VendorRequests(IntEnum):
ILA_STOP_CAPTURE = 0
TOGGLE_CONVOLUTION = 1
class UAC2RequestHandlers(USBRequestHandler):
""" request handlers to implement UAC2 functionality. """
def __init__(self):
super().__init__()
self.output_interface_altsetting_nr = Signal(3)
self.input_interface_altsetting_nr = Signal(3)
self.interface_settings_changed = Signal()
self.enable_convolution = Signal()
def elaborate(self, platform):
m = Module()
interface = self.interface
setup = self.interface.setup
m.submodules.transmitter = transmitter = \
StreamSerializer(data_length=14, domain="usb", stream_type=USBInStreamInterface, max_length_width=14)
m.d.usb += self.interface_settings_changed.eq(0)
m.d.comb += self.enable_convolution.eq(0)
#
# Class request handlers.
#
with m.If(setup.type == USBRequestType.STANDARD):
with m.If((setup.recipient == USBRequestRecipient.INTERFACE) &
(setup.request == USBStandardRequests.SET_INTERFACE)):
interface_nr = setup.index
alt_setting_nr = setup.value
m.d.usb += [
self.output_interface_altsetting_nr.eq(0),
self.input_interface_altsetting_nr.eq(0),
self.interface_settings_changed.eq(1),
]
with m.Switch(interface_nr):
with m.Case(1):
m.d.usb += self.output_interface_altsetting_nr.eq(alt_setting_nr)
with m.Case(2):
m.d.usb += self.input_interface_altsetting_nr.eq(alt_setting_nr)
# Always ACK the data out...
with m.If(interface.rx_ready_for_response):
m.d.comb += interface.handshakes_out.ack.eq(1)
# ... and accept whatever the request was.
with m.If(interface.status_requested):
m.d.comb += self.send_zlp()
clock_freq = (setup.value == Const(ClockSourceControlSelectors.CS_SAM_FREQ_CONTROL << 8, 16)) \
& (setup.index == Const(USBDescriptors.CLOCK_ID << 8, 16))
request_clock_freq = clock_freq & setup.is_in_request
set_clock_freq = clock_freq & ~setup.is_in_request
SRATE_44_1k = Const(44100, 32)
SRATE_48k = Const(48000, 32)
ZERO = Const(0, 32)
with m.Elif(setup.type == USBRequestType.CLASS):
with m.Switch(setup.request):
with m.Case(AudioClassSpecificRequestCodes.RANGE):
m.d.comb += transmitter.stream.attach(self.interface.tx)
with m.If(request_clock_freq):
m.d.comb += [
Cat(transmitter.data).eq(
Cat(Const(0x1, 16), # no triples
SRATE_48k, # MIN
SRATE_48k, # MAX
ZERO)), # RES
transmitter.max_length.eq(setup.length)
]
with m.Else():
m.d.comb += interface.handshakes_out.stall.eq(1)
# ... trigger it to respond when data's requested...
with m.If(interface.data_requested):
m.d.comb += transmitter.start.eq(1)
# ... and ACK our status stage.
with m.If(interface.status_requested):
m.d.comb += interface.handshakes_out.ack.eq(1)
with m.Case(AudioClassSpecificRequestCodes.CUR):
m.d.comb += transmitter.stream.attach(self.interface.tx)
with m.If(request_clock_freq & (setup.length == 4)):
m.d.comb += [
Cat(transmitter.data[0:4]).eq(Const(48000, 32)),
transmitter.max_length.eq(4)
]
with m.Else():
m.d.comb += interface.handshakes_out.stall.eq(1)
# ... trigger it to respond when data's requested...
with m.If(interface.data_requested):
m.d.comb += transmitter.start.eq(1)
# ... and ACK our status stage.
with m.If(interface.status_requested):
m.d.comb += interface.handshakes_out.ack.eq(1)
with m.Default():
#
# Stall unhandled requests.
#
with m.If(interface.status_requested | interface.data_requested):
m.d.comb += interface.handshakes_out.stall.eq(1)
with m.Elif(setup.type == USBRequestType.VENDOR):
with m.Switch(setup.request):
with m.Case(VendorRequests.TOGGLE_CONVOLUTION):
m.d.comb += self.enable_convolution.eq(1)
# m.d.usb += self.enable_convolution.eq(~self.enable_convolution)
# ... and ACK our status stage.
with m.If(interface.status_requested | interface.data_requested):
m.d.comb += interface.handshakes_out.ack.eq(1)
# m.d.comb += self.interface.handshakes_out.stall.eq(1)
# pass
with m.Case(VendorRequests.ILA_STOP_CAPTURE):
# TODO - will be implemented when needed
pass
with m.Default():
m.d.comb += self.interface.handshakes_out.stall.eq(1)
with m.Else():
m.d.comb += self.interface.handshakes_out.stall.eq(1)
return m

View File

@@ -0,0 +1,9 @@
wheel
setuptools
git+https://github.com/amaranth-lang/amaranth.git@v0.4.5
git+https://github.com/amaranth-lang/amaranth-soc.git@59223a82399df45addf1db362ad6fb9670e72b51
git+https://github.com/amaranth-farm/python-usb-descriptors.git
git+https://github.com/amaranth-farm/usb2-highspeed-core.git
git+https://github.com/amaranth-farm/adat-core.git
git+https://github.com/amaranth-farm/amlib.git
git+https://github.com/amaranth-farm/amaranth-boards.git

View File

@@ -0,0 +1,45 @@
from amaranth import *
from amaranth.build import Platform
from amaranth.lib.fifo import SyncFIFOBuffered
from amlib.stream import StreamInterface, connect_fifo_to_stream
class StereoPairExtractor(Elaboratable):
def __init__(self, max_no_channels: int, fifo_depth):
self._channel_bits = Shape.cast(range(max_no_channels)).width
self._fifo_depth = fifo_depth
# I/O
self.channel_stream_in = StreamInterface(name="channel_stream_in", payload_width=24, extra_fields=[("channel_nr", self._channel_bits)])
self.selected_channel_in = Signal(range(max_no_channels))
# the first=left and last=right signals mark the channel on the output stream
self.channel_stream_out = StreamInterface(name="channel_stream_out", payload_width=24)
self.level = Signal(range(fifo_depth))
def elaborate(self, platform: Platform) -> Module:
m = Module()
m.submodules.fifo = fifo = SyncFIFOBuffered(width=24+1, depth=self._fifo_depth)
in_channel_nr = self.channel_stream_in.channel_nr
out_channel_nr = Signal(self._channel_bits)
# the ready signal is not wired in the input stream because this
# module must not exert upstream back pressure
with m.If( self.channel_stream_in.valid
& ( (in_channel_nr == self.selected_channel_in)
| (in_channel_nr == (self.selected_channel_in + 1)))):
m.d.comb += [
fifo.w_data.eq(Cat(self.channel_stream_in.payload, out_channel_nr[0])),
fifo.w_en.eq(1)
]
m.d.comb += [
self.level.eq(fifo.r_level),
out_channel_nr.eq(in_channel_nr - self.selected_channel_in),
*connect_fifo_to_stream(fifo, self.channel_stream_out),
self.channel_stream_out.first.eq(~fifo.r_data[-1]),
self.channel_stream_out.last.eq(fifo.r_data[-1]),
]
return m

302
gateware/usb_descriptors.py Normal file
View File

@@ -0,0 +1,302 @@
#!/usr/bin/env python3
#
# Copyright (c) 2021 Hans Baier <hansfbaier@gmail.com>
# SPDX-License-Identifier: CERN-OHL-W-2.0
from amaranth import *
from usb_protocol.types import USBRequestType, USBRequestRecipient, USBTransferType, USBSynchronizationType, USBUsageType, USBDirection, USBStandardRequests
from usb_protocol.types.descriptors.uac2 import AudioClassSpecificRequestCodes
from usb_protocol.emitters import DeviceDescriptorCollection
from usb_protocol.emitters.descriptors import uac2, standard
from usb_protocol.emitters.descriptors import midi1
class USBDescriptors():
MAX_PACKET_SIZE_MIDI = 64
CLOCK_ID = 1
def __init__(self, *, ila_max_packet_size: int, use_ila=False) -> None:
# ILA
self.USE_ILA = use_ila
self.ILA_MAX_PACKET_SIZE = ila_max_packet_size
def create_usb1_descriptors(self, no_channels: int, max_packet_size: int):
""" Creates the descriptors for the main USB interface """
return self.create_descriptors("ADATface (USB1)", no_channels, max_packet_size, self.USE_ILA)
def create_usb2_descriptors(self, no_channels: int, max_packet_size: int):
""" Creates the descriptors for the secondary USB interface """
return self.create_descriptors("ADATface (USB2)", no_channels, max_packet_size)
def create_descriptors(self, product_id: str, no_channels: int, max_packet_size: int, create_ila=False):
""" Creates the descriptors for the main USB interface """
descriptors = DeviceDescriptorCollection()
with descriptors.DeviceDescriptor() as d:
d.bcdUSB = 2.00
d.bDeviceClass = 0xEF
d.bDeviceSubclass = 0x02
d.bDeviceProtocol = 0x01
d.idVendor = 0x1209
d.idProduct = 0xADA1 if "USB1" in product_id else 0xADA2
d.iManufacturer = "OpenAudioGear"
d.iProduct = product_id
d.iSerialNumber = "0"
d.bcdDevice = 0.01
d.bNumConfigurations = 1
with descriptors.ConfigurationDescriptor() as configDescr:
# Interface Association
interfaceAssociationDescriptor = uac2.InterfaceAssociationDescriptorEmitter()
interfaceAssociationDescriptor.bInterfaceCount = 3 # Audio Control + Inputs + Outputs
configDescr.add_subordinate_descriptor(interfaceAssociationDescriptor)
# Interface Descriptor (Control)
interfaceDescriptor = uac2.StandardAudioControlInterfaceDescriptorEmitter()
interfaceDescriptor.bInterfaceNumber = 0
configDescr.add_subordinate_descriptor(interfaceDescriptor)
# AudioControl Interface Descriptor
audioControlInterface = self.create_audio_control_interface_descriptor(no_channels)
configDescr.add_subordinate_descriptor(audioControlInterface)
self.create_output_channels_descriptor(configDescr, no_channels, max_packet_size)
self.create_input_channels_descriptor(configDescr, no_channels, max_packet_size)
midi_interface, midi_streaming_interface = self.create_midi_interface_descriptor()
configDescr.add_subordinate_descriptor(midi_interface)
configDescr.add_subordinate_descriptor(midi_streaming_interface)
if create_ila:
with configDescr.InterfaceDescriptor() as i:
i.bInterfaceNumber = 4
with i.EndpointDescriptor() as e:
e.bEndpointAddress = USBDirection.IN.to_endpoint_address(4)
e.wMaxPacketSize = self.ILA_MAX_PACKET_SIZE
return descriptors
def create_audio_control_interface_descriptor(self, number_of_channels):
audioControlInterface = uac2.ClassSpecificAudioControlInterfaceDescriptorEmitter()
# AudioControl Interface Descriptor (ClockSource)
clockSource = uac2.ClockSourceDescriptorEmitter()
clockSource.bClockID = self.CLOCK_ID
clockSource.bmAttributes = uac2.ClockAttributes.INTERNAL_FIXED_CLOCK
clockSource.bmControls = uac2.ClockFrequencyControl.HOST_READ_ONLY
audioControlInterface.add_subordinate_descriptor(clockSource)
# streaming input port from the host to the USB interface
inputTerminal = uac2.InputTerminalDescriptorEmitter()
inputTerminal.bTerminalID = 2
inputTerminal.wTerminalType = uac2.USBTerminalTypes.USB_STREAMING
# The number of channels needs to be 2 here in order to be recognized
# default audio out device by Windows. We provide an alternate
# setting with the full channel count, which also references
# this terminal ID
inputTerminal.bNrChannels = 2
inputTerminal.bCSourceID = 1
audioControlInterface.add_subordinate_descriptor(inputTerminal)
# audio output port from the USB interface to the outside world
outputTerminal = uac2.OutputTerminalDescriptorEmitter()
outputTerminal.bTerminalID = 3
outputTerminal.wTerminalType = uac2.OutputTerminalTypes.SPEAKER
outputTerminal.bSourceID = 2
outputTerminal.bCSourceID = 1
audioControlInterface.add_subordinate_descriptor(outputTerminal)
# audio input port from the outside world to the USB interface
inputTerminal = uac2.InputTerminalDescriptorEmitter()
inputTerminal.bTerminalID = 4
inputTerminal.wTerminalType = uac2.InputTerminalTypes.MICROPHONE
inputTerminal.bNrChannels = number_of_channels
inputTerminal.bCSourceID = 1
audioControlInterface.add_subordinate_descriptor(inputTerminal)
# audio output port from the USB interface to the host
outputTerminal = uac2.OutputTerminalDescriptorEmitter()
outputTerminal.bTerminalID = 5
outputTerminal.wTerminalType = uac2.USBTerminalTypes.USB_STREAMING
outputTerminal.bSourceID = 4
outputTerminal.bCSourceID = 1
audioControlInterface.add_subordinate_descriptor(outputTerminal)
return audioControlInterface
def create_output_streaming_interface(self, c, *, no_channels: int, alt_setting_nr: int, max_packet_size):
# Interface Descriptor (Streaming, OUT, active setting)
activeAudioStreamingInterface = uac2.AudioStreamingInterfaceDescriptorEmitter()
activeAudioStreamingInterface.bInterfaceNumber = 1
activeAudioStreamingInterface.bAlternateSetting = alt_setting_nr
activeAudioStreamingInterface.bNumEndpoints = 2
c.add_subordinate_descriptor(activeAudioStreamingInterface)
# AudioStreaming Interface Descriptor (General)
audioStreamingInterface = uac2.ClassSpecificAudioStreamingInterfaceDescriptorEmitter()
audioStreamingInterface.bTerminalLink = 2
audioStreamingInterface.bFormatType = uac2.FormatTypes.FORMAT_TYPE_I
audioStreamingInterface.bmFormats = uac2.TypeIFormats.PCM
audioStreamingInterface.bNrChannels = no_channels
c.add_subordinate_descriptor(audioStreamingInterface)
# AudioStreaming Interface Descriptor (Type I)
typeIStreamingInterface = uac2.TypeIFormatTypeDescriptorEmitter()
typeIStreamingInterface.bSubslotSize = 4
typeIStreamingInterface.bBitResolution = 24
c.add_subordinate_descriptor(typeIStreamingInterface)
# Endpoint Descriptor (Audio out)
audioOutEndpoint = standard.EndpointDescriptorEmitter()
audioOutEndpoint.bEndpointAddress = USBDirection.OUT.to_endpoint_address(1) # EP 1 OUT
audioOutEndpoint.bmAttributes = USBTransferType.ISOCHRONOUS | \
(USBSynchronizationType.ASYNC << 2) | \
(USBUsageType.DATA << 4)
audioOutEndpoint.wMaxPacketSize = max_packet_size
audioOutEndpoint.bInterval = 1
c.add_subordinate_descriptor(audioOutEndpoint)
# AudioControl Endpoint Descriptor
audioControlEndpoint = uac2.ClassSpecificAudioStreamingIsochronousAudioDataEndpointDescriptorEmitter()
c.add_subordinate_descriptor(audioControlEndpoint)
# Endpoint Descriptor (Feedback IN)
feedbackInEndpoint = standard.EndpointDescriptorEmitter()
feedbackInEndpoint.bEndpointAddress = USBDirection.IN.to_endpoint_address(1) # EP 1 IN
feedbackInEndpoint.bmAttributes = USBTransferType.ISOCHRONOUS | \
(USBSynchronizationType.NONE << 2) | \
(USBUsageType.FEEDBACK << 4)
feedbackInEndpoint.wMaxPacketSize = 4
feedbackInEndpoint.bInterval = 4
c.add_subordinate_descriptor(feedbackInEndpoint)
def create_output_channels_descriptor(self, c, no_channels: int, max_packet_size: int):
#
# Interface Descriptor (Streaming, OUT, quiet setting)
#
quietAudioStreamingInterface = uac2.AudioStreamingInterfaceDescriptorEmitter()
quietAudioStreamingInterface.bInterfaceNumber = 1
quietAudioStreamingInterface.bAlternateSetting = 0
c.add_subordinate_descriptor(quietAudioStreamingInterface)
# we need the default alternate setting to be stereo
# out for windows to automatically recognize
# and use this audio interface
self.create_output_streaming_interface(c, no_channels=2, alt_setting_nr=1, max_packet_size=max_packet_size)
if no_channels > 2:
self.create_output_streaming_interface(c, no_channels=no_channels, alt_setting_nr=2, max_packet_size=max_packet_size)
def create_input_streaming_interface(self, c, *, no_channels: int, alt_setting_nr: int, channel_config: int=0, max_packet_size: int):
# Interface Descriptor (Streaming, IN, active setting)
activeAudioStreamingInterface = uac2.AudioStreamingInterfaceDescriptorEmitter()
activeAudioStreamingInterface.bInterfaceNumber = 2
activeAudioStreamingInterface.bAlternateSetting = alt_setting_nr
activeAudioStreamingInterface.bNumEndpoints = 1
c.add_subordinate_descriptor(activeAudioStreamingInterface)
# AudioStreaming Interface Descriptor (General)
audioStreamingInterface = uac2.ClassSpecificAudioStreamingInterfaceDescriptorEmitter()
audioStreamingInterface.bTerminalLink = 5
audioStreamingInterface.bFormatType = uac2.FormatTypes.FORMAT_TYPE_I
audioStreamingInterface.bmFormats = uac2.TypeIFormats.PCM
audioStreamingInterface.bNrChannels = no_channels
audioStreamingInterface.bmChannelConfig = channel_config
c.add_subordinate_descriptor(audioStreamingInterface)
# AudioStreaming Interface Descriptor (Type I)
typeIStreamingInterface = uac2.TypeIFormatTypeDescriptorEmitter()
typeIStreamingInterface.bSubslotSize = 4
typeIStreamingInterface.bBitResolution = 24 # we use all 24 bits
c.add_subordinate_descriptor(typeIStreamingInterface)
# Endpoint Descriptor (Audio out)
audioOutEndpoint = standard.EndpointDescriptorEmitter()
audioOutEndpoint.bEndpointAddress = USBDirection.IN.to_endpoint_address(2) # EP 2 IN
audioOutEndpoint.bmAttributes = USBTransferType.ISOCHRONOUS | \
(USBSynchronizationType.ASYNC << 2) | \
(USBUsageType.DATA << 4)
audioOutEndpoint.wMaxPacketSize = max_packet_size
audioOutEndpoint.bInterval = 1
c.add_subordinate_descriptor(audioOutEndpoint)
# AudioControl Endpoint Descriptor
audioControlEndpoint = uac2.ClassSpecificAudioStreamingIsochronousAudioDataEndpointDescriptorEmitter()
c.add_subordinate_descriptor(audioControlEndpoint)
def create_input_channels_descriptor(self, c, no_channels: int, max_packet_size: int):
#
# Interface Descriptor (Streaming, IN, quiet setting)
#
quietAudioStreamingInterface = uac2.AudioStreamingInterfaceDescriptorEmitter()
quietAudioStreamingInterface.bInterfaceNumber = 2
quietAudioStreamingInterface.bAlternateSetting = 0
c.add_subordinate_descriptor(quietAudioStreamingInterface)
# Windows wants a stereo pair as default setting, so let's have it
self.create_input_streaming_interface(c, no_channels=2, alt_setting_nr=1, channel_config=0x3, max_packet_size=max_packet_size)
if no_channels > 2:
self.create_input_streaming_interface(c, no_channels=no_channels, alt_setting_nr=2, channel_config=0x0, max_packet_size=max_packet_size)
def create_midi_interface_descriptor(self):
midi_interface = midi1.StandardMidiStreamingInterfaceDescriptorEmitter()
midi_interface.bInterfaceNumber = 3
midi_interface.bNumEndpoints = 2
midi_streaming_interface = midi1.ClassSpecificMidiStreamingInterfaceDescriptorEmitter()
outToHostJack = midi1.MidiOutJackDescriptorEmitter()
outToHostJack.bJackID = 1
outToHostJack.bJackType = midi1.MidiStreamingJackTypes.EMBEDDED
outToHostJack.add_source(2)
midi_streaming_interface.add_subordinate_descriptor(outToHostJack)
inToDeviceJack = midi1.MidiInJackDescriptorEmitter()
inToDeviceJack.bJackID = 2
inToDeviceJack.bJackType = midi1.MidiStreamingJackTypes.EXTERNAL
midi_streaming_interface.add_subordinate_descriptor(inToDeviceJack)
inFromHostJack = midi1.MidiInJackDescriptorEmitter()
inFromHostJack.bJackID = 3
inFromHostJack.bJackType = midi1.MidiStreamingJackTypes.EMBEDDED
midi_streaming_interface.add_subordinate_descriptor(inFromHostJack)
outFromDeviceJack = midi1.MidiOutJackDescriptorEmitter()
outFromDeviceJack.bJackID = 4
outFromDeviceJack.bJackType = midi1.MidiStreamingJackTypes.EXTERNAL
outFromDeviceJack.add_source(3)
midi_streaming_interface.add_subordinate_descriptor(outFromDeviceJack)
outEndpoint = midi1.StandardMidiStreamingBulkDataEndpointDescriptorEmitter()
outEndpoint.bEndpointAddress = USBDirection.OUT.to_endpoint_address(3)
outEndpoint.wMaxPacketSize = self.MAX_PACKET_SIZE_MIDI
midi_streaming_interface.add_subordinate_descriptor(outEndpoint)
outMidiEndpoint = midi1.ClassSpecificMidiStreamingBulkDataEndpointDescriptorEmitter()
outMidiEndpoint.add_associated_jack(3)
midi_streaming_interface.add_subordinate_descriptor(outMidiEndpoint)
inEndpoint = midi1.StandardMidiStreamingBulkDataEndpointDescriptorEmitter()
inEndpoint.bEndpointAddress = USBDirection.IN.to_endpoint_address(3)
inEndpoint.wMaxPacketSize = self.MAX_PACKET_SIZE_MIDI
midi_streaming_interface.add_subordinate_descriptor(inEndpoint)
inMidiEndpoint = midi1.ClassSpecificMidiStreamingBulkDataEndpointDescriptorEmitter()
inMidiEndpoint.add_associated_jack(1)
midi_streaming_interface.add_subordinate_descriptor(inMidiEndpoint)
return (midi_interface, midi_streaming_interface)

View File

@@ -0,0 +1,49 @@
[*]
[*] GTKWave Analyzer v3.3.109 (w)1999-2020 BSI
[*] Tue Aug 31 23:46:03 2021
[*]
[dumpfile] "usb_stream_to_channels.vcd"
[dumpfile_mtime] "Tue Aug 31 23:45:35 2021"
[dumpfile_size] 7952
[savefile] "gateware/usb_stream_to_channels-bench.gtkw"
[timestart] 0
[size] 3828 2090
[pos] -1 -1
*-17.716705 169900 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 357
[signals_width] 345
[sst_expanded] 1
[sst_vpaned_height] 628
@28
top.clk
@200
-Input Stream
@28
top.usb_first
top.usb_valid
top.out_ready
@22
top.usb_payload[7:0]
@200
-Core
@28
top.fsm_state
@24
top.out_channel_nr[2:0]
@200
-Output Stream
@25
[color] 2
top.channel_nr[2:0]
@22
[color] 2
top.payload$1[23:0]
@28
[color] 2
top.valid$1
[color] 2
top.first$1
[color] 2
top.last
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env python3
from usb_stream_to_channels import USBStreamToChannels
from amaranth.sim import Simulator, Tick
if __name__ == "__main__":
dut = USBStreamToChannels(8)
def send_one_frame(seamless=False, drop_valid=False, drop_ready=False):
data = [n % 4 + (n//4 << 4) for n in range(32)]
yield dut.no_channels_in.eq(8)
yield dut.usb_stream_in.valid.eq(1)
yield dut.usb_stream_in.first.eq(1)
yield dut.channel_stream_out.ready.eq(1)
for pos, byte in enumerate(data):
yield dut.usb_stream_in.payload.eq(byte)
yield Tick()
yield dut.usb_stream_in.first.eq(0)
if drop_valid and pos == 7 * 4 + 2:
yield dut.usb_stream_in.valid.eq(0)
for _ in range(4): yield Tick()
yield dut.usb_stream_in.valid.eq(1)
if drop_ready and pos == 7 * 2 + 3:
yield dut.channel_stream_out.ready.eq(0)
for _ in range(7): yield Tick()
yield dut.channel_stream_out.ready.eq(1)
yield dut.usb_stream_in.last.eq(1)
yield dut.usb_stream_in.valid.eq(0)
if not seamless:
for _ in range(10): yield Tick()
yield dut.usb_stream_in.first.eq(1)
yield dut.usb_stream_in.payload.eq(data[0])
yield dut.usb_stream_in.last.eq(0)
def process():
yield dut.usb_stream_in.payload.eq(0xff)
yield Tick()
yield from send_one_frame()
yield Tick()
yield Tick()
yield from send_one_frame(seamless=True, drop_valid=True)
yield from send_one_frame(seamless=True, drop_ready=True)
for _ in range(5): yield Tick()
sim = Simulator(dut)
sim.add_clock(1.0/60e6,)
sim.add_sync_process(process)
with sim.write_vcd(f'usb_stream_to_channels.vcd'):
sim.run()

View File

@@ -0,0 +1,91 @@
from amaranth import *
from amaranth.build import Platform
from amlib.stream import StreamInterface
class USBStreamToChannels(Elaboratable):
def __init__(self, max_no_channels=2):
# parameters
self._max_nr_channels = max_no_channels
self._channel_bits = Shape.cast(range(max_no_channels)).width
# ports
self.no_channels_in = Signal(self._channel_bits + 1)
self.usb_stream_in = StreamInterface()
self.channel_stream_out = StreamInterface(payload_width=24, extra_fields=[("channel_nr", self._channel_bits)])
self.garbage_seen_out = Signal()
def elaborate(self, platform: Platform) -> Module:
m = Module()
out_channel_nr = Signal(self._channel_bits)
out_sample = Signal(16)
usb_valid = Signal()
usb_first = Signal()
usb_payload = Signal(8)
out_ready = Signal()
last_channel = Signal(self._channel_bits)
m.d.comb += [
usb_first.eq(self.usb_stream_in.first),
usb_valid.eq(self.usb_stream_in.valid),
usb_payload.eq(self.usb_stream_in.payload),
out_ready.eq(self.channel_stream_out.ready),
self.usb_stream_in.ready.eq(out_ready),
last_channel.eq(self.no_channels_in - 1),
]
m.d.sync += [
self.channel_stream_out.valid.eq(0),
self.channel_stream_out.first.eq(0),
self.channel_stream_out.last.eq(0),
]
with m.If(usb_valid & out_ready):
with m.FSM() as fsm:
with m.State("B0"):
with m.If(usb_first):
m.d.sync += out_channel_nr.eq(0)
with m.Else():
m.d.sync += out_channel_nr.eq(out_channel_nr + 1)
m.next = "B1"
with m.State("B1"):
with m.If(usb_first):
m.d.sync += out_channel_nr.eq(0)
m.d.comb += self.garbage_seen_out.eq(1)
m.next = "B1"
with m.Else():
m.d.sync += out_sample[:8].eq(usb_payload)
m.next = "B2"
with m.State("B2"):
with m.If(usb_first):
m.d.sync += out_channel_nr.eq(0)
m.d.comb += self.garbage_seen_out.eq(1)
m.next = "B1"
with m.Else():
m.d.sync += out_sample[8:16].eq(usb_payload)
m.next = "B3"
with m.State("B3"):
with m.If(usb_first):
m.d.sync += out_channel_nr.eq(0)
m.d.comb += self.garbage_seen_out.eq(1)
m.next = "B1"
with m.Else():
m.d.sync += [
self.channel_stream_out.payload.eq(Cat(out_sample, usb_payload)),
self.channel_stream_out.valid.eq(1),
self.channel_stream_out.channel_nr.eq(out_channel_nr),
self.channel_stream_out.first.eq(out_channel_nr == 0),
self.channel_stream_out.last.eq(out_channel_nr == last_channel),
]
with m.If(out_channel_nr == last_channel):
m.d.sync += out_channel_nr.eq(-1)
m.next = "B0"
return m

30
hardware/rev0/.gitignore vendored Normal file
View File

@@ -0,0 +1,30 @@
# For PCBs designed using KiCad: https://www.kicad.org/
# Format documentation: https://kicad.org/help/file-formats/
# Temporary files
\#auto_saved_files\#
*.000
*.bak
*.bck
*.kicad_pcb-bak
*.kicad_sch-bak
**/*-backups/*
**/bak/*
*.kicad_prl
*.sch-bak
*~
_autosave-*
*.tmp
*-save.pro
*-save.kicad_pcb
fp-info-cache
# Netlist files (exported from Eeschema)
*.net
# Autorouter files (exported from Pcbnew)
*.dsn
*.ses
# Exported BOM files
*.xml

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# SquantorLabels:OHWLOGO
#
DEF SquantorLabels:OHWLOGO N 0 40 Y Y 1 F N
F0 "N" 0 150 60 H V C CNN
F1 "SquantorLabels:OHWLOGO" 0 -150 60 H V C CNN
F2 "" 0 0 60 H I C CNN
F3 "" 0 0 60 H I C CNN
DRAW
C 0 0 50 0 1 0 N
C 0 0 100 0 1 0 N
ENDDRAW
ENDDEF
#
# SquantorLabels:VYYYYMMDD
#
DEF SquantorLabels:VYYYYMMDD N 0 40 Y Y 1 F N
F0 "N" 0 100 60 H V C CNN
F1 "SquantorLabels:VYYYYMMDD" 0 0 60 H V C CNN
F2 "" 0 0 60 H I C CNN
F3 "" 0 0 60 H I C CNN
DRAW
S 300 -50 -300 150 0 1 0 N
ENDDRAW
ENDDEF
#
#End Library

View File

@@ -0,0 +1,94 @@
(version 1)
# 4-layer, 1oz copper
# In global rules
#(rule "Minimum Trace Width and Spacing (outer layer)"
# (constraint track_width (min 3.5mil))
# (constraint clearance (min 3.5mil))
# (layer outer)
# (condition "A.Type == 'track' && B.Type != 'Zone'"))
(rule "Minimum Trace Width and Spacing (inner layer)"
(constraint track_width (min 5mil))
(constraint clearance (min 5mil))
(layer inner)
(condition "A.Type == 'track' && B.Type != 'Zone'"))
# silkscreen
# This is just JLCPCB being overly cautious, <6mil is readable.
#(rule "Minimum line width"
# (constraint track_width (min 6mil))
# (layer "F.Silkscreen") (layer "B.Silkscreen"))
(rule "Pad to Silkscreen"
(constraint clearance (min 0.15mm))
(layer outer)
(condition "A.Type == 'pad' && (B.Type == 'text' || B.Type == 'graphic')"))
# edge clearance
# in global rules
#(rule "Trace to Outline"
# (constraint edge_clearance (min 0.2mm))
# (condition "A.Type == 'track'"))
# drill/hole size
# in global rules
#(rule "drill hole size (mechanical)"
# (constraint hole (min 0.2mm) (max 6.3mm))
# (condition "A.Type == 'hole'"))
#
#(rule "Minimum Via Hole Size"
# (constraint hole (min 0.2mm))
# (condition "A.Type == 'via'"))
#
#(rule "Minimum Via Diameter"
# (constraint length (min 0.4mm))
# (condition "A.Type == 'via' && Lay"))
# JLCPCB's guidelines here are contradictory; they say that PTH hole size minimum is .2,
# then they immediately after that they say that the pad has to be 1mm in size with a minimum .5mm hole size?
# At first they say that the minimum PTH annular width is .15, but then they say it's .25?
# this is very confusing, we'll just go with the smaller number.
(rule "PTH Hole Size"
(constraint hole (min 0.2mm) )
(condition "A.isPlated() && A.Type != 'via'"))
(rule "PTH Annular Width"
(constraint annular_width (min 0.15mm) )
(condition "A.isPlated() && A.Type != 'via'"))
(rule "Minimum Non-plated Hole Size"
(constraint hole (min 0.5mm))
(condition "A.Type == 'pad' && !A.isPlated()"))
# clearance
(rule "via to track clearance"
(constraint hole_clearance (min 0.254mm))
(condition "A.Type == 'via' && B.Type == 'track'"))
(rule "via to via clearance (same nets)"
(constraint hole_clearance (min 0.254mm))
(condition "A.Type == 'via' && B.Type == 'via' && A.Net == B.Net"))
(rule "pad to pad clearance (with hole, different nets)"
(constraint hole_clearance (min 0.5mm))
(condition "A.Type == 'through-hole' && B.Type == A.Type && A.Net != B.Net"))
(rule "pad to pad clearance (without hole, different nets)"
(constraint clearance (min 0.127mm))
(condition "A.Type == 'pad' && B.Type == A.Type && A.Net != B.Net"))
(rule "NPTH to Track clearance)"
(constraint hole_clearance (min 0.254mm))
(condition "A.Pad_Type == 'NPTH, mechanical' && B.Type == 'track'"))
(rule "PTH to Track clearance)"
(constraint hole_clearance (min 0.33mm))
(condition "A.isPlated() && B.Type == 'track'"))
#Only non-via pads
(rule "Pad to Track clearance)"
(constraint clearance (min 0.2mm))
(condition "A.isPlated() && A.type != 'via' && B.Type == 'track'"))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,475 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.15,
"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.09999999999999999,
"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": {
"filename": "board_design_settings.json",
"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": "ignore",
"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.08889999999999999,
"min_copper_edge_clearance": 0.19999999999999998,
"min_hole_clearance": 0.254,
"min_hole_to_hole": 0.5,
"min_microvia_diameter": 0.381,
"min_microvia_drill": 0.254,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.19999999999999998,
"min_track_width": 0.08889999999999999,
"min_via_annular_width": 0.13,
"min_via_diameter": 0.44999999999999996,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.15,
0.2,
0.3,
0.4,
0.6,
1.0,
1.5,
2.0
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
},
{
"diameter": 0.46,
"drill": 0.2
},
{
"diameter": 0.66,
"drill": 0.4
},
{
"diameter": 0.86,
"drill": 0.6
},
{
"diameter": 1.08,
"drill": 0.8
},
{
"diameter": 1.3,
"drill": 1.0
},
{
"diameter": 1.5,
"drill": 1.2
},
{
"diameter": 1.7,
"drill": 1.4
},
{
"diameter": 1.9,
"drill": 1.6
}
],
"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": "adatface_baseboard.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.09,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.6,
"microvia_drill": 0.3,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.0889,
"via_diameter": 0.46,
"via_drill": 0.2,
"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_bus_thickness": 12.0,
"default_junction_size": 40.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"default_wire_thickness": 6.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.3,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.3
},
"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": [
[
"8c8ee5d7-3451-4a2e-85b6-a20d3d490147",
""
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
update=do 26 jul 2018 21:08:19 CEST
version=1
last_client=kicad
[pcbnew]
version=1
LastNetListRead=
UseCmpFile=1
PadDrill=0.600000000000
PadDrillOvalY=0.600000000000
PadSizeH=1.500000000000
PadSizeV=1.500000000000
PcbTextSizeV=1.500000000000
PcbTextSizeH=1.500000000000
PcbTextThickness=0.300000000000
ModuleTextSizeV=1.000000000000
ModuleTextSizeH=1.000000000000
ModuleTextSizeThickness=0.150000000000
SolderMaskClearance=0.000000000000
SolderMaskMinWidth=0.000000000000
DrawSegmentWidth=0.200000000000
BoardOutlineThickness=0.100000000000
ModuleOutlineThickness=0.150000000000
[cvpcb]
version=1
NetIExt=net
[general]
version=1
[eeschema]
version=1
LibDir=

View File

@@ -0,0 +1,39 @@
EESchema Schematic File Version 4
LIBS:adatface_baseboard-cache
EELAYER 26 0
EELAYER END
$Descr A4 11693 8268
encoding utf-8
Sheet 1 1
Title ""
Date ""
Rev ""
Comp ""
Comment1 ""
Comment2 ""
Comment3 ""
Comment4 ""
$EndDescr
$Comp
L SquantorLabels:VYYYYMMDD N2
U 1 1 5A1357A5
P 850 7700
F 0 "N2" H 850 7800 60 0000 C CNN
F 1 "V20180726" H 850 7700 60 0000 C CNN
F 2 "SquantorLabels:Label_version" H 850 7700 60 0001 C CNN
F 3 "" H 850 7700 60 0001 C CNN
1 850 7700
1 0 0 -1
$EndComp
$Comp
L SquantorLabels:OHWLOGO N1
U 1 1 5A135869
P 850 7350
F 0 "N1" H 850 7500 60 0000 C CNN
F 1 "OHWLOGO" H 850 7200 60 0000 C CNN
F 2 "Symbols:OSHW-Symbol_6.7x6mm_SilkScreen" H 850 7350 60 0001 C CNN
F 3 "" H 850 7350 60 0001 C CNN
1 850 7350
1 0 0 -1
$EndComp
$EndSCHEMATC

Binary file not shown.

View File

@@ -0,0 +1,13 @@
Copyright 2006, 2007, 2008, 2009, 2010 Google Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,6 @@
Droid Sans Mono for Powerline
=============================
:Font creator: Ascender Corporation
:Source: Provided by system
:Patched by: `mt3 <https://github.com/mt3>`_

View File

@@ -0,0 +1,77 @@
(module QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm (layer F.Cu) (tedit 5E2FFDFC)
(descr "QFN, 32 Pin (http://ww1.microchip.com/downloads/en/DeviceDoc/00002164B.pdf#page=68), generated with kicad-footprint-generator ipc_noLead_generator.py")
(tags "QFN NoLead")
(attr smd)
(fp_text reference REF** (at 0 -3.82) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm (at 0 3.82) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 2.135 -2.61) (end 2.61 -2.61) (layer F.SilkS) (width 0.12))
(fp_line (start 2.61 -2.61) (end 2.61 -2.135) (layer F.SilkS) (width 0.12))
(fp_line (start -2.135 2.61) (end -2.61 2.61) (layer F.SilkS) (width 0.12))
(fp_line (start -2.61 2.61) (end -2.61 2.135) (layer F.SilkS) (width 0.12))
(fp_line (start 2.135 2.61) (end 2.61 2.61) (layer F.SilkS) (width 0.12))
(fp_line (start 2.61 2.61) (end 2.61 2.135) (layer F.SilkS) (width 0.12))
(fp_line (start -2.135 -2.61) (end -2.61 -2.61) (layer F.SilkS) (width 0.12))
(fp_line (start -1.5 -2.5) (end 2.5 -2.5) (layer F.Fab) (width 0.1))
(fp_line (start 2.5 -2.5) (end 2.5 2.5) (layer F.Fab) (width 0.1))
(fp_line (start 2.5 2.5) (end -2.5 2.5) (layer F.Fab) (width 0.1))
(fp_line (start -2.5 2.5) (end -2.5 -1.5) (layer F.Fab) (width 0.1))
(fp_line (start -2.5 -1.5) (end -1.5 -2.5) (layer F.Fab) (width 0.1))
(fp_line (start -3.12 -3.12) (end -3.12 3.12) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.12 3.12) (end 3.12 3.12) (layer F.CrtYd) (width 0.05))
(fp_line (start 3.12 3.12) (end 3.12 -3.12) (layer F.CrtYd) (width 0.05))
(fp_line (start 3.12 -3.12) (end -3.12 -3.12) (layer F.CrtYd) (width 0.05))
(pad 1 smd roundrect (at -2.4375 -1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 2 smd roundrect (at -2.4375 -1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 3 smd roundrect (at -2.4375 -0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 4 smd roundrect (at -2.4375 -0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 5 smd roundrect (at -2.4375 0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 6 smd roundrect (at -2.4375 0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 7 smd roundrect (at -2.4375 1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 8 smd roundrect (at -2.4375 1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 9 smd roundrect (at -1.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 10 smd roundrect (at -1.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 11 smd roundrect (at -0.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 12 smd roundrect (at -0.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 13 smd roundrect (at 0.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 14 smd roundrect (at 0.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 15 smd roundrect (at 1.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 16 smd roundrect (at 1.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 17 smd roundrect (at 2.4375 1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 18 smd roundrect (at 2.4375 1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 19 smd roundrect (at 2.4375 0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 20 smd roundrect (at 2.4375 0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 21 smd roundrect (at 2.4375 -0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 22 smd roundrect (at 2.4375 -0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 23 smd roundrect (at 2.4375 -1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 24 smd roundrect (at 2.4375 -1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 25 smd roundrect (at 1.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 26 smd roundrect (at 1.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 27 smd roundrect (at 0.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 28 smd roundrect (at 0.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 29 smd roundrect (at -0.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 30 smd roundrect (at -0.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 31 smd roundrect (at -1.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 32 smd roundrect (at -1.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 33 smd rect (at 0 0) (size 3.3 3.3) (layers F.Cu F.Mask))
(pad "" smd roundrect (at -1.1 -1.1) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at -1.1 0) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at -1.1 1.1) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 0 -1.1) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 0 0) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 0 1.1) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 1.1 -1.1) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 1.1 0) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 1.1 1.1) (size 0.89 0.89) (layers F.Paste) (roundrect_rratio 0.25))
(fp_text user %R (at 0 0) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(model ${KISYS3DMOD}/Package_DFN_QFN.3dshapes/QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@@ -0,0 +1,166 @@
(module QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm_ThermalVias (layer F.Cu) (tedit 5E2FFDFC)
(descr "QFN, 32 Pin (http://ww1.microchip.com/downloads/en/DeviceDoc/00002164B.pdf#page=68), generated with kicad-footprint-generator ipc_noLead_generator.py")
(tags "QFN NoLead")
(attr smd)
(fp_text reference REF** (at 0 -3.82) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm_ThermalVias (at 0 3.82) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 2.135 -2.61) (end 2.61 -2.61) (layer F.SilkS) (width 0.12))
(fp_line (start 2.61 -2.61) (end 2.61 -2.135) (layer F.SilkS) (width 0.12))
(fp_line (start -2.135 2.61) (end -2.61 2.61) (layer F.SilkS) (width 0.12))
(fp_line (start -2.61 2.61) (end -2.61 2.135) (layer F.SilkS) (width 0.12))
(fp_line (start 2.135 2.61) (end 2.61 2.61) (layer F.SilkS) (width 0.12))
(fp_line (start 2.61 2.61) (end 2.61 2.135) (layer F.SilkS) (width 0.12))
(fp_line (start -2.135 -2.61) (end -2.61 -2.61) (layer F.SilkS) (width 0.12))
(fp_line (start -1.5 -2.5) (end 2.5 -2.5) (layer F.Fab) (width 0.1))
(fp_line (start 2.5 -2.5) (end 2.5 2.5) (layer F.Fab) (width 0.1))
(fp_line (start 2.5 2.5) (end -2.5 2.5) (layer F.Fab) (width 0.1))
(fp_line (start -2.5 2.5) (end -2.5 -1.5) (layer F.Fab) (width 0.1))
(fp_line (start -2.5 -1.5) (end -1.5 -2.5) (layer F.Fab) (width 0.1))
(fp_line (start -3.12 -3.12) (end -3.12 3.12) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.12 3.12) (end 3.12 3.12) (layer F.CrtYd) (width 0.05))
(fp_line (start 3.12 3.12) (end 3.12 -3.12) (layer F.CrtYd) (width 0.05))
(fp_line (start 3.12 -3.12) (end -3.12 -3.12) (layer F.CrtYd) (width 0.05))
(pad 1 smd roundrect (at -2.4375 -1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 2 smd roundrect (at -2.4375 -1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 3 smd roundrect (at -2.4375 -0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 4 smd roundrect (at -2.4375 -0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 5 smd roundrect (at -2.4375 0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 6 smd roundrect (at -2.4375 0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 7 smd roundrect (at -2.4375 1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 8 smd roundrect (at -2.4375 1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 9 smd roundrect (at -1.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 10 smd roundrect (at -1.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 11 smd roundrect (at -0.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 12 smd roundrect (at -0.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 13 smd roundrect (at 0.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 14 smd roundrect (at 0.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 15 smd roundrect (at 1.25 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 16 smd roundrect (at 1.75 2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 17 smd roundrect (at 2.4375 1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 18 smd roundrect (at 2.4375 1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 19 smd roundrect (at 2.4375 0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 20 smd roundrect (at 2.4375 0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 21 smd roundrect (at 2.4375 -0.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 22 smd roundrect (at 2.4375 -0.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 23 smd roundrect (at 2.4375 -1.25) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 24 smd roundrect (at 2.4375 -1.75) (size 0.875 0.25) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 25 smd roundrect (at 1.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 26 smd roundrect (at 1.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 27 smd roundrect (at 0.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 28 smd roundrect (at 0.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 29 smd roundrect (at -0.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 30 smd roundrect (at -0.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 31 smd roundrect (at -1.25 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 32 smd roundrect (at -1.75 -2.4375) (size 0.25 0.875) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))
(pad 33 smd rect (at 0 0) (size 3.3 3.3) (layers F.Cu F.Mask))
(pad 33 thru_hole circle (at -1 -1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at 0 -1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at 1 -1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at -1 0) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at 0 0) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at 1 0) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at -1 1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at 0 1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 thru_hole circle (at 1 1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))
(pad 33 smd rect (at 0 0) (size 2.5 2.5) (layers B.Cu))
(pad "" smd roundrect (at -0.5 -0.5) (size 0.806226 0.806226) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at -0.5 0.5) (size 0.806226 0.806226) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 0.5 -0.5) (size 0.806226 0.806226) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd roundrect (at 0.5 0.5) (size 0.806226 0.806226) (layers F.Paste) (roundrect_rratio 0.25))
(pad "" smd custom (at -1.325 -0.5) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.175064 -0.316154) (xy 0.103025 -0.316154) (xy 0.175064 -0.244114) (xy 0.175064 0.244114)
(xy 0.103025 0.316154) (xy -0.175064 0.316154)) (width 0.173919))
))
(pad "" smd custom (at -1.325 0.5) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.175064 -0.316154) (xy 0.103025 -0.316154) (xy 0.175064 -0.244114) (xy 0.175064 0.244114)
(xy 0.103025 0.316154) (xy -0.175064 0.316154)) (width 0.173919))
))
(pad "" smd custom (at 1.325 -0.5) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.175064 -0.244114) (xy -0.103025 -0.316154) (xy 0.175064 -0.316154) (xy 0.175064 0.316154)
(xy -0.103025 0.316154) (xy -0.175064 0.244114)) (width 0.173919))
))
(pad "" smd custom (at 1.325 0.5) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.175064 -0.244114) (xy -0.103025 -0.316154) (xy 0.175064 -0.316154) (xy 0.175064 0.316154)
(xy -0.103025 0.316154) (xy -0.175064 0.244114)) (width 0.173919))
))
(pad "" smd custom (at -0.5 -1.325) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.316154 -0.175064) (xy 0.316154 -0.175064) (xy 0.316154 0.103025) (xy 0.244114 0.175064)
(xy -0.244114 0.175064) (xy -0.316154 0.103025)) (width 0.173919))
))
(pad "" smd custom (at 0.5 -1.325) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.316154 -0.175064) (xy 0.316154 -0.175064) (xy 0.316154 0.103025) (xy 0.244114 0.175064)
(xy -0.244114 0.175064) (xy -0.316154 0.103025)) (width 0.173919))
))
(pad "" smd custom (at -0.5 1.325) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.316154 -0.103025) (xy -0.244114 -0.175064) (xy 0.244114 -0.175064) (xy 0.316154 -0.103025)
(xy 0.316154 0.175064) (xy -0.316154 0.175064)) (width 0.173919))
))
(pad "" smd custom (at 0.5 1.325) (size 0.437087 0.437087) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.316154 -0.103025) (xy -0.244114 -0.175064) (xy 0.244114 -0.175064) (xy 0.316154 -0.103025)
(xy 0.316154 0.175064) (xy -0.316154 0.175064)) (width 0.173919))
))
(pad "" smd custom (at -1.325 -1.325) (size 0.413109 0.413109) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.151086 -0.151086) (xy 0.151086 -0.151086) (xy 0.151086 0.059182) (xy 0.059182 0.151086)
(xy -0.151086 0.151086)) (width 0.221875))
))
(pad "" smd custom (at -1.325 1.325) (size 0.413109 0.413109) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.151086 -0.151086) (xy 0.059182 -0.151086) (xy 0.151086 -0.059182) (xy 0.151086 0.151086)
(xy -0.151086 0.151086)) (width 0.221875))
))
(pad "" smd custom (at 1.325 -1.325) (size 0.413109 0.413109) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.151086 -0.151086) (xy 0.151086 -0.151086) (xy 0.151086 0.151086) (xy -0.059182 0.151086)
(xy -0.151086 0.059182)) (width 0.221875))
))
(pad "" smd custom (at 1.325 1.325) (size 0.413109 0.413109) (layers F.Paste)
(options (clearance outline) (anchor circle))
(primitives
(gr_poly (pts
(xy -0.151086 -0.059182) (xy -0.059182 -0.151086) (xy 0.151086 -0.151086) (xy 0.151086 0.151086)
(xy -0.151086 0.151086)) (width 0.221875))
))
(fp_text user %R (at 0 0) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(model ${KISYS3DMOD}/Package_DFN_QFN.3dshapes/QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@@ -0,0 +1,54 @@
(module USB_C_Receptacle_XKB_U262-16XN-4BVC11 (layer F.Cu) (tedit 5E1305FC)
(descr "USB Type C, right-angle, SMT, https://datasheet.lcsc.com/szlcsc/1811141824_XKB-Enterprise-U262-161N-4BVC11_C319148.pdf")
(tags "USB C Type-C Receptacle SMD")
(attr smd)
(fp_text reference REF** (at 0 -5.715) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value USB_C_Receptacle_XKB_U262-16XN-4BVC11 (at 0 4.935) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start -4.58 -1.85) (end -4.58 0.07) (layer F.SilkS) (width 0.12))
(fp_line (start 4.58 0.07) (end 4.58 -1.85) (layer F.SilkS) (width 0.12))
(fp_line (start 4.58 2.08) (end 4.58 3.785) (layer F.SilkS) (width 0.12))
(fp_line (start -4.58 3.785) (end -4.58 2.08) (layer F.SilkS) (width 0.12))
(fp_line (start 4.58 3.785) (end -4.58 3.785) (layer F.SilkS) (width 0.12))
(fp_line (start -5.32 -4.75) (end 5.32 -4.75) (layer F.CrtYd) (width 0.05))
(fp_line (start 5.32 -4.75) (end 5.32 4.18) (layer F.CrtYd) (width 0.05))
(fp_line (start 5.32 4.18) (end -5.32 4.18) (layer F.CrtYd) (width 0.05))
(fp_line (start -5.32 4.18) (end -5.32 -4.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -4.47 -3.675) (end -4.47 3.675) (layer F.Fab) (width 0.1))
(fp_line (start -4.47 3.675) (end 4.47 3.675) (layer F.Fab) (width 0.1))
(fp_line (start 4.47 3.675) (end 4.47 -3.675) (layer F.Fab) (width 0.1))
(fp_line (start -4.47 -3.675) (end 4.47 -3.675) (layer F.Fab) (width 0.1))
(fp_text user %R (at 0 0) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(pad S1 thru_hole oval (at -4.32 -3.105) (size 1 2.1) (drill oval 0.6 1.7) (layers *.Cu *.Mask))
(pad S1 thru_hole oval (at 4.32 -3.105) (size 1 2.1) (drill oval 0.6 1.7) (layers *.Cu *.Mask))
(pad S1 thru_hole oval (at -4.32 1.075) (size 1 1.6) (drill oval 0.6 1.2) (layers *.Cu *.Mask))
(pad S1 thru_hole oval (at 4.32 1.075) (size 1 1.6) (drill oval 0.6 1.2) (layers *.Cu *.Mask))
(pad "" np_thru_hole circle (at 2.89 -2.605) (size 0.65 0.65) (drill 0.65) (layers *.Cu *.Mask))
(pad "" np_thru_hole circle (at -2.89 -2.605) (size 0.65 0.65) (drill 0.65) (layers *.Cu *.Mask))
(pad B1 smd rect (at 3.05 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B4 smd rect (at 2.25 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B5 smd rect (at 1.75 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A8 smd rect (at 1.25 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B6 smd rect (at 0.75 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A7 smd rect (at 0.25 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A6 smd rect (at -0.25 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B7 smd rect (at -0.75 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A5 smd rect (at -1.25 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B8 smd rect (at -1.75 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A4 smd rect (at -2.55 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A1 smd rect (at -3.35 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B12 smd rect (at -3.05 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad B9 smd rect (at -2.25 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A9 smd rect (at 2.55 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(pad A12 smd rect (at 3.35 -3.67) (size 0.3 1.15) (layers F.Cu F.Paste F.Mask))
(model ${KISYS3DMOD}/Connector_USB.3dshapes/USB_C_Receptacle_XKB_U262-16XN-4BVC11.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@@ -0,0 +1,4 @@
(fp_lib_table
(lib (name "toslink")(type "KiCad")(uri "${KIPRJMOD}/toslink")(options "")(descr ""))
(lib (name "footprints")(type "KiCad")(uri "${KIPRJMOD}/footprints")(options "")(descr ""))
)

View File

@@ -0,0 +1,38 @@
Comment,Designator,Footprint,LCSC
10k,"R10,R3,R4,R5,R6,R9",R_0603_1608Metric, C25804
USB3320,"U5,U6",QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm,C132156
PLR135_T8,"U1,U2,U3,U4",PLR135-T8_PLT133-T8,C133351
47uH,"L1,L2,L3,L4",L_0805_2012Metric,C14304
100n,"C1,C12,C14,C15,C17,C2,C20,C3,C4,C5,C6,C7,C8",C_0603_1608Metric,C14663
1u,"C11,C13",C_0603_1608Metric,C15849
10u,C21,C_0805_2012Metric,C15850
Connector_USB_C_Receptacle_USB2.0,"J4,J5",USB_C_Receptacle_XKB_U262-16XN-4BVC11,C165948
1.5A,FB1,L_1206_3216Metric,C16902
10n,C19,C_0805_2012Metric,C1710
1k,"R1,R11,R2,R21,R23,R25,R8",R_0603_1608Metric,C21190
Schottky,"D12,D13",D_SMA,C22452
red,D1,LED_0603_1608Metric,C2286
1M,"R12,R7",R_0603_1608Metric,C22935
2k,"R24,R26",R_0603_1608Metric,C22975
8k06 1%,"R17,R18",R_0603_1608Metric,C23112
5k1,"R13,R14,R15,R16",R_0603_1608Metric,C23186
2u2,"C10,C16,C18,C9",C_0603_1608Metric,C23630
ME6212C18M5G,U7,SOT-23-5,C236669
10k,"R19,R20",R_0603_1608Metric,C25804
PLT133_T8,"TR1,TR2,TR3,TR4",PLT133_T8,C2940206
yellow,"D10,D11,D2,D7",LED_0603_1608Metric,C72038
green,"D3,D4,D5,D6,D8,D9",LED_0603_1608Metric,C72043
MountingHole,H3,MountingHole_3.2mm_M3_Pad_Via,
MountingHole,H4,MountingHole_3.2mm_M3_Pad_Via,
Conn_02x32_Odd_Even,J3,PinHeader_2x32_P2.54mm_Vertical,
Conn_01x26_Male,J7,PinHeader_1x26_P2.54mm_Horizontal,
Conn_01x06_Male,J6,PinHeader_1x06_P2.54mm_Vertical,
TestPoint,TP5,TestPoint_Pad_D1.5mm,
Conn_01x01_Male,J9,PinHeader_1x01_P2.54mm_Horizontal,
MountingHole,H2,MountingHole_3.2mm_M3_Pad_Via,
Conn_01x06_Male,J1,PinHeader_1x06_P2.54mm_Vertical,
Conn_01x01_Male,J8,PinHeader_1x01_P2.54mm_Horizontal,
MountingHole,H1,MountingHole_3.2mm_M3_Pad_Via,
Conn_02x32_Odd_Even,J2,PinHeader_2x32_P2.54mm_Vertical,
Conn_01x04_Male,J11,PinHeader_1x04_P2.54mm_Horizontal,
Conn_01x04_Male,J10,PinHeader_1x04_P2.54mm_Horizontal,
1 Comment Designator Footprint LCSC
2 10k R10,R3,R4,R5,R6,R9 R_0603_1608Metric C25804
3 USB3320 U5,U6 QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm C132156
4 PLR135_T8 U1,U2,U3,U4 PLR135-T8_PLT133-T8 C133351
5 47uH L1,L2,L3,L4 L_0805_2012Metric C14304
6 100n C1,C12,C14,C15,C17,C2,C20,C3,C4,C5,C6,C7,C8 C_0603_1608Metric C14663
7 1u C11,C13 C_0603_1608Metric C15849
8 10u C21 C_0805_2012Metric C15850
9 Connector_USB_C_Receptacle_USB2.0 J4,J5 USB_C_Receptacle_XKB_U262-16XN-4BVC11 C165948
10 1.5A FB1 L_1206_3216Metric C16902
11 10n C19 C_0805_2012Metric C1710
12 1k R1,R11,R2,R21,R23,R25,R8 R_0603_1608Metric C21190
13 Schottky D12,D13 D_SMA C22452
14 red D1 LED_0603_1608Metric C2286
15 1M R12,R7 R_0603_1608Metric C22935
16 2k R24,R26 R_0603_1608Metric C22975
17 8k06 1% R17,R18 R_0603_1608Metric C23112
18 5k1 R13,R14,R15,R16 R_0603_1608Metric C23186
19 2u2 C10,C16,C18,C9 C_0603_1608Metric C23630
20 ME6212C18M5G U7 SOT-23-5 C236669
21 10k R19,R20 R_0603_1608Metric C25804
22 PLT133_T8 TR1,TR2,TR3,TR4 PLT133_T8 C2940206
23 yellow D10,D11,D2,D7 LED_0603_1608Metric C72038
24 green D3,D4,D5,D6,D8,D9 LED_0603_1608Metric C72043
25 MountingHole H3 MountingHole_3.2mm_M3_Pad_Via
26 MountingHole H4 MountingHole_3.2mm_M3_Pad_Via
27 Conn_02x32_Odd_Even J3 PinHeader_2x32_P2.54mm_Vertical
28 Conn_01x26_Male J7 PinHeader_1x26_P2.54mm_Horizontal
29 Conn_01x06_Male J6 PinHeader_1x06_P2.54mm_Vertical
30 TestPoint TP5 TestPoint_Pad_D1.5mm
31 Conn_01x01_Male J9 PinHeader_1x01_P2.54mm_Horizontal
32 MountingHole H2 MountingHole_3.2mm_M3_Pad_Via
33 Conn_01x06_Male J1 PinHeader_1x06_P2.54mm_Vertical
34 Conn_01x01_Male J8 PinHeader_1x01_P2.54mm_Horizontal
35 MountingHole H1 MountingHole_3.2mm_M3_Pad_Via
36 Conn_02x32_Odd_Even J2 PinHeader_2x32_P2.54mm_Vertical
37 Conn_01x04_Male J11 PinHeader_1x04_P2.54mm_Horizontal
38 Conn_01x04_Male J10 PinHeader_1x04_P2.54mm_Horizontal

View File

@@ -0,0 +1,87 @@
Designator,Val,Package,Mid X,Mid Y,Rotation,Layer
C1,100n,C_0603_1608Metric,55.65,-138.6,90.0,top
C2,100n,C_0603_1608Metric,55.65,-54.85,90.0,top
C3,100n,C_0603_1608Metric,55.65,-82.6375,90.0,top
C4,100n,C_0603_1608Metric,55.525979,-110.519892,90.0,top
C5,100n,C_0603_1608Metric,55.65,-127.85,-90.0,top
C6,100n,C_0603_1608Metric,55.5,-44.675,-90.0,top
C7,100n,C_0603_1608Metric,55.45,-72.65,-90.0,top
C8,100n,C_0603_1608Metric,56.136737,-100.320543,-90.0,top
C9,2u2,C_0603_1608Metric,152.4,-60.35,-90.0,top
C10,2u2,C_0603_1608Metric,151.3,-90.5,180.0,top
C11,1u,C_0603_1608Metric,150.45,-70.95,-90.0,top
C12,100n,C_0603_1608Metric,137.97,-82.5,180.0,top
C13,1u,C_0603_1608Metric,157.75,-71.25,-90.0,top
C14,100n,C_0603_1608Metric,137.72,-53.69,180.0,top
C15,100n,C_0603_1608Metric,140.21,-80.73,180.0,top
C16,2u2,C_0603_1608Metric,146.825,-83.9,90.0,top
C17,100n,C_0603_1608Metric,139.45,-51.74,180.0,top
C18,2u2,C_0603_1608Metric,147.55,-54.67,90.0,top
C19,10n,C_0805_2012Metric,157.25,-102.0,0.0,top
C20,100n,C_0603_1608Metric,157.5,-99.25,0.0,top
C21,10u,C_0805_2012Metric,157.5,-97.25,0.0,top
D1,red,LED_0603_1608Metric,157.0,-128.6,180.0,top
D2,yellow,LED_0603_1608Metric,157.0,-122.816664,180.0,top
D3,green,LED_0603_1608Metric,157.0,-111.25,180.0,top
D4,green,LED_0603_1608Metric,157.0,-114.141666,180.0,top
D5,green,LED_0603_1608Metric,157.0,-117.033332,180.0,top
D6,green,LED_0603_1608Metric,157.0,-119.924998,180.0,top
D7,yellow,LED_0603_1608Metric,146.025,-101.02,180.0,top
D8,green,LED_0603_1608Metric,146.025,-103.597321,180.0,top
D9,green,LED_0603_1608Metric,146.025,-108.751964,180.0,top
D10,yellow,LED_0603_1608Metric,146.025,-106.174642,180.0,top
D11,yellow,LED_0603_1608Metric,157.0,-125.70833,180.0,top
D12,Schottky,D_SMA,156.9,-48.9,180.0,top
D13,Schottky,D_SMA,157.0,-94.0,180.0,top
FB1,1.5A,L_1206_3216Metric,160.5,-100.75,90.0,top
J1,Conn_01x06_Male,PinHeader_1x06_P2.54mm_Vertical,132.25,-132.9,0.0,top
J2,Conn_02x32_Odd_Even,PinHeader_2x32_P2.54mm_Vertical,67.945,-41.91,0.0,top
J3,Conn_02x32_Odd_Even,PinHeader_2x32_P2.54mm_Vertical,128.65,-41.91,0.0,top
J4,Connector_USB_C_Receptacle_USB2.0,USB_C_Receptacle_XKB_U262-16XN-4BVC11,158.65,-85.85,90.0,top
J5,Connector_USB_C_Receptacle_USB2.0,USB_C_Receptacle_XKB_U262-16XN-4BVC11,158.65,-56.85,90.0,top
J6,Conn_01x06_Male,PinHeader_1x06_P2.54mm_Vertical,99.0,-132.9,0.0,top
J7,Conn_01x26_Male,PinHeader_1x26_P2.54mm_Horizontal,80.01,-41.783,0.0,top
J8,Conn_01x01_Male,PinHeader_1x01_P2.54mm_Horizontal,124.25,-47.0,180.0,top
J9,Conn_01x01_Male,PinHeader_1x01_P2.54mm_Horizontal,124.25,-43.25,180.0,top
J10,Conn_01x04_Male,PinHeader_1x04_P2.54mm_Horizontal,107.49,-39.31,90.0,top
J11,Conn_01x04_Male,PinHeader_1x04_P2.54mm_Horizontal,93.64,-39.365,90.0,top
L1,47uH,L_0805_2012Metric,58.4,-136.85,-90.0,top
L2,47uH,L_0805_2012Metric,58.65,-53.09375,-90.0,top
L3,47uH,L_0805_2012Metric,58.45,-80.85,-90.0,top
L4,47uH,L_0805_2012Metric,58.55,-108.8125,-90.0,top
R1,1k,R_0603_1608Metric,135.8,-128.64,180.0,top
R2,1k,R_0603_1608Metric,135.8,-122.856664,180.0,top
R3,10k,R_0603_1608Metric,135.8,-111.29,180.0,top
R4,10k,R_0603_1608Metric,135.8,-114.181666,180.0,top
R5,10k,R_0603_1608Metric,135.8,-117.073332,180.0,top
R6,10k,R_0603_1608Metric,135.8,-119.964998,180.0,top
R7,1M,R_0603_1608Metric,157.7625,-79.25,0.0,top
R8,1k,R_0603_1608Metric,135.8,-101.027811,180.0,top
R9,10k,R_0603_1608Metric,135.8,-103.593358,180.0,top
R10,10k,R_0603_1608Metric,135.8,-108.724452,180.0,top
R11,1k,R_0603_1608Metric,135.8,-106.158905,180.0,top
R12,1M,R_0603_1608Metric,157.65,-63.85,0.0,top
R13,5k1,R_0603_1608Metric,151.2875,-87.2,180.0,top
R14,5k1,R_0603_1608Metric,151.725,-82.675,180.0,top
R15,5k1,R_0603_1608Metric,149.85,-58.3,180.0,top
R16,5k1,R_0603_1608Metric,150.22,-55.07,0.0,top
R17,8k06 1%,R_0603_1608Metric,144.8,-50.4,90.0,top
R18,8k06 1%,R_0603_1608Metric,146.05,-80.85,0.0,top
R19,10k,R_0603_1608Metric,149.7,-49.1,180.0,top
R20,10k,R_0603_1608Metric,151.2625,-88.9,180.0,top
R21,1k,R_0603_1608Metric,135.8,-125.74833,180.0,top
R23,1k,R_0603_1608Metric,149.9,-61.1,180.0,top
R24,2k,R_0603_1608Metric,146.3,-62.425,-90.0,top
R25,1k,R_0603_1608Metric,150.925,-77.3625,180.0,top
R26,2k,R_0603_1608Metric,148.51,-76.6375,90.0,top
TR1,PLT133_T8,PLT133_T8,48.416023,-126.551533,-90.0,top
TR2,PLT133_T8,PLT133_T8,48.430408,-43.357745,-90.0,top
TR3,PLT133_T8,PLT133_T8,48.406111,-71.121385,-90.0,top
TR4,PLT133_T8,PLT133_T8,48.32653,-98.843594,-90.0,top
U1,PLR135_T8,PLR135-T8_PLT133-T8,48.426023,-139.789033,90.0,top
U2,PLR135_T8,PLR135-T8_PLT133-T8,48.440408,-56.120245,90.0,top
U3,PLR135_T8,PLR135-T8_PLT133-T8,48.4,-83.85,90.0,top
U4,PLR135_T8,PLR135-T8_PLT133-T8,48.426023,-111.789033,90.0,top
U5,USB3320,QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm,142.65,-55.85,270.0,top
U6,USB3320,QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm,142.7,-84.875,270.0,top
U7,ME6212C18M5G,SOT-23-5,154.15,-71.3875,180.0,top
1 Designator Val Package Mid X Mid Y Rotation Layer
2 C1 100n C_0603_1608Metric 55.65 -138.6 90.0 top
3 C2 100n C_0603_1608Metric 55.65 -54.85 90.0 top
4 C3 100n C_0603_1608Metric 55.65 -82.6375 90.0 top
5 C4 100n C_0603_1608Metric 55.525979 -110.519892 90.0 top
6 C5 100n C_0603_1608Metric 55.65 -127.85 -90.0 top
7 C6 100n C_0603_1608Metric 55.5 -44.675 -90.0 top
8 C7 100n C_0603_1608Metric 55.45 -72.65 -90.0 top
9 C8 100n C_0603_1608Metric 56.136737 -100.320543 -90.0 top
10 C9 2u2 C_0603_1608Metric 152.4 -60.35 -90.0 top
11 C10 2u2 C_0603_1608Metric 151.3 -90.5 180.0 top
12 C11 1u C_0603_1608Metric 150.45 -70.95 -90.0 top
13 C12 100n C_0603_1608Metric 137.97 -82.5 180.0 top
14 C13 1u C_0603_1608Metric 157.75 -71.25 -90.0 top
15 C14 100n C_0603_1608Metric 137.72 -53.69 180.0 top
16 C15 100n C_0603_1608Metric 140.21 -80.73 180.0 top
17 C16 2u2 C_0603_1608Metric 146.825 -83.9 90.0 top
18 C17 100n C_0603_1608Metric 139.45 -51.74 180.0 top
19 C18 2u2 C_0603_1608Metric 147.55 -54.67 90.0 top
20 C19 10n C_0805_2012Metric 157.25 -102.0 0.0 top
21 C20 100n C_0603_1608Metric 157.5 -99.25 0.0 top
22 C21 10u C_0805_2012Metric 157.5 -97.25 0.0 top
23 D1 red LED_0603_1608Metric 157.0 -128.6 180.0 top
24 D2 yellow LED_0603_1608Metric 157.0 -122.816664 180.0 top
25 D3 green LED_0603_1608Metric 157.0 -111.25 180.0 top
26 D4 green LED_0603_1608Metric 157.0 -114.141666 180.0 top
27 D5 green LED_0603_1608Metric 157.0 -117.033332 180.0 top
28 D6 green LED_0603_1608Metric 157.0 -119.924998 180.0 top
29 D7 yellow LED_0603_1608Metric 146.025 -101.02 180.0 top
30 D8 green LED_0603_1608Metric 146.025 -103.597321 180.0 top
31 D9 green LED_0603_1608Metric 146.025 -108.751964 180.0 top
32 D10 yellow LED_0603_1608Metric 146.025 -106.174642 180.0 top
33 D11 yellow LED_0603_1608Metric 157.0 -125.70833 180.0 top
34 D12 Schottky D_SMA 156.9 -48.9 180.0 top
35 D13 Schottky D_SMA 157.0 -94.0 180.0 top
36 FB1 1.5A L_1206_3216Metric 160.5 -100.75 90.0 top
37 J1 Conn_01x06_Male PinHeader_1x06_P2.54mm_Vertical 132.25 -132.9 0.0 top
38 J2 Conn_02x32_Odd_Even PinHeader_2x32_P2.54mm_Vertical 67.945 -41.91 0.0 top
39 J3 Conn_02x32_Odd_Even PinHeader_2x32_P2.54mm_Vertical 128.65 -41.91 0.0 top
40 J4 Connector_USB_C_Receptacle_USB2.0 USB_C_Receptacle_XKB_U262-16XN-4BVC11 158.65 -85.85 90.0 top
41 J5 Connector_USB_C_Receptacle_USB2.0 USB_C_Receptacle_XKB_U262-16XN-4BVC11 158.65 -56.85 90.0 top
42 J6 Conn_01x06_Male PinHeader_1x06_P2.54mm_Vertical 99.0 -132.9 0.0 top
43 J7 Conn_01x26_Male PinHeader_1x26_P2.54mm_Horizontal 80.01 -41.783 0.0 top
44 J8 Conn_01x01_Male PinHeader_1x01_P2.54mm_Horizontal 124.25 -47.0 180.0 top
45 J9 Conn_01x01_Male PinHeader_1x01_P2.54mm_Horizontal 124.25 -43.25 180.0 top
46 J10 Conn_01x04_Male PinHeader_1x04_P2.54mm_Horizontal 107.49 -39.31 90.0 top
47 J11 Conn_01x04_Male PinHeader_1x04_P2.54mm_Horizontal 93.64 -39.365 90.0 top
48 L1 47uH L_0805_2012Metric 58.4 -136.85 -90.0 top
49 L2 47uH L_0805_2012Metric 58.65 -53.09375 -90.0 top
50 L3 47uH L_0805_2012Metric 58.45 -80.85 -90.0 top
51 L4 47uH L_0805_2012Metric 58.55 -108.8125 -90.0 top
52 R1 1k R_0603_1608Metric 135.8 -128.64 180.0 top
53 R2 1k R_0603_1608Metric 135.8 -122.856664 180.0 top
54 R3 10k R_0603_1608Metric 135.8 -111.29 180.0 top
55 R4 10k R_0603_1608Metric 135.8 -114.181666 180.0 top
56 R5 10k R_0603_1608Metric 135.8 -117.073332 180.0 top
57 R6 10k R_0603_1608Metric 135.8 -119.964998 180.0 top
58 R7 1M R_0603_1608Metric 157.7625 -79.25 0.0 top
59 R8 1k R_0603_1608Metric 135.8 -101.027811 180.0 top
60 R9 10k R_0603_1608Metric 135.8 -103.593358 180.0 top
61 R10 10k R_0603_1608Metric 135.8 -108.724452 180.0 top
62 R11 1k R_0603_1608Metric 135.8 -106.158905 180.0 top
63 R12 1M R_0603_1608Metric 157.65 -63.85 0.0 top
64 R13 5k1 R_0603_1608Metric 151.2875 -87.2 180.0 top
65 R14 5k1 R_0603_1608Metric 151.725 -82.675 180.0 top
66 R15 5k1 R_0603_1608Metric 149.85 -58.3 180.0 top
67 R16 5k1 R_0603_1608Metric 150.22 -55.07 0.0 top
68 R17 8k06 1% R_0603_1608Metric 144.8 -50.4 90.0 top
69 R18 8k06 1% R_0603_1608Metric 146.05 -80.85 0.0 top
70 R19 10k R_0603_1608Metric 149.7 -49.1 180.0 top
71 R20 10k R_0603_1608Metric 151.2625 -88.9 180.0 top
72 R21 1k R_0603_1608Metric 135.8 -125.74833 180.0 top
73 R23 1k R_0603_1608Metric 149.9 -61.1 180.0 top
74 R24 2k R_0603_1608Metric 146.3 -62.425 -90.0 top
75 R25 1k R_0603_1608Metric 150.925 -77.3625 180.0 top
76 R26 2k R_0603_1608Metric 148.51 -76.6375 90.0 top
77 TR1 PLT133_T8 PLT133_T8 48.416023 -126.551533 -90.0 top
78 TR2 PLT133_T8 PLT133_T8 48.430408 -43.357745 -90.0 top
79 TR3 PLT133_T8 PLT133_T8 48.406111 -71.121385 -90.0 top
80 TR4 PLT133_T8 PLT133_T8 48.32653 -98.843594 -90.0 top
81 U1 PLR135_T8 PLR135-T8_PLT133-T8 48.426023 -139.789033 90.0 top
82 U2 PLR135_T8 PLR135-T8_PLT133-T8 48.440408 -56.120245 90.0 top
83 U3 PLR135_T8 PLR135-T8_PLT133-T8 48.4 -83.85 90.0 top
84 U4 PLR135_T8 PLR135-T8_PLT133-T8 48.426023 -111.789033 90.0 top
85 U5 USB3320 QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm 142.65 -55.85 270.0 top
86 U6 USB3320 QFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm 142.7 -84.875 270.0 top
87 U7 ME6212C18M5G SOT-23-5 154.15 -71.3875 180.0 top

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
%TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7)*%
%TF.CreationDate,2022-08-08T23:44:24-07:00*%
%TF.ProjectId,adatface_baseboard,61646174-6661-4636-955f-62617365626f,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.7)) date 2022-08-08 23:44:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%TA.AperFunction,Profile*%
%ADD10C,0.150000*%
%TD*%
G04 APERTURE END LIST*
D10*
X41350000Y-36650000D02*
X162650000Y-36650000D01*
X162650000Y-36650000D02*
X162650000Y-148250000D01*
X162650000Y-148250000D02*
X41350000Y-148250000D01*
X41350000Y-148250000D02*
X41350000Y-36650000D01*
M02*

View File

@@ -0,0 +1,670 @@
%TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7)*%
%TF.CreationDate,2022-08-08T23:44:24-07:00*%
%TF.ProjectId,adatface_baseboard,61646174-6661-4636-955f-62617365626f,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.7)) date 2022-08-08 23:44:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10C,2.100000*%
%ADD11C,1.708000*%
%ADD12C,1.700000*%
%ADD13C,2.050000*%
%ADD14RoundRect,0.200000X-0.679000X0.679000X-0.679000X-0.679000X0.679000X-0.679000X0.679000X0.679000X0*%
%ADD15C,1.758000*%
%ADD16C,2.125000*%
%ADD17RoundRect,0.200000X0.850000X-0.850000X0.850000X0.850000X-0.850000X0.850000X-0.850000X-0.850000X0*%
%ADD18O,2.100000X2.100000*%
%ADD19C,1.200000*%
%ADD20C,6.800000*%
%ADD21RoundRect,0.200000X-0.850000X-0.850000X0.850000X-0.850000X0.850000X0.850000X-0.850000X0.850000X0*%
%ADD22C,1.050000*%
%ADD23O,2.500000X1.400000*%
%ADD24O,2.000000X1.400000*%
%ADD25RoundRect,0.200000X0.850000X0.850000X-0.850000X0.850000X-0.850000X-0.850000X0.850000X-0.850000X0*%
%ADD26C,0.860000*%
%ADD27C,1.900000*%
%ADD28C,1.060000*%
%ADD29C,1.480000*%
%ADD30C,1.260000*%
G04 APERTURE END LIST*
D10*
%TO.C,U1*%
X45816023Y-142589033D03*
X45816023Y-136989033D03*
D11*
X51056023Y-137249033D03*
D12*
X51056023Y-139789033D03*
D11*
X51056023Y-142329033D03*
D13*
X48426023Y-137249033D03*
X48426023Y-142329033D03*
%TD*%
D10*
%TO.C,TR2*%
X45810408Y-40557745D03*
X45810408Y-46157745D03*
D14*
X51050408Y-40817745D03*
D15*
X51050408Y-43357745D03*
X51050408Y-45897745D03*
D16*
X48430408Y-40817745D03*
X48430408Y-45897745D03*
%TD*%
D10*
%TO.C,TR3*%
X45786111Y-68321385D03*
X45786111Y-73921385D03*
D14*
X51026111Y-68581385D03*
D15*
X51026111Y-71121385D03*
X51026111Y-73661385D03*
D16*
X48406111Y-68581385D03*
X48406111Y-73661385D03*
%TD*%
D17*
%TO.C,J11*%
X93640000Y-39365000D03*
D18*
X96180000Y-39365000D03*
X98720000Y-39365000D03*
X101260000Y-39365000D03*
%TD*%
D19*
%TO.C,H3*%
X60050000Y-63700000D03*
X64147056Y-62002944D03*
X64850000Y-63700000D03*
X60752944Y-62002944D03*
X64147056Y-65397056D03*
D20*
X62450000Y-63700000D03*
D19*
X62450000Y-66100000D03*
X60752944Y-65397056D03*
X62450000Y-61300000D03*
%TD*%
%TO.C,H4*%
X121793000Y-115049000D03*
X123490056Y-110951944D03*
X124193000Y-112649000D03*
X123490056Y-114346056D03*
X120095944Y-110951944D03*
D20*
X121793000Y-112649000D03*
D19*
X121793000Y-110249000D03*
X119393000Y-112649000D03*
X120095944Y-114346056D03*
%TD*%
D17*
%TO.C,J10*%
X107490000Y-39310000D03*
D18*
X110030000Y-39310000D03*
X112570000Y-39310000D03*
X115110000Y-39310000D03*
%TD*%
D10*
%TO.C,U2*%
X45830408Y-58920245D03*
X45830408Y-53320245D03*
D11*
X51070408Y-53580245D03*
D12*
X51070408Y-56120245D03*
D11*
X51070408Y-58660245D03*
D13*
X48440408Y-53580245D03*
X48440408Y-58660245D03*
%TD*%
D21*
%TO.C,J3*%
X128650000Y-41910000D03*
D18*
X131190000Y-41910000D03*
X128650000Y-44450000D03*
X131190000Y-44450000D03*
X128650000Y-46990000D03*
X131190000Y-46990000D03*
X128650000Y-49530000D03*
X131190000Y-49530000D03*
X128650000Y-52070000D03*
X131190000Y-52070000D03*
X128650000Y-54610000D03*
X131190000Y-54610000D03*
X128650000Y-57150000D03*
X131190000Y-57150000D03*
X128650000Y-59690000D03*
X131190000Y-59690000D03*
X128650000Y-62230000D03*
X131190000Y-62230000D03*
X128650000Y-64770000D03*
X131190000Y-64770000D03*
X128650000Y-67310000D03*
X131190000Y-67310000D03*
X128650000Y-69850000D03*
X131190000Y-69850000D03*
X128650000Y-72390000D03*
X131190000Y-72390000D03*
X128650000Y-74930000D03*
X131190000Y-74930000D03*
X128650000Y-77470000D03*
X131190000Y-77470000D03*
X128650000Y-80010000D03*
X131190000Y-80010000D03*
X128650000Y-82550000D03*
X131190000Y-82550000D03*
X128650000Y-85090000D03*
X131190000Y-85090000D03*
X128650000Y-87630000D03*
X131190000Y-87630000D03*
X128650000Y-90170000D03*
X131190000Y-90170000D03*
X128650000Y-92710000D03*
X131190000Y-92710000D03*
X128650000Y-95250000D03*
X131190000Y-95250000D03*
X128650000Y-97790000D03*
X131190000Y-97790000D03*
X128650000Y-100330000D03*
X131190000Y-100330000D03*
X128650000Y-102870000D03*
X131190000Y-102870000D03*
X128650000Y-105410000D03*
X131190000Y-105410000D03*
X128650000Y-107950000D03*
X131190000Y-107950000D03*
X128650000Y-110490000D03*
X131190000Y-110490000D03*
X128650000Y-113030000D03*
X131190000Y-113030000D03*
X128650000Y-115570000D03*
X131190000Y-115570000D03*
X128650000Y-118110000D03*
X131190000Y-118110000D03*
X128650000Y-120650000D03*
X131190000Y-120650000D03*
%TD*%
D21*
%TO.C,J7*%
X80010000Y-41783000D03*
D18*
X80010000Y-44323000D03*
X80010000Y-46863000D03*
X80010000Y-49403000D03*
X80010000Y-51943000D03*
X80010000Y-54483000D03*
X80010000Y-57023000D03*
X80010000Y-59563000D03*
X80010000Y-62103000D03*
X80010000Y-64643000D03*
X80010000Y-67183000D03*
X80010000Y-69723000D03*
X80010000Y-72263000D03*
X80010000Y-74803000D03*
X80010000Y-77343000D03*
X80010000Y-79883000D03*
X80010000Y-82423000D03*
X80010000Y-84963000D03*
X80010000Y-87503000D03*
X80010000Y-90043000D03*
X80010000Y-92583000D03*
X80010000Y-95123000D03*
X80010000Y-97663000D03*
X80010000Y-100203000D03*
X80010000Y-102743000D03*
X80010000Y-105283000D03*
%TD*%
D21*
%TO.C,J6*%
X99000000Y-132900000D03*
D18*
X99000000Y-135440000D03*
X99000000Y-137980000D03*
X99000000Y-140520000D03*
X99000000Y-143060000D03*
X99000000Y-145600000D03*
%TD*%
D22*
%TO.C,J4*%
X156045000Y-82960000D03*
X156045000Y-88740000D03*
D23*
X155545000Y-90170000D03*
D24*
X159725000Y-90170000D03*
X159725000Y-81530000D03*
D23*
X155545000Y-81530000D03*
%TD*%
D10*
%TO.C,U3*%
X45790000Y-86650000D03*
X45790000Y-81050000D03*
D11*
X51030000Y-81310000D03*
D12*
X51030000Y-83850000D03*
D11*
X51030000Y-86390000D03*
D13*
X48400000Y-81310000D03*
X48400000Y-86390000D03*
%TD*%
D25*
%TO.C,J9*%
X124250000Y-43250000D03*
%TD*%
D19*
%TO.C,H2*%
X62752944Y-141902944D03*
X66850000Y-143600000D03*
X64450000Y-146000000D03*
X66147056Y-145297056D03*
X64450000Y-141200000D03*
X66147056Y-141902944D03*
X62752944Y-145297056D03*
X62050000Y-143600000D03*
D20*
X64450000Y-143600000D03*
%TD*%
D21*
%TO.C,J1*%
X132250000Y-132900000D03*
D18*
X132250000Y-135440000D03*
X132250000Y-137980000D03*
X132250000Y-140520000D03*
X132250000Y-143060000D03*
X132250000Y-145600000D03*
%TD*%
D10*
%TO.C,TR4*%
X45706530Y-96043594D03*
X45706530Y-101643594D03*
D14*
X50946530Y-96303594D03*
D15*
X50946530Y-98843594D03*
X50946530Y-101383594D03*
D16*
X48326530Y-96303594D03*
X48326530Y-101383594D03*
%TD*%
D25*
%TO.C,J8*%
X124250000Y-47000000D03*
%TD*%
D20*
%TO.C,H1*%
X137925000Y-42100000D03*
D19*
X137925000Y-39700000D03*
X137925000Y-44500000D03*
X140325000Y-42100000D03*
X139622056Y-43797056D03*
X136227944Y-40402944D03*
X135525000Y-42100000D03*
X136227944Y-43797056D03*
X139622056Y-40402944D03*
%TD*%
D10*
%TO.C,U4*%
X45816023Y-108989033D03*
X45816023Y-114589033D03*
D11*
X51056023Y-109249033D03*
D12*
X51056023Y-111789033D03*
D11*
X51056023Y-114329033D03*
D13*
X48426023Y-109249033D03*
X48426023Y-114329033D03*
%TD*%
D10*
%TO.C,TR1*%
X45796023Y-123751533D03*
X45796023Y-129351533D03*
D14*
X51036023Y-124011533D03*
D15*
X51036023Y-126551533D03*
X51036023Y-129091533D03*
D16*
X48416023Y-124011533D03*
X48416023Y-129091533D03*
%TD*%
D21*
%TO.C,J2*%
X67945000Y-41910000D03*
D18*
X70485000Y-41910000D03*
X67945000Y-44450000D03*
X70485000Y-44450000D03*
X67945000Y-46990000D03*
X70485000Y-46990000D03*
X67945000Y-49530000D03*
X70485000Y-49530000D03*
X67945000Y-52070000D03*
X70485000Y-52070000D03*
X67945000Y-54610000D03*
X70485000Y-54610000D03*
X67945000Y-57150000D03*
X70485000Y-57150000D03*
X67945000Y-59690000D03*
X70485000Y-59690000D03*
X67945000Y-62230000D03*
X70485000Y-62230000D03*
X67945000Y-64770000D03*
X70485000Y-64770000D03*
X67945000Y-67310000D03*
X70485000Y-67310000D03*
X67945000Y-69850000D03*
X70485000Y-69850000D03*
X67945000Y-72390000D03*
X70485000Y-72390000D03*
X67945000Y-74930000D03*
X70485000Y-74930000D03*
X67945000Y-77470000D03*
X70485000Y-77470000D03*
X67945000Y-80010000D03*
X70485000Y-80010000D03*
X67945000Y-82550000D03*
X70485000Y-82550000D03*
X67945000Y-85090000D03*
X70485000Y-85090000D03*
X67945000Y-87630000D03*
X70485000Y-87630000D03*
X67945000Y-90170000D03*
X70485000Y-90170000D03*
X67945000Y-92710000D03*
X70485000Y-92710000D03*
X67945000Y-95250000D03*
X70485000Y-95250000D03*
X67945000Y-97790000D03*
X70485000Y-97790000D03*
X67945000Y-100330000D03*
X70485000Y-100330000D03*
X67945000Y-102870000D03*
X70485000Y-102870000D03*
X67945000Y-105410000D03*
X70485000Y-105410000D03*
X67945000Y-107950000D03*
X70485000Y-107950000D03*
X67945000Y-110490000D03*
X70485000Y-110490000D03*
X67945000Y-113030000D03*
X70485000Y-113030000D03*
X67945000Y-115570000D03*
X70485000Y-115570000D03*
X67945000Y-118110000D03*
X70485000Y-118110000D03*
X67945000Y-120650000D03*
X70485000Y-120650000D03*
%TD*%
D22*
%TO.C,J5*%
X156045000Y-53960000D03*
X156045000Y-59740000D03*
D23*
X155545000Y-52530000D03*
D24*
X159725000Y-61170000D03*
X159725000Y-52530000D03*
D23*
X155545000Y-61170000D03*
%TD*%
D26*
X156425000Y-57125000D03*
X156425000Y-56000000D03*
X156035000Y-57775000D03*
X155895500Y-56579500D03*
X143650000Y-54850000D03*
X141550000Y-61940000D03*
D27*
X155000000Y-97250000D03*
D26*
X142630000Y-91570000D03*
X138430000Y-88610000D03*
D28*
X133030000Y-47130000D03*
X135720000Y-47070000D03*
D26*
X141754384Y-83960199D03*
X137350000Y-93040000D03*
D12*
X150450000Y-73100000D03*
D26*
X143650000Y-55850000D03*
X149850000Y-50340000D03*
X142750000Y-85950000D03*
D28*
X148500000Y-74250000D03*
D26*
X143310000Y-60280000D03*
X137420000Y-86410000D03*
D29*
X144850000Y-63275000D03*
D26*
X133460000Y-66360000D03*
X142650000Y-56850000D03*
D28*
X132940000Y-54600000D03*
X153560000Y-82570000D03*
D26*
X132600000Y-59100000D03*
X133010000Y-82430000D03*
D27*
X155000000Y-99300000D03*
D30*
X153550000Y-89200000D03*
D26*
X139990000Y-89530000D03*
D29*
X159600000Y-119900000D03*
D26*
X140480000Y-94090000D03*
X135600000Y-77900000D03*
X133020000Y-69860000D03*
D28*
X144800000Y-48750000D03*
D26*
X138300000Y-84650000D03*
X138540000Y-64980000D03*
X139180000Y-95670000D03*
X143130000Y-89860000D03*
X135060000Y-66330000D03*
X141650000Y-54850000D03*
X141750000Y-84850000D03*
D28*
X135710000Y-53680000D03*
D26*
X132490000Y-63710000D03*
X141650000Y-55850000D03*
D30*
X153825000Y-53325000D03*
D26*
X142750000Y-83800000D03*
X143650000Y-84850000D03*
X141750000Y-85950000D03*
D28*
X137980000Y-80730000D03*
D26*
X136890000Y-64530000D03*
D28*
X137400000Y-51740000D03*
D26*
X133370000Y-90340000D03*
X132600000Y-95790000D03*
X143650000Y-85950000D03*
X132860000Y-79660000D03*
X147820000Y-87080000D03*
D27*
X154700000Y-102000000D03*
D26*
X147080000Y-60210000D03*
X142750000Y-84850000D03*
D29*
X149420000Y-53910000D03*
D28*
X149412500Y-87200000D03*
D26*
X141200000Y-49890000D03*
X133330000Y-77890000D03*
X143650000Y-56850000D03*
X135870000Y-91820000D03*
D28*
X136150000Y-82330000D03*
D26*
X138190000Y-92130000D03*
X139940000Y-61480000D03*
D28*
X146825000Y-81975000D03*
X149425000Y-90525000D03*
X135950000Y-55600000D03*
D26*
X137330000Y-49910000D03*
X143650000Y-83800000D03*
X141650000Y-56850000D03*
X140400000Y-91300000D03*
D12*
X155650000Y-63850000D03*
D26*
X132910000Y-75370000D03*
X137520000Y-75810000D03*
X135480000Y-80250000D03*
X141400000Y-89670000D03*
D28*
X147520000Y-52640000D03*
D26*
X142650000Y-55850000D03*
X135050000Y-93210000D03*
X142650000Y-54850000D03*
D12*
X155400000Y-79250000D03*
D29*
X152400000Y-62550000D03*
D26*
X137420000Y-84850000D03*
D12*
X157750000Y-73800000D03*
D29*
X147841950Y-58391950D03*
D30*
X153775000Y-60500000D03*
D26*
X141290000Y-92730000D03*
X135530000Y-67940000D03*
X133790000Y-49070000D03*
X141870000Y-76460000D03*
D12*
X58550000Y-106150000D03*
X57650000Y-71850000D03*
D26*
X143529500Y-88095000D03*
D28*
X139667911Y-58032917D03*
X143630000Y-59230000D03*
X139240000Y-53920500D03*
D26*
X142029500Y-88114428D03*
D12*
X58650000Y-50343750D03*
X58450000Y-78112500D03*
D28*
X142074144Y-59210155D03*
D12*
X153100000Y-68900000D03*
X57900000Y-127100000D03*
X153050000Y-73900000D03*
D28*
X140000000Y-82500000D03*
D12*
X58450000Y-99450000D03*
D28*
X139270000Y-87810000D03*
D12*
X58400000Y-134100000D03*
X57150000Y-43850000D03*
D28*
X146350000Y-55850000D03*
X145975000Y-84900000D03*
D27*
X159775000Y-68050000D03*
D12*
X145737840Y-67109048D03*
D26*
X142954263Y-80810000D03*
D28*
X141705105Y-52364145D03*
D26*
X141795263Y-81290000D03*
D28*
X142760000Y-51420000D03*
D30*
X133000000Y-127500000D03*
D28*
X133500000Y-121000000D03*
X142460000Y-61320000D03*
X137490000Y-47380000D03*
D26*
X143479500Y-52170000D03*
X153070000Y-55710000D03*
D28*
X148912500Y-52427598D03*
X146600000Y-54800000D03*
D26*
X148350000Y-83875000D03*
D28*
X149425000Y-88900000D03*
X138950098Y-72390000D03*
X149490000Y-59810000D03*
X151730000Y-79770000D03*
X153470000Y-83480000D03*
D26*
X142890000Y-77280000D03*
X142970000Y-78004500D03*
X145910000Y-83530000D03*
X145900000Y-79490000D03*
X143491719Y-81519809D03*
X132150000Y-91450000D03*
X139129124Y-86811999D03*
X150450000Y-84625000D03*
X153400000Y-87375000D03*
X156425000Y-85000000D03*
X156425000Y-86125000D03*
X155895500Y-85579500D03*
X156035000Y-86775000D03*
M02*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
M48
; DRILL file {KiCad (6.0.7)} date Mon Aug 8 23:44:24 2022
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2022-08-08T23:44:24-07:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.7)
; #@! TF.FileFunction,NonPlated,1,4,NPTH
FMAT,2
INCH
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
T1C0.0256
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
T2C0.0669
%
G90
G05
T1
X6.1435Y-2.1244
X6.1435Y-2.352
X6.1435Y-3.2661
X6.1435Y-3.4937
T2
X1.7995Y-3.7812
X1.7995Y-4.0017
X1.8026Y-2.6898
X1.8026Y-2.9103
X1.8028Y-3.1909
X1.8028Y-3.4114
X1.803Y-4.8721
X1.803Y-5.0926
X1.8036Y-1.5968
X1.8036Y-1.8172
X1.8038Y-4.2909
X1.8038Y-4.5114
X1.8038Y-5.3933
X1.8038Y-5.6137
X1.8043Y-2.0992
X1.8043Y-2.3197
T0
M30

View File

@@ -0,0 +1,495 @@
M48
; DRILL file {KiCad (6.0.7)} date Mon Aug 8 23:44:24 2022
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2022-08-08T23:44:24-07:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,(6.0.7)
; #@! TF.FileFunction,Plated,1,4,PTH
FMAT,2
INCH
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T1C0.0079
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T2C0.0157
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T3C0.0197
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T4C0.0236
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T5C0.0236
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T6C0.0315
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T7C0.0315
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T8C0.0335
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T9C0.0394
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T10C0.0394
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T11C0.0433
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T12C0.0453
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T13C0.0472
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T14C0.1260
%
G90
G05
T1
X5.2028Y-3.6004
X5.2161Y-2.5083
X5.2205Y-2.3268
X5.2205Y-3.7713
X5.2307Y-3.1362
X5.2327Y-2.9673
X5.2366Y-3.2453
X5.237Y-2.7504
X5.2492Y-3.0665
X5.2508Y-3.5567
X5.2543Y-2.6126
X5.2673Y-1.9319
X5.3169Y-3.6697
X5.3173Y-2.6114
X5.3339Y-3.1594
X5.3358Y-2.6748
X5.3386Y-3.0669
X5.3492Y-3.615
X5.3894Y-2.5406
X5.4067Y-1.965
X5.4075Y-3.663
X5.4102Y-3.3406
X5.4102Y-3.402
X5.4142Y-2.9846
X5.4406Y-3.6272
X5.4449Y-3.3327
X5.45Y-3.4886
X5.4543Y-2.5583
X5.4775Y-3.4178
X5.4795Y-3.7665
X5.5094Y-2.4205
X5.5114Y-3.5248
X5.5276Y-3.5945
X5.5307Y-3.7043
X5.5591Y-1.9642
X5.5626Y-3.6508
X5.5669Y-3.5303
X5.5728Y-2.4386
X5.5768Y-2.1594
X5.5768Y-2.1988
X5.5768Y-2.2382
X5.5807Y-3.3406
X5.5807Y-3.3839
X5.5809Y-3.3055
X5.5825Y-3.2004
X5.5854Y-3.0102
X5.5917Y-3.4691
X5.6154Y-3.6051
X5.6161Y-2.1594
X5.6161Y-2.1988
X5.6161Y-2.2382
X5.6201Y-3.2992
X5.6201Y-3.3406
X5.6201Y-3.3839
X5.6256Y-3.0425
X5.6281Y-3.1815
X5.6287Y-3.071
X5.635Y-3.5378
X5.6421Y-2.3732
X5.6488Y-2.0539
X5.6493Y-3.2094
X5.6508Y-3.4683
X5.6555Y-2.1594
X5.6555Y-2.1988
X5.6555Y-2.2382
X5.6555Y-3.2992
X5.6555Y-3.3406
X5.6555Y-3.3839
X5.7441Y-3.1295
X5.7445Y-3.2886
X5.7906Y-2.3705
X5.8197Y-3.4283
X5.8406Y-3.3022
X5.8996Y-1.9819
X5.9232Y-3.3317
X6.0264Y-2.1933
X6.0394Y-3.44
X6.1376Y-2.2275
X6.1376Y-3.3693
X6.1431Y-2.2746
X6.1431Y-3.4163
X6.1585Y-2.2047
X6.1585Y-2.249
X6.1585Y-3.3465
X6.1585Y-3.3907
T2
X5.2339Y-2.1496
X5.2374Y-1.8555
X5.2559Y-4.7638
X5.3429Y-2.1134
X5.3433Y-1.8531
X5.3524Y-2.189
X5.3602Y-3.2413
X5.4094Y-2.037
X5.413Y-1.8654
X5.4323Y-3.1783
X5.4705Y-2.85
X5.4819Y-2.1229
X5.4831Y-3.4571
X5.4987Y-2.2848
X5.5118Y-3.248
X5.5789Y-2.0616
X5.5935Y-2.3311
X5.6087Y-2.4142
X5.6205Y-2.0244
X5.6547Y-2.3319
X5.7008Y-1.9193
X5.747Y-3.3425
X5.7618Y-2.1988
X5.7717Y-2.1575
X5.7805Y-3.2274
X5.8079Y-2.0724
X5.8465Y-2.9232
X5.8627Y-2.0641
X5.8824Y-3.4331
X5.8829Y-3.5
X5.8829Y-3.564
X5.8854Y-2.3547
X5.9736Y-3.1406
X6.0421Y-3.2866
X6.0457Y-3.2508
T3
X2.3642Y-2.5079
X2.3918Y-2.4411
X2.3918Y-2.5747
X2.4429Y-5.6535
X2.4587Y-2.4134
X2.4587Y-2.6024
X2.4706Y-5.5867
X2.4706Y-5.7204
X2.5255Y-2.4411
X2.5255Y-2.5747
X2.5374Y-5.5591
X2.5374Y-5.748
X2.5531Y-2.5079
X2.6042Y-5.5867
X2.6042Y-5.7204
X2.6319Y-5.6535
X4.7005Y-4.435
X4.7282Y-4.3682
X4.7282Y-4.5018
X4.795Y-4.3405
X4.795Y-4.5295
X4.8618Y-4.3682
X4.8618Y-4.5018
X4.8895Y-4.435
X5.3356Y-1.6575
X5.3633Y-1.5907
X5.3633Y-1.7243
X5.4301Y-1.563
X5.4301Y-1.752
X5.4969Y-1.5907
X5.4969Y-1.7243
X5.5246Y-1.6575
T4
X5.2362Y-5.0197
X6.0453Y-3.5118
X6.0541Y-2.3819
X6.0561Y-2.0994
T6
X5.7028Y-2.4911
X5.8205Y-2.2989
X5.8827Y-2.1224
X6.0Y-2.4626
X6.2835Y-4.7205
T7
X2.0091Y-3.2012
X2.0091Y-3.3012
X2.0091Y-3.4012
X2.0101Y-4.3011
X2.0101Y-4.4011
X2.0101Y-4.5011
X2.0101Y-5.4035
X2.0101Y-5.5035
X2.0101Y-5.6035
X2.0106Y-2.1095
X2.0106Y-2.2095
X2.0106Y-2.3095
T8
X2.0058Y-3.7915
X2.0058Y-3.8915
X2.0058Y-3.9915
X2.0089Y-2.7001
X2.0089Y-2.8001
X2.0089Y-2.9001
X2.0093Y-4.8823
X2.0093Y-4.9823
X2.0093Y-5.0823
X2.0099Y-1.607
X2.0099Y-1.707
X2.0099Y-1.807
T9
X2.25Y-1.7264
X2.2697Y-2.8287
X2.2795Y-5.0039
X2.2992Y-5.2795
X2.3012Y-3.0753
X2.3012Y-3.9154
X2.3051Y-4.1791
X2.3091Y-1.982
X5.7377Y-2.6421
X5.9232Y-2.878
X6.0256Y-2.9094
X6.0276Y-2.7126
X6.1181Y-3.1201
X6.128Y-2.5138
X6.2106Y-2.9055
T10
X2.675Y-1.65
X2.675Y-1.75
X2.675Y-1.85
X2.675Y-1.95
X2.675Y-2.05
X2.675Y-2.15
X2.675Y-2.25
X2.675Y-2.35
X2.675Y-2.45
X2.675Y-2.55
X2.675Y-2.65
X2.675Y-2.75
X2.675Y-2.85
X2.675Y-2.95
X2.675Y-3.05
X2.675Y-3.15
X2.675Y-3.25
X2.675Y-3.35
X2.675Y-3.45
X2.675Y-3.55
X2.675Y-3.65
X2.675Y-3.75
X2.675Y-3.85
X2.675Y-3.95
X2.675Y-4.05
X2.675Y-4.15
X2.675Y-4.25
X2.675Y-4.35
X2.675Y-4.45
X2.675Y-4.55
X2.675Y-4.65
X2.675Y-4.75
X2.775Y-1.65
X2.775Y-1.75
X2.775Y-1.85
X2.775Y-1.95
X2.775Y-2.05
X2.775Y-2.15
X2.775Y-2.25
X2.775Y-2.35
X2.775Y-2.45
X2.775Y-2.55
X2.775Y-2.65
X2.775Y-2.75
X2.775Y-2.85
X2.775Y-2.95
X2.775Y-3.05
X2.775Y-3.15
X2.775Y-3.25
X2.775Y-3.35
X2.775Y-3.45
X2.775Y-3.55
X2.775Y-3.65
X2.775Y-3.75
X2.775Y-3.85
X2.775Y-3.95
X2.775Y-4.05
X2.775Y-4.15
X2.775Y-4.25
X2.775Y-4.35
X2.775Y-4.45
X2.775Y-4.55
X2.775Y-4.65
X2.775Y-4.75
X3.15Y-1.645
X3.15Y-1.745
X3.15Y-1.845
X3.15Y-1.945
X3.15Y-2.045
X3.15Y-2.145
X3.15Y-2.245
X3.15Y-2.345
X3.15Y-2.445
X3.15Y-2.545
X3.15Y-2.645
X3.15Y-2.745
X3.15Y-2.845
X3.15Y-2.945
X3.15Y-3.045
X3.15Y-3.145
X3.15Y-3.245
X3.15Y-3.345
X3.15Y-3.445
X3.15Y-3.545
X3.15Y-3.645
X3.15Y-3.745
X3.15Y-3.845
X3.15Y-3.945
X3.15Y-4.045
X3.15Y-4.145
X3.6866Y-1.5498
X3.7866Y-1.5498
X3.8866Y-1.5498
X3.8976Y-5.2323
X3.8976Y-5.3323
X3.8976Y-5.4323
X3.8976Y-5.5323
X3.8976Y-5.6323
X3.8976Y-5.7323
X3.9866Y-1.5498
X4.2319Y-1.5476
X4.3319Y-1.5476
X4.4319Y-1.5476
X4.5319Y-1.5476
X4.8917Y-1.7028
X4.8917Y-1.8504
X5.065Y-1.65
X5.065Y-1.75
X5.065Y-1.85
X5.065Y-1.95
X5.065Y-2.05
X5.065Y-2.15
X5.065Y-2.25
X5.065Y-2.35
X5.065Y-2.45
X5.065Y-2.55
X5.065Y-2.65
X5.065Y-2.75
X5.065Y-2.85
X5.065Y-2.95
X5.065Y-3.05
X5.065Y-3.15
X5.065Y-3.25
X5.065Y-3.35
X5.065Y-3.45
X5.065Y-3.55
X5.065Y-3.65
X5.065Y-3.75
X5.065Y-3.85
X5.065Y-3.95
X5.065Y-4.05
X5.065Y-4.15
X5.065Y-4.25
X5.065Y-4.35
X5.065Y-4.45
X5.065Y-4.55
X5.065Y-4.65
X5.065Y-4.75
X5.165Y-1.65
X5.165Y-1.75
X5.165Y-1.85
X5.165Y-1.95
X5.165Y-2.05
X5.165Y-2.15
X5.165Y-2.25
X5.165Y-2.35
X5.165Y-2.45
X5.165Y-2.55
X5.165Y-2.65
X5.165Y-2.75
X5.165Y-2.85
X5.165Y-2.95
X5.165Y-3.05
X5.165Y-3.15
X5.165Y-3.25
X5.165Y-3.35
X5.165Y-3.45
X5.165Y-3.55
X5.165Y-3.65
X5.165Y-3.75
X5.165Y-3.85
X5.165Y-3.95
X5.165Y-4.05
X5.165Y-4.15
X5.165Y-4.25
X5.165Y-4.35
X5.165Y-4.45
X5.165Y-4.55
X5.165Y-4.65
X5.165Y-4.75
X5.2067Y-5.2323
X5.2067Y-5.3323
X5.2067Y-5.4323
X5.2067Y-5.5323
X5.2067Y-5.6323
X5.2067Y-5.7323
T11
X1.9055Y-3.2012
X1.9055Y-3.4012
X1.9065Y-4.3011
X1.9065Y-4.5011
X1.9065Y-5.4035
X1.9065Y-5.6035
X1.9071Y-2.1095
X1.9071Y-2.3095
T12
X1.9026Y-3.7915
X1.9026Y-3.9915
X1.9058Y-2.7001
X1.9058Y-2.9001
X1.9061Y-4.8823
X1.9061Y-5.0823
X1.9067Y-1.607
X1.9067Y-1.807
T13
X6.0906Y-4.0157
X6.1024Y-3.8287
X6.1024Y-3.9094
X6.2904Y-2.6791
T14
X2.4587Y-2.5079
X2.5374Y-5.6535
X4.795Y-4.435
X5.4301Y-1.6575
T5
G00X6.1022Y-2.0681
M15
G01X6.1455Y-2.0681
M16
G05
G00X6.1022Y-2.4083
M15
G01X6.1455Y-2.4083
M16
G05
G00X6.1022Y-3.2098
M15
G01X6.1455Y-3.2098
M16
G05
G00X6.1022Y-3.55
M15
G01X6.1455Y-3.55
M16
G05
G00X6.2766Y-2.0681
M15
G01X6.3002Y-2.0681
M16
G05
G00X6.2766Y-2.4083
M15
G01X6.3002Y-2.4083
M16
G05
G00X6.2766Y-3.2098
M15
G01X6.3002Y-3.2098
M16
G05
G00X6.2766Y-3.55
M15
G01X6.3002Y-3.55
M16
G05
T0
M30

View File

@@ -0,0 +1,15 @@
%TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7)*%
%TF.CreationDate,2022-08-08T23:44:24-07:00*%
%TF.ProjectId,adatface_baseboard,61646174-6661-4636-955f-62617365626f,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.7)) date 2022-08-08 23:44:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@@ -0,0 +1,492 @@
%TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7)*%
%TF.CreationDate,2022-08-08T23:44:24-07:00*%
%TF.ProjectId,adatface_baseboard,61646174-6661-4636-955f-62617365626f,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.7)) date 2022-08-08 23:44:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.218750X0.218750X0.256250X-0.218750X0.256250X-0.218750X-0.256250X0.218750X-0.256250X0*%
%ADD11RoundRect,0.243750X-0.456250X0.243750X-0.456250X-0.243750X0.456250X-0.243750X0.456250X0.243750X0*%
%ADD12RoundRect,0.218750X-0.256250X0.218750X-0.256250X-0.218750X0.256250X-0.218750X0.256250X0.218750X0*%
%ADD13RoundRect,0.250000X0.625000X-0.375000X0.625000X0.375000X-0.625000X0.375000X-0.625000X-0.375000X0*%
%ADD14R,1.060000X0.650000*%
%ADD15RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
%ADD16RoundRect,0.218750X-0.218750X-0.256250X0.218750X-0.256250X0.218750X0.256250X-0.218750X0.256250X0*%
%ADD17RoundRect,0.243750X-0.243750X-0.456250X0.243750X-0.456250X0.243750X0.456250X-0.243750X0.456250X0*%
%ADD18R,1.150000X0.300000*%
%ADD19R,2.500000X1.800000*%
%ADD20RoundRect,0.222500X-0.222500X-0.222500X0.222500X-0.222500X0.222500X0.222500X-0.222500X0.222500X0*%
%ADD21RoundRect,0.062500X-0.375000X-0.062500X0.375000X-0.062500X0.375000X0.062500X-0.375000X0.062500X0*%
%ADD22RoundRect,0.062500X-0.062500X-0.375000X0.062500X-0.375000X0.062500X0.375000X-0.062500X0.375000X0*%
G04 APERTURE END LIST*
D10*
%TO.C,C10*%
X152087500Y-90500000D03*
X150512500Y-90500000D03*
%TD*%
%TO.C,R4*%
X136587500Y-114181666D03*
X135012500Y-114181666D03*
%TD*%
D11*
%TO.C,L3*%
X58450000Y-79912500D03*
X58450000Y-81787500D03*
%TD*%
D12*
%TO.C,C9*%
X152400000Y-59562500D03*
X152400000Y-61137500D03*
%TD*%
D13*
%TO.C,FB1*%
X160500000Y-102150000D03*
X160500000Y-99350000D03*
%TD*%
D10*
%TO.C,R8*%
X136587500Y-101027811D03*
X135012500Y-101027811D03*
%TD*%
D12*
%TO.C,C5*%
X55650000Y-127062500D03*
X55650000Y-128637500D03*
%TD*%
D14*
%TO.C,U7*%
X153050000Y-70437500D03*
X153050000Y-71387500D03*
X153050000Y-72337500D03*
X155250000Y-72337500D03*
X155250000Y-70437500D03*
%TD*%
D10*
%TO.C,D4*%
X157787500Y-114141666D03*
X156212500Y-114141666D03*
%TD*%
%TO.C,R13*%
X152075000Y-87200000D03*
X150500000Y-87200000D03*
%TD*%
%TO.C,D5*%
X157787500Y-117033332D03*
X156212500Y-117033332D03*
%TD*%
D12*
%TO.C,C7*%
X55450000Y-71862500D03*
X55450000Y-73437500D03*
%TD*%
D10*
%TO.C,R14*%
X152512500Y-82675000D03*
X150937500Y-82675000D03*
%TD*%
%TO.C,C12*%
X138757500Y-82500000D03*
X137182500Y-82500000D03*
%TD*%
D15*
%TO.C,R17*%
X144800000Y-51187500D03*
X144800000Y-49612500D03*
%TD*%
D12*
%TO.C,C11*%
X150450000Y-70162500D03*
X150450000Y-71737500D03*
%TD*%
D11*
%TO.C,L4*%
X58550000Y-107875000D03*
X58550000Y-109750000D03*
%TD*%
D16*
%TO.C,R18*%
X145262500Y-80850000D03*
X146837500Y-80850000D03*
%TD*%
D10*
%TO.C,D1*%
X157787500Y-128600000D03*
X156212500Y-128600000D03*
%TD*%
D15*
%TO.C,C3*%
X55650000Y-83425000D03*
X55650000Y-81850000D03*
%TD*%
D17*
%TO.C,C21*%
X156562500Y-97250000D03*
X158437500Y-97250000D03*
%TD*%
D11*
%TO.C,L1*%
X58400000Y-135912500D03*
X58400000Y-137787500D03*
%TD*%
D10*
%TO.C,C14*%
X138507500Y-53690000D03*
X136932500Y-53690000D03*
%TD*%
D15*
%TO.C,C2*%
X55650000Y-55637500D03*
X55650000Y-54062500D03*
%TD*%
D10*
%TO.C,R3*%
X136587500Y-111290000D03*
X135012500Y-111290000D03*
%TD*%
D16*
%TO.C,R12*%
X156862500Y-63850000D03*
X158437500Y-63850000D03*
%TD*%
D18*
%TO.C,J4*%
X154980000Y-89200000D03*
X154980000Y-88400000D03*
X154980000Y-87100000D03*
X154980000Y-86100000D03*
X154980000Y-85600000D03*
X154980000Y-84600000D03*
X154980000Y-83300000D03*
X154980000Y-82500000D03*
X154980000Y-82800000D03*
X154980000Y-83600000D03*
X154980000Y-84100000D03*
X154980000Y-85100000D03*
X154980000Y-86600000D03*
X154980000Y-87600000D03*
X154980000Y-88100000D03*
X154980000Y-88900000D03*
%TD*%
D15*
%TO.C,C1*%
X55650000Y-139387500D03*
X55650000Y-137812500D03*
%TD*%
D10*
%TO.C,D2*%
X157787500Y-122816664D03*
X156212500Y-122816664D03*
%TD*%
D19*
%TO.C,D12*%
X158900000Y-48900000D03*
X154900000Y-48900000D03*
%TD*%
D12*
%TO.C,R24*%
X146300000Y-61637500D03*
X146300000Y-63212500D03*
%TD*%
D10*
%TO.C,R15*%
X150637500Y-58300000D03*
X149062500Y-58300000D03*
%TD*%
%TO.C,D9*%
X146812500Y-108751964D03*
X145237500Y-108751964D03*
%TD*%
%TO.C,R9*%
X136587500Y-103593358D03*
X135012500Y-103593358D03*
%TD*%
%TO.C,R1*%
X136587500Y-128640000D03*
X135012500Y-128640000D03*
%TD*%
D12*
%TO.C,C8*%
X56136737Y-99533043D03*
X56136737Y-101108043D03*
%TD*%
D15*
%TO.C,R26*%
X148510000Y-77425000D03*
X148510000Y-75850000D03*
%TD*%
D10*
%TO.C,D6*%
X157787500Y-119924998D03*
X156212500Y-119924998D03*
%TD*%
%TO.C,R5*%
X136587500Y-117073332D03*
X135012500Y-117073332D03*
%TD*%
%TO.C,R23*%
X150687500Y-61100000D03*
X149112500Y-61100000D03*
%TD*%
D15*
%TO.C,C18*%
X147550000Y-55457500D03*
X147550000Y-53882500D03*
%TD*%
D10*
%TO.C,R11*%
X136587500Y-106158905D03*
X135012500Y-106158905D03*
%TD*%
D16*
%TO.C,R16*%
X149432500Y-55070000D03*
X151007500Y-55070000D03*
%TD*%
D10*
%TO.C,R19*%
X150487500Y-49100000D03*
X148912500Y-49100000D03*
%TD*%
%TO.C,D10*%
X146812500Y-106174642D03*
X145237500Y-106174642D03*
%TD*%
%TO.C,R10*%
X136587500Y-108724452D03*
X135012500Y-108724452D03*
%TD*%
%TO.C,D7*%
X146812500Y-101020000D03*
X145237500Y-101020000D03*
%TD*%
D15*
%TO.C,C4*%
X55525979Y-111307392D03*
X55525979Y-109732392D03*
%TD*%
D10*
%TO.C,D11*%
X157787500Y-125708330D03*
X156212500Y-125708330D03*
%TD*%
D15*
%TO.C,C16*%
X146825000Y-84687500D03*
X146825000Y-83112500D03*
%TD*%
D10*
%TO.C,C17*%
X140237500Y-51740000D03*
X138662500Y-51740000D03*
%TD*%
%TO.C,D3*%
X157787500Y-111250000D03*
X156212500Y-111250000D03*
%TD*%
D12*
%TO.C,C6*%
X55500000Y-43887500D03*
X55500000Y-45462500D03*
%TD*%
D10*
%TO.C,R6*%
X136587500Y-119964998D03*
X135012500Y-119964998D03*
%TD*%
%TO.C,R25*%
X151712500Y-77362500D03*
X150137500Y-77362500D03*
%TD*%
%TO.C,C15*%
X140997500Y-80730000D03*
X139422500Y-80730000D03*
%TD*%
D16*
%TO.C,R7*%
X156975000Y-79250000D03*
X158550000Y-79250000D03*
%TD*%
%TO.C,C20*%
X156712500Y-99250000D03*
X158287500Y-99250000D03*
%TD*%
D10*
%TO.C,R21*%
X136587500Y-125748330D03*
X135012500Y-125748330D03*
%TD*%
D12*
%TO.C,C13*%
X157750000Y-70462500D03*
X157750000Y-72037500D03*
%TD*%
D10*
%TO.C,D8*%
X146812500Y-103597321D03*
X145237500Y-103597321D03*
%TD*%
D20*
%TO.C,U5*%
X143750000Y-55850000D03*
X142650000Y-55850000D03*
X142650000Y-54750000D03*
X143750000Y-54750000D03*
X141550000Y-56950000D03*
X141550000Y-55850000D03*
X141550000Y-54750000D03*
X142650000Y-56950000D03*
X143750000Y-56950000D03*
D21*
X140212500Y-54100000D03*
X140212500Y-54600000D03*
X140212500Y-55100000D03*
X140212500Y-55600000D03*
X140212500Y-56100000D03*
X140212500Y-56600000D03*
X140212500Y-57100000D03*
X140212500Y-57600000D03*
D22*
X140900000Y-58287500D03*
X141400000Y-58287500D03*
X141900000Y-58287500D03*
X142400000Y-58287500D03*
X142900000Y-58287500D03*
X143400000Y-58287500D03*
X143900000Y-58287500D03*
X144400000Y-58287500D03*
D21*
X145087500Y-57600000D03*
X145087500Y-57100000D03*
X145087500Y-56600000D03*
X145087500Y-56100000D03*
X145087500Y-55600000D03*
X145087500Y-55100000D03*
X145087500Y-54600000D03*
X145087500Y-54100000D03*
D22*
X144400000Y-53412500D03*
X143900000Y-53412500D03*
X143400000Y-53412500D03*
X142900000Y-53412500D03*
X142400000Y-53412500D03*
X141900000Y-53412500D03*
X141400000Y-53412500D03*
X140900000Y-53412500D03*
%TD*%
D17*
%TO.C,C19*%
X156312500Y-102000000D03*
X158187500Y-102000000D03*
%TD*%
D10*
%TO.C,R2*%
X136587500Y-122856664D03*
X135012500Y-122856664D03*
%TD*%
D18*
%TO.C,J5*%
X154980000Y-60200000D03*
X154980000Y-59400000D03*
X154980000Y-58100000D03*
X154980000Y-57100000D03*
X154980000Y-56600000D03*
X154980000Y-55600000D03*
X154980000Y-54300000D03*
X154980000Y-53500000D03*
X154980000Y-53800000D03*
X154980000Y-54600000D03*
X154980000Y-55100000D03*
X154980000Y-56100000D03*
X154980000Y-57600000D03*
X154980000Y-58600000D03*
X154980000Y-59100000D03*
X154980000Y-59900000D03*
%TD*%
D20*
%TO.C,U6*%
X141600000Y-85975000D03*
X143800000Y-84875000D03*
X141600000Y-84875000D03*
X141600000Y-83775000D03*
X142700000Y-83775000D03*
X143800000Y-85975000D03*
X143800000Y-83775000D03*
X142700000Y-84875000D03*
X142700000Y-85975000D03*
D21*
X140262500Y-83125000D03*
X140262500Y-83625000D03*
X140262500Y-84125000D03*
X140262500Y-84625000D03*
X140262500Y-85125000D03*
X140262500Y-85625000D03*
X140262500Y-86125000D03*
X140262500Y-86625000D03*
D22*
X140950000Y-87312500D03*
X141450000Y-87312500D03*
X141950000Y-87312500D03*
X142450000Y-87312500D03*
X142950000Y-87312500D03*
X143450000Y-87312500D03*
X143950000Y-87312500D03*
X144450000Y-87312500D03*
D21*
X145137500Y-86625000D03*
X145137500Y-86125000D03*
X145137500Y-85625000D03*
X145137500Y-85125000D03*
X145137500Y-84625000D03*
X145137500Y-84125000D03*
X145137500Y-83625000D03*
X145137500Y-83125000D03*
D22*
X144450000Y-82437500D03*
X143950000Y-82437500D03*
X143450000Y-82437500D03*
X142950000Y-82437500D03*
X142450000Y-82437500D03*
X141950000Y-82437500D03*
X141450000Y-82437500D03*
X140950000Y-82437500D03*
%TD*%
D19*
%TO.C,D13*%
X159000000Y-94000000D03*
X155000000Y-94000000D03*
%TD*%
D10*
%TO.C,R20*%
X152050000Y-88900000D03*
X150475000Y-88900000D03*
%TD*%
D11*
%TO.C,L2*%
X58650000Y-52156250D03*
X58650000Y-54031250D03*
%TD*%
M02*

View File

@@ -0,0 +1,671 @@
%TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7)*%
%TF.CreationDate,2022-08-08T23:44:24-07:00*%
%TF.ProjectId,adatface_baseboard,61646174-6661-4636-955f-62617365626f,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.7)) date 2022-08-08 23:44:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10C,2.100000*%
%ADD11C,1.708000*%
%ADD12C,1.700000*%
%ADD13C,2.050000*%
%ADD14RoundRect,0.200000X-0.679000X0.679000X-0.679000X-0.679000X0.679000X-0.679000X0.679000X0.679000X0*%
%ADD15C,1.758000*%
%ADD16C,2.125000*%
%ADD17RoundRect,0.200000X0.850000X-0.850000X0.850000X0.850000X-0.850000X0.850000X-0.850000X-0.850000X0*%
%ADD18O,2.100000X2.100000*%
%ADD19C,1.200000*%
%ADD20C,6.800000*%
%ADD21RoundRect,0.200000X-0.850000X-0.850000X0.850000X-0.850000X0.850000X0.850000X-0.850000X0.850000X0*%
%ADD22C,1.050000*%
%ADD23O,2.500000X1.400000*%
%ADD24O,2.000000X1.400000*%
%ADD25RoundRect,0.200000X0.850000X0.850000X-0.850000X0.850000X-0.850000X-0.850000X0.850000X-0.850000X0*%
%ADD26C,0.860000*%
%ADD27C,1.900000*%
%ADD28C,1.060000*%
%ADD29C,1.480000*%
%ADD30C,1.260000*%
G04 APERTURE END LIST*
%LPC*%
D10*
%TO.C,U1*%
X45816023Y-142589033D03*
X45816023Y-136989033D03*
D11*
X51056023Y-137249033D03*
D12*
X51056023Y-139789033D03*
D11*
X51056023Y-142329033D03*
D13*
X48426023Y-137249033D03*
X48426023Y-142329033D03*
%TD*%
D10*
%TO.C,TR2*%
X45810408Y-40557745D03*
X45810408Y-46157745D03*
D14*
X51050408Y-40817745D03*
D15*
X51050408Y-43357745D03*
X51050408Y-45897745D03*
D16*
X48430408Y-40817745D03*
X48430408Y-45897745D03*
%TD*%
D10*
%TO.C,TR3*%
X45786111Y-68321385D03*
X45786111Y-73921385D03*
D14*
X51026111Y-68581385D03*
D15*
X51026111Y-71121385D03*
X51026111Y-73661385D03*
D16*
X48406111Y-68581385D03*
X48406111Y-73661385D03*
%TD*%
D17*
%TO.C,J11*%
X93640000Y-39365000D03*
D18*
X96180000Y-39365000D03*
X98720000Y-39365000D03*
X101260000Y-39365000D03*
%TD*%
D19*
%TO.C,H3*%
X60050000Y-63700000D03*
X64147056Y-62002944D03*
X64850000Y-63700000D03*
X60752944Y-62002944D03*
X64147056Y-65397056D03*
D20*
X62450000Y-63700000D03*
D19*
X62450000Y-66100000D03*
X60752944Y-65397056D03*
X62450000Y-61300000D03*
%TD*%
%TO.C,H4*%
X121793000Y-115049000D03*
X123490056Y-110951944D03*
X124193000Y-112649000D03*
X123490056Y-114346056D03*
X120095944Y-110951944D03*
D20*
X121793000Y-112649000D03*
D19*
X121793000Y-110249000D03*
X119393000Y-112649000D03*
X120095944Y-114346056D03*
%TD*%
D17*
%TO.C,J10*%
X107490000Y-39310000D03*
D18*
X110030000Y-39310000D03*
X112570000Y-39310000D03*
X115110000Y-39310000D03*
%TD*%
D10*
%TO.C,U2*%
X45830408Y-58920245D03*
X45830408Y-53320245D03*
D11*
X51070408Y-53580245D03*
D12*
X51070408Y-56120245D03*
D11*
X51070408Y-58660245D03*
D13*
X48440408Y-53580245D03*
X48440408Y-58660245D03*
%TD*%
D21*
%TO.C,J3*%
X128650000Y-41910000D03*
D18*
X131190000Y-41910000D03*
X128650000Y-44450000D03*
X131190000Y-44450000D03*
X128650000Y-46990000D03*
X131190000Y-46990000D03*
X128650000Y-49530000D03*
X131190000Y-49530000D03*
X128650000Y-52070000D03*
X131190000Y-52070000D03*
X128650000Y-54610000D03*
X131190000Y-54610000D03*
X128650000Y-57150000D03*
X131190000Y-57150000D03*
X128650000Y-59690000D03*
X131190000Y-59690000D03*
X128650000Y-62230000D03*
X131190000Y-62230000D03*
X128650000Y-64770000D03*
X131190000Y-64770000D03*
X128650000Y-67310000D03*
X131190000Y-67310000D03*
X128650000Y-69850000D03*
X131190000Y-69850000D03*
X128650000Y-72390000D03*
X131190000Y-72390000D03*
X128650000Y-74930000D03*
X131190000Y-74930000D03*
X128650000Y-77470000D03*
X131190000Y-77470000D03*
X128650000Y-80010000D03*
X131190000Y-80010000D03*
X128650000Y-82550000D03*
X131190000Y-82550000D03*
X128650000Y-85090000D03*
X131190000Y-85090000D03*
X128650000Y-87630000D03*
X131190000Y-87630000D03*
X128650000Y-90170000D03*
X131190000Y-90170000D03*
X128650000Y-92710000D03*
X131190000Y-92710000D03*
X128650000Y-95250000D03*
X131190000Y-95250000D03*
X128650000Y-97790000D03*
X131190000Y-97790000D03*
X128650000Y-100330000D03*
X131190000Y-100330000D03*
X128650000Y-102870000D03*
X131190000Y-102870000D03*
X128650000Y-105410000D03*
X131190000Y-105410000D03*
X128650000Y-107950000D03*
X131190000Y-107950000D03*
X128650000Y-110490000D03*
X131190000Y-110490000D03*
X128650000Y-113030000D03*
X131190000Y-113030000D03*
X128650000Y-115570000D03*
X131190000Y-115570000D03*
X128650000Y-118110000D03*
X131190000Y-118110000D03*
X128650000Y-120650000D03*
X131190000Y-120650000D03*
%TD*%
D21*
%TO.C,J7*%
X80010000Y-41783000D03*
D18*
X80010000Y-44323000D03*
X80010000Y-46863000D03*
X80010000Y-49403000D03*
X80010000Y-51943000D03*
X80010000Y-54483000D03*
X80010000Y-57023000D03*
X80010000Y-59563000D03*
X80010000Y-62103000D03*
X80010000Y-64643000D03*
X80010000Y-67183000D03*
X80010000Y-69723000D03*
X80010000Y-72263000D03*
X80010000Y-74803000D03*
X80010000Y-77343000D03*
X80010000Y-79883000D03*
X80010000Y-82423000D03*
X80010000Y-84963000D03*
X80010000Y-87503000D03*
X80010000Y-90043000D03*
X80010000Y-92583000D03*
X80010000Y-95123000D03*
X80010000Y-97663000D03*
X80010000Y-100203000D03*
X80010000Y-102743000D03*
X80010000Y-105283000D03*
%TD*%
D21*
%TO.C,J6*%
X99000000Y-132900000D03*
D18*
X99000000Y-135440000D03*
X99000000Y-137980000D03*
X99000000Y-140520000D03*
X99000000Y-143060000D03*
X99000000Y-145600000D03*
%TD*%
D22*
%TO.C,J4*%
X156045000Y-82960000D03*
X156045000Y-88740000D03*
D23*
X155545000Y-90170000D03*
D24*
X159725000Y-90170000D03*
X159725000Y-81530000D03*
D23*
X155545000Y-81530000D03*
%TD*%
D10*
%TO.C,U3*%
X45790000Y-86650000D03*
X45790000Y-81050000D03*
D11*
X51030000Y-81310000D03*
D12*
X51030000Y-83850000D03*
D11*
X51030000Y-86390000D03*
D13*
X48400000Y-81310000D03*
X48400000Y-86390000D03*
%TD*%
D25*
%TO.C,J9*%
X124250000Y-43250000D03*
%TD*%
D19*
%TO.C,H2*%
X62752944Y-141902944D03*
X66850000Y-143600000D03*
X64450000Y-146000000D03*
X66147056Y-145297056D03*
X64450000Y-141200000D03*
X66147056Y-141902944D03*
X62752944Y-145297056D03*
X62050000Y-143600000D03*
D20*
X64450000Y-143600000D03*
%TD*%
D21*
%TO.C,J1*%
X132250000Y-132900000D03*
D18*
X132250000Y-135440000D03*
X132250000Y-137980000D03*
X132250000Y-140520000D03*
X132250000Y-143060000D03*
X132250000Y-145600000D03*
%TD*%
D10*
%TO.C,TR4*%
X45706530Y-96043594D03*
X45706530Y-101643594D03*
D14*
X50946530Y-96303594D03*
D15*
X50946530Y-98843594D03*
X50946530Y-101383594D03*
D16*
X48326530Y-96303594D03*
X48326530Y-101383594D03*
%TD*%
D25*
%TO.C,J8*%
X124250000Y-47000000D03*
%TD*%
D20*
%TO.C,H1*%
X137925000Y-42100000D03*
D19*
X137925000Y-39700000D03*
X137925000Y-44500000D03*
X140325000Y-42100000D03*
X139622056Y-43797056D03*
X136227944Y-40402944D03*
X135525000Y-42100000D03*
X136227944Y-43797056D03*
X139622056Y-40402944D03*
%TD*%
D10*
%TO.C,U4*%
X45816023Y-108989033D03*
X45816023Y-114589033D03*
D11*
X51056023Y-109249033D03*
D12*
X51056023Y-111789033D03*
D11*
X51056023Y-114329033D03*
D13*
X48426023Y-109249033D03*
X48426023Y-114329033D03*
%TD*%
D10*
%TO.C,TR1*%
X45796023Y-123751533D03*
X45796023Y-129351533D03*
D14*
X51036023Y-124011533D03*
D15*
X51036023Y-126551533D03*
X51036023Y-129091533D03*
D16*
X48416023Y-124011533D03*
X48416023Y-129091533D03*
%TD*%
D21*
%TO.C,J2*%
X67945000Y-41910000D03*
D18*
X70485000Y-41910000D03*
X67945000Y-44450000D03*
X70485000Y-44450000D03*
X67945000Y-46990000D03*
X70485000Y-46990000D03*
X67945000Y-49530000D03*
X70485000Y-49530000D03*
X67945000Y-52070000D03*
X70485000Y-52070000D03*
X67945000Y-54610000D03*
X70485000Y-54610000D03*
X67945000Y-57150000D03*
X70485000Y-57150000D03*
X67945000Y-59690000D03*
X70485000Y-59690000D03*
X67945000Y-62230000D03*
X70485000Y-62230000D03*
X67945000Y-64770000D03*
X70485000Y-64770000D03*
X67945000Y-67310000D03*
X70485000Y-67310000D03*
X67945000Y-69850000D03*
X70485000Y-69850000D03*
X67945000Y-72390000D03*
X70485000Y-72390000D03*
X67945000Y-74930000D03*
X70485000Y-74930000D03*
X67945000Y-77470000D03*
X70485000Y-77470000D03*
X67945000Y-80010000D03*
X70485000Y-80010000D03*
X67945000Y-82550000D03*
X70485000Y-82550000D03*
X67945000Y-85090000D03*
X70485000Y-85090000D03*
X67945000Y-87630000D03*
X70485000Y-87630000D03*
X67945000Y-90170000D03*
X70485000Y-90170000D03*
X67945000Y-92710000D03*
X70485000Y-92710000D03*
X67945000Y-95250000D03*
X70485000Y-95250000D03*
X67945000Y-97790000D03*
X70485000Y-97790000D03*
X67945000Y-100330000D03*
X70485000Y-100330000D03*
X67945000Y-102870000D03*
X70485000Y-102870000D03*
X67945000Y-105410000D03*
X70485000Y-105410000D03*
X67945000Y-107950000D03*
X70485000Y-107950000D03*
X67945000Y-110490000D03*
X70485000Y-110490000D03*
X67945000Y-113030000D03*
X70485000Y-113030000D03*
X67945000Y-115570000D03*
X70485000Y-115570000D03*
X67945000Y-118110000D03*
X70485000Y-118110000D03*
X67945000Y-120650000D03*
X70485000Y-120650000D03*
%TD*%
D22*
%TO.C,J5*%
X156045000Y-53960000D03*
X156045000Y-59740000D03*
D23*
X155545000Y-52530000D03*
D24*
X159725000Y-61170000D03*
X159725000Y-52530000D03*
D23*
X155545000Y-61170000D03*
%TD*%
D26*
X156425000Y-57125000D03*
X156425000Y-56000000D03*
X156035000Y-57775000D03*
X155895500Y-56579500D03*
X143650000Y-54850000D03*
X141550000Y-61940000D03*
D27*
X155000000Y-97250000D03*
D26*
X142630000Y-91570000D03*
X138430000Y-88610000D03*
D28*
X133030000Y-47130000D03*
X135720000Y-47070000D03*
D26*
X141754384Y-83960199D03*
X137350000Y-93040000D03*
D12*
X150450000Y-73100000D03*
D26*
X143650000Y-55850000D03*
X149850000Y-50340000D03*
X142750000Y-85950000D03*
D28*
X148500000Y-74250000D03*
D26*
X143310000Y-60280000D03*
X137420000Y-86410000D03*
D29*
X144850000Y-63275000D03*
D26*
X133460000Y-66360000D03*
X142650000Y-56850000D03*
D28*
X132940000Y-54600000D03*
X153560000Y-82570000D03*
D26*
X132600000Y-59100000D03*
X133010000Y-82430000D03*
D27*
X155000000Y-99300000D03*
D30*
X153550000Y-89200000D03*
D26*
X139990000Y-89530000D03*
D29*
X159600000Y-119900000D03*
D26*
X140480000Y-94090000D03*
X135600000Y-77900000D03*
X133020000Y-69860000D03*
D28*
X144800000Y-48750000D03*
D26*
X138300000Y-84650000D03*
X138540000Y-64980000D03*
X139180000Y-95670000D03*
X143130000Y-89860000D03*
X135060000Y-66330000D03*
X141650000Y-54850000D03*
X141750000Y-84850000D03*
D28*
X135710000Y-53680000D03*
D26*
X132490000Y-63710000D03*
X141650000Y-55850000D03*
D30*
X153825000Y-53325000D03*
D26*
X142750000Y-83800000D03*
X143650000Y-84850000D03*
X141750000Y-85950000D03*
D28*
X137980000Y-80730000D03*
D26*
X136890000Y-64530000D03*
D28*
X137400000Y-51740000D03*
D26*
X133370000Y-90340000D03*
X132600000Y-95790000D03*
X143650000Y-85950000D03*
X132860000Y-79660000D03*
X147820000Y-87080000D03*
D27*
X154700000Y-102000000D03*
D26*
X147080000Y-60210000D03*
X142750000Y-84850000D03*
D29*
X149420000Y-53910000D03*
D28*
X149412500Y-87200000D03*
D26*
X141200000Y-49890000D03*
X133330000Y-77890000D03*
X143650000Y-56850000D03*
X135870000Y-91820000D03*
D28*
X136150000Y-82330000D03*
D26*
X138190000Y-92130000D03*
X139940000Y-61480000D03*
D28*
X146825000Y-81975000D03*
X149425000Y-90525000D03*
X135950000Y-55600000D03*
D26*
X137330000Y-49910000D03*
X143650000Y-83800000D03*
X141650000Y-56850000D03*
X140400000Y-91300000D03*
D12*
X155650000Y-63850000D03*
D26*
X132910000Y-75370000D03*
X137520000Y-75810000D03*
X135480000Y-80250000D03*
X141400000Y-89670000D03*
D28*
X147520000Y-52640000D03*
D26*
X142650000Y-55850000D03*
X135050000Y-93210000D03*
X142650000Y-54850000D03*
D12*
X155400000Y-79250000D03*
D29*
X152400000Y-62550000D03*
D26*
X137420000Y-84850000D03*
D12*
X157750000Y-73800000D03*
D29*
X147841950Y-58391950D03*
D30*
X153775000Y-60500000D03*
D26*
X141290000Y-92730000D03*
X135530000Y-67940000D03*
X133790000Y-49070000D03*
X141870000Y-76460000D03*
D12*
X58550000Y-106150000D03*
X57650000Y-71850000D03*
D26*
X143529500Y-88095000D03*
D28*
X139667911Y-58032917D03*
X143630000Y-59230000D03*
X139240000Y-53920500D03*
D26*
X142029500Y-88114428D03*
D12*
X58650000Y-50343750D03*
X58450000Y-78112500D03*
D28*
X142074144Y-59210155D03*
D12*
X153100000Y-68900000D03*
X57900000Y-127100000D03*
X153050000Y-73900000D03*
D28*
X140000000Y-82500000D03*
D12*
X58450000Y-99450000D03*
D28*
X139270000Y-87810000D03*
D12*
X58400000Y-134100000D03*
X57150000Y-43850000D03*
D28*
X146350000Y-55850000D03*
X145975000Y-84900000D03*
D27*
X159775000Y-68050000D03*
D12*
X145737840Y-67109048D03*
D26*
X142954263Y-80810000D03*
D28*
X141705105Y-52364145D03*
D26*
X141795263Y-81290000D03*
D28*
X142760000Y-51420000D03*
D30*
X133000000Y-127500000D03*
D28*
X133500000Y-121000000D03*
X142460000Y-61320000D03*
X137490000Y-47380000D03*
D26*
X143479500Y-52170000D03*
X153070000Y-55710000D03*
D28*
X148912500Y-52427598D03*
X146600000Y-54800000D03*
D26*
X148350000Y-83875000D03*
D28*
X149425000Y-88900000D03*
X138950098Y-72390000D03*
X149490000Y-59810000D03*
X151730000Y-79770000D03*
X153470000Y-83480000D03*
D26*
X142890000Y-77280000D03*
X142970000Y-78004500D03*
X145910000Y-83530000D03*
X145900000Y-79490000D03*
X143491719Y-81519809D03*
X132150000Y-91450000D03*
X139129124Y-86811999D03*
X150450000Y-84625000D03*
X153400000Y-87375000D03*
X156425000Y-85000000D03*
X156425000Y-86125000D03*
X155895500Y-85579500D03*
X156035000Y-86775000D03*
M02*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
%TF.GenerationSoftware,KiCad,Pcbnew,(6.0.7)*%
%TF.CreationDate,2022-08-08T23:44:24-07:00*%
%TF.ProjectId,adatface_baseboard,61646174-6661-4636-955f-62617365626f,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Other,Comment*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW (6.0.7)) date 2022-08-08 23:44:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.150000*%
G04 APERTURE END LIST*
D10*
%TO.C,H3*%
X65650000Y-63700000D02*
G75*
G03*
X65650000Y-63700000I-3200000J0D01*
G01*
%TO.C,H4*%
X124993000Y-112649000D02*
G75*
G03*
X124993000Y-112649000I-3200000J0D01*
G01*
%TO.C,H2*%
X67650000Y-143600000D02*
G75*
G03*
X67650000Y-143600000I-3200000J0D01*
G01*
%TO.C,H1*%
X141125000Y-42100000D02*
G75*
G03*
X141125000Y-42100000I-3200000J0D01*
G01*
%TD*%
M02*

View File

@@ -0,0 +1,90 @@
N1,,1,1
C10,C23630,0,0
R4, C25804,0,0
U1,,0,0
TR2,,0,0
L3,C14304,0,0
TR3,,0,0
C9,C23630,0,0
FB1,C16902,0,0
R8,C21190,0,0
C5,C14663,0,0
U7,C236669,0,0
H3,,0,1
H4,,0,1
D4,C72043,0,0
R13,C23186,0,0
D5,C72043,0,0
C7,C14663,0,0
R14,C23186,0,0
C12,C14663,0,0
R17,C23112,0,0
C11,C15849,0,0
L4,C14304,0,0
R18,C23112,0,0
U2,,0,0
D1,C2286,0,0
C3,C14663,0,0
C21,C15850,0,0
L1,C14304,0,0
J3,,0,0
C14,C14663,0,0
C2,C14663,0,0
R3, C25804,0,0
J6,,0,0
R12,C22935,0,0
TP5,,0,1
J4,C165948,0,0
C1,C14663,0,0
D2,C72038,0,0
D12,C22452,0,0
R24,C22975,0,0
R15,C23186,0,0
D9,C72043,0,0
R9, C25804,0,0
R1,C21190,0,0
U3,,0,0
C8,C14663,0,0
R26,C22975,0,0
D6,C72043,0,0
R5, C25804,0,0
R23,C21190,0,0
C18,C23630,0,0
R11,C21190,0,0
R16,C23186,0,0
R19,C25804,0,0
D10,C72038,0,0
R10, C25804,0,0
D7,C72038,0,0
J9,,0,0
H2,,0,1
J1,,0,0
C4,C14663,0,0
D11,C72038,0,0
C16,C23630,0,0
C17,C14663,0,0
D3,C72043,0,0
C6,C14663,0,0
TR4,,0,0
R6, C25804,0,0
R25,C21190,0,0
J8,,0,0
J7,,0,0
C15,C14663,0,0
R7,C22935,0,0
C20,C14663,0,0
H1,,0,1
R21,C21190,0,0
U4,,0,0
C13,C15849,0,0
D8,C72043,0,0
TR1,,0,0
J2,,0,0
U5,C132156,0,0
C19,C1710,0,0
R2,C21190,0,0
J5,C165948,0,0
U6,C132156,0,0
D13,C22452,0,0
R20,C25804,0,0
L2,C14304,0,0

Binary file not shown.

View File

@@ -0,0 +1,4 @@
(sym_lib_table
(lib (name "usb_ulpi")(type "KiCad")(uri "${KIPRJMOD}/usb_ulpi.kicad_sym")(options "")(descr ""))
(lib (name "toslink")(type "KiCad")(uri "${KIPRJMOD}/toslink.kicad_sym")(options "")(descr ""))
)

View File

@@ -0,0 +1,242 @@
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
(symbol "PLR135_T10" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U?" (id 0) (at 10.0585 0.9085 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "PLR135_T10" (id 1) (at 10.0585 -1.8666 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "toslink:PLR135-T10_PLT133-T10W" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(symbol "PLR135_T10_0_0"
(rectangle (start -5.08 -10.16) (end 5.08 10.16)
(stroke (width 0.254) (type default) (color 0 0 0 0))
(fill (type background))
)
(polyline
(pts
(xy 9.271 0.8636)
(xy 7.62 -0.7874)
)
(stroke (width 0.3048) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 9.271 2.8956)
(xy 7.62 1.2446)
)
(stroke (width 0.3048) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 6.604 -1.8034)
(xy 7.239 -0.1524)
(xy 8.255 -1.1684)
(xy 6.604 -1.8034)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type background))
)
(polyline
(pts
(xy 6.604 0.2286)
(xy 7.239 1.8796)
(xy 8.255 0.8636)
(xy 6.604 0.2286)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type background))
)
(pin input line (at -10.16 0 0) (length 5.08)
(name "VCC" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at -10.16 -7.62 0) (length 5.08)
(name "GND" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin output line (at -10.16 7.62 0) (length 5.08)
(name "VOUT" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
)
)
(symbol "PLR135_T8" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U?" (id 0) (at 10.0585 0.9085 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "PLR135_T8" (id 1) (at 10.0585 -1.8666 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "toslink:PLR135-T8_PLT133-T8" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(symbol "PLR135_T8_0_0"
(rectangle (start -5.08 -10.16) (end 5.08 10.16)
(stroke (width 0.254) (type default) (color 0 0 0 0))
(fill (type background))
)
(polyline
(pts
(xy 9.271 0.8636)
(xy 7.62 -0.7874)
)
(stroke (width 0.3048) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 9.271 2.8956)
(xy 7.62 1.2446)
)
(stroke (width 0.3048) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 6.604 -1.8034)
(xy 7.239 -0.1524)
(xy 8.255 -1.1684)
(xy 6.604 -1.8034)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type background))
)
(polyline
(pts
(xy 6.604 0.2286)
(xy 7.239 1.8796)
(xy 8.255 0.8636)
(xy 6.604 0.2286)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type background))
)
(pin input line (at -10.16 0 0) (length 5.08)
(name "VCC" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at -10.16 -7.62 0) (length 5.08)
(name "GND" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin output line (at -10.16 7.62 0) (length 5.08)
(name "VOUT" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
)
)
(symbol "PLT133_T10W" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "TR?" (id 0) (at 0 11.5866 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "PLT133_T10W" (id 1) (at 0 8.8115 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "toslink:PLT133_T10W" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "MAXIMUM_PACKAGE_HEIGHT" "10.3 mm" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "MANUFACTURER" "Everlight Electronics" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "PARTREV" "5" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "STANDARD" "Manufacturer Recommendations" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(symbol "PLT133_T10W_0_0"
(rectangle (start -10.16 -7.62) (end 10.16 7.62)
(stroke (width 0.254) (type default) (color 0 0 0 0))
(fill (type background))
)
(pin input line (at -15.24 0 0) (length 5.08)
(name "VIN" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 15.24 5.08 180) (length 5.08)
(name "VCC" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 15.24 -5.08 180) (length 5.08)
(name "GND" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin no_connect line (at 15.24 -1.27 180) (length 5.08)
(name "NC" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
(pin no_connect line (at 15.24 1.27 180) (length 5.08)
(name "NC" (effects (font (size 1.016 1.016))))
(number "5" (effects (font (size 1.016 1.016))))
)
)
)
(symbol "PLT133_T8" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "TR?" (id 0) (at 0 11.5866 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "PLT133_T8" (id 1) (at 0 8.8115 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "toslink:PLT133_T8" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "MAXIMUM_PACKAGE_HEIGHT" "10.3 mm" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "MANUFACTURER" "Everlight Electronics" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "PARTREV" "5" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "STANDARD" "Manufacturer Recommendations" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(symbol "PLT133_T8_0_0"
(rectangle (start -10.16 -7.62) (end 10.16 7.62)
(stroke (width 0.254) (type default) (color 0 0 0 0))
(fill (type background))
)
(pin input line (at -15.24 0 0) (length 5.08)
(name "VIN" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 15.24 5.08 180) (length 5.08)
(name "VCC" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 15.24 -5.08 180) (length 5.08)
(name "GND" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin no_connect line (at 15.24 -1.27 180) (length 5.08)
(name "NC" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
(pin no_connect line (at 15.24 1.27 180) (length 5.08)
(name "NC" (effects (font (size 1.016 1.016))))
(number "5" (effects (font (size 1.016 1.016))))
)
)
)
)

View File

@@ -0,0 +1,33 @@
(footprint "PLR135-T10_PLT133-T10W" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 62ED845D)
(property "Sheetfile" "adatface_baseboard.kicad_sch")
(property "Sheetname" "")
(attr through_hole)
(fp_text reference "U?" (at 4.520245 6.659592) (layer "F.SilkS")
(effects (font (size 1.001236 1.001236) (thickness 0.15)))
(tstamp 274a4512-10db-4170-a2fe-62e969b54fbd)
)
(fp_text value "PLR135-T10" (at 8.9712 6.365845) (layer "F.Fab") hide
(effects (font (size 1.000134 1.000134) (thickness 0.15)))
(tstamp c8e00d1e-5e9f-40d8-bace-ba352f916ad9)
)
(fp_line (start 4.85 -8.49) (end -4.85 -8.49) (layer "F.SilkS") (width 0.127) (tstamp 4713bb18-4205-4e4e-b7c4-681760de8a9d))
(fp_line (start 4.85 -8.49) (end 4.85 5.01) (layer "F.SilkS") (width 0.127) (tstamp 61bccab3-566f-4dea-a450-cfd1d6e147ea))
(fp_line (start -4.85 -8.49) (end -4.85 5.01) (layer "F.SilkS") (width 0.127) (tstamp 87d30ef5-7a07-4598-bf9a-1bebed659240))
(fp_line (start 4.85 5.01) (end -4.85 5.01) (layer "F.SilkS") (width 0.127) (tstamp bd808326-5148-4995-ba70-28d10caf13d8))
(fp_line (start -5.1 5.2) (end -5.1 -8.7) (layer "F.CrtYd") (width 0.127) (tstamp 2646ffa2-edd6-45fa-83aa-d8e75466a3e8))
(fp_line (start -5.1 -8.7) (end 5.1 -8.7) (layer "F.CrtYd") (width 0.127) (tstamp 39aaf0c6-7e8d-4c33-bb2d-4f99396fcfb3))
(fp_line (start 5.1 5.2) (end -5.1 5.2) (layer "F.CrtYd") (width 0.127) (tstamp 4812c9a8-aab9-4c0f-a6ef-12729e3cb61c))
(fp_line (start 5.1 -8.7) (end 5.1 5.2) (layer "F.CrtYd") (width 0.127) (tstamp 9f9a383c-f1ba-4e21-94e5-2ab4285fcfde))
(pad "1" thru_hole circle (at 2.54 2.63) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask) (tstamp 5772fbf1-8203-492b-a675-93c30d3ed452))
(pad "2" thru_hole circle (at 0 2.63 180) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask) (tstamp 6d8a4612-2528-4718-9ceb-40e9028e8579))
(pad "3" thru_hole circle (at -2.54 2.63) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask) (tstamp fcf637c4-a1c4-4fb4-bb87-8a7012a89df0))
(pad "NC1" thru_hole circle (at 2.54 0) (size 1.65 1.65) (drill 1.1) (layers *.Cu *.Mask) (tstamp f5ecd236-566b-453a-a3d0-afc83a913511))
(pad "NC2" thru_hole circle (at -2.54 0) (size 1.65 1.65) (drill 1.1) (layers *.Cu *.Mask) (tstamp 0770cbe5-4f07-4fb4-ae36-8abcb1535653))
(model "${KIPRJMOD}/3d/PLT133_T10.step"
(offset (xyz 0 8.5 0))
(scale (xyz 1 1 1))
(rotate (xyz -90 0 0))
)
)

View File

@@ -0,0 +1,35 @@
(footprint "PLR135-T8_PLT133-T8" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 62ED8454)
(property "Sheetfile" "adatface_baseboard.kicad_sch")
(property "Sheetname" "")
(attr through_hole)
(fp_text reference "U?" (at 4.520245 6.659592) (layer "F.SilkS")
(effects (font (size 1.001236 1.001236) (thickness 0.15)))
(tstamp 274a4512-10db-4170-a2fe-62e969b54fbd)
)
(fp_text value "PLR135-T10" (at 8.9712 6.365845) (layer "F.Fab") hide
(effects (font (size 1.000134 1.000134) (thickness 0.15)))
(tstamp c8e00d1e-5e9f-40d8-bace-ba352f916ad9)
)
(fp_line (start 4.85 -8.49) (end -4.85 -8.49) (layer "F.SilkS") (width 0.127) (tstamp 4713bb18-4205-4e4e-b7c4-681760de8a9d))
(fp_line (start 4.85 -8.49) (end 4.85 5.01) (layer "F.SilkS") (width 0.127) (tstamp 61bccab3-566f-4dea-a450-cfd1d6e147ea))
(fp_line (start -4.85 -8.49) (end -4.85 5.01) (layer "F.SilkS") (width 0.127) (tstamp 87d30ef5-7a07-4598-bf9a-1bebed659240))
(fp_line (start 4.85 5.01) (end -4.85 5.01) (layer "F.SilkS") (width 0.127) (tstamp bd808326-5148-4995-ba70-28d10caf13d8))
(fp_line (start -5.1 5.2) (end -5.1 -8.7) (layer "F.CrtYd") (width 0.127) (tstamp 2646ffa2-edd6-45fa-83aa-d8e75466a3e8))
(fp_line (start -5.1 -8.7) (end 5.1 -8.7) (layer "F.CrtYd") (width 0.127) (tstamp 39aaf0c6-7e8d-4c33-bb2d-4f99396fcfb3))
(fp_line (start 5.1 5.2) (end -5.1 5.2) (layer "F.CrtYd") (width 0.127) (tstamp 4812c9a8-aab9-4c0f-a6ef-12729e3cb61c))
(fp_line (start 5.1 -8.7) (end 5.1 5.2) (layer "F.CrtYd") (width 0.127) (tstamp 9f9a383c-f1ba-4e21-94e5-2ab4285fcfde))
(pad "" np_thru_hole circle (at 2.8 -2.61 180) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask) (tstamp 35d5c8cf-202c-492a-b75c-50edd0f3cf49))
(pad "" np_thru_hole circle (at -2.8 -2.61 180) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask) (tstamp 9712cf59-dc7b-4c7d-8d23-b5a296888b8c))
(pad "1" thru_hole circle (at 2.54 2.63) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask) (tstamp 5772fbf1-8203-492b-a675-93c30d3ed452))
(pad "2" thru_hole circle (at 0 2.63 180) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask) (tstamp 6d8a4612-2528-4718-9ceb-40e9028e8579))
(pad "3" thru_hole circle (at -2.54 2.63) (size 1.308 1.308) (drill 0.8) (layers *.Cu *.Mask) (tstamp fcf637c4-a1c4-4fb4-bb87-8a7012a89df0))
(pad "NC1" thru_hole circle (at 2.54 0) (size 1.65 1.65) (drill 1.1) (layers *.Cu *.Mask) (tstamp f5ecd236-566b-453a-a3d0-afc83a913511))
(pad "NC2" thru_hole circle (at -2.54 0) (size 1.65 1.65) (drill 1.1) (layers *.Cu *.Mask) (tstamp 0770cbe5-4f07-4fb4-ae36-8abcb1535653))
(model "${KIPRJMOD}/3d/PLR135_T8.stp"
(offset (xyz -2.54 -2.54 -0.127))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 180))
)
)

View File

@@ -0,0 +1,43 @@
(footprint "PLT133_T10W" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 62ED8104)
(property "MANUFACTURER" "Everlight Electronics")
(property "MAXIMUM_PACKAGE_HEIGHT" "10.3 mm")
(property "PARTREV" "5")
(property "STANDARD" "Manufacturer Recommendations")
(property "Sheetfile" "adatface_baseboard.kicad_sch")
(property "Sheetname" "")
(attr through_hole)
(fp_text reference "TR?" (at -3.757745 -6.669592 180) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 4846382d-ddbf-4e1e-8ac7-85b7bcae3eea)
)
(fp_text value "PLT133_T10W" (at 5.16 9.865 180) (layer "F.Fab") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 353f31aa-4004-42a5-b0f9-0015aa1d630c)
)
(fp_line (start -4.85 8.49) (end -4.85 -5.01) (layer "F.SilkS") (width 0.127) (tstamp 0eca6b4a-1db8-4dc0-acb1-3583d299a29e))
(fp_line (start -4.85 8.49) (end 4.85 8.49) (layer "F.SilkS") (width 0.127) (tstamp 1298dce0-8173-4279-88dd-1e6f490be095))
(fp_line (start -4.85 -5.01) (end 4.85 -5.01) (layer "F.SilkS") (width 0.127) (tstamp caf4e03a-b4ac-4289-a81a-5b1f96d9b3eb))
(fp_line (start 4.85 8.49) (end 4.85 -5.01) (layer "F.SilkS") (width 0.127) (tstamp d6aa1abe-a47f-427e-807e-631bf58e4b42))
(fp_circle (center -5.4 -2.62) (end -5.3 -2.62) (layer "F.SilkS") (width 0.2) (fill none) (tstamp d21d7616-8bd3-4879-8a20-b6e388d2f492))
(fp_line (start 5.1 8.74) (end -5.1 8.74) (layer "F.CrtYd") (width 0.05) (tstamp 0dbf5f00-0fcf-4062-b0e8-b71667c6750c))
(fp_line (start -5.1 8.74) (end -5.1 -5.26) (layer "F.CrtYd") (width 0.05) (tstamp 359a6f95-9f71-4b49-9093-61a6c7538fd9))
(fp_line (start -5.1 -5.26) (end 5.1 -5.26) (layer "F.CrtYd") (width 0.05) (tstamp 4cde9787-61b9-40c9-b61e-2f1ddb6197d9))
(fp_line (start 5.1 -5.26) (end 5.1 8.74) (layer "F.CrtYd") (width 0.05) (tstamp e4461b35-cb34-496c-a55c-b06d6ea6de0e))
(fp_line (start -4.85 8.49) (end -4.85 -5.01) (layer "F.Fab") (width 0.127) (tstamp 33ec82cd-cac8-46d4-bfe2-883cfdc799a6))
(fp_line (start -4.85 8.49) (end 4.85 8.49) (layer "F.Fab") (width 0.127) (tstamp 6262c5a8-8816-4e5c-b532-127e6bc15e9b))
(fp_line (start -4.85 -5.01) (end 4.85 -5.01) (layer "F.Fab") (width 0.127) (tstamp 7e690956-6dfd-455f-ab4b-877cde9bbec3))
(fp_line (start 4.85 8.49) (end 4.85 -5.01) (layer "F.Fab") (width 0.127) (tstamp 956a6877-d519-4f7b-b5f6-0fb0be55f6da))
(fp_circle (center -5.4 -2.62) (end -5.3 -2.62) (layer "F.Fab") (width 0.2) (fill none) (tstamp 1472c624-edd9-4b58-ae41-7b50a4a0d5be))
(pad "1" thru_hole rect (at -2.54 -2.62) (size 1.358 1.358) (drill 0.85) (layers *.Cu *.Mask) (tstamp 1264c3d6-3a9d-4304-a1ba-2ecf28689c84))
(pad "2" thru_hole circle (at 0 -2.62) (size 1.358 1.358) (drill 0.85) (layers *.Cu *.Mask) (tstamp 42b86eb2-da34-4245-a669-2ed06961957a))
(pad "3" thru_hole circle (at 2.54 -2.62) (size 1.358 1.358) (drill 0.85) (layers *.Cu *.Mask) (tstamp 76553da1-0353-45af-926a-42bcf4ee5e4c))
(pad "4" thru_hole circle (at -2.54 0) (size 1.725 1.725) (drill 1.15) (layers *.Cu *.Mask) (tstamp 23136332-1fec-402d-97cf-3f04eb336397))
(pad "5" thru_hole circle (at 2.54 0) (size 1.725 1.725) (drill 1.15) (layers *.Cu *.Mask) (tstamp d462d8ce-bf59-4e64-bbff-abe63047bba1))
(model "${KIPRJMOD}/3d/PLT133_T10.step"
(offset (xyz 0 -8.5 0))
(scale (xyz 1 1 1))
(rotate (xyz -90 0 180))
)
)

View File

@@ -0,0 +1,45 @@
(footprint "PLT133_T8" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 62ED84F6)
(property "MANUFACTURER" "Everlight Electronics")
(property "MAXIMUM_PACKAGE_HEIGHT" "10.3 mm")
(property "PARTREV" "5")
(property "STANDARD" "Manufacturer Recommendations")
(property "Sheetfile" "adatface_baseboard.kicad_sch")
(property "Sheetname" "")
(attr through_hole)
(fp_text reference "TR?" (at -3.757745 -6.669592 180) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 4846382d-ddbf-4e1e-8ac7-85b7bcae3eea)
)
(fp_text value "PLT133_T8" (at 5.16 9.865 180) (layer "F.Fab") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 353f31aa-4004-42a5-b0f9-0015aa1d630c)
)
(fp_line (start -4.85 8.49) (end -4.85 -5.01) (layer "F.SilkS") (width 0.127) (tstamp 0eca6b4a-1db8-4dc0-acb1-3583d299a29e))
(fp_line (start -4.85 8.49) (end 4.85 8.49) (layer "F.SilkS") (width 0.127) (tstamp 1298dce0-8173-4279-88dd-1e6f490be095))
(fp_line (start -4.85 -5.01) (end 4.85 -5.01) (layer "F.SilkS") (width 0.127) (tstamp caf4e03a-b4ac-4289-a81a-5b1f96d9b3eb))
(fp_line (start 4.85 8.49) (end 4.85 -5.01) (layer "F.SilkS") (width 0.127) (tstamp d6aa1abe-a47f-427e-807e-631bf58e4b42))
(fp_circle (center -5.4 -2.62) (end -5.3 -2.62) (layer "F.SilkS") (width 0.2) (fill none) (tstamp d21d7616-8bd3-4879-8a20-b6e388d2f492))
(fp_line (start 5.1 8.74) (end -5.1 8.74) (layer "F.CrtYd") (width 0.05) (tstamp 0dbf5f00-0fcf-4062-b0e8-b71667c6750c))
(fp_line (start -5.1 8.74) (end -5.1 -5.26) (layer "F.CrtYd") (width 0.05) (tstamp 359a6f95-9f71-4b49-9093-61a6c7538fd9))
(fp_line (start -5.1 -5.26) (end 5.1 -5.26) (layer "F.CrtYd") (width 0.05) (tstamp 4cde9787-61b9-40c9-b61e-2f1ddb6197d9))
(fp_line (start 5.1 -5.26) (end 5.1 8.74) (layer "F.CrtYd") (width 0.05) (tstamp e4461b35-cb34-496c-a55c-b06d6ea6de0e))
(fp_line (start -4.85 8.49) (end -4.85 -5.01) (layer "F.Fab") (width 0.127) (tstamp 33ec82cd-cac8-46d4-bfe2-883cfdc799a6))
(fp_line (start -4.85 8.49) (end 4.85 8.49) (layer "F.Fab") (width 0.127) (tstamp 6262c5a8-8816-4e5c-b532-127e6bc15e9b))
(fp_line (start -4.85 -5.01) (end 4.85 -5.01) (layer "F.Fab") (width 0.127) (tstamp 7e690956-6dfd-455f-ab4b-877cde9bbec3))
(fp_line (start 4.85 8.49) (end 4.85 -5.01) (layer "F.Fab") (width 0.127) (tstamp 956a6877-d519-4f7b-b5f6-0fb0be55f6da))
(fp_circle (center -5.4 -2.62) (end -5.3 -2.62) (layer "F.Fab") (width 0.2) (fill none) (tstamp 1472c624-edd9-4b58-ae41-7b50a4a0d5be))
(pad "" np_thru_hole circle (at 2.8 2.62) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask) (tstamp 291bc89b-10f0-4cb4-8690-9bfbd70a4754))
(pad "" np_thru_hole circle (at -2.8 2.62) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask) (tstamp ee6098c6-69d8-4db6-9aa6-97c9de7b6cdf))
(pad "1" thru_hole rect (at -2.54 -2.62) (size 1.358 1.358) (drill 0.85) (layers *.Cu *.Mask) (tstamp 1264c3d6-3a9d-4304-a1ba-2ecf28689c84))
(pad "2" thru_hole circle (at 0 -2.62) (size 1.358 1.358) (drill 0.85) (layers *.Cu *.Mask) (tstamp 42b86eb2-da34-4245-a669-2ed06961957a))
(pad "3" thru_hole circle (at 2.54 -2.62) (size 1.358 1.358) (drill 0.85) (layers *.Cu *.Mask) (tstamp 76553da1-0353-45af-926a-42bcf4ee5e4c))
(pad "4" thru_hole circle (at -2.54 0) (size 1.725 1.725) (drill 1.15) (layers *.Cu *.Mask) (tstamp 23136332-1fec-402d-97cf-3f04eb336397))
(pad "5" thru_hole circle (at 2.54 0) (size 1.725 1.725) (drill 1.15) (layers *.Cu *.Mask) (tstamp d462d8ce-bf59-4e64-bbff-abe63047bba1))
(model "${KIPRJMOD}/3d/PLR135_T8.stp"
(offset (xyz 2.54 2.54 -0.127))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

File diff suppressed because it is too large Load Diff

299
hardware/rev0/usb_ulpi.lib Normal file
View File

@@ -0,0 +1,299 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# Connector_Generic_Conn_02x06_Odd_Even
#
DEF Connector_Generic_Conn_02x06_Odd_Even J 0 40 Y N 1 F N
F0 "J" 50 300 50 H V C CNN
F1 "Connector_Generic_Conn_02x06_Odd_Even" 50 -400 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_2x??_*
$ENDFPLIST
DRAW
S -50 -295 0 -305 1 1 6 N
S -50 -195 0 -205 1 1 6 N
S -50 -95 0 -105 1 1 6 N
S -50 5 0 -5 1 1 6 N
S -50 105 0 95 1 1 6 N
S -50 205 0 195 1 1 6 N
S -50 250 150 -350 1 1 10 f
S 150 -295 100 -305 1 1 6 N
S 150 -195 100 -205 1 1 6 N
S 150 -95 100 -105 1 1 6 N
S 150 5 100 -5 1 1 6 N
S 150 105 100 95 1 1 6 N
S 150 205 100 195 1 1 6 N
X Pin_1 1 -200 200 150 R 50 50 1 1 P
X Pin_10 10 300 -200 150 L 50 50 1 1 P
X Pin_11 11 -200 -300 150 R 50 50 1 1 P
X Pin_12 12 300 -300 150 L 50 50 1 1 P
X Pin_2 2 300 200 150 L 50 50 1 1 P
X Pin_3 3 -200 100 150 R 50 50 1 1 P
X Pin_4 4 300 100 150 L 50 50 1 1 P
X Pin_5 5 -200 0 150 R 50 50 1 1 P
X Pin_6 6 300 0 150 L 50 50 1 1 P
X Pin_7 7 -200 -100 150 R 50 50 1 1 P
X Pin_8 8 300 -100 150 L 50 50 1 1 P
X Pin_9 9 -200 -200 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Connector_USB_C_Receptacle_USB2.0
#
DEF Connector_USB_C_Receptacle_USB2.0 J 0 40 Y Y 1 F N
F0 "J" -400 750 50 H V L CNN
F1 "Connector_USB_C_Receptacle_USB2.0" 750 750 50 H V R CNN
F2 "" 150 0 50 H I C CNN
F3 "" 150 0 50 H I C CNN
$FPLIST
USB*C*Receptacle*
$ENDFPLIST
DRAW
A -275 -150 75 -1799 -1 0 1 20 N -350 -150 -200 -150
A -275 -150 25 -1799 -1 0 1 10 N -300 -150 -250 -150
A -275 -150 25 -1799 -1 0 1 10 F -300 -150 -250 -150
A -275 150 25 1 1799 0 1 10 F -250 150 -300 150
A -275 150 25 1 1799 0 1 10 N -250 150 -300 150
A -275 150 75 1 1799 0 1 20 N -200 150 -350 150
C -100 45 25 0 1 10 F
C 0 -230 50 0 1 0 F
S -10 -700 10 -660 0 0 0 N
S 400 -590 360 -610 0 0 0 N
S 400 -490 360 -510 0 0 0 N
S 400 -190 360 -210 0 0 0 N
S 400 -90 360 -110 0 0 0 N
S 400 10 360 -10 0 0 0 N
S 400 110 360 90 0 0 0 N
S 400 310 360 290 0 0 0 N
S 400 410 360 390 0 0 0 N
S 400 610 360 590 0 0 0 N
S -400 700 400 -700 0 1 10 f
S -300 -150 -250 150 0 1 10 F
S 75 70 125 120 0 1 10 F
P 2 0 1 20 -350 -150 -350 150 N
P 2 0 1 20 -200 150 -200 -150 N
P 2 0 1 20 0 -230 0 170 N
P 3 0 1 20 0 -130 -100 -30 -100 20 N
P 3 0 1 20 0 -80 100 20 100 70 N
P 4 0 1 10 -50 170 0 270 50 170 -50 170 F
X GND A1 0 -900 200 U 50 50 1 1 P
X GND A12 0 -900 200 U 50 50 1 1 P N
X VBUS A4 600 600 200 L 50 50 1 1 P
X CC1 A5 600 400 200 L 50 50 1 1 B
X D+ A6 600 -100 200 L 50 50 1 1 B
X D- A7 600 100 200 L 50 50 1 1 B
X SBU1 A8 600 -500 200 L 50 50 1 1 B
X VBUS A9 600 600 200 L 50 50 1 1 P N
X GND B1 0 -900 200 U 50 50 1 1 P N
X GND B12 0 -900 200 U 50 50 1 1 P N
X VBUS B4 600 600 200 L 50 50 1 1 P N
X CC2 B5 600 300 200 L 50 50 1 1 B
X D+ B6 600 -200 200 L 50 50 1 1 B
X D- B7 600 0 200 L 50 50 1 1 B
X SBU2 B8 600 -600 200 L 50 50 1 1 B
X VBUS B9 600 600 200 L 50 50 1 1 P N
X SHIELD S1 -300 -900 200 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_C_Small
#
DEF Device_C_Small C 0 10 N N 1 F N
F0 "C" 10 70 50 H V L CNN
F1 "Device_C_Small" 10 -80 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
C_*
$ENDFPLIST
DRAW
P 2 0 1 13 -60 -20 60 -20 N
P 2 0 1 12 -60 20 60 20 N
X ~ 1 0 100 80 D 50 50 1 1 P
X ~ 2 0 -100 80 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_LED_Small
#
DEF Device_LED_Small D 0 10 N N 1 F N
F0 "D" -50 125 50 H V L CNN
F1 "Device_LED_Small" -175 -100 50 H V L CNN
F2 "" 0 0 50 V I C CNN
F3 "" 0 0 50 V I C CNN
$FPLIST
LED*
LED_SMD:*
LED_THT:*
$ENDFPLIST
DRAW
P 2 0 1 10 -30 -40 -30 40 N
P 2 0 1 0 40 0 -30 0 N
P 4 0 1 10 30 -40 -30 0 30 40 30 -40 N
P 5 0 1 0 0 30 -20 50 -10 50 -20 50 -20 40 N
P 5 0 1 0 20 50 0 70 10 70 0 70 0 60 N
X K 1 -100 0 70 R 50 50 1 1 P
X A 2 100 0 70 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_R_Small
#
DEF Device_R_Small R 0 10 N N 1 F N
F0 "R" 30 20 50 H V L CNN
F1 "Device_R_Small" 30 -40 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
R_*
$ENDFPLIST
DRAW
S -30 70 30 -70 0 1 8 N
X ~ 1 0 100 30 D 50 50 1 1 P
X ~ 2 0 -100 30 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Regulator_Linear_TPS76318
#
DEF Regulator_Linear_TPS76318 U 0 10 Y Y 1 F N
F0 "U" -150 225 50 H V C CNN
F1 "Regulator_Linear_TPS76318" 0 225 50 H V L CNN
F2 "Package_TO_SOT_SMD:SOT-23-5" 0 325 50 H I C CIN
F3 "" 0 0 50 H I C CNN
ALIAS TPS76318 TPS76325 TPS76327 TPS76329 TPS76330 TPS76333 TPS76338 TPS76350
$FPLIST
SOT?23*
$ENDFPLIST
DRAW
S -200 175 200 -200 0 1 10 f
X VIN 1 -300 100 100 R 50 50 1 1 W
X GND 2 0 -300 100 U 50 50 1 1 W
X EN 3 -300 0 100 R 50 50 1 1 I
X NC 4 300 0 100 L 50 50 1 1 N N
X VOUT 5 300 100 100 L 50 50 1 1 w
ENDDRAW
ENDDEF
#
# power_+1V8
#
DEF power_+1V8 #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN
F1 "power_+1V8" 0 140 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 2 0 1 0 -30 50 0 100 N
P 2 0 1 0 0 0 0 100 N
P 2 0 1 0 0 100 30 50 N
X +1V8 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# power_+3.3V
#
DEF power_+3.3V #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN
F1 "power_+3.3V" 0 140 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 2 0 1 0 -30 50 0 100 N
P 2 0 1 0 0 0 0 100 N
P 2 0 1 0 0 100 30 50 N
X +3V3 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# power_+3V3
#
DEF power_+3V3 #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN
F1 "power_+3V3" 0 140 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
ALIAS +3.3V
DRAW
P 2 0 1 0 -30 50 0 100 N
P 2 0 1 0 0 0 0 100 N
P 2 0 1 0 0 100 30 50 N
X +3V3 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# power_GND
#
DEF power_GND #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -250 50 H I C CNN
F1 "power_GND" 0 -150 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
X GND 1 0 0 0 D 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# power_VBUS
#
DEF power_VBUS #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN
F1 "power_VBUS" 0 150 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 2 0 1 0 -30 50 0 100 N
P 2 0 1 0 0 0 0 100 N
P 2 0 1 0 0 100 30 50 N
X VBUS 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# twam-Misc_USB3320
#
DEF twam-Misc_USB3320 U 0 40 Y Y 1 F N
F0 "U" 0 1250 50 H V C CNN
F1 "twam-Misc_USB3320" 0 -1150 50 H V C CNN
F2 "" 2600 600 50 H I C CNN
F3 "" 2600 600 50 H I C CNN
DRAW
S -500 1200 500 -1100 0 1 0 f
X CLKOUT 1 -600 -100 100 R 50 50 1 1 O
X DATA6 10 -600 500 100 R 50 50 1 1 B
X REFSEL1 11 -600 -400 100 R 50 50 1 1 I
X ~ 12 -600 -1000 100 R 50 50 1 1 N N
X DATA7 13 -600 400 100 R 50 50 1 1 B
X REFSEL2 14 -600 -500 100 R 50 50 1 1 I
X SPK_L 15 600 -500 100 L 50 50 1 1 B
X SPK_R 16 600 -600 100 L 50 50 1 1 B
X CPEN 17 600 200 100 L 50 50 1 1 O
X DP 18 600 -200 100 L 50 50 1 1 B
X DM 19 600 -100 100 L 50 50 1 1 B
X NXT 2 -600 100 100 R 50 50 1 1 O
X VDD33 20 600 900 100 L 50 50 1 1 w
X VBAT 21 600 1100 100 L 50 50 1 1 W
X VBUS 22 600 0 100 L 50 50 1 1 I
X ID 23 600 -300 100 L 50 50 1 1 I
X RBIAS 24 600 -800 100 L 50 50 1 1 P
X XO 25 -600 -700 100 R 50 50 1 1 O
X REFCLK 26 -600 -800 100 R 50 50 1 1 I
X RESETB 27 -600 -900 100 R 50 50 1 1 I
X VDD18 28 600 700 100 L 50 50 1 1 W
X STP 29 -600 200 100 R 50 50 1 1 I
X DATA0 3 -600 1100 100 R 50 50 1 1 B
X VDD18 30 600 600 100 L 50 50 1 1 W
X DIR 31 -600 0 100 R 50 50 1 1 O
X VDDIO 32 600 400 100 L 50 50 1 1 W
X GND 33 600 -1000 100 L 50 50 1 1 W
X DATA1 4 -600 1000 100 R 50 50 1 1 B
X DATA2 5 -600 900 100 R 50 50 1 1 B
X DATA3 6 -600 800 100 R 50 50 1 1 B
X DATA4 7 -600 700 100 R 50 50 1 1 B
X REFSEL0 8 -600 -300 100 R 50 50 1 1 I
X DATA5 9 -600 600 100 R 50 50 1 1 B
ENDDRAW
ENDDEF
#
#End Library

11
ila.py Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env python3
import usb
from luna.gateware.usb.devices.ila import USBIntegratedLogicAnalyzerFrontend
from amlib.debug.ila import ILACoreParameters
dev=usb.core.find(idVendor=0x1209, idProduct=0xADA1)
print(dev)
frontend = USBIntegratedLogicAnalyzerFrontend(ila=ILACoreParameters.unpickle(), idVendor=0x1209, idProduct=0xADA1, endpoint_no=4)
frontend.interactive_display()