CMSIS FIR filter using real time input from ADC and displaying output on DAC not working properly

Hello,

I am new to this forum and I am facing some difficulty in my program. I am taking ADC input from a DSO- a sine wave at 1kHz frequency, and I am processing the received data and applying filters to the received data and sending output on DAC. I am using both ADC and DAC using DMA. Sampling frequency of ADC and DAC is 8kHz. ADC DMA buffer is circular while DAC DMA is normal that I am re-starting the DMA irq handler. I have generated filter coefficients using FDA tool in MATLAB. The data that I am receiving on the DSO is very distorted. I am using the STM32L476 Discovery Board. I have written the code in Atollic Truestudio using STM32CubeMX. I don't know exactly what is wrong here. The code is written below. What changes should I make to the code to make this code work?

main.c :

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdbool.h"
#include "audio.h"
#include "cs43l22.h"
#include "kaiser_10000_order20.h"
#include "arm_math.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */


/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define ADC_CALIBRATION_TIMEOUT_MS ((uint32_t) 1)
#define ADC_ENABLE_TIMEOUT_MS ((uint32_t) 1)
#define ADC_DISABLE_TIMEOUT_MS ((uint32_t) 1)
#define ADC_STOP_CONVERSION_TIMEOUT_MS ((uint32_t) 1)
#define ADC_CONVERSION_TIMEOUT_MS ((uint32_t) 500)

#define ADC_DELAY_CALIB_ENABLE_CPU_CYCLES (LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES * 32)

#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 256)

/* Init variable out of expected ADC conversion data range */
#define VAR_CONVERTED_DATA_INIT_VALUE (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)

/*DAC Private define ---------------------------------------------------------*/
/* Size of array containing DAC waveform samples */
#define WAVEFORM_SAMPLES_SIZE ADC_CONVERTED_DATA_BUFFER_SIZE

#define AUDIO_I2C_ADDRESS ((uint16_t) 0x94)
#define I2c1Timeout 3000

#define NUM_TAPS BL
#define BLOCK_SIZE 2

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

I2C_HandleTypeDef hi2c1;

SAI_HandleTypeDef hsai_BlockA1;
DMA_HandleTypeDef hdma_sai1_a;

/* USER CODE BEGIN PV */
AUDIO_DrvTypeDef *audio_drv;

__IO uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]; /* ADC group regular conversion data */

/* Variables for ADC conversion data computation to scaled values */
float32_t aADCConvertedData_Scaled[ADC_CONVERTED_DATA_BUFFER_SIZE];

/* Variables for FIR Filter Output Data */
float32_t aFilteredData[ADC_CONVERTED_DATA_BUFFER_SIZE]; /* FIR Filter Output Values (array of data) */

/* Variables for storing FIR filtered values */
static int16_t finalOutput[ADC_CONVERTED_DATA_BUFFER_SIZE];

/* Variable flag to check the status of ADC Conversion*/
static bool dacStartFlag = true;
volatile bool adcHalfConversionComplete = false;
volatile bool adcFullConversionComplete = false;

static float32_t firStateF321[68];

/*Variable for number of blocks based on buffer size and block size*/
uint32_t numBlocks = ADC_CONVERTED_DATA_BUFFER_SIZE/BLOCK_SIZE;

/*Pointers for handling ADC data and filter data buffer */
float32_t *aADCConverted_Full_Scaled_Ptr, *aADCConverted_Half_Scaled_Ptr, *aFilteredData_Half_Ptr, *aFilteredData_Full_Ptr;

int16_t PlayBuff[ADC_CONVERTED_DATA_BUFFER_SIZE];
volatile int16_t UpdatePointer = -1;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SAI1_Init(void);
static void MX_I2C1_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM15_Init(void);
static void MX_DAC1_Init(void);
static void MX_TIM7_Init(void);
/* USER CODE BEGIN PFP */
void AdcDmaTransferComplete_Callback();
void AdcDmaTransferHalf_Callback();

void Activate_ADC(void);
void Activate_DAC(void);
void Configure_DMA(void);
void AdcGrpRegularOverrunError_Callback(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
//#define blockSize BLOCK_SIZE
uint32_t tmp_index_adc_converted_data = 0; //Variable for ADC operation loop index
aADCConverted_Half_Scaled_Ptr = &aADCConvertedData_Scaled[0]; //Assigning ADC buffer starting element's address
aADCConverted_Full_Scaled_Ptr = &aADCConvertedData_Scaled[ADC_CONVERTED_DATA_BUFFER_SIZE/2];//Assigning ADC buffer middle element's address
aFilteredData_Half_Ptr = &aFilteredData[0]; //Assigning filter buffer starting element's address
aFilteredData_Full_Ptr = &aFilteredData[ADC_CONVERTED_DATA_BUFFER_SIZE/2]; //Assigning filter buffer middle element's address
arm_fir_instance_f32 S;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&B[0], &firStateF321[0], BLOCK_SIZE);
/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SAI1_Init();
MX_I2C1_Init();
MX_ADC1_Init();
MX_TIM15_Init();
MX_DAC1_Init();
MX_TIM7_Init();
/* USER CODE BEGIN 2 */
for(int i=0; i < ADC_CONVERTED_DATA_BUFFER_SIZE; i+=1)
{
PlayBuff[i]=finalOutput[i];
}

for (tmp_index_adc_converted_data = 0; tmp_index_adc_converted_data < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index_adc_converted_data++)
{
aADCxConvertedData[tmp_index_adc_converted_data] = VAR_CONVERTED_DATA_INIT_VALUE;
}

Configure_DMA();


//Enable timers of ADC and DAC
LL_TIM_EnableCounter(TIM15);
LL_TIM_EnableCounter(TIM7);

Activate_DAC();
Activate_ADC();

if ((LL_ADC_IsEnabled(ADC1) == 1) &&
(LL_ADC_IsDisableOngoing(ADC1) == 0) &&
(LL_ADC_REG_IsConversionOngoing(ADC1) == 0) )
{
LL_ADC_REG_StartConversion(ADC1);
}
else
{
Error_Handler();
}

if(0 != audio_drv->Play(AUDIO_I2C_ADDRESS, NULL, 0))
{
Error_Handler();
}
if(HAL_OK != HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)PlayBuff, ADC_CONVERTED_DATA_BUFFER_SIZE))
{
Error_Handler();
}

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

if(adcFullConversionComplete == true)
{

if(dacStartFlag == true)
{
dacStartFlag = false;
LL_DAC_EnableDMAReq(DAC1,LL_DAC_CHANNEL_2);
}

uint32_t tmp_index = 0;

for (tmp_index = 0; tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index++)
{
aADCConvertedData_Scaled[tmp_index] = ((float32_t)aADCxConvertedData[tmp_index] - 2048.0) / 2048.0 ;
}

for (int i=0; i < (numBlocks); i++)
{

arm_fir_f32((arm_fir_instance_f32*)&S, aADCConverted_Half_Scaled_Ptr + (i * BLOCK_SIZE), aFilteredData_Half_Ptr + (i * BLOCK_SIZE), BLOCK_SIZE);
}

//Converting back the filtered data to make it compatible for DAC processing
for (tmp_index =0; tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index++)
{
finalOutput[tmp_index] = (int16_t)(aFilteredData[tmp_index] * 2048.0) + 2048;
}

for (tmp_index =0; tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index++)
{
PlayBuff[tmp_index]=finalOutput[tmp_index];
}

//Reset ADC Full Conversion flag
adcFullConversionComplete = false;

}

}

/* USER CODE END 3 */
}

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_I2C1
|RCC_PERIPHCLK_ADC;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI2;
PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_MSI;
PeriphClkInit.PLLSAI2.PLLSAI2M = 1;
PeriphClkInit.PLLSAI2.PLLSAI2N = 40;
PeriphClkInit.PLLSAI2.PLLSAI2P = RCC_PLLP_DIV7;
PeriphClkInit.PLLSAI2.PLLSAI2R = RCC_PLLR_DIV2;
PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_ADC2CLK;
PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;
PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
PeriphClkInit.PLLSAI1.PLLSAI1N = 40;
PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
}

/**
* @brief ADC1 Initialization Function
* @param None
* @retval None
*/
static void MX_ADC1_Init(void)
{

/* USER CODE BEGIN ADC1_Init 0 */

/* USER CODE END ADC1_Init 0 */

LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};

LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

/* Peripheral clock enable */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);

LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
/**ADC1 GPIO Configuration
PA3 ------> ADC1_IN8
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

LL_GPIO_EnablePinAnalogControl(GPIOA, LL_GPIO_PIN_3);

/* ADC1 DMA Init */

/* ADC1 Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMA_REQUEST_0);

LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);

LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);

LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);

LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);

LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);

LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);

/* ADC1 interrupt Init */
NVIC_SetPriority(ADC1_2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(ADC1_2_IRQn);

/* USER CODE BEGIN ADC1_Init 1 */

/* USER CODE END ADC1_Init 1 */
/** Common config
*/
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_EXT_TIM15_TRGO;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
LL_ADC_DisableIT_EOC(ADC1);
LL_ADC_DisableIT_EOS(ADC1);
LL_ADC_DisableDeepPowerDown(ADC1);
LL_ADC_EnableInternalRegulator(ADC1);
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1;
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_RISING);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_8);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_2CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SINGLE_ENDED);
/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */

}

/**
* @brief DAC1 Initialization Function
* @param None
* @retval None
*/
static void MX_DAC1_Init(void)
{

/* USER CODE BEGIN DAC1_Init 0 */

/* USER CODE END DAC1_Init 0 */

LL_DAC_InitTypeDef DAC_InitStruct = {0};

LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DAC1);

LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
/**DAC1 GPIO Configuration
PA5 ------> DAC1_OUT2
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* DAC1 DMA Init */

/* DAC_CH2 Init */
LL_DMA_SetPeriphRequest(DMA2, LL_DMA_CHANNEL_5, LL_DMA_REQUEST_3);

LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_CHANNEL_5, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);

LL_DMA_SetChannelPriorityLevel(DMA2, LL_DMA_CHANNEL_5, LL_DMA_PRIORITY_LOW);

LL_DMA_SetMode(DMA2, LL_DMA_CHANNEL_5, LL_DMA_MODE_NORMAL);

LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_CHANNEL_5, LL_DMA_PERIPH_NOINCREMENT);

LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_CHANNEL_5, LL_DMA_MEMORY_INCREMENT);

LL_DMA_SetPeriphSize(DMA2, LL_DMA_CHANNEL_5, LL_DMA_PDATAALIGN_HALFWORD);

LL_DMA_SetMemorySize(DMA2, LL_DMA_CHANNEL_5, LL_DMA_MDATAALIGN_HALFWORD);

/* USER CODE BEGIN DAC1_Init 1 */

/* USER CODE END DAC1_Init 1 */
/** DAC channel OUT2 config
*/
DAC_InitStruct.TriggerSource = LL_DAC_TRIG_EXT_TIM7_TRGO;
DAC_InitStruct.WaveAutoGeneration = LL_DAC_WAVE_AUTO_GENERATION_NONE;
DAC_InitStruct.OutputBuffer = LL_DAC_OUTPUT_BUFFER_ENABLE;
DAC_InitStruct.OutputConnection = LL_DAC_OUTPUT_CONNECT_GPIO;
DAC_InitStruct.OutputMode = LL_DAC_OUTPUT_MODE_NORMAL;
LL_DAC_Init(DAC1, LL_DAC_CHANNEL_2, &DAC_InitStruct);
LL_DAC_EnableTrigger(DAC1, LL_DAC_CHANNEL_2);
/* USER CODE BEGIN DAC1_Init 2 */

/* USER CODE END DAC1_Init 2 */

}

/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void)
{

/* USER CODE BEGIN I2C1_Init 0 */

/* USER CODE END I2C1_Init 0 */

/* USER CODE BEGIN I2C1_Init 1 */

/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x50B03644;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_DISABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
HAL_I2C_MspInit(&hi2c1);
HAL_I2C_Init(&hi2c1);
/* USER CODE END I2C1_Init 2 */

}

/**
* @brief SAI1 Initialization Function
* @param None
* @retval None
*/
static void MX_SAI1_Init(void)
{

/* USER CODE BEGIN SAI1_Init 0 */

/* USER CODE END SAI1_Init 0 */

/* USER CODE BEGIN SAI1_Init 1 */

/* USER CODE END SAI1_Init 1 */
hsai_BlockA1.Instance = SAI1_Block_A;
hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;
hsai_BlockA1.Init.DataSize = SAI_DATASIZE_16;
hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_MSB;
hsai_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_8K;
hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED;
hsai_BlockA1.FrameInit.FrameLength = 32;
hsai_BlockA1.FrameInit.ActiveFrameLength = 16;
hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
hsai_BlockA1.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
hsai_BlockA1.SlotInit.FirstBitOffset = 0;
hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
hsai_BlockA1.SlotInit.SlotNumber = 2;
hsai_BlockA1.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SAI1_Init 2 */
__HAL_SAI_ENABLE(&hsai_BlockA1);

/* Initialize audio driver */
if(CS43L22_ID != cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS))
{
Error_Handler();
}
audio_drv = &cs43l22_drv;
audio_drv->Reset(AUDIO_I2C_ADDRESS);
if(0 != audio_drv->Init(AUDIO_I2C_ADDRESS, OUTPUT_DEVICE_HEADPHONE, 90, AUDIO_FREQUENCY_16K))
{
Error_Handler();
}
/* USER CODE END SAI1_Init 2 */

}

/**
* @brief TIM7 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM7_Init(void)
{

/* USER CODE BEGIN TIM7_Init 0 */

/* USER CODE END TIM7_Init 0 */

LL_TIM_InitTypeDef TIM_InitStruct = {0};

/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM7);

/* USER CODE BEGIN TIM7_Init 1 */

/* USER CODE END TIM7_Init 1 */
TIM_InitStruct.Prescaler = 99;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 99;
LL_TIM_Init(TIM7, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM7);
LL_TIM_SetTriggerOutput(TIM7, LL_TIM_TRGO_UPDATE);
LL_TIM_DisableMasterSlaveMode(TIM7);
/* USER CODE BEGIN TIM7_Init 2 */

/* USER CODE END TIM7_Init 2 */

}

/**
* @brief TIM15 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM15_Init(void)
{

/* USER CODE BEGIN TIM15_Init 0 */

/* USER CODE END TIM15_Init 0 */

LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0};

/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM15);

/* USER CODE BEGIN TIM15_Init 1 */

/* USER CODE END TIM15_Init 1 */
TIM_InitStruct.Prescaler = 99;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 99;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
TIM_InitStruct.RepetitionCounter = 0;
LL_TIM_Init(TIM15, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM15);
LL_TIM_SetClockSource(TIM15, LL_TIM_CLOCKSOURCE_INTERNAL);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_FROZEN;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.CompareValue = 0;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
LL_TIM_OC_Init(TIM15, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
LL_TIM_OC_DisableFast(TIM15, LL_TIM_CHANNEL_CH1);
LL_TIM_SetTriggerInput(TIM15, LL_TIM_TS_ITR0);
LL_TIM_SetSlaveMode(TIM15, LL_TIM_SLAVEMODE_DISABLED);
LL_TIM_DisableIT_TRIG(TIM15);
LL_TIM_DisableDMAReq_TRIG(TIM15);
LL_TIM_SetTriggerOutput(TIM15, LL_TIM_TRGO_UPDATE);
LL_TIM_DisableMasterSlaveMode(TIM15);
TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE;
TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE;
TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF;
TIM_BDTRInitStruct.DeadTime = 0;
TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE;
TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
LL_TIM_BDTR_Init(TIM15, &TIM_BDTRInitStruct);
/* USER CODE BEGIN TIM15_Init 2 */

/* USER CODE END TIM15_Init 2 */

}

/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{

/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();

/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA2_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn);
/* DMA2_Channel5_IRQn interrupt configuration */
NVIC_SetPriority(DMA2_Channel5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA2_Channel5_IRQn);

}

/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

/* GPIO Ports Clock Enable */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);

/**/
LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_2);

/**/
LL_GPIO_ResetOutputPin(GPIOE, LL_GPIO_PIN_8);

/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_8;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOE, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
void AdcDmaTransferComplete_Callback()
{
adcFullConversionComplete = 1;
}

void AdcDmaTransferHalf_Callback()
{
adcHalfConversionComplete = 1 ;
}

void Activate_ADC(void)
{
volatile uint32_t wait_loop_index = 0;
#if (USE_TIMEOUT == 1)
uint32_t Timeout = 0; /* Variable used for timeout management */
#endif /* USE_TIMEOUT */

if (LL_ADC_IsEnabled(ADC1) == 0)
{
/* Disable ADC deep power down (enabled by default after reset state) */
LL_ADC_DisableDeepPowerDown(ADC1);

/* Enable ADC internal voltage regulator */
LL_ADC_EnableInternalRegulator(ADC1);

/* Delay for ADC internal voltage regulator stabilization. */
/* Compute number of CPU cycles to wait for, from delay in us. */
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles (depends on compilation optimization). */
/* Note: If system core clock frequency is below 200kHz, wait time */
/* is only a few CPU processing cycles. */
wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
while(wait_loop_index != 0)
{
wait_loop_index--;
}

/* Run ADC self calibration */
LL_ADC_StartCalibration(ADC1, LL_ADC_SINGLE_ENDED);

/* Poll for ADC effectively calibrated */
#if (USE_TIMEOUT == 1)
Timeout = ADC_CALIBRATION_TIMEOUT_MS;
#endif /* USE_TIMEOUT */

while (LL_ADC_IsCalibrationOnGoing(ADC1) != 0)
{
#if (USE_TIMEOUT == 1)
/* Check Systick counter flag to decrement the time-out value */
if (LL_SYSTICK_IsActiveCounterFlag())
{
if(Timeout-- == 0)
{
/* Time-out occurred. Set LED to blinking mode */
LED_Blinking(LED_BLINK_ERROR);
}
}
#endif /* USE_TIMEOUT */
}

/* Delay between ADC end of calibration and ADC enable. */
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles (depends on compilation optimization). */
wait_loop_index = (ADC_DELAY_CALIB_ENABLE_CPU_CYCLES >> 1);
while(wait_loop_index != 0)
{
wait_loop_index--;
}

/* Enable ADC */
LL_ADC_Enable(ADC1);

/* Poll for ADC ready to convert */
#if (USE_TIMEOUT == 1)
Timeout = ADC_ENABLE_TIMEOUT_MS;
#endif /* USE_TIMEOUT */

while (LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0)
{
#if (USE_TIMEOUT == 1)
/* Check Systick counter flag to decrement the time-out value */
if (LL_SYSTICK_IsActiveCounterFlag())
{
if(Timeout-- == 0)
{
/* Time-out occurred. Set LED to blinking mode */
LED_Blinking(LED_BLINK_ERROR);
}
}
#endif /* USE_TIMEOUT */
}
}
}

void Activate_DAC(void)
{
volatile uint32_t wait_loop_index = 0;

/* Enable DAC channel */
LL_DAC_Enable(DAC1, LL_DAC_CHANNEL_2);

/* Delay for DAC channel voltage settling time from DAC channel startup. */
/* Compute number of CPU cycles to wait for, from delay in us. */
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles (depends on compilation optimization). */
/* Note: If system core clock frequency is below 200kHz, wait time */
/* is only a few CPU processing cycles. */
wait_loop_index = ((LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US * (SystemCoreClock / (100000 * 2))) / 10);
while(wait_loop_index != 0)
{
wait_loop_index--;
}

}

void Configure_DMA(void)
{
//Data Length an address has to be configured before enabling the channel
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, ADC_CONVERTED_DATA_BUFFER_SIZE);
LL_DMA_EnableIT_TC(DMA1,LL_DMA_CHANNEL_1);
//LL_DMA_EnableIT_HT(DMA1,LL_DMA_CHANNEL_1);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1,LL_ADC_DMA_GetRegAddr(ADC1,LL_ADC_DMA_REG_REGULAR_DATA),(uint32_t)aADCxConvertedData, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);

//DAC address must be configured and data length must be set before channel is enabled
LL_DMA_ConfigAddresses(DMA2,LL_DMA_CHANNEL_5,(uint32_t)&PlayBuff[0],LL_DAC_DMA_GetRegAddr(DAC1,LL_DAC_CHANNEL_2, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED), LL_DMA_DIRECTION_MEMORY_TO_PERIPH );
LL_DMA_SetDataLength(DMA2, LL_DMA_CHANNEL_5, ADC_CONVERTED_DATA_BUFFER_SIZE);
//Transfer complete and half transfer complete interrupts are enabled
LL_DMA_EnableIT_TC(DMA2,LL_DMA_CHANNEL_5);
LL_DMA_EnableIT_TE(DMA2,LL_DMA_CHANNEL_5);
//Channel is enabled
LL_DMA_EnableChannel(DMA2,LL_DMA_CHANNEL_5);

}

void AdcGrpRegularOverrunError_Callback(void)
{
/* Note: Disable ADC interruption that caused this error before entering in */
/* infinite loop below. */

/* Disable ADC group regular overrun interruption */
LL_ADC_DisableIT_OVR(ADC1);

/* Error from ADC */
}

