arduino-audio-driver
Loading...
Searching...
No Matches
PCM3168.h
Go to the documentation of this file.
1/* Adapted from Audio Library for Teensy 3.X
2 * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
3 * Copyright (c) 2024, phil schatzmann
4 *
5 * Development of this audio library was funded by PJRC.COM, LLC by sales of
6 * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
7 * open source software by purchasing Teensy or other PJRC products.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice, development funding notice, and this permission
17 * notice shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
27 */
28
29#pragma once
30
31#include <math.h>
32
33#include "Platforms/API_I2C.h"
34
35namespace audio_driver {
36
37/***
38 * Set up the PCM3168 in slave mode
39 */
40
41class PCM3168 {
42 enum PCM3168reg {
43 RESET_CONTROL = 0x40,
44 DAC_CONTROL_1,
45 DAC_CONTROL_2,
46 DAC_OUTPUT_PHASE,
47 DAC_SOFT_MUTE_CONTROL,
48 DAC_ZERO_FLAG,
49 DAC_CONTROL_3,
50 DAC_ATTENUATION_ALL,
51 DAC_ATTENUATION_BASE /* 8 registers */,
52 ADC_SAMPLING_MODE = 0x50,
53 ADC_CONTROL_1,
54 ADC_CONTROL_2,
55 ADC_INPUT_CONFIGURATION,
56 ADC_INPUT_PHASE,
57 ADC_SOFT_MUTE_CONTROL,
58 ADC_OVERFLOW_FLAG,
59 ADC_CONTROL_3,
60 ADC_ATTENUATION_ALL,
61 ADC_ATTENUATION_BASE /* 6 registers */
62 };
63
64 public:
77
78 PCM3168() = default;
79
80 void setAddress(uint8_t addr) { i2c_addr = addr; }
81
82 void setWire(i2c_bus_handle_t w) { wire = w; }
83
85 // wire->begin();
86 return write(DAC_CONTROL_1, fmt) && write(ADC_CONTROL_1, fmt) &&
87 setMute(false) && setMuteADC(false);
88 }
89
90 bool end(void) {
91 // not really disabled, but it is muted
92 return setMute(true) && setMuteADC(true);
93 }
94
95 bool setMute(int channel, bool mute) {
96 mute_dac = bit_set_to(mute_dac, channel, mute);
97 return write(DAC_SOFT_MUTE_CONTROL, mute_dac);
98 }
99
100 bool setMute(bool mute) {
101 mute_dac = mute ? 0xFF : 0x00;
102 return write(DAC_SOFT_MUTE_CONTROL, mute_dac);
103 }
104
105 bool setMuteADC(bool mute) {
106 mute_adc = mute ? 0xFF : 0x00;
107 return write(ADC_SOFT_MUTE_CONTROL, mute_adc);
108 }
109
110 bool setVolume(float level) { return volumeInteger(volumebyte(level)); }
111
112 bool setVolume(int channel, float level) {
113 if (channel < 1 || channel > DAC_CHANNELS_MAX) return false;
114 return volumeInteger(channel, volumebyte(level));
115 }
116
117 bool setInputVolume(float level) {
118 return inputLevelInteger(inputlevelbyte(level));
119 }
120
121 bool setInputVolume(int channel, float level) {
122 if (channel < 1 || channel > DAC_CHANNELS_MAX) return false;
123 return inputLevelInteger(channel, inputlevelbyte(level));
124 }
125
126 // these bits will invert the signal polarity of their respective DAC
127 // channels (1-8)
128 bool invertDAC(uint32_t data) { return write(DAC_OUTPUT_PHASE, data); }
129
130 // these bits will invert the signal polarity of their respective ADC
131 // channels (1-8)
132 bool invertADC(uint32_t data) { return write(ADC_INPUT_PHASE, data); }
133
134 protected:
135 const uint8_t I2C_BASE = 0x44;
136 const int ADC_CHANNELS_MAX = 6;
137 const int DAC_CHANNELS_MAX = 8;
141 uint8_t mute_dac = 0;
142 uint8_t mute_adc = 0;
143
144 inline uint8_t bit_set_to(uint8_t number, uint8_t n, bool x) {
145 return (number & ~((uint8_t)1 << n)) | ((uint8_t)x << n);
146 }
147
148 // convert level to volume byte, Table 21, page 45
149 uint32_t volumebyte(float level) {
150 if (level >= 1.0f) return 255;
151 if (level <= 1.0e-5f) return 54; // below -100dB, mute
152 // 0.5dB steps: 0dB attenuation is 255
153 return 255 + roundf(log10f(level) * 40.0f);
154 }
155
156 // convert level to input gain, Table 20, page 50
157 int32_t inputlevelbyte(float level) {
158 if (level > 10.0) return 255;
159 if (level < 1.0e-5f) return 15;
160 return 215 + roundf(log10f(level) * 40.0f);
161 }
162
163 bool volumeInteger(uint32_t n) { return write(DAC_ATTENUATION_ALL, n); }
164
165 bool volumeInteger(int channel, uint32_t n) {
166 bool rv = false;
167
168 if (0 != channel && channel <= DAC_CHANNELS_MAX)
169 rv = write(DAC_ATTENUATION_BASE + channel - 1, n);
170
171 return rv;
172 }
173
174 bool inputLevelInteger(int32_t n) {
175 uint8_t levels[ADC_CHANNELS_MAX];
176
177 for (int i = 0; i < ADC_CHANNELS_MAX; i++) levels[i] = n;
178
179 return write(ADC_ATTENUATION_BASE, levels, ADC_CHANNELS_MAX);
180 }
181
182 bool inputLevelInteger(int channel, int32_t n) {
183 bool rv = false;
184
185 if (0 != channel && channel <= ADC_CHANNELS_MAX)
186 rv = write(ADC_ATTENUATION_BASE + channel - 1, n);
187
188 return rv;
189 }
190
191 bool write(uint32_t address, uint32_t data) {
192 assert(wire != nullptr);
193 uint8_t reg = static_cast<uint8_t>(address);
194 uint8_t value = static_cast<uint8_t>(data);
195 return i2c_bus_write_bytes(wire, i2c_addr, &reg, 1, &value, 1) == 0;
196 }
197
198 bool write(uint32_t address, const void* data, uint32_t len) {
199 assert(wire != nullptr);
200 uint8_t reg = static_cast<uint8_t>(address);
201 return i2c_bus_write_bytes(wire, i2c_addr, &reg, 1, (uint8_t*)data,
202 len) == 0;
203 }
204};
205
206} // namespace audio_driver
Definition PCM3168.h:41
bool setInputVolume(int channel, float level)
Definition PCM3168.h:121
bool inputLevelInteger(int32_t n)
Definition PCM3168.h:174
bool invertADC(uint32_t data)
Definition PCM3168.h:132
bool end(void)
Definition PCM3168.h:90
const int ADC_CHANNELS_MAX
Definition PCM3168.h:136
bool setMute(int channel, bool mute)
Definition PCM3168.h:95
bool begin(FMT fmt=I2SHighSpeedTDM24bit)
Definition PCM3168.h:84
uint8_t i2c_addr
Definition PCM3168.h:139
bool setVolume(int channel, float level)
Definition PCM3168.h:112
bool setInputVolume(float level)
Definition PCM3168.h:117
uint8_t mute_dac
Definition PCM3168.h:141
uint8_t bit_set_to(uint8_t number, uint8_t n, bool x)
Definition PCM3168.h:144
bool write(uint32_t address, uint32_t data)
Definition PCM3168.h:191
FMT fmt
Definition PCM3168.h:140
void setWire(i2c_bus_handle_t w)
Definition PCM3168.h:82
uint32_t volumebyte(float level)
Definition PCM3168.h:149
const int DAC_CHANNELS_MAX
Definition PCM3168.h:137
uint8_t mute_adc
Definition PCM3168.h:142
bool setMuteADC(bool mute)
Definition PCM3168.h:105
int32_t inputlevelbyte(float level)
Definition PCM3168.h:157
void setAddress(uint8_t addr)
Definition PCM3168.h:80
bool setMute(bool mute)
Definition PCM3168.h:100
bool volumeInteger(uint32_t n)
Definition PCM3168.h:163
bool volumeInteger(int channel, uint32_t n)
Definition PCM3168.h:165
bool invertDAC(uint32_t data)
Definition PCM3168.h:128
bool setVolume(float level)
Definition PCM3168.h:110
i2c_bus_handle_t wire
Definition PCM3168.h:138
const uint8_t I2C_BASE
Definition PCM3168.h:135
bool inputLevelInteger(int channel, int32_t n)
Definition PCM3168.h:182
FMT
Definition PCM3168.h:65
@ I2SHighSpeedTDM24bit
Definition PCM3168.h:74
@ LeftTDM24bit
Definition PCM3168.h:73
@ LeftDSP24bit
Definition PCM3168.h:71
@ I2S24bit
Definition PCM3168.h:66
@ I2STDM24bit
Definition PCM3168.h:72
@ I2SDSP24bit
Definition PCM3168.h:70
@ Right24bit
Definition PCM3168.h:68
@ Right16bit
Definition PCM3168.h:69
@ LeftHighSpeedTDM24bit
Definition PCM3168.h:75
@ Left24bit
Definition PCM3168.h:67
bool write(uint32_t address, const void *data, uint32_t len)
Definition PCM3168.h:198
Namespace for audio driver components.
Definition AudioBoard.h:5
void * i2c_bus_handle_t
Definition DriverCommon.h:155