i2s: improve performance, add extra methods
This commit is contained in:
parent
1373c95224
commit
63b8c33205
|
@ -24,19 +24,19 @@ I2SClass::I2SClass(SPI_TypeDef *instance, uint8_t sd, uint8_t ws, uint8_t ck, ui
|
|||
stm32SetMCK(mck);
|
||||
}
|
||||
|
||||
void I2SClass::setBuffer(uint16_t *buffer, int bufferSize) {
|
||||
void I2SClass::setBuffer(int16_t *buffer, int bufferSize) {
|
||||
this->doubleBuffer = buffer;
|
||||
this->halfBufferSize = bufferSize / 2;
|
||||
this->bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
int I2SClass::getBufferSize() {
|
||||
return halfBufferSize * 2;
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
uint8_t I2SClass::begin(i2s_mode_t mode, uint32_t sampleRate, uint8_t bitsPerSample) {
|
||||
static uint16_t static_buffer[2048];
|
||||
static int16_t static_buffer[2048];
|
||||
|
||||
setBuffer((uint16_t*)&static_buffer, 2048);
|
||||
setBuffer(static_buffer, 2048);
|
||||
|
||||
#ifdef SPI1
|
||||
if (handle.Instance == SPI1) __HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
@ -139,28 +139,42 @@ uint8_t I2SClass::begin(i2s_mode_t mode, uint32_t sampleRate, uint8_t bitsPerSam
|
|||
I2SClass *i2sDma;
|
||||
|
||||
extern "C" void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) {
|
||||
i2sDma->dmaDone = true;
|
||||
i2sDma->tail += i2sDma->dmaSendSize;
|
||||
|
||||
if ((uint32_t)(i2sDma->head - i2sDma->tail) > i2sDma->dmaSendSize) {
|
||||
HAL_I2S_Transmit_DMA(hi2s, (uint16_t*)(i2sDma->doubleBuffer + (i2sDma->tail % i2sDma->bufferSize)), i2sDma->dmaSendSize);
|
||||
} else {
|
||||
i2sDma->dmaDone = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void I2SClass::write(int16_t data) {
|
||||
doubleBuffer[dataIndex + bufferIndex * halfBufferSize] = data;
|
||||
dataIndex++;
|
||||
while((head + 1) % bufferSize == tail % bufferSize);
|
||||
|
||||
if (dataIndex == halfBufferSize) {
|
||||
while(!dmaDone);
|
||||
doubleBuffer[head % bufferSize] = data;
|
||||
head++;
|
||||
|
||||
if (dmaDone && (uint32_t)(head - tail) > dmaSendSize) {
|
||||
i2sDma = this;
|
||||
dmaDone = false;
|
||||
HAL_I2S_Transmit_DMA(&handle, doubleBuffer + bufferIndex * halfBufferSize, halfBufferSize);
|
||||
dataIndex = 0;
|
||||
bufferIndex++;
|
||||
bufferIndex %= 2;
|
||||
HAL_I2S_Transmit_DMA(&handle, (uint16_t*)(doubleBuffer + (tail % bufferSize)), dmaSendSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void I2SClass::write(int16_t *data, size_t samples) {
|
||||
for(size_t i=0; i<samples; i++) {
|
||||
write(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void I2SClass::write(int16_t *data, uint16_t size) {
|
||||
for(int i=0; i<size; i++) {
|
||||
write(data[i]);
|
||||
}
|
||||
uint32_t I2SClass::availableForWrite() {
|
||||
return bufferSize - (head - tail);
|
||||
}
|
||||
|
||||
uint32_t I2SClass::getDelay() {
|
||||
return dmaSendSize;
|
||||
}
|
||||
|
||||
void I2SClass::stm32SetSD(uint8_t sd) {
|
||||
|
|
|
@ -19,13 +19,17 @@ class I2SClass {
|
|||
|
||||
uint8_t begin(i2s_mode_t mode, uint32_t sampleRate, uint8_t bitsPerSample);
|
||||
|
||||
void setBuffer(uint16_t *buffer, int bufferSize);
|
||||
void setBuffer(int16_t *buffer, int bufferSize);
|
||||
|
||||
int getBufferSize();
|
||||
|
||||
uint32_t getDelay();
|
||||
|
||||
uint32_t availableForWrite();
|
||||
|
||||
void write(int16_t data);
|
||||
|
||||
void write(int16_t *data, uint16_t size);
|
||||
void write(int16_t *data, size_t size);
|
||||
|
||||
void stm32SetSD(uint8_t sd);
|
||||
void stm32SetWS(uint8_t ws);
|
||||
|
@ -47,9 +51,11 @@ class I2SClass {
|
|||
|
||||
DMA_HandleTypeDef dmaHandle;
|
||||
|
||||
int halfBufferSize;
|
||||
uint16_t *doubleBuffer;
|
||||
volatile uint16_t dataIndex, bufferIndex;
|
||||
uint32_t bufferSize;
|
||||
int16_t *doubleBuffer;
|
||||
uint16_t dmaSendSize = 512;
|
||||
|
||||
volatile uint32_t head = 0, tail = 0;
|
||||
volatile bool dmaDone = true;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue