Skip to the content
2 layers17.3 × 30 mmTac5, the printed circuit board in 3D

CircuitPython support for TI's TAC5XXX audio codecs

Size
17.3 × 30 mm
Copper layers
2
Thickness
1.6 mm
Parts
14
Nets
24
Pads
89
Tracks, vias
171, 41
Pours
1
Routed
Yes
KiCad
KiCad 8.0 (file 20240108)
Created
26 Aug 2024
Updated
27 Jan 2025

Overview

Tac5 is an open-source printed circuit board by timchinowsky, from the timchinowsky/tac5 repository on GitHub, published under the MIT licence. It is a 2-layer board of 17.3 × 30 mm with 14 parts on 24 nets, routed with 171 tracks and 41 vias.

Its parts include 7 capacitors, 4 resistors, 2 connectors and 1 IC. It belongs with the audio and music boards of this library.

README

README.md

tac5

This repo describes PCBs and rp2040/rp2350 CircuitPython support for TI's TAC5xxx audio codecs. This code depends on extensions to CircuitPython's rp2pio library found in https://github.com/adafruit/circuitpython/pull/9659.

  • pcm.py uses the rp2 PIO to implement a PCM interface to the TAC5 which supports arbitrary numbers of channels, word sizes, and sample rates.

  • tac5.py implements a TAC5 class which knows how to initialize the TAC5xxx over I2C, write to its DACs, and read from its ADCs.

  • If multiple TAC5xxx parts with different I2C addresses are present, they are assumed to be wired in parallel for multichannel operation and configured appropriately. In this mode, each chip uses one time slot in the DOUT signal and makes its DOUT Hi-Z at other times.

  • Chips are mounted on breakout boards. KiCad files for these boards are here. Schematic and layout look like this:

Playing multichannel audio files

If you have speakers attached to the codecs, multi-track audio files stored on an SD card accessible to the rp2040 can be played on the codecs as follows:

python
Adafruit CircuitPython 9.1.0-beta.3-252-g10dfea4284-dirty on 2024-11-07; Adafruit Feather RP2040 with rp2040
>>> import tac5
>>> t=tac5.TAC5()
>>> t.play('/count_8ch_32bit_16000Hz.raw')
playing...
opening /count_8ch_32bit_16000Hz.raw ...
repeating...
repeating...
repeating...
...

Codec test, analog loopback

In this example, 4 TAC5212's are connected with BCLK, FSYNC, DOUT, DIN, SCL, and SDA in parallel, and on each chip, the differential DAC outputs are connected to the differential ADC inputs to provide test signals for the ADCs, i.e. OUT1P -> IN1P, OUT1M -> IN1M, OUT2P -> IN2P, OUT2M -> IN2M.

python
Adafruit CircuitPython 9.1.0-beta.3-76-g2f62612186-dirty on 2024-07-18; Adafruit Feather RP2040 with rp2040
>>> 
>>> import tac5
>>> t = tac5.TAC5()
>>> t.play()
playing...
>>> t.record()
sample,record0,record1,record2,record3,record4,record5,record6,record7,
0,-1,-1,-1,-1,-21642,13829,-311,-14878,
1,22355,-20880,-14861,22749,-19762,8760,6829,-20253,
2,21608,-13819,-15930,23037,-17183,3144,13306,-22783,
3,18190,-3347,-16936,22962,-13994,-2666,18482,-22111,
4,10858,7951,-17876,22524,-10311,-8313,21849,-18332,
5,602,17291,-18745,21730,-6263,-13440,23074,-11979,
6,-8849,22352,-19541,20593,-1995,-17725,22040,-3945,
7,-17070,21881,-20257,19131,2341,-20896,18845,4634,
8,-21748,15993,-20896,17368,6597,-22754,13806,12577,
9,-22490,6149,-21452,15331,10620,-23182,7417,18743,
...(115 more lines)

When called without arguments, play() creates test output (right now sine waves of various frequencies separated by gaps) for each DAC channel and sets up the interface to repeatedly send the data to the DACs in the background. When record() is called without arguments, it creates a buffer the same size as the playing buffer, fills it with ADC samples, and prints out the returned data in CSV format. The table below compares the DAC outputs as seen on a scope with the ADC outputs plotted on a spreadsheet:

DAC output                                  ADC output

Digital loopback test, no codec, single buffered

  • This example shows how a loopback test can be used to test streaming data transfer when if a codec is not present. Connect DOUT to DIN.
python
Adafruit CircuitPython 9.1.0-beta.0-426-g65556b42a5 on 2025-01-27; Adafruit Feather RP2350 with rp2350a
>>> 
>>> import tac5
>>> t = tac5.TAC5(channels=2, width=8, sample_rate=12000, address=None)
>>> t.rec(length=10)
recording...
>>> t.play(length=10, init='count')
playing...
>>> t.show(t.record_loop_buffer)
'sample'; 'ch0'; 'ch1'
0; -10; -9
1; -7; -6
2; -5; -4
3; -4; -3
4; -2; -1
5; 1; 2
6; 2; 3
7; 4; 5
8; 7; 8
9; 9; 10
>>> t.show(t.play_loop_buffer, shift=False)
'sample'; 'ch0'; 'ch1'
0; -10; -9
1; -8; -7

