diff options
Diffstat (limited to 'controller/fw/src/main.c')
-rw-r--r-- | controller/fw/src/main.c | 143 |
1 files changed, 119 insertions, 24 deletions
diff --git a/controller/fw/src/main.c b/controller/fw/src/main.c index 3131df1..58977f7 100644 --- a/controller/fw/src/main.c +++ b/controller/fw/src/main.c @@ -1,45 +1,126 @@ #include <stdbool.h> +#include <stdint.h> +#include <assert.h> -#include <libopencm3/stm32/rcc.h> -#include <libopencm3/stm32/spi.h> -#include <libopencm3/stm32/gpio.h> +#include <stm32f407xx.h> +#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) { - rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]); - rcc_periph_clock_enable(RCC_GPIOA); - rcc_periph_clock_enable(RCC_GPIOB); - rcc_periph_clock_enable(RCC_SPI1); + /* 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 2 -> 168 MHz (max freq for our chip) */ +#define PLL_P 2 + /* Aux clock for USB OTG, SDIO, RNG: divide VCO frequency (336 MHz) by 7 -> 48 MHz (required by USB OTG) */ +#define PLL_Q 7 + + 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 4 */ + RCC->CFGR |= (5 << RCC_CFGR_PPRE1_Pos); + /* set ABP2 prescaler to 2 */ + RCC->CFGR |= (0x4 << RCC_CFGR_PPRE2_Pos); + + /* 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); + RCC->PLLCFGR = (PLL_M<<RCC_PLLCFGR_PLLM_Pos) + | (PLL_N << RCC_PLLCFGR_PLLM_Pos) + | ((PLL_P/2 - 1) << RCC_PLLCFGR_PLLP_Pos) + | (PLL_Q << RCC_PLLCFGR_PLLQ_Pos) + | RCC_PLLCFGR_PLLSRC; /* select HSE as PLL source */ + RCC->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<<FLASH_ACR_LATENCY); + + /* Select PLL as system clock source */ + RCC->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) { - gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO6 | GPIO7); + GPIOA->MODER |= (1<<GPIO_MODER_MODER6_Pos) | (1<<GPIO_MODER_MODER7_Pos); } static void spi_flash_if_set_cs(bool val) { if (val) - gpio_set(GPIOB, GPIO0); + GPIOB->BSRR = 1<<0; else - gpio_clear(GPIOB, GPIO0); + GPIOB->BSRR = 1<<16; } static void spi_flash_setup(void) { - gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO3 | GPIO4 | GPIO5); /* SPI flash SCK/MISO/MOSI */ - gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO0); /* SPI flash CS */ - gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO0 | GPIO3 | GPIO4 | GPIO5); - gpio_set_af(GPIOB, 5, GPIO3 | GPIO4 | GPIO5); + GPIOB->MODER &= ~GPIO_MODER_MODER3_Msk & ~GPIO_MODER_MODER4_Msk & ~GPIO_MODER_MODER5_Msk & ~GPIO_MODER_MODER0_Msk; + GPIOB->MODER |= (2<<GPIO_MODER_MODER3_Pos) /* SCK */ + | (2<<GPIO_MODER_MODER4_Pos) /* MISO */ + | (2<<GPIO_MODER_MODER5_Pos) /* MOSI */ + | (1<<GPIO_MODER_MODER0_Pos); /* CS */ + + GPIOB->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED3_Msk & ~GPIO_OSPEEDR_OSPEED4_Msk + & ~GPIO_OSPEEDR_OSPEED5_Msk & ~GPIO_OSPEEDR_OSPEED0_Msk; + GPIOB->OSPEEDR |= (2<<GPIO_OSPEEDR_OSPEED3_Pos) /* SCK */ + | (2<<GPIO_OSPEEDR_OSPEED4_Pos) /* MISO */ + | (2<<GPIO_OSPEEDR_OSPEED5_Pos) /* MOSI */ + | (2<<GPIO_OSPEEDR_OSPEED0_Pos); /* CS */ + + GPIOB->AFR[0] &= ~GPIO_AFRL_AFSEL3_Msk & ~GPIO_AFRL_AFSEL4_Msk & ~GPIO_AFRL_AFSEL5_Msk; + GPIOB->AFR[0] |= (5<<GPIO_AFRL_AFSEL3_Pos) | (5<<GPIO_AFRL_AFSEL4_Pos) | (5<<GPIO_AFRL_AFSEL5_Pos); + + RCC->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); @@ -48,7 +129,7 @@ void spi_flash_test(void) { for (size_t i=0; i<sizeof(buf); i+= sizeof(buf[0])) buf[i/sizeof(buf[0])] = addr + i; - spif_write(&spif, addr, sizeof(buf), (char *)buf); + spif_write(&spif, addr, sizeof(buf), (char *)buf); } for (size_t i=0; i<sizeof(buf)/sizeof(buf[0]); i++) @@ -56,21 +137,35 @@ void spi_flash_test(void) { spif_read(&spif, 0x1030, sizeof(buf), (char *)buf); asm volatile ("bkpt"); } -*/ +#endif + +static unsigned int measurement_errors = 0; +static struct dsss_demod_state demod_state; +static uint32_t freq_sample_ts = 0; int main(void) { clock_setup(); led_setup(); spi_flash_setup(); - - gpio_set(GPIOA, GPIO6); - - while (1) { - gpio_toggle(GPIOA, GPIO6 | GPIO7); - for (int i = 0; i < 6000000; i++) - __asm__("nop"); + adc_init(); + + while (23) { + if (adc_fft_buf_ready_idx != -1) { + float out; + if (adc_buf_measure_freq(adc_fft_buf[adc_fft_buf_ready_idx], &out)) { + measurement_errors++; + continue; + } + + dsss_demod_init(&demod_state); + dsss_demod_step(&demod_state, out, freq_sample_ts); + + freq_sample_ts++; /* TODO: also increase in case of freq measurement error? */ + adc_fft_buf_ready_idx = -1; + } } return 0; } + |