void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_SAI_TxCpltCallback could be implemented in the user file
*/
UpdatePointer = ADC_CONVERTED_DATA_BUFFER_SIZE/2;

}

void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_SAI_TxHalfCpltCallback could be implenetd in the user file
*/
UpdatePointer = 0;
}

/* USER CODE END 4 */

/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */

/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(char *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

stm32l4xx_it.c

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32l4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 256)
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

extern void AdcDmaTransferComplete_Callback();
extern void AdcDmaTransferHalf_Callback();
extern void AdcGrpRegularOverrunError_Callback(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_sai1_a;
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */

/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */

/* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */

/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}

/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */

/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}

/**
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */

/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}

/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */

/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}

/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */

/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */

/* USER CODE END SVCall_IRQn 1 */
}

/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */

/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */

/* USER CODE END DebugMonitor_IRQn 1 */
}

/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */

/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */

/* USER CODE END PendSV_IRQn 1 */
}

/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */

/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */

/* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32l4xx.s). */
/******************************************************************************/

/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

if(LL_DMA_IsActiveFlag_TC1(DMA1) == 1)
{
/* Clear flag DMA transfer complete */
LL_DMA_ClearFlag_TC1(DMA1);

AdcDmaTransferComplete_Callback();
/* Call interruption treatment function */

}

/* USER CODE END DMA1_Channel1_IRQn 0 */

/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

/* USER CODE END DMA1_Channel1_IRQn 1 */
}

/**
* @brief This function handles ADC1 and ADC2 interrupts.
*/
void ADC1_2_IRQHandler(void)
{
/* USER CODE BEGIN ADC1_2_IRQn 0 */
if(LL_ADC_IsActiveFlag_OVR(ADC1) != 0)
{
/* Clear flag ADC group regular overrun */
LL_ADC_ClearFlag_OVR(ADC1);

/* Call interruption treatment function */
AdcGrpRegularOverrunError_Callback();
}
/* USER CODE END ADC1_2_IRQn 0 */

/* USER CODE BEGIN ADC1_2_IRQn 1 */

/* USER CODE END ADC1_2_IRQn 1 */
}

/**
* @brief This function handles DMA2 channel1 global interrupt.
*/
void DMA2_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Channel1_IRQn 0 */

/* USER CODE END DMA2_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_sai1_a);
/* USER CODE BEGIN DMA2_Channel1_IRQn 1 */

/* USER CODE END DMA2_Channel1_IRQn 1 */
}

/**
* @brief This function handles DMA2 channel5 global interrupt.
*/
void DMA2_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Channel5_IRQn 0 */

if(LL_DMA_IsActiveFlag_TC5(DMA2) == 1)
{
LL_DMA_DisableChannel(DMA2,LL_DMA_CHANNEL_5);
LL_DMA_ClearFlag_TC5(DMA2);
DMA2_Channel5->CNDTR = ADC_CONVERTED_DATA_BUFFER_SIZE;
LL_DMA_EnableChannel(DMA2,LL_DMA_CHANNEL_5);
}

if(LL_DMA_IsActiveFlag_TE5(DMA2) == 1)
{
LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_2);
}


/* USER CODE END DMA2_Channel5_IRQn 0 */

/* USER CODE BEGIN DMA2_Channel5_IRQn 1 */

/* USER CODE END DMA2_Channel5_IRQn 1 */
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Parents
  • but I don't think anyone is going to plough through all that!

    What have you done to find the source of the problem(s)?

    You've mentioned a number of processes going on in your code - what have you done to make sure each one is working in isolation?

    Have you started with ST's examples to make sure you are using the peripherals correctly?

    I am taking ADC input from a DSO

    What do you mean by that?

    "DSO" usually means "Digital Storage Oscilloscope".

    The data that I am receiving on the DSO is very distorted

    Again, what do you mean by that?

Reply
  • but I don't think anyone is going to plough through all that!

    What have you done to find the source of the problem(s)?

    You've mentioned a number of processes going on in your code - what have you done to make sure each one is working in isolation?

    Have you started with ST's examples to make sure you are using the peripherals correctly?

    I am taking ADC input from a DSO

    What do you mean by that?

    "DSO" usually means "Digital Storage Oscilloscope".

    The data that I am receiving on the DSO is very distorted

    Again, what do you mean by that?

Children
No data