Start with integration of everything
This commit is contained in:
parent
0cd07d397f
commit
0af1a534e2
22 changed files with 2298 additions and 145 deletions
|
|
@ -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();
|
||||
adc_init();
|
||||
|
||||
gpio_set(GPIOA, GPIO6);
|
||||
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;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
gpio_toggle(GPIOA, GPIO6 | GPIO7);
|
||||
for (int i = 0; i < 6000000; i++)
|
||||
__asm__("nop");
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue