Skip to content

Commit 5b4dff9

Browse files
Add optional callback parameters for I2S/PWMAudio (#2677)
Like GPIO interrupts, allow the user to pass in a callback data pointer.
1 parent abc07ef commit 5b4dff9

File tree

6 files changed

+72
-3
lines changed

6 files changed

+72
-3
lines changed

libraries/AudioBufferManager/src/AudioBufferManager.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ AudioBufferManager::AudioBufferManager(size_t bufferCount, size_t bufferWords, i
4242
_dmaSize = dmaSize;
4343
_overunderflow = false;
4444
_callback = nullptr;
45+
_callbackCB = nullptr;
46+
_useData = false;
4547
_userOff = 0;
4648

4749
// Create the silence buffer, fill with appropriate value
@@ -101,6 +103,13 @@ AudioBufferManager::~AudioBufferManager() {
101103

102104
void AudioBufferManager::setCallback(void (*fn)()) {
103105
_callback = fn;
106+
_useData = false;
107+
}
108+
109+
void AudioBufferManager::setCallback(void (*fn)(void *), void *cbData) {
110+
_callbackCB = fn;
111+
_callbackData = cbData;
112+
_useData = true;
104113
}
105114

106115
bool AudioBufferManager::begin(int dreq, volatile void *pioFIFOAddr) {
@@ -265,7 +274,9 @@ void __not_in_flash_func(AudioBufferManager::_dmaIRQ)(int channel) {
265274
}
266275
dma_channel_set_trans_count(channel, _wordsPerBuffer * (_dmaSize == DMA_SIZE_16 ? 2 : 1), false);
267276
dma_channel_acknowledge_irq0(channel);
268-
if (_callback) {
277+
if (_callbackCB) {
278+
_callbackCB(_callbackData);
279+
} else if (_callback) {
269280
_callback();
270281
}
271282
}

libraries/AudioBufferManager/src/AudioBufferManager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class AudioBufferManager {
2929
~AudioBufferManager();
3030

3131
void setCallback(void (*fn)());
32+
void setCallback(void (*fn)(void *), void *cbData);
3233

3334
bool begin(int dreq, volatile void *pioFIFOAddr);
3435

@@ -93,7 +94,11 @@ class AudioBufferManager {
9394
bool _isOutput;
9495

9596
int _channelDMA[2];
97+
98+
bool _useData;
9699
void (*_callback)();
100+
void (*_callbackCB)(void *);
101+
void *_callbackData;
97102

98103
bool _overunderflow;
99104

libraries/I2S/src/I2S.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ I2S::I2S(PinMode direction) {
5151
_freq = 48000;
5252
_arb = nullptr;
5353
_cb = nullptr;
54+
_cbd = nullptr;
5455
_buffers = 6;
5556
_bufferWords = 0;
5657
_silenceSample = 0;
@@ -185,6 +186,16 @@ void I2S::onTransmit(void(*fn)(void)) {
185186
}
186187
}
187188

189+
void I2S::onTransmit(void(*fn)(void *), void *cbData) {
190+
if (_isOutput) {
191+
_cbd = fn;
192+
_cbdata = cbData;
193+
if (_running) {
194+
_arb->setCallback(_cbd, _cbdata);
195+
}
196+
}
197+
}
198+
188199
void I2S::onReceive(void(*fn)(void)) {
189200
if (!_isOutput) {
190201
_cb = fn;
@@ -194,6 +205,16 @@ void I2S::onReceive(void(*fn)(void)) {
194205
}
195206
}
196207

208+
void I2S::onReceive(void(*fn)(void *), void *cbData) {
209+
if (!_isOutput) {
210+
_cbd = fn;
211+
_cbdata = cbData;
212+
if (_running) {
213+
_arb->setCallback(_cbd, _cbdata);
214+
}
215+
}
216+
}
217+
197218
void I2S::MCLKbegin() {
198219
int off = 0;
199220
_i2sMCLK = new PIOProgram(&pio_i2s_mclk_program);
@@ -256,7 +277,11 @@ bool I2S::begin() {
256277
_i2s = nullptr;
257278
return false;
258279
}
259-
_arb->setCallback(_cb);
280+
if (_cbd) {
281+
_arb->setCallback(_cbd, _cbdata);
282+
} else {
283+
_arb->setCallback(_cb);
284+
}
260285
pio_sm_set_enabled(_pio, _sm, true);
261286

262287
return true;

libraries/I2S/src/I2S.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ class I2S : public Stream {
110110
// Note that these callback are called from **INTERRUPT CONTEXT** and hence
111111
// should be in RAM, not FLASH, and should be quick to execute.
112112
void onTransmit(void(*)(void));
113+
void onTransmit(void(*)(void *), void *);
113114
void onReceive(void(*)(void));
115+
void onReceive(void(*)(void *), void *);
114116

115117
private:
116118
pin_size_t _pinBCLK;
@@ -142,6 +144,9 @@ class I2S : public Stream {
142144
int _isHolding = 0;
143145

144146
void (*_cb)();
147+
void (*_cbd)(void *);
148+
void *_cbdata;
149+
145150
void MCLKbegin();
146151

147152
AudioBufferManager *_arb;

libraries/PWMAudio/src/PWMAudio.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ void PWMAudio::onTransmit(void(*fn)(void)) {
112112
}
113113
}
114114

115+
void PWMAudio::onTransmit(void(*fn)(void *), void *cbData) {
116+
_cbd = fn;
117+
_cbdata = cbData;
118+
if (_running) {
119+
_arb->setCallback(_cbd, _cbdata);
120+
}
121+
}
122+
115123
bool PWMAudio::begin() {
116124
if (_running) {
117125
return false;
@@ -155,7 +163,11 @@ bool PWMAudio::begin() {
155163
return false;
156164
}
157165

158-
_arb->setCallback(_cb);
166+
if (_cbd) {
167+
_arb->setCallback(_cbd, _cbdata);
168+
} else {
169+
_arb->setCallback(_cb);
170+
}
159171

160172
return true;
161173
}

libraries/PWMAudio/src/PWMAudio.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ class PWMAudio : public Stream {
7373
// Note that these callback are called from **INTERRUPT CONTEXT** and hence
7474
// should be in RAM, not FLASH, and should be quick to execute.
7575
void onTransmit(void(*)(void));
76+
void onTransmit(void(*)(void *), void *data);
77+
78+
bool getUnderflow() {
79+
if (!_running) {
80+
return false;
81+
} else {
82+
return _arb->getOverUnderflow();
83+
}
84+
}
7685

7786
private:
7887
pin_size_t _pin;
@@ -94,6 +103,8 @@ class PWMAudio : public Stream {
94103
uint32_t _holdWord;
95104

96105
void (*_cb)();
106+
void (*_cbd)(void *);
107+
void *_cbdata;
97108

98109
AudioBufferManager *_arb;
99110

0 commit comments

Comments
 (0)