#include "stm32f4xx.h" #include "math.h" #define pi 3.14159 int x1[4096], x2[4096], xyPtr; // declaration of circular buffers int w[1024]; // declaration of FIR weights void ADC_setup(void) { RCC->APB2ENR |= 0x00000100; // clock for ADC1 RCC->APB2ENR |= 0x00000200; // clock for ADC2 ADC->CCR = 0x00000006; // Regular simultaneous mode only ADC1->CR2 = 0x00000001; // ADC1 ON ADC1->SQR3 = 0x00000002; // use PA02 as input ADC2->CR2 = 0x00000001; // ADC1 ON ADC2->SQR3 = 0x00000003; // use PA03 as input GPIOA->MODER |= 0x000000f0; // PA02, PA03 are analog inputs ADC1->CR2 |= 0x06000000; // use TIM2, TRG0 as SC source ADC1->CR2 |= 0x10000000; // Enable external SC, rising edge ADC1->CR1 |= 0x00000020; // Enable ADC Interrupt for EOC } void DAC_setup(void) { RCC->APB1ENR |= 0x20000000; // Enable clock for DAC DAC->CR |= 0x00010001; // DAC control reg, both channels ON GPIOA->MODER |= 0x00000f00; // PA04, PA05 are analog outputs } void GPIO_setup(void) { RCC->AHB1ENR |= 0x00000001; // Enable clock for GPIOA RCC->AHB1ENR |= 0x00000010; // Enable clock for GPIOE GPIOE->MODER |= 0x00010000; // output pin PE08: time mark GPIOE->MODER |= 0x00040000; // output pin PE09: toggle GPIOA->MODER |= 0x00001000; // output pin PA06: LED D390 } void Timer2_setup(void) { RCC->APB1ENR |= 0x0001; // Enable clock for Timer 2 TIM2->ARR = 8400; // Auto Reload value: 8400 == 100us TIM2->CR2 |= 0x0020; // select TRGO to be update event (UE) TIM2->CR1 |= 0x0001; // Enable Counting } int main () { GPIO_setup(); // GPIO clock enable, digital pin definitions DAC_setup(); // DAC set-up ADC_setup(); // ADC set-up Timer2_setup(); // Timer 2 set-up NVIC_EnableIRQ(ADC_IRQn); // Enable IRQ for ADC in NVIC w[0] = 0; for (short k = 1; k < 64; k++) // FIR weights w[k] = (int)(65536.0 * (-1.0 + cos(pi * k)) / (pi * k)); for (short k = 1; k < 64; k++) // windowing, Hanning w[k] = (int)((float)w[k] * cos(pi/2 * k / 63.0)); // waste time - indefinite while (1) { if (GPIOE->IDR & 0x0001) GPIOA->ODR |= 0x0040; // LED on else GPIOA->ODR &= ~0x0040; // else LED off GPIOE->ODR |= 0x0200; // PE09 up GPIOE->ODR &= ~0x0200; // PE09 down }; } // IRQ function void ADC_IRQHandler(void) // PASS takes approx 5us of CPU time! { GPIOE->ODR |= 0x0100; // PE08 up x1[xyPtr] = ADC1->DR; // pass ADC -> circular buffer x1 x2[xyPtr] = ADC2->DR; // pass ADC -> circular buffer x2 int conv = 0; // take central weight for (int k = 1; k < 64; k +=2) // convolve the rest conv += w[k] * (x1[(xyPtr - 100 + k) & 4095] - x1[(xyPtr - 100 - k) & 4095]); DAC->DHR12R1 = (conv >> 16) + 2048; // result -> DAC DAC->DHR12R2 = x1[(xyPtr - 100) & 4095]; // original -> DAC xyPtr = (xyPtr + 1) & 4095; // increment pointer to circulat buffer GPIOE->ODR &= ~0x0100; // PE08 down }