2020-09-15 04:38 PM
Hey guys!
I am trying to implement a difference equation into the STM32 MCU, however Iam getting this from the output of my DAC and I have no idea why this is happening?
#include "main.h"
#include <stdint.h>
#include "arm_math.h"
void init_Interrupt(void);
void init_Clock(void);
void init_Interrupt(void);
void init_DAC(void);
void init_ADC(void);
void init_GPIO_Test(void);
void init_Debug(void);
void print_ADC(short);
void init_Timer(void);
char buffer[20] = "ADC Value: \n\r";
typedef struct PLL{
uint8_t PLLN;
uint8_t PLLR;
uint8_t PLLM;
uint8_t PLLSAI1N;
uint8_t PLLSAI1R;
} PLL;
PLL find_PLL(uint32_t, uint32_t);
PLL CFGR;
uint8_t escape = 0;
uint8_t half_transfer_complete = 0;
uint8_t transfer_complete = 0;
uint32_t PLLN_MAX = 86;
uint32_t PLLSAI1N_MAX = 86;
uint32_t PLLR_MAX = 8;
uint32_t PLLSAI1R_MAX = 8;
uint32_t PLLM_MAX = 8;
uint32_t CPU_Speed = 80000000;
uint32_t ADC_Speed = 29000000;
float ADC_Value[8]; // Hold 8 Samples
float ADC_Value_Output[8];
float iir_coeffs[5] = {0.00452, 0.009039, 0.00452, 1.801, -0.8189}; //B0, B1, B2, A1, A2
float iir_mono_state[4];
arm_biquad_casd_df1_inst_f32 monoChannel;
void DMA2_Channel3_IRQHandler(void){
if (((DMA2->ISR) & (DMA_ISR_HTIF3)) != 0){
half_transfer_complete = 1;
DMA2->IFCR |= DMA_IFCR_CHTIF3;
} else if (((DMA2->ISR) & (DMA_ISR_TCIF3)) != 0){
transfer_complete = 1;
DMA2->IFCR |= DMA_IFCR_CTCIF3;
}
}
int main(void) {
init_Clock();
//init_Debug();
init_ADC();
init_DAC();
init_GPIO_Test();
init_Interrupt();
init_Timer();
arm_biquad_cascade_df1_init_f32(&monoChannel, 1, iir_coeffs, iir_mono_state);
while (1) {
if (half_transfer_complete == 1){
GPIOA->BSRR |= GPIO_BSRR_BS0;
arm_biquad_cascade_df1_f32(&monoChannel, &ADC_Value[0], &ADC_Value_Output[0], 4);
TIM6 ->CR1 |= TIM_CR1_CEN;
half_transfer_complete = 0;
}
if (transfer_complete == 1){
GPIOA->BSRR |= GPIO_BSRR_BR0;
arm_biquad_cascade_df1_f32(&monoChannel, &ADC_Value[4], &ADC_Value_Output[4], 4);
transfer_complete = 0;
}
};
}
void init_ADC(){
//Pin - A6
RCC -> AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_ADCEN;
RCC -> AHB1ENR |= RCC_AHB1ENR_DMA2EN;
RCC -> CCIPR |= RCC_CCIPR_ADCSEL_1;
GPIOA -> MODER &= ~GPIO_MODER_MODE7;
GPIOA -> MODER |= GPIO_MODER_MODE7_Analog; //PIN A6
// |------------------- ADC VALUE ----------------------|
// 16-bit @ Sampling ~44.410kHZ
//Holding 8 samples at a time
// 16-bit = 2 byte * 8 = 16 bytes
DMA2_Channel3 -> CCR |= (DMA_CCR_PSIZE_16_Bit) |
(DMA_CCR_MSIZE_16_Bit) |
(DMA_CCR_MINC) |
(DMA_CCR_CIRC) |
(DMA_CCR_TCIE) |
(DMA_CCR_HTIE) |
(DMA_CCR_PL_Very_High);
DMA2_CSELR -> CSELR &= ~DMA_CSELR_C3S;
DMA2_Channel3 -> CNDTR |= 0x08;
DMA2_Channel3 -> CMAR = (uint32_t)ADC_Value; //Memory Address
DMA2_Channel3 -> CPAR = (uint32_t)&ADC1->DR; //Peripheral Addres
DMA2_Channel3 -> CCR |= DMA_CCR_EN;
ADC1 -> CR &= ~ADC_CR_DEEPPWD;
ADC1 -> CR |= ADC_CR_ADVREGEN;
ADC1 -> CR &= ~ADC_CR_ADCALDIF;
ADC1 -> CR |= ADC_CR_ADCAL;
while((ADC1->CR & ADC_CR_ADCAL) != 0) //Wait for Calibration to be done
;
ADC1 -> CFGR |= ADC_CFGR_CONT | ADC_CFGR_DMACFG;
ADC1 -> CFGR &= ~ADC_CFGR_ALIGN_RIGHT | ADC_CFGR_RES_12_Bit;
ADC1 -> SMPR2 |= ADC_SMPR2_SMP12_640_ADC_CYCLES;
ADC1 -> SQR1 |= ADC_SQR1_SQ1_12;
ADC1 -> ISR |= ADC_ISR_ADRDY;
ADC1 -> CR |= ADC_CR_ADEN; //Enable: ADC
while((ADC1->ISR & ADC_ISR_ADRDY) == 0) //Wait for the ADC to be ready
;
ADC1 -> ISR |= ADC_ISR_ADRDY; //Clear the ARDYFlAG
ADC1 -> CR |= ADC_CR_ADSTART; //Start the ADC
ADC1 -> CFGR |= ADC_CFGR_DMAEN;
}
void init_DAC(){
//Pin A3
RCC -> APB1ENR1 |= RCC_APB1ENR1_DAC1EN;
RCC -> AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
GPIOA -> MODER &= ~GPIO_MODER_MODE4;
GPIOA -> MODER |= GPIO_MODER_MODE4_Analog;
DAC1 -> CR |= DAC_CR_EN1;
}
void init_Interrupt(){
NVIC_EnableIRQ(DMA2_Channel3_IRQn);
NVIC_SetPriority(DMA2_Channel3_IRQn,0);
}
void init_Timer(){
RCC -> AHB1ENR |= RCC_AHB1ENR_DMA1EN;
RCC -> APB1ENR1 |= RCC_APB1ENR1_TIM6EN;
DMA1_Channel3 -> CCR |= DMA_CCR_PL_Very_High |
DMA_CCR_MSIZE_16_Bit |
DMA_CCR_PSIZE_16_Bit |
DMA_CCR_MINC |
DMA_CCR_CIRC |
DMA_CCR_DIR;
DMA1_Channel3 -> CNDTR = 0x08;
DMA1_Channel3 -> CPAR = (uint32_t)&DAC1->DHR12R1;
DMA1_Channel3 -> CMAR = (uint32_t)ADC_Value_Output;
DMA1_CSELR -> CSELR |= DMA_CSELR_C3S_TIM_6_UP;
DMA1_Channel3 -> CCR |= DMA_CCR_EN;
TIM6 -> DIER |= TIM_DIER_UDE;
TIM6 -> ARR = 0x708;
TIM6 -> PSC = 0x0;
}