cancel
Showing results for 
Search instead for 
Did you mean: 

I2S + DMA on a Nucleo F411 with CS4344 DAC

florent2
Associate II
Posted on April 24, 2016 at 15:07

Hello!

I'm trying to output a sine wave on my CS4344 DAC using I2S and DMA but it's not going well... First step was to output the correct clocks ie LRCLK = 1kHz and MCLK = 256 * LRCLK = 289MHz. I tried several PLLI2S set ups and I never get exactly the right values. The closest I got was : MCLK = 36 MHz and LRCLK = 943 kHz (that might also be because my old oscilloscope isn't so precise). I figured it was good enough and wrote the DMA transfer part. I just get some kind og fluctuating pulse signal on the output of my DAC... Could someone help me figuring out if the problem comes from my code or from the hardware? To be honest I'm really lost here : every piece of code that I find online is different from the other and there's not much resource for a beginner to start with... here is my main.c :

/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx_hal.h''
/* Private variables ---------------------------------------------------------*/
I2S_HandleTypeDef hi2s2;
DMA_HandleTypeDef hdma_spi2_tx;
/* Private variables ---------------------------------------------------------*/
uint16_t sine_table[256] = {
0x0000, 0x0324, ... , 0xf9b9, 0xfcdc,
};
/* Private function prototypes -----------------------------------------------*/
void
SystemClock_Config(
void
);
static
void
MX_GPIO_Init(
void
);
static
void
MX_DMA_Init(
void
);
static
void
MX_I2S2_Init(
void
);
int
main(
void
)
{
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2S2_Init();
HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t*)sine_table, 256);
while
(1)
{
}
}
/** System Clock Configuration
*/
void
SystemClock_Config(
void
)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
PeriphClkInitStruct.PLLI2S.PLLI2SN = 271;
PeriphClkInitStruct.PLLI2S.PLLI2SM = 16;
PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* I2S2 init function */
void
MX_I2S2_Init(
void
)
{
hi2s2.Instance = SPI2;
hi2s2.Init.Mode = I2S_MODE_MASTER_TX;
hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_44K;
hi2s2.Init.CPOL = I2S_CPOL_LOW;
hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
HAL_I2S_Init(&hi2s2);
}
/** 
* Enable DMA controller clock
*/
void
MX_DMA_Init(
void
) 
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
}
/** Configure pins as 
* Analog 
* Input 
* Output
* EVENT_OUT
* EXTI
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
void
MX_GPIO_Init(
void
)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : USART_TX_Pin USART_RX_Pin */
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
}

and my STM32F4xx_hal_msp.c :

/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx_hal.h''
extern
DMA_HandleTypeDef hdma_spi2_tx;
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void
HAL_MspInit(
void
)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
/* System interrupt init*/
/* MemoryManagement_IRQn interrupt configuration */
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
/* BusFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
/* UsageFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
/* DebugMonitor_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
void
HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s)
{
GPIO_InitTypeDef GPIO_InitStruct;
if
(hi2s->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
/**I2S2 GPIO Configuration 
PC3 ------> I2S2_SD
PA6 ------> I2S2_MCK
PB10 ------> I2S2_CK
PB12 ------> I2S2_WS 
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_spi2_tx.Instance = DMA1_Stream4;
hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi2_tx);
__HAL_LINKDMA(hi2s,hdmatx,hdma_spi2_tx);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
}
void
HAL_I2S_MspDeInit(I2S_HandleTypeDef* hi2s)
{
if
(hi2s->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspDeInit 0 */
/* USER CODE END SPI2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE();
/**I2S2 GPIO Configuration 
PC3 ------> I2S2_SD
PA6 ------> I2S2_MCK
PB10 ------> I2S2_CK
PB12 ------> I2S2_WS 
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_12);
/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(hi2s->hdmatx);
}
}

I hope someone here can make it a bit clearer for me, it's all mixed up in my head! Thanks a lot 🙂 #dma #dac #i2s #audio
1 REPLY 1
florent2
Associate II
Posted on April 24, 2016 at 19:39

Nevermind, it was a hardware problem... the code works!

Sorry about that