#include #include #include #include #include #include "sr_global.h" #include "adc.h" #include "spi_flash.h" #include "freq_meas.h" #include "dsss_demod.h" static struct spi_flash_if spif; void __libc_init_array(void) { /* we don't need this. */ } void __assert_func (unused_a const char *file, unused_a int line, unused_a const char *function, unused_a const char *expr) { asm volatile ("bkpt"); while(1) {} } static void clock_setup(void) { /* 8MHz HSE clock as PLL source. * * Divide by 8 -> 1 MHz */ #define PLL_M 8 /* Multiply by 336 -> 336 MHz VCO frequency */ #define PLL_N 336 /* Divide by 4 -> 84 MHz (max freq for our chip) */ #define PLL_P 4 /* Aux clock for USB OTG, SDIO, RNG: divide VCO frequency (336 MHz) by 7 -> 48 MHz (required by USB OTG) */ #define PLL_Q 7 if (((RCC->CFGR & RCC_CFGR_SWS_Msk) >> RCC_CFGR_SW_Pos) != 0) asm volatile ("bkpt"); if (RCC->CR & RCC_CR_HSEON) asm volatile ("bkpt"); RCC->CR |= RCC_CR_HSEON; while(!(RCC->CR & RCC_CR_HSERDY)) ; RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* set voltage scale to 1 for max frequency * (0b0) scale 2 for fCLK <= 144 Mhz * (0b1) scale 1 for 144 Mhz < fCLK <= 168 Mhz */ PWR->CR |= PWR_CR_VOS; /* set AHB prescaler to /1 (CFGR:bits 7:4) */ RCC->CFGR |= (0 << RCC_CFGR_HPRE_Pos); /* set ABP1 prescaler to 2 -> 42MHz */ RCC->CFGR |= (4 << RCC_CFGR_PPRE1_Pos); /* set ABP2 prescaler to 1 -> 84MHz */ RCC->CFGR |= (0 << RCC_CFGR_PPRE2_Pos); if (RCC->CR & RCC_CR_PLLON) asm volatile ("bkpt"); /* Configure PLL */ static_assert(PLL_P % 2 == 0); static_assert(PLL_P >= 2 && PLL_P <= 8); static_assert(PLL_N >= 50 && PLL_N <= 432); static_assert(PLL_M >= 2 && PLL_M <= 63); static_assert(PLL_Q >= 2 && PLL_Q <= 15); uint32_t old = RCC->PLLCFGR & ~(RCC_PLLCFGR_PLLM_Msk | RCC_PLLCFGR_PLLN_Msk | RCC_PLLCFGR_PLLP_Msk | RCC_PLLCFGR_PLLQ_Msk | RCC_PLLCFGR_PLLSRC); RCC->PLLCFGR = old | (PLL_M<CR |= RCC_CR_PLLON; /* Wait for main PLL */ while(!(RCC->CR & RCC_CR_PLLRDY)) ; /* Configure Flash: enable prefetch, insn cache, data cache; set latency = 5 wait states * See reference manual (RM0090), Section 3.5.1, Table 10 (p. 80) */ FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | (5<CFGR &= ~RCC_CFGR_SW_Msk; RCC->CFGR |= 2 << RCC_CFGR_SW_Pos; /* Wait for clock to switch over */ while ((RCC->CFGR & RCC_CFGR_SWS_Msk)>>RCC_CFGR_SWS_Pos != 2) ; } static void led_setup(void) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; GPIOA->MODER |= (1<BSRR = 1<<0; else GPIOB->BSRR = 1<<16; } static void spi_flash_setup(void) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; GPIOB->MODER &= ~GPIO_MODER_MODER3_Msk & ~GPIO_MODER_MODER4_Msk & ~GPIO_MODER_MODER5_Msk & ~GPIO_MODER_MODER0_Msk; GPIOB->MODER |= (2<OSPEEDR &= ~GPIO_OSPEEDR_OSPEED3_Msk & ~GPIO_OSPEEDR_OSPEED4_Msk & ~GPIO_OSPEEDR_OSPEED5_Msk & ~GPIO_OSPEEDR_OSPEED0_Msk; GPIOB->OSPEEDR |= (2<AFR[0] &= ~GPIO_AFRL_AFSEL3_Msk & ~GPIO_AFRL_AFSEL4_Msk & ~GPIO_AFRL_AFSEL5_Msk; GPIOB->AFR[0] |= (5<APB2ENR |= RCC_APB2ENR_SPI1EN; RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST; RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST; spif_init(&spif, 256, SPI1, &spi_flash_if_set_cs); } /* SPI flash test routine to be called from gdb */ #ifdef SPI_FLASH_TEST void spi_flash_test(void) { spif_clear_mem(&spif); uint32_t buf[1024]; for (size_t addr=0; addr<0x10000; addr += sizeof(buf)) { for (size_t i=0; iAHB1ENR |= RCC_AHB1ENR_GPIOCEN; GPIOC->MODER &= ~GPIO_MODER_MODER9_Msk; GPIOC->MODER |= (2<AFR[1] &= ~GPIO_AFRH_AFSEL9_Msk; GPIOC->OSPEEDR |= (3<CFGR |= (6<MODER &= ~GPIO_MODER_MODER8_Msk; GPIOA->MODER |= (2<AFR[1] &= ~GPIO_AFRH_AFSEL8_Msk; GPIOA->AFR[1] |= 1<ODR ^= 1<<6; } if (adc_fft_buf_ready_idx != -1) { memcpy(adc_fft_buf[!adc_fft_buf_ready_idx], adc_fft_buf[adc_fft_buf_ready_idx] + FMEAS_FFT_LEN/2, sizeof(adc_fft_buf[0][0]) * FMEAS_FFT_LEN/2); #if 0 float out; if (adc_buf_measure_freq(adc_fft_buf[adc_fft_buf_ready_idx], &out)) { measurement_errors++; debug_last_freq = -1; } else { debug_last_freq = out; /* dsss_demod_init(&demod_state); dsss_demod_step(&demod_state, out, freq_sample_ts); */ } #endif freq_sample_ts++; /* TODO: also increase in case of freq measurement error? */ adc_fft_buf_ready_idx = -1; } } return 0; }