working audio
This commit is contained in:
@@ -7,19 +7,21 @@ Features: Circular Buffer with DMA IRQ (half full, full), Master Clock enabled
|
||||
This example uses the SPI3 port tested on STM32F407VET "black" board. On other boards please define LED0_BUILTIN and LED1_BUILTIN
|
||||
*/
|
||||
#define I2S_BUFFER_SIZE 64
|
||||
I2S_HandleTypeDef hi2s3;
|
||||
DMA_HandleTypeDef hdma_spi3_tx;
|
||||
I2S_HandleTypeDef hi2s4;
|
||||
DMA_HandleTypeDef hdma_spi4_tx;
|
||||
uint32_t dma_buffer[I2S_BUFFER_SIZE];
|
||||
//int16_t sine[WAV_SIZE] = {0};
|
||||
// sinus oszillator
|
||||
float osc_phi = 0;
|
||||
float osc_phi_inc = 440.0f / 44100.0f; // generating 440HZ
|
||||
|
||||
float scale[] = {C4_HZ, D4_HZ, E4_HZ, F4_HZ, G4_HZ, A4_HZ, B4_HZ, A4_HZ, G4_HZ, F4_HZ, E4_HZ, D4_HZ, C4_HZ};
|
||||
|
||||
void MX_DMA_Init(void);
|
||||
|
||||
extern "C" void DMA1_Stream5_IRQHandler(void) // this function must be included to avoid DMA to crash!
|
||||
{
|
||||
HAL_DMA_IRQHandler(&hdma_spi3_tx);
|
||||
HAL_DMA_IRQHandler(&hdma_spi4_tx);
|
||||
}
|
||||
|
||||
void Error_Handler2(byte errorcode)
|
||||
@@ -88,17 +90,16 @@ extern "C" void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
|
||||
// setting up I2S
|
||||
extern "C" void MX_I2S3_Init(void)
|
||||
{
|
||||
hi2s3.Instance = SPI3;
|
||||
hi2s3.Init.Mode = I2S_MODE_MASTER_TX;
|
||||
hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;
|
||||
hi2s3.Init.DataFormat = I2S_DATAFORMAT_16B;
|
||||
//hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
|
||||
hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
|
||||
hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_44K;
|
||||
hi2s3.Init.CPOL = I2S_CPOL_LOW;
|
||||
hi2s3.Init.ClockSource = I2S_CLOCK_PLL;
|
||||
hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
|
||||
if (HAL_I2S_Init(&hi2s3) != HAL_OK)
|
||||
hi2s4.Instance = SPI4;
|
||||
hi2s4.Init.Mode = I2S_MODE_MASTER_TX;
|
||||
hi2s4.Init.Standard = I2S_STANDARD_PHILIPS;
|
||||
hi2s4.Init.DataFormat = I2S_DATAFORMAT_16B;
|
||||
hi2s4.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
|
||||
hi2s4.Init.AudioFreq = I2S_AUDIOFREQ_44K;
|
||||
hi2s4.Init.CPOL = I2S_CPOL_LOW;
|
||||
hi2s4.Init.ClockSource = I2S_CLOCK_PLL;
|
||||
hi2s4.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
|
||||
if (HAL_I2S_Init(&hi2s4) != HAL_OK)
|
||||
{
|
||||
Error_Handler2(1); // on error: one blink
|
||||
}
|
||||
@@ -134,45 +135,51 @@ extern "C" void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
|
||||
PC7 MCK
|
||||
*/
|
||||
//I2S3 used GPIO configuration in this example:
|
||||
// PB5 DIN / SD
|
||||
// PA4 LRC /WD
|
||||
// PB3 SCLK /CK
|
||||
// PB5 DIN / SD ==> PA1
|
||||
// PA4 LRC /WD ==> PB12
|
||||
// PB3 SCLK /CK ==> PB13
|
||||
// PC7 MCK
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4;
|
||||
|
||||
//LRCLL
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_5;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_SPI4;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
// master clock
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
||||
|
||||
//DIN
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_1;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI4;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
// clock
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_13;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_SPI4;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
// Peripheral DMA init
|
||||
hdma_spi3_tx.Instance = DMA1_Stream5;
|
||||
hdma_spi3_tx.Init.Channel = DMA_CHANNEL_0;
|
||||
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi3_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
hdma_spi3_tx.Init.Mode = DMA_CIRCULAR;
|
||||
hdma_spi3_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
if (HAL_DMA_Init(&hdma_spi3_tx) != HAL_OK)
|
||||
hdma_spi4_tx.Instance = DMA1_Stream5;
|
||||
hdma_spi4_tx.Init.Channel = DMA_CHANNEL_0;
|
||||
hdma_spi4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_spi4_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi4_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
hdma_spi4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
hdma_spi4_tx.Init.Mode = DMA_CIRCULAR;
|
||||
hdma_spi4_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
hdma_spi4_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
if (HAL_DMA_Init(&hdma_spi4_tx) != HAL_OK)
|
||||
{
|
||||
Error_Handler2(5); // on error: five blinks
|
||||
}
|
||||
__HAL_LINKDMA(hi2s, hdmatx, hdma_spi3_tx);
|
||||
__HAL_LINKDMA(hi2s, hdmatx, hdma_spi4_tx);
|
||||
}
|
||||
extern "C" void HAL_MspInit(void) // maybe useful, not included in this example
|
||||
{
|
||||
@@ -194,21 +201,17 @@ extern "C" void HAL_MspInit(void) // maybe useful, not included in this example
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void initAudio()
|
||||
{
|
||||
// HAL_MspInit(); // not important by default
|
||||
HAL_I2S_MspInit(&hi2s3); // setting up pins and clocks; routing SPI3 to DMA
|
||||
HAL_I2S_MspInit(&hi2s4); // setting up pins and clocks; routing SPI3 to DMA
|
||||
MX_DMA_Init();
|
||||
MX_I2S3_Init();
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
pinMode(PIN_I2S_SDMODE, OUTPUT);
|
||||
digitalWrite(PIN_I2S_SDMODE, HIGH);
|
||||
digitalWrite(LED_BUILTIN, 0);
|
||||
StartAudioBuffers(&hi2s3);
|
||||
StartAudioBuffers(&hi2s4);
|
||||
digitalWrite(LED_BUILTIN, 1);
|
||||
}
|
||||
|
||||
@@ -220,28 +223,34 @@ void handleAudio()
|
||||
// just a dummy code in loop, audio out is generated by ISR
|
||||
digitalWrite(LED_BUILTIN, 1);
|
||||
delay(250);
|
||||
//HAL_I2S_Transmit(&hi2s3,&sine,WAV_SIZE,1000);
|
||||
//HAL_I2S_Transmit(&hi2s4,&sine,WAV_SIZE,1000);
|
||||
HAL_StatusTypeDef res;
|
||||
int16_t signal[46876];
|
||||
int16_t signal[4096];
|
||||
int nsamples = sizeof(signal) / sizeof(signal[0]);
|
||||
|
||||
int i = 0;
|
||||
while(i < nsamples) {
|
||||
double t = ((double)i/2.0)/((double)nsamples);
|
||||
signal[i] = 32767*sin(100.0 * TAU * t); // left
|
||||
signal[i+1] = signal[i]; // right
|
||||
i += 2;
|
||||
while (i < nsamples)
|
||||
{
|
||||
double t = ((double)i / 2.0) / ((double)nsamples);
|
||||
signal[i] = 32767 * sin(100.0 * TAU * t); // left
|
||||
signal[i + 1] = signal[i]; // right
|
||||
i += 2;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
res = HAL_I2S_Transmit(&hi2s3, (uint16_t*)signal, nsamples, HAL_MAX_DELAY);
|
||||
if(res != HAL_OK) {
|
||||
Serial.printf("I2S - ERROR, res = %d!\r\n", res);
|
||||
break;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
res = HAL_I2S_Transmit(&hi2s4, (uint16_t *)signal, nsamples, HAL_MAX_DELAY);
|
||||
if (res != HAL_OK)
|
||||
{
|
||||
Serial.printf("I2S - ERROR, res = %d!\r\n", res);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("I2S - HAL_OK\r\n");
|
||||
}
|
||||
}
|
||||
digitalWrite(LED_BUILTIN, 0);
|
||||
delay(250);
|
||||
|
||||
|
||||
}
|
||||
@@ -26,8 +26,6 @@
|
||||
#define B4_HZ 493.88
|
||||
|
||||
// Define a C-major scale to play all the notes up and down.
|
||||
float scale[] = { C4_HZ, D4_HZ, E4_HZ, F4_HZ, G4_HZ, A4_HZ, B4_HZ, A4_HZ, G4_HZ, F4_HZ, E4_HZ, D4_HZ, C4_HZ };
|
||||
|
||||
|
||||
void initAudio(void);
|
||||
void handleAudio(void);
|
||||
|
||||
Reference in New Issue
Block a user