Digital loopback test, no codec, double buffered

Note that the count test data generated by tac5 is offset by 1 in play_loop2_buffer to distinguish it from the other buffer's data.

python
Adafruit CircuitPython 9.1.0-beta.0-426-g65556b42a5 on 2025-01-27; Adafruit Feather RP2350 with rp2350a
>>> 
>>> import tac5
>>> t = tac5.TAC5(channels=2, width=8, sample_rate=12000, address=None)
>>> t.rec(length=10, double_buffer=True)
recording...
>>> t.play(length=10, init='count', double_buffer=True)
playing...
>>> t.show(t.record_loop_buffer)
'sample'; 'ch0'; 'ch1'
0; -10; -9
1; -8; -7
2; -6; -5
3; -4; -3
4; -2; -1
5; 0; 1
6; 2; 3
7; 4; 5
8; 6; 7
9; 8; 9
>>> t.show(t.record_loop2_buffer)
'sample'; 'ch0'; 'ch1'
0; -9; -8
1; -7; -6

Digital loopback test, no codec, double buffered, recording to "tape"

python
Adafruit CircuitPython 9.1.0-beta.3-180-geda524f85c-dirty on 2024-10-24; Adafruit Feather RP2040 with rp2040
>>> import tac5
>>> t = tac5.TAC5(channels=2, width=8, sample_rate=12000, address=None)
>>> t.rec(length=10, double_buffer=True)
recording...
>>> t.play(length=10, test='count', double_buffer=True)
playing...
>>> t.show(t.record_loop_buffer)
'sample'; 'ch0'; 'ch1'
0; -9; -8
1; -7; -6
2; -5; -4
3; -3; -2
4; -1; 0
5; 1; 2
6; 3; 4
7; 5; 6
8; 7; 8
9; 9; 10
>>> t.tape('/foo.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "tac5.py", line 347, in tape
KeyboardInterrupt: 

Parts

14
QtyValueFootprintReferences
4R_USResistor_SMD:R_0603_1608MetricR1, R2, R3, R4
30.1uFCapacitor_SMD:C_0603_1608MetricC4, C6, C7
310uFCapacitor_SMD:C_0603_1608MetricC1, C3, C5
2Conn_01x12Connector_PinHeader_2.54mm:PinHeader_1x12_P2.54mm_VerticalJ1, J2
11uFCapacitor_SMD:C_0603_1608MetricC2
1TAC5212...timc:VQFN-24-1EP_4x4mm_P0.5mm_EP2.45x2.45mm_ThermalViasU1

Similar boards

  • 2 layers116.8 × 30 mmType d, the printed circuit board in 3D

    Type d

    google/mozc-devices

    Circuit diagrams and firmware source code for Gboard DIY keyboards

    14 parts3kApache-2.0
  • 2 layers32 × 22 mmDiff driver, the printed circuit board in 3D

    Diff driver

    rene-dev/stmbl

    AC Servo Driver for STM32F4

    14 parts990GPL-3.0
  • 2 layers34 × 45 mm2032Charger, the printed circuit board in 3D

    2032Charger

    hackclub/OnBoard

    💡 Join 1,000 teenagers and make your first PCB with a $100 grant!

    14 parts915
  • 2 layers34 × 109.9 mmTdisplay s3, the printed circuit board in 3D

    Tdisplay s3

    landonr/homeThing

    Wifi Smart Home Remotes that run on ESPHome

    14 parts551GPL-3.0
  • 2 layers45.3 × 42.7 mmMainPcb, the printed circuit board in 3D

    MainPcb

    adamb314/ServoProject

    Getting the most out of your hobby servo

    14 parts545
  • 2 layers42.5 × 28.8 mmC5VRX JACK DIY, the printed circuit board in 3D

    C5VRX JACK DIY

    Twotoz/C5VRX

    Ultra-minimal, zero-CPU 5.8 GHz analog FPV video receiver using ESP32-C5 Wi-Fi 6 PHY MODEM_DIAG, BitScrambler WBFM demodulation & resistor DAC CVBS

    14 parts515GPL-3.0
  • 2 layers62 × 24 mmMai button, the printed circuit board in 3D

    Mai button

    whowechina/mai_pico

    Pico controller for Maimai

    14 parts475

Questions

How big is the Tac5 PCB?

It measures 17.3 × 30 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Tac5 use?

14 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Tac5 KiCad files?

From the timchinowsky/tac5 repository on GitHub, at the commit this page was made from: the board is pcb/tac5/tac5.kicad_pcb and its schematic pcb/tac5/tac5.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Tac5 design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).