Skip to content

Commit e12aec1

Browse files
committed
better I2S double buffer
1 parent fd4b3e9 commit e12aec1

File tree

2 files changed

+43
-27
lines changed

2 files changed

+43
-27
lines changed

libraries/I2S/src/I2S.cpp

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ I2SClass::I2SClass(uint8_t uc_index, uint8_t uc_clock_generator, uint8_t uc_pinS
1313
_uc_fs(uc_pinFS),
1414

1515
_i_dma_channel(-1),
16-
freeBuffers(2),
17-
inIndex(0),
16+
17+
_b_dma_transfer_in_progress(false),
18+
_i_buffer_index(0),
1819

1920
_onTransmit(NULL)
2021
{
22+
_i_buffer_length[0] = 0;
23+
_i_buffer_length[1] = 0;
2124
}
2225

2326
int I2SClass::begin(int mode, long sampleRate, int bitsPerSample, int driveClock)
@@ -238,26 +241,29 @@ size_t I2SClass::write(const uint8_t *buffer, size_t size)
238241
{
239242
__disable_irq();
240243

241-
if (freeBuffers == 0) {
244+
int space = (I2S_BUFFER_SIZE - _i_buffer_length[_i_buffer_index]);
245+
if (size > space) {
246+
size = space;
247+
}
248+
249+
if (space == 0) {
242250
__enable_irq();
243251
return 0;
244252
}
245253

246-
if (size > I2S_BUFFER_SIZE) {
247-
size = I2S_BUFFER_SIZE;
248-
}
254+
memcpy(&_auc_buffer[_i_buffer_index][_i_buffer_length[_i_buffer_index]], buffer, size);
249255

250-
freeBuffers--;
251-
memcpy(&_auc_buffer[inIndex], buffer, size);
256+
_i_buffer_length[_i_buffer_index] += size;
252257

253-
if (freeBuffers == 1) {
254-
DMA.transfer(_i_dma_channel, &_auc_buffer[inIndex], (void*)&_i2s->DATA[_uc_index].reg, size);
255-
}
258+
if (_b_dma_transfer_in_progress == false) {
259+
_b_dma_transfer_in_progress = true;
260+
DMA.transfer(_i_dma_channel, _auc_buffer[_i_buffer_index], (void*)&_i2s->DATA[_uc_index].reg, _i_buffer_length[_i_buffer_index]);
256261

257-
if (inIndex == 0) {
258-
inIndex = I2S_BUFFER_SIZE;
259-
} else {
260-
inIndex = 0;
262+
if (_i_buffer_index == 0) {
263+
_i_buffer_index = 1;
264+
} else {
265+
_i_buffer_index = 0;
266+
}
261267
}
262268

263269
__enable_irq();
@@ -267,7 +273,15 @@ size_t I2SClass::write(const uint8_t *buffer, size_t size)
267273

268274
size_t I2SClass::availableForWrite()
269275
{
270-
return (freeBuffers * I2S_BUFFER_SIZE);
276+
int space = 0;
277+
278+
__disable_irq();
279+
280+
space = (I2S_BUFFER_SIZE - _i_buffer_length[_i_buffer_index]);
281+
282+
__enable_irq();
283+
284+
return space;
271285
}
272286

273287
void I2SClass::onTransmit(void(*function)(void))
@@ -287,18 +301,19 @@ void I2SClass::onDmaTransferError()
287301

288302
void I2SClass::onTransferComplete(void)
289303
{
290-
freeBuffers++;
304+
int nextTransferLength = _i_buffer_length[_i_buffer_index];
291305

292-
int outIndex;
306+
if (nextTransferLength) {
307+
DMA.transfer(_i_dma_channel, _auc_buffer[_i_buffer_index], (void*)&_i2s->DATA[_uc_index].reg, nextTransferLength);
293308

294-
if (inIndex == 0) {
295-
outIndex = I2S_BUFFER_SIZE;
296-
} else {
297-
outIndex = 0;
309+
if (_i_buffer_index == 0) {
310+
_i_buffer_index = 1;
311+
} else {
312+
_i_buffer_index = 0;
313+
}
314+
_i_buffer_length[_i_buffer_index] = 0;
298315
}
299316

300-
DMA.transfer(_i_dma_channel, &_auc_buffer[outIndex], (void*)&_i2s->DATA[_uc_index].reg, 512);
301-
302317
if (_onTransmit) {
303318
_onTransmit();
304319
}

libraries/I2S/src/I2S.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ class I2SClass : public Stream
5555

5656
int _i_dma_channel;
5757

58-
uint8_t* _auc_buffer[I2S_BUFFER_SIZE * 2];
59-
volatile int freeBuffers;
60-
volatile int inIndex;
58+
volatile bool _b_dma_transfer_in_progress;
59+
uint8_t* _auc_buffer[2][I2S_BUFFER_SIZE];
60+
volatile int _i_buffer_length[2];
61+
volatile int _i_buffer_index;
6162

6263
void (*_onTransmit)(void);
6364
};

0 commit comments

Comments
 (